BscScan - Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 174 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer From | 45325058 | 11 mins ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45323639 | 1 hr ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45322427 | 2 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45322000 | 2 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45321012 | 3 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45320710 | 3 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45319803 | 4 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45319406 | 4 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45318285 | 5 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45318115 | 5 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45297234 | 23 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45297108 | 23 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45296631 | 23 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45296320 | 24 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45293878 | 26 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45291143 | 28 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45290906 | 28 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45290867 | 28 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45290846 | 28 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45273490 | 43 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45271073 | 45 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45269349 | 46 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45268503 | 47 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45268457 | 47 hrs ago | IN | 0 BNB | 0.00009493 | ||||
| Transfer From | 45268393 | 47 hrs ago | IN | 0 BNB | 0.00009493 |
Loading...
Loading
Contract Name:
TOPNFT
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/**
*Submitted for verification at BscScan.com on 2024-11-11
*/
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
/**
* @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.
*
* The initial owner is set to the address provided by the deployer. 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;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling 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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_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);
}
}
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* 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[ERC 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);
}
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.20;
/**
* @dev Required interface of an ERC-721 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 ERC-721 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 ERC-721
* 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 address zero.
*
* 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);
}
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.20;
/**
* @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);
}
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.20;
/**
* @title ERC-721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC-721 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);
}
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/utils/ERC721Utils.sol)
pragma solidity ^0.8.20;
/**
* @dev Library that provide common ERC-721 utility functions.
*
* See https://eips.ethereum.org/EIPS/eip-721[ERC-721].
*
* _Available since v5.1._
*/
library ERC721Utils {
/**
* @dev Performs an acceptance check for the provided `operator` by calling {IERC721-onERC721Received}
* on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`).
*
* The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA).
* Otherwise, the recipient must implement {IERC721Receiver-onERC721Received} and return the acceptance magic value to accept
* the transfer.
*/
function checkOnERC721Received(
address operator,
address from,
address to,
uint256 tokenId,
bytes memory data
) internal {
if (to.code.length > 0) {
try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) {
if (retval != IERC721Receiver.onERC721Received.selector) {
// Token rejected
revert IERC721Errors.ERC721InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
// non-IERC721Receiver implementer
revert IERC721Errors.ERC721InvalidReceiver(to);
} else {
assembly ("memory-safe") {
revert(add(32, reason), mload(reason))
}
}
}
}
}
}
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)
pragma solidity ^0.8.20;
/**
* @dev Helper library for emitting standardized panic codes.
*
* ```solidity
* contract Example {
* using Panic for uint256;
*
* // Use any of the declared internal constants
* function foo() { Panic.GENERIC.panic(); }
*
* // Alternatively
* function foo() { Panic.panic(Panic.GENERIC); }
* }
* ```
*
* Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
*
* _Available since v5.1._
*/
// slither-disable-next-line unused-state
library Panic {
/// @dev generic / unspecified error
uint256 internal constant GENERIC = 0x00;
/// @dev used by the assert() builtin
uint256 internal constant ASSERT = 0x01;
/// @dev arithmetic underflow or overflow
uint256 internal constant UNDER_OVERFLOW = 0x11;
/// @dev division or modulo by zero
uint256 internal constant DIVISION_BY_ZERO = 0x12;
/// @dev enum conversion error
uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
/// @dev invalid encoding in storage
uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
/// @dev empty array pop
uint256 internal constant EMPTY_ARRAY_POP = 0x31;
/// @dev array out of bounds access
uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
/// @dev resource error (too large allocation or too large array)
uint256 internal constant RESOURCE_ERROR = 0x41;
/// @dev calling invalid internal function
uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;
/// @dev Reverts with a panic code. Recommended to use with
/// the internal constants with predefined codes.
function panic(uint256 code) internal pure {
assembly ("memory-safe") {
mstore(0x00, 0x4e487b71)
mstore(0x20, code)
revert(0x1c, 0x24)
}
}
}
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.20;
/**
* @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeCast {
/**
* @dev Value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
/**
* @dev An int value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedIntToUint(int256 value);
/**
* @dev Value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
/**
* @dev An uint value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedUintToInt(uint256 value);
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
/**
* @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
*/
function toUint(bool b) internal pure returns (uint256 u) {
assembly ("memory-safe") {
u := iszero(iszero(b))
}
}
}
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an success flag (no overflow).
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow).
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow).
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
*
* IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
* However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
* one branch when needed, making this function more expensive.
*/
function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
unchecked {
// branchless ternary works because:
// b ^ (a ^ b) == a
// b ^ 0 == b
return b ^ ((a ^ b) * SafeCast.toUint(condition));
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return ternary(a > b, a, b);
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return ternary(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 towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
Panic.panic(Panic.DIVISION_BY_ZERO);
}
// The following calculation ensures accurate ceiling division without overflow.
// Since a is non-zero, (a - 1) / b will not overflow.
// The largest possible result occurs when (a - 1) / b is type(uint256).max,
// but the largest value we can obtain is type(uint256).max - 1, which happens
// when a = type(uint256).max and b = 1.
unchecked {
return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
}
}
/**
* @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
*
* 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²⁵⁶ and mod 2²⁵⁶ - 1, then use
// the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2²⁵⁶ + prod0.
uint256 prod0 = x * y; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
if (denominator <= prod1) {
Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));
}
///////////////////////////////////////////////
// 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.
uint256 twos = denominator & (0 - denominator);
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²⁵⁶ / 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²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
// that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv ≡ 1 mod 2⁴.
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⁸
inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
inverse *= 2 - denominator * inverse; // inverse mod 2³²
inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶
// 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²⁵⁶. Since the preconditions guarantee that the outcome is
// less than 2²⁵⁶, 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;
}
}
/**
* @dev 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) {
return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
}
/**
* @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
*
* If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
* If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
*
* If the input value is not inversible, 0 is returned.
*
* NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
* inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
*/
function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
unchecked {
if (n == 0) return 0;
// The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
// Used to compute integers x and y such that: ax + ny = gcd(a, n).
// When the gcd is 1, then the inverse of a modulo n exists and it's x.
// ax + ny = 1
// ax = 1 + (-y)n
// ax ≡ 1 (mod n) # x is the inverse of a modulo n
// If the remainder is 0 the gcd is n right away.
uint256 remainder = a % n;
uint256 gcd = n;
// Therefore the initial coefficients are:
// ax + ny = gcd(a, n) = n
// 0a + 1n = n
int256 x = 0;
int256 y = 1;
while (remainder != 0) {
uint256 quotient = gcd / remainder;
(gcd, remainder) = (
// The old remainder is the next gcd to try.
remainder,
// Compute the next remainder.
// Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
// where gcd is at most n (capped to type(uint256).max)
gcd - remainder * quotient
);
(x, y) = (
// Increment the coefficient of a.
y,
// Decrement the coefficient of n.
// Can overflow, but the result is casted to uint256 so that the
// next value of y is "wrapped around" to a value between 0 and n - 1.
x - y * int256(quotient)
);
}
if (gcd != 1) return 0; // No inverse exists.
return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
}
}
/**
* @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
*
* From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
* prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
* `a**(p-2)` is the modular multiplicative inverse of a in Fp.
*
* NOTE: this function does NOT check that `p` is a prime greater than `2`.
*/
function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
unchecked {
return Math.modExp(a, p - 2, p);
}
}
/**
* @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
*
* Requirements:
* - modulus can't be zero
* - underlying staticcall to precompile must succeed
*
* IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
* sure the chain you're using it on supports the precompiled contract for modular exponentiation
* at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
* the underlying function will succeed given the lack of a revert, but the result may be incorrectly
* interpreted as 0.
*/
function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
(bool success, uint256 result) = tryModExp(b, e, m);
if (!success) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
return result;
}
/**
* @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
* It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
* to operate modulo 0 or if the underlying precompile reverted.
*
* IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
* you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
* https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
* of a revert, but the result may be incorrectly interpreted as 0.
*/
function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {
if (m == 0) return (false, 0);
assembly ("memory-safe") {
let ptr := mload(0x40)
// | Offset | Content | Content (Hex) |
// |-----------|------------|--------------------------------------------------------------------|
// | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x60:0x7f | value of b | 0x<.............................................................b> |
// | 0x80:0x9f | value of e | 0x<.............................................................e> |
// | 0xa0:0xbf | value of m | 0x<.............................................................m> |
mstore(ptr, 0x20)
mstore(add(ptr, 0x20), 0x20)
mstore(add(ptr, 0x40), 0x20)
mstore(add(ptr, 0x60), b)
mstore(add(ptr, 0x80), e)
mstore(add(ptr, 0xa0), m)
// Given the result < m, it's guaranteed to fit in 32 bytes,
// so we can use the memory scratch space located at offset 0.
success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
result := mload(0x00)
}
}
/**
* @dev Variant of {modExp} that supports inputs of arbitrary length.
*/
function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {
(bool success, bytes memory result) = tryModExp(b, e, m);
if (!success) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
return result;
}
/**
* @dev Variant of {tryModExp} that supports inputs of arbitrary length.
*/
function tryModExp(
bytes memory b,
bytes memory e,
bytes memory m
) internal view returns (bool success, bytes memory result) {
if (_zeroBytes(m)) return (false, new bytes(0));
uint256 mLen = m.length;
// Encode call args in result and move the free memory pointer
result = abi.encodePacked(b.length, e.length, mLen, b, e, m);
assembly ("memory-safe") {
let dataPtr := add(result, 0x20)
// Write result on top of args to avoid allocating extra memory.
success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
// Overwrite the length.
// result.length > returndatasize() is guaranteed because returndatasize() == m.length
mstore(result, mLen)
// Set the memory pointer after the returned data.
mstore(0x40, add(dataPtr, mLen))
}
}
/**
* @dev Returns whether the provided byte array is zero.
*/
function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
for (uint256 i = 0; i < byteArray.length; ++i) {
if (byteArray[i] != 0) {
return false;
}
}
return true;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* This method is based on Newton's method for computing square roots; the algorithm is restricted to only
* using integer operations.
*/
function sqrt(uint256 a) internal pure returns (uint256) {
unchecked {
// Take care of easy edge cases when a == 0 or a == 1
if (a <= 1) {
return a;
}
// In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
// sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
// the current value as `ε_n = | x_n - sqrt(a) |`.
//
// For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
// of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
// bigger than any uint256.
//
// By noticing that
// `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
// we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
// to the msb function.
uint256 aa = a;
uint256 xn = 1;
if (aa >= (1 << 128)) {
aa >>= 128;
xn <<= 64;
}
if (aa >= (1 << 64)) {
aa >>= 64;
xn <<= 32;
}
if (aa >= (1 << 32)) {
aa >>= 32;
xn <<= 16;
}
if (aa >= (1 << 16)) {
aa >>= 16;
xn <<= 8;
}
if (aa >= (1 << 8)) {
aa >>= 8;
xn <<= 4;
}
if (aa >= (1 << 4)) {
aa >>= 4;
xn <<= 2;
}
if (aa >= (1 << 2)) {
xn <<= 1;
}
// We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
//
// We can refine our estimation by noticing that the middle of that interval minimizes the error.
// If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
// This is going to be our x_0 (and ε_0)
xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)
// From here, Newton's method give us:
// x_{n+1} = (x_n + a / x_n) / 2
//
// One should note that:
// x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
// = ((x_n² + a) / (2 * x_n))² - a
// = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
// = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
// = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
// = (x_n² - a)² / (2 * x_n)²
// = ((x_n² - a) / (2 * x_n))²
// ≥ 0
// Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
//
// This gives us the proof of quadratic convergence of the sequence:
// ε_{n+1} = | x_{n+1} - sqrt(a) |
// = | (x_n + a / x_n) / 2 - sqrt(a) |
// = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
// = | (x_n - sqrt(a))² / (2 * x_n) |
// = | ε_n² / (2 * x_n) |
// = ε_n² / | (2 * x_n) |
//
// For the first iteration, we have a special case where x_0 is known:
// ε_1 = ε_0² / | (2 * x_0) |
// ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
// ≤ 2**(2*e-4) / (3 * 2**(e-1))
// ≤ 2**(e-3) / 3
// ≤ 2**(e-3-log2(3))
// ≤ 2**(e-4.5)
//
// For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
// ε_{n+1} = ε_n² / | (2 * x_n) |
// ≤ (2**(e-k))² / (2 * 2**(e-1))
// ≤ 2**(2*e-2*k) / 2**e
// ≤ 2**(e-2*k)
xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above
xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5
xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9
xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18
xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36
xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72
// Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
// ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
// sqrt(a) or sqrt(a) + 1.
return xn - SafeCast.toUint(xn > a / xn);
}
}
/**
* @dev 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
uint256 exp;
unchecked {
exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);
value >>= exp;
result += exp;
exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);
value >>= exp;
result += exp;
exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);
value >>= exp;
result += exp;
exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);
value >>= exp;
result += exp;
exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);
value >>= exp;
result += exp;
exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);
value >>= exp;
result += exp;
exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);
value >>= exp;
result += exp;
result += SafeCast.toUint(value > 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* 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;
uint256 isGt;
unchecked {
isGt = SafeCast.toUint(value > (1 << 128) - 1);
value >>= isGt * 128;
result += isGt * 16;
isGt = SafeCast.toUint(value > (1 << 64) - 1);
value >>= isGt * 64;
result += isGt * 8;
isGt = SafeCast.toUint(value > (1 << 32) - 1);
value >>= isGt * 32;
result += isGt * 4;
isGt = SafeCast.toUint(value > (1 << 16) - 1);
value >>= isGt * 16;
result += isGt * 2;
result += SafeCast.toUint(value > (1 << 8) - 1);
}
return result;
}
/**
* @dev Return the log in base 256, 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
*
* IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
* However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
* one branch when needed, making this function more expensive.
*/
function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) {
unchecked {
// branchless ternary works because:
// b ^ (a ^ b) == a
// b ^ 0 == b
return b ^ ((a ^ b) * int256(SafeCast.toUint(condition)));
}
}
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return ternary(a > b, a, b);
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return ternary(a < b, a, b);
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson.
// Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift,
// taking advantage of the most significant (or "sign" bit) in two's complement representation.
// This opcode adds new most significant bits set to the value of the previous most significant bit. As a result,
// the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative).
int256 mask = n >> 255;
// A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it.
return uint256((n + mask) ^ mask);
}
}
}
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Strings.sol)
pragma solidity ^0.8.20;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
/**
* @dev The `value` string doesn't fit in the specified `length`.
*/
error StringsInsufficientHexLength(uint256 value, uint256 length);
/**
* @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;
assembly ("memory-safe") {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly ("memory-safe") {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
/**
* @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) {
uint256 localValue = value;
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
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);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal
* representation, according to EIP-55.
*/
function toChecksumHexString(address addr) internal pure returns (string memory) {
bytes memory buffer = bytes(toHexString(addr));
// hash the hex part of buffer (skip length + 2 bytes, length 40)
uint256 hashValue;
assembly ("memory-safe") {
hashValue := shr(96, keccak256(add(buffer, 0x22), 40))
}
for (uint256 i = 41; i > 1; --i) {
// possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f)
if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) {
// case shift by xoring with 0x20
buffer[i] ^= 0x20;
}
hashValue >>= 4;
}
return string(buffer);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 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);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.20;
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC-721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
mapping(uint256 tokenId => address) private _owners;
mapping(address owner => uint256) private _balances;
mapping(uint256 tokenId => address) private _tokenApprovals;
mapping(address owner => mapping(address operator => 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 returns (uint256) {
if (owner == address(0)) {
revert ERC721InvalidOwner(address(0));
}
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual returns (address) {
return _requireOwned(tokenId);
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
_requireOwned(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string.concat(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 {
_approve(to, tokenId, _msgSender());
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual returns (address) {
_requireOwned(tokenId);
return _getApproved(tokenId);
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(address from, address to, uint256 tokenId) public virtual {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
// Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists
// (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.
address previousOwner = _update(to, tokenId, _msgSender());
if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
transferFrom(from, to, tokenId);
ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data);
}
/**
* @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
*
* IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
* core ERC-721 logic MUST be matched with the use of {_increaseBalance} to keep balances
* consistent with ownership. The invariant to preserve is that for any address `a` the value returned by
* `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.
*/
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
/**
* @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.
*/
function _getApproved(uint256 tokenId) internal view virtual returns (address) {
return _tokenApprovals[tokenId];
}
/**
* @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in
* particular (ignoring whether it is owned by `owner`).
*
* WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
* assumption.
*/
function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
return
spender != address(0) &&
(owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
}
/**
* @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.
* Reverts if:
* - `spender` does not have approval from `owner` for `tokenId`.
* - `spender` does not have approval to manage all of `owner`'s assets.
*
* WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
* assumption.
*/
function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
if (!_isAuthorized(owner, spender, tokenId)) {
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else {
revert ERC721InsufficientApproval(spender, tokenId);
}
}
}
/**
* @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
*
* NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that
* a uint256 would ever overflow from increments when these increments are bounded to uint128 values.
*
* WARNING: Increasing an account's balance using this function tends to be paired with an override of the
* {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership
* remain consistent with one another.
*/
function _increaseBalance(address account, uint128 value) internal virtual {
unchecked {
_balances[account] += value;
}
}
/**
* @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner
* (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.
*
* The `auth` argument is optional. If the value passed is non 0, then this function will check that
* `auth` is either the owner of the token, or approved to operate on the token (by the owner).
*
* Emits a {Transfer} event.
*
* NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.
*/
function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
address from = _ownerOf(tokenId);
// Perform (optional) operator check
if (auth != address(0)) {
_checkAuthorized(from, auth, tokenId);
}
// Execute the update
if (from != address(0)) {
// Clear approval. No need to re-authorize or emit the Approval event
_approve(address(0), tokenId, address(0), false);
unchecked {
_balances[from] -= 1;
}
}
if (to != address(0)) {
unchecked {
_balances[to] += 1;
}
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
return from;
}
/**
* @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 {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner != address(0)) {
revert ERC721InvalidSender(address(0));
}
}
/**
* @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.
*
* 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 {
_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);
ERC721Utils.checkOnERC721Received(_msgSender(), address(0), to, tokenId, data);
}
/**
* @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 {
address previousOwner = _update(address(0), tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(address from, address to, uint256 tokenId) internal {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients
* are aware of the ERC-721 standard 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 like {safeTransferFrom} in the sense that it invokes
* {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `tokenId` token must exist and be owned by `from`.
* - `to` cannot be the zero address.
* - `from` cannot be the zero address.
* - 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) internal {
_safeTransfer(from, to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
_transfer(from, to, tokenId);
ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is
* either the owner of the token, or approved to operate on all tokens held by this owner.
*
* Emits an {Approval} event.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address to, uint256 tokenId, address auth) internal {
_approve(to, tokenId, auth, true);
}
/**
* @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not
* emitted in the context of transfers.
*/
function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {
// Avoid reading the owner unless necessary
if (emitEvent || auth != address(0)) {
address owner = _requireOwned(tokenId);
// We do not use _isAuthorized because single-token approvals should not be able to call approve
if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
revert ERC721InvalidApprover(auth);
}
if (emitEvent) {
emit Approval(owner, to, tokenId);
}
}
_tokenApprovals[tokenId] = to;
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Requirements:
* - operator can't be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
if (operator == address(0)) {
revert ERC721InvalidOperator(operator);
}
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).
* Returns the owner.
*
* Overrides to ownership logic should be done to {_ownerOf}.
*/
function _requireOwned(uint256 tokenId) internal view returns (address) {
address owner = _ownerOf(tokenId);
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
return owner;
}
}
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.20;
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/extensions/ERC721Enumerable.sol)
pragma solidity ^0.8.20;
/**
* @dev This implements an optional extension of {ERC721} defined in the ERC that adds enumerability
* of all the token ids in the contract as well as all token ids owned by each account.
*
* CAUTION: {ERC721} extensions that implement custom `balanceOf` logic, such as {ERC721Consecutive},
* interfere with enumerability and should not be used together with {ERC721Enumerable}.
*/
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
mapping(address owner => mapping(uint256 index => uint256)) private _ownedTokens;
mapping(uint256 tokenId => uint256) private _ownedTokensIndex;
uint256[] private _allTokens;
mapping(uint256 tokenId => uint256) private _allTokensIndex;
/**
* @dev An `owner`'s token query was out of bounds for `index`.
*
* NOTE: The owner being `address(0)` indicates a global out of bounds index.
*/
error ERC721OutOfBoundsIndex(address owner, uint256 index);
/**
* @dev Batch mint is not allowed.
*/
error ERC721EnumerableForbiddenBatchMint();
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) {
if (index >= balanceOf(owner)) {
revert ERC721OutOfBoundsIndex(owner, index);
}
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual returns (uint256) {
if (index >= totalSupply()) {
revert ERC721OutOfBoundsIndex(address(0), index);
}
return _allTokens[index];
}
/**
* @dev See {ERC721-_update}.
*/
function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {
address previousOwner = super._update(to, tokenId, auth);
if (previousOwner == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (previousOwner != to) {
_removeTokenFromOwnerEnumeration(previousOwner, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (previousOwner != to) {
_addTokenToOwnerEnumeration(to, tokenId);
}
return previousOwner;
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = balanceOf(to) - 1;
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = balanceOf(from);
uint256 tokenIndex = _ownedTokensIndex[tokenId];
mapping(uint256 index => uint256) storage _ownedTokensByOwner = _ownedTokens[from];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokensByOwner[lastTokenIndex];
_ownedTokensByOwner[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[tokenId];
delete _ownedTokensByOwner[lastTokenIndex];
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
/**
* See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch
*/
function _increaseBalance(address account, uint128 amount) internal virtual override {
if (amount > 0) {
revert ERC721EnumerableForbiddenBatchMint();
}
super._increaseBalance(account, amount);
}
}
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/utils/ERC721Holder.sol)
pragma solidity ^0.8.20;
/**
* @dev Implementation of the {IERC721Receiver} interface.
*
* Accepts all token transfers.
* Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or
* {IERC721-setApprovalForAll}.
*/
abstract contract ERC721Holder is IERC721Receiver {
/**
* @dev See {IERC721Receiver-onERC721Received}.
*
* Always returns `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) {
return this.onERC721Received.selector;
}
}
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
pragma solidity ^0.8.20;
contract TOPNFT is Ownable, ERC721Enumerable ,ERC721Holder, Pausable {
using Strings for uint256;
string private _customBaseURI;
uint256 private totalMinted;
uint256 public TOTAL_COUNT = 500;
address public initialOwnerAddress = address(0x9Df5dAfd0AC54b2A75Cce36F9CDbC7da5Ba9eBb0);
event PreMint(address indexed minter, uint256 count);
constructor() ERC721("TOP MINER", "TOP MINER") Ownable(initialOwnerAddress) {
_customBaseURI = "https://www.topminer.info/nft/metadata/";
totalMinted = 0;
}
function totalSupply() public view override returns (uint256) {
return totalMinted;
}
function _baseURI() internal view virtual override returns (string memory) {
return _customBaseURI;
}
function setBaseURI(string memory newBaseURI) external onlyOwner {
_customBaseURI = newBaseURI;
}
function setTotalCount(uint256 count) external onlyOwner {
TOTAL_COUNT = TOTAL_COUNT + count;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require( _ownerOf(tokenId) != address(0) , "ATPNFT: URI query for nonexistent token");
return string(abi.encodePacked(_baseURI(), tokenId.toString()));
}
function burn(uint256 tokenId) external onlyOwner {
_burn(tokenId);
totalMinted--;
}
function mint(address to, uint256 tokenId) external onlyOwner whenNotPaused{
_safeMint(to, tokenId);
}
function preMint(address to,uint256 _count) external onlyOwner whenNotPaused{
require(_count > 0, "NFT: zero count");
require(totalMinted + _count <= TOTAL_COUNT, "NFT: not enough NFT");
for (uint256 i = 0; i < _count; i++) {
uint256 tokenId = totalMinted + 1;
_safeMint(to, tokenId);
totalMinted++;
}
emit PreMint( to , _count);
}
function depositNFT(address nftContract, uint256 tokenId) public {
IERC721(nftContract).safeTransferFrom(msg.sender, address(this), tokenId);
}
function withdrawNFT(address nftContract, uint256 tokenId, address to) public onlyOwner {
IERC721(nftContract).safeTransferFrom(address(this), to, tokenId);
}
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC721EnumerableForbiddenBatchMint","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ERC721OutOfBoundsIndex","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"PreMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"TOTAL_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"depositNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialOwnerAddress","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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","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":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"preMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"setTotalCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawNFT","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526101f4600e55739df5dafd0ac54b2a75cce36f9cdbc7da5ba9ebb0600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200006a575f80fd5b506040518060400160405280600981526020017f544f50204d494e455200000000000000000000000000000000000000000000008152506040518060400160405280600981526020017f544f50204d494e45520000000000000000000000000000000000000000000000815250600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200016c575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620001639190620002f9565b60405180910390fd5b6200017d81620001f560201b60201c565b5081600190816200018f919062000578565b508060029081620001a1919062000578565b5050505f600b5f6101000a81548160ff02191690831515021790555060405180606001604052806027815260200162003a4160279139600c9081620001e7919062000578565b505f600d819055506200065c565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620002e182620002b6565b9050919050565b620002f381620002d5565b82525050565b5f6020820190506200030e5f830184620002e8565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200039057607f821691505b602082108103620003a657620003a56200034b565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200040a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003cd565b620004168683620003cd565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620004606200045a62000454846200042e565b62000437565b6200042e565b9050919050565b5f819050919050565b6200047b8362000440565b620004936200048a8262000467565b848454620003d9565b825550505050565b5f90565b620004a96200049b565b620004b681848462000470565b505050565b5b81811015620004dd57620004d15f826200049f565b600181019050620004bc565b5050565b601f8211156200052c57620004f681620003ac565b6200050184620003be565b8101602085101562000511578190505b620005296200052085620003be565b830182620004bb565b50505b505050565b5f82821c905092915050565b5f6200054e5f198460080262000531565b1980831691505092915050565b5f6200056883836200053d565b9150826002028217905092915050565b620005838262000314565b67ffffffffffffffff8111156200059f576200059e6200031e565b5b620005ab825462000378565b620005b8828285620004e1565b5f60209050601f831160018114620005ee575f8415620005d9578287015190505b620005e585826200055b565b86555062000654565b601f198416620005fe86620003ac565b5f5b82811015620006275784890151825560018201915060208501945060208101905062000600565b8683101562000647578489015162000643601f8916826200053d565b8355505b6001600288020188555050505b505050505050565b6133d7806200066a5f395ff3fe608060405234801561000f575f80fd5b50600436106101ed575f3560e01c806355f804b31161010d57806395d89b41116100a0578063c87b56dd1161006f578063c87b56dd14610563578063d5a172f214610593578063e985e9c5146105b1578063f2fde38b146105e1576101ed565b806395d89b41146104f15780639b5b9b181461050f578063a22cb4651461052b578063b88d4fde14610547576101ed565b806370a08231116100dc57806370a082311461048f578063715018a6146104bf5780638456cb59146104c95780638da5cb5b146104d3576101ed565b806355f804b31461040957806357df110a146104255780635c975abb146104415780636352211e1461045f576101ed565b806323b872dd1161018557806340c10f191161015457806340c10f191461038557806342842e0e146103a157806342966c68146103bd5780634f6ccce7146103d9576101ed565b806323b872dd14610313578063290c292d1461032f5780632f745c591461034b5780633f4ba83a1461037b576101ed565b8063095ea7b3116101c1578063095ea7b31461028b5780630f0beece146102a7578063150b7a02146102c557806318160ddd146102f5576101ed565b8062f2a6ab146101f157806301ffc9a71461020d57806306fdde031461023d578063081812fc1461025b575b5f80fd5b61020b600480360381019061020691906125e9565b6105fd565b005b6102276004803603810190610222919061268e565b610674565b60405161023491906126d3565b60405180910390f35b6102456106ed565b6040516102529190612776565b60405180910390f35b61027560048036038101906102709190612796565b61077d565b60405161028291906127d0565b60405180910390f35b6102a560048036038101906102a091906127e9565b610798565b005b6102af6107ae565b6040516102bc9190612836565b60405180910390f35b6102df60048036038101906102da919061297b565b6107b4565b6040516102ec9190612a0a565b60405180910390f35b6102fd6107c7565b60405161030a9190612836565b60405180910390f35b61032d60048036038101906103289190612a23565b6107d0565b005b610349600480360381019061034491906127e9565b6108cf565b005b610365600480360381019061036091906127e9565b610a17565b6040516103729190612836565b60405180910390f35b610383610abb565b005b61039f600480360381019061039a91906127e9565b610acd565b005b6103bb60048036038101906103b69190612a23565b610aeb565b005b6103d760048036038101906103d29190612796565b610b0a565b005b6103f360048036038101906103ee9190612796565b610b35565b6040516104009190612836565b60405180910390f35b610423600480360381019061041e9190612b11565b610ba7565b005b61043f600480360381019061043a9190612796565b610bc2565b005b610449610be1565b60405161045691906126d3565b60405180910390f35b61047960048036038101906104749190612796565b610bf6565b60405161048691906127d0565b60405180910390f35b6104a960048036038101906104a49190612b58565b610c07565b6040516104b69190612836565b60405180910390f35b6104c7610cbd565b005b6104d1610cd0565b005b6104db610ce2565b6040516104e891906127d0565b60405180910390f35b6104f9610d09565b6040516105069190612776565b60405180910390f35b610529600480360381019061052491906127e9565b610d99565b005b61054560048036038101906105409190612bad565b610e07565b005b610561600480360381019061055c919061297b565b610e1d565b005b61057d60048036038101906105789190612796565b610e42565b60405161058a9190612776565b60405180910390f35b61059b610ef2565b6040516105a891906127d0565b60405180910390f35b6105cb60048036038101906105c69190612beb565b610f17565b6040516105d891906126d3565b60405180910390f35b6105fb60048036038101906105f69190612b58565b610fa5565b005b610605611029565b8273ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b815260040161064293929190612c29565b5f604051808303815f87803b158015610659575f80fd5b505af115801561066b573d5f803e3d5ffd5b50505050505050565b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106e657506106e5826110b0565b5b9050919050565b6060600180546106fc90612c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461072890612c8b565b80156107735780601f1061074a57610100808354040283529160200191610773565b820191905f5260205f20905b81548152906001019060200180831161075657829003601f168201915b5050505050905090565b5f61078782611191565b5061079182611217565b9050919050565b6107aa82826107a5611250565b611257565b5050565b600e5481565b5f63150b7a0260e01b9050949350505050565b5f600d54905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610840575f6040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161083791906127d0565b60405180910390fd5b5f610853838361084e611250565b611269565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108c9578382826040517f64283d7b0000000000000000000000000000000000000000000000000000000081526004016108c093929190612cbb565b60405180910390fd5b50505050565b6108d7611029565b6108df611383565b5f8111610921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091890612d3a565b60405180910390fd5b600e5481600d546109329190612d85565b1115610973576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096a90612e02565b60405180910390fd5b5f5b818110156109c4575f6001600d5461098d9190612d85565b905061099984826113c4565b600d5f8154809291906109ab90612e20565b91905055505080806109bc90612e20565b915050610975565b508173ffffffffffffffffffffffffffffffffffffffff167faa8cea5b9b55c0967a846322a639d3bc70b13695058b5c9cb34928b75b0d20fe82604051610a0b9190612836565b60405180910390a25050565b5f610a2183610c07565b8210610a665782826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610a5d929190612e67565b60405180910390fd5b60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b610ac3611029565b610acb6113e1565b565b610ad5611029565b610add611383565b610ae782826113c4565b5050565b610b0583838360405180602001604052805f815250610e1d565b505050565b610b12611029565b610b1b81611442565b600d5f815480929190610b2d90612e8e565b919050555050565b5f610b3e6107c7565b8210610b83575f826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610b7a929190612e67565b60405180910390fd5b60098281548110610b9757610b96612eb5565b5b905f5260205f2001549050919050565b610baf611029565b80600c9081610bbe919061307f565b5050565b610bca611029565b80600e54610bd89190612d85565b600e8190555050565b5f600b5f9054906101000a900460ff16905090565b5f610c0082611191565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610c78575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610c6f91906127d0565b60405180910390fd5b60045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610cc5611029565b610cce5f6114c4565b565b610cd8611029565b610ce0611585565b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060028054610d1890612c8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4490612c8b565b8015610d8f5780601f10610d6657610100808354040283529160200191610d8f565b820191905f5260205f20905b815481529060010190602001808311610d7257829003601f168201915b5050505050905090565b8173ffffffffffffffffffffffffffffffffffffffff166342842e0e3330846040518463ffffffff1660e01b8152600401610dd693929190612c29565b5f604051808303815f87803b158015610ded575f80fd5b505af1158015610dff573d5f803e3d5ffd5b505050505050565b610e19610e12611250565b83836115e7565b5050565b610e288484846107d0565b610e3c610e33611250565b85858585611750565b50505050565b60605f73ffffffffffffffffffffffffffffffffffffffff16610e64836118fc565b73ffffffffffffffffffffffffffffffffffffffff1603610eba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb1906131be565b60405180910390fd5b610ec2611935565b610ecb836119c5565b604051602001610edc929190613216565b6040516020818303038152906040529050919050565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b610fad611029565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361101d575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161101491906127d0565b60405180910390fd5b611026816114c4565b50565b611031611250565b73ffffffffffffffffffffffffffffffffffffffff1661104f610ce2565b73ffffffffffffffffffffffffffffffffffffffff16146110ae57611072611250565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016110a591906127d0565b60405180910390fd5b565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061117a57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061118a575061118982611a8f565b5b9050919050565b5f8061119c836118fc565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361120e57826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112059190612836565b60405180910390fd5b80915050919050565b5f60055f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b6112648383836001611af8565b505050565b5f80611276858585611cb7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112b9576112b484611ec2565b6112f8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146112f7576112f68185611f06565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113395761133484611fdd565b611378565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461137757611376858561209d565b5b5b809150509392505050565b61138b610be1565b156113c2576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6113dd828260405180602001604052805f815250612121565b5050565b6113e9612144565b5f600b5f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61142b611250565b60405161143891906127d0565b60405180910390a1565b5f61144e5f835f611269565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114c057816040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016114b79190612836565b60405180910390fd5b5050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61158d611383565b6001600b5f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115d0611250565b6040516115dd91906127d0565b60405180910390a1565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361165757816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161164e91906127d0565b60405180910390fd5b8060065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161174391906126d3565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156118f5578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02868685856040518563ffffffff1660e01b81526004016117ae949392919061328b565b6020604051808303815f875af19250505080156117e957506040513d601f19601f820116820180604052508101906117e691906132e9565b60015b61186a573d805f8114611817576040519150601f19603f3d011682016040523d82523d5f602084013e61181c565b606091505b505f81510361186257836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161185991906127d0565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146118f357836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016118ea91906127d0565b60405180910390fd5b505b5050505050565b5f60035f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6060600c805461194490612c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461197090612c8b565b80156119bb5780601f10611992576101008083540402835291602001916119bb565b820191905f5260205f20905b81548152906001019060200180831161199e57829003601f168201915b5050505050905090565b60605f60016119d384612184565b0190505f8167ffffffffffffffff8111156119f1576119f0612857565b5b6040519080825280601f01601f191660200182016040528015611a235781602001600182028036833780820191505090505b5090505f82602001820190505b600115611a84578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611a7957611a78613314565b5b0494505f8503611a30575b819350505050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8080611b3057505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611c62575f611b3f84611191565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611ba957508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611bbc5750611bba8184610f17565b155b15611bfe57826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401611bf591906127d0565b60405180910390fd5b8115611c6057838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360055f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f80611cc2846118fc565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611d0357611d028184866122d5565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d8e57611d425f855f80611af8565b600160045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611e0d57600160045f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460035f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b600980549050600a5f8381526020019081526020015f2081905550600981908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f611f1083610c07565b90505f60085f8481526020019081526020015f205490505f60075f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050828214611faf575f815f8581526020019081526020015f2054905080825f8581526020019081526020015f20819055508260085f8381526020019081526020015f2081905550505b60085f8581526020019081526020015f205f9055805f8481526020019081526020015f205f90555050505050565b5f6001600980549050611ff09190613341565b90505f600a5f8481526020019081526020015f205490505f6009838154811061201c5761201b612eb5565b5b905f5260205f2001549050806009838154811061203c5761203b612eb5565b5b905f5260205f20018190555081600a5f8381526020019081526020015f2081905550600a5f8581526020019081526020015f205f9055600980548061208457612083613374565b5b600190038181905f5260205f20015f9055905550505050565b5f60016120a984610c07565b6120b39190613341565b90508160075f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060085f8481526020019081526020015f2081905550505050565b61212b8383612398565b61213f612136611250565b5f858585611750565b505050565b61214c610be1565b612182576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106121e0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816121d6576121d5613314565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061221d576d04ee2d6d415b85acef8100000000838161221357612212613314565b5b0492506020810190505b662386f26fc10000831061224c57662386f26fc10000838161224257612241613314565b5b0492506010810190505b6305f5e1008310612275576305f5e100838161226b5761226a613314565b5b0492506008810190505b612710831061229a5761271083816122905761228f613314565b5b0492506004810190505b606483106122bd57606483816122b3576122b2613314565b5b0492506002810190505b600a83106122cc576001810190505b80915050919050565b6122e083838361248b565b612393575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361235457806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040161234b9190612836565b60405180910390fd5b81816040517f177e802f00000000000000000000000000000000000000000000000000000000815260040161238a929190612e67565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612408575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016123ff91906127d0565b60405180910390fd5b5f61241483835f611269565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612486575f6040517f73c6ac6e00000000000000000000000000000000000000000000000000000000815260040161247d91906127d0565b60405180910390fd5b505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561254257508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061250357506125028484610f17565b5b8061254157508273ffffffffffffffffffffffffffffffffffffffff1661252983611217565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125858261255c565b9050919050565b6125958161257b565b811461259f575f80fd5b50565b5f813590506125b08161258c565b92915050565b5f819050919050565b6125c8816125b6565b81146125d2575f80fd5b50565b5f813590506125e3816125bf565b92915050565b5f805f60608486031215612600576125ff612554565b5b5f61260d868287016125a2565b935050602061261e868287016125d5565b925050604061262f868287016125a2565b9150509250925092565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61266d81612639565b8114612677575f80fd5b50565b5f8135905061268881612664565b92915050565b5f602082840312156126a3576126a2612554565b5b5f6126b08482850161267a565b91505092915050565b5f8115159050919050565b6126cd816126b9565b82525050565b5f6020820190506126e65f8301846126c4565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612723578082015181840152602081019050612708565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612748826126ec565b61275281856126f6565b9350612762818560208601612706565b61276b8161272e565b840191505092915050565b5f6020820190508181035f83015261278e818461273e565b905092915050565b5f602082840312156127ab576127aa612554565b5b5f6127b8848285016125d5565b91505092915050565b6127ca8161257b565b82525050565b5f6020820190506127e35f8301846127c1565b92915050565b5f80604083850312156127ff576127fe612554565b5b5f61280c858286016125a2565b925050602061281d858286016125d5565b9150509250929050565b612830816125b6565b82525050565b5f6020820190506128495f830184612827565b92915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61288d8261272e565b810181811067ffffffffffffffff821117156128ac576128ab612857565b5b80604052505050565b5f6128be61254b565b90506128ca8282612884565b919050565b5f67ffffffffffffffff8211156128e9576128e8612857565b5b6128f28261272e565b9050602081019050919050565b828183375f83830152505050565b5f61291f61291a846128cf565b6128b5565b90508281526020810184848401111561293b5761293a612853565b5b6129468482856128ff565b509392505050565b5f82601f8301126129625761296161284f565b5b813561297284826020860161290d565b91505092915050565b5f805f806080858703121561299357612992612554565b5b5f6129a0878288016125a2565b94505060206129b1878288016125a2565b93505060406129c2878288016125d5565b925050606085013567ffffffffffffffff8111156129e3576129e2612558565b5b6129ef8782880161294e565b91505092959194509250565b612a0481612639565b82525050565b5f602082019050612a1d5f8301846129fb565b92915050565b5f805f60608486031215612a3a57612a39612554565b5b5f612a47868287016125a2565b9350506020612a58868287016125a2565b9250506040612a69868287016125d5565b9150509250925092565b5f67ffffffffffffffff821115612a8d57612a8c612857565b5b612a968261272e565b9050602081019050919050565b5f612ab5612ab084612a73565b6128b5565b905082815260208101848484011115612ad157612ad0612853565b5b612adc8482856128ff565b509392505050565b5f82601f830112612af857612af761284f565b5b8135612b08848260208601612aa3565b91505092915050565b5f60208284031215612b2657612b25612554565b5b5f82013567ffffffffffffffff811115612b4357612b42612558565b5b612b4f84828501612ae4565b91505092915050565b5f60208284031215612b6d57612b6c612554565b5b5f612b7a848285016125a2565b91505092915050565b612b8c816126b9565b8114612b96575f80fd5b50565b5f81359050612ba781612b83565b92915050565b5f8060408385031215612bc357612bc2612554565b5b5f612bd0858286016125a2565b9250506020612be185828601612b99565b9150509250929050565b5f8060408385031215612c0157612c00612554565b5b5f612c0e858286016125a2565b9250506020612c1f858286016125a2565b9150509250929050565b5f606082019050612c3c5f8301866127c1565b612c4960208301856127c1565b612c566040830184612827565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612ca257607f821691505b602082108103612cb557612cb4612c5e565b5b50919050565b5f606082019050612cce5f8301866127c1565b612cdb6020830185612827565b612ce860408301846127c1565b949350505050565b7f4e46543a207a65726f20636f756e7400000000000000000000000000000000005f82015250565b5f612d24600f836126f6565b9150612d2f82612cf0565b602082019050919050565b5f6020820190508181035f830152612d5181612d18565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612d8f826125b6565b9150612d9a836125b6565b9250828201905080821115612db257612db1612d58565b5b92915050565b7f4e46543a206e6f7420656e6f756768204e4654000000000000000000000000005f82015250565b5f612dec6013836126f6565b9150612df782612db8565b602082019050919050565b5f6020820190508181035f830152612e1981612de0565b9050919050565b5f612e2a826125b6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e5c57612e5b612d58565b5b600182019050919050565b5f604082019050612e7a5f8301856127c1565b612e876020830184612827565b9392505050565b5f612e98826125b6565b91505f8203612eaa57612ea9612d58565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612f3e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612f03565b612f488683612f03565b95508019841693508086168417925050509392505050565b5f819050919050565b5f612f83612f7e612f79846125b6565b612f60565b6125b6565b9050919050565b5f819050919050565b612f9c83612f69565b612fb0612fa882612f8a565b848454612f0f565b825550505050565b5f90565b612fc4612fb8565b612fcf818484612f93565b505050565b5b81811015612ff257612fe75f82612fbc565b600181019050612fd5565b5050565b601f8211156130375761300881612ee2565b61301184612ef4565b81016020851015613020578190505b61303461302c85612ef4565b830182612fd4565b50505b505050565b5f82821c905092915050565b5f6130575f198460080261303c565b1980831691505092915050565b5f61306f8383613048565b9150826002028217905092915050565b613088826126ec565b67ffffffffffffffff8111156130a1576130a0612857565b5b6130ab8254612c8b565b6130b6828285612ff6565b5f60209050601f8311600181146130e7575f84156130d5578287015190505b6130df8582613064565b865550613146565b601f1984166130f586612ee2565b5f5b8281101561311c578489015182556001820191506020850194506020810190506130f7565b868310156131395784890151613135601f891682613048565b8355505b6001600288020188555050505b505050505050565b7f4154504e46543a2055524920717565727920666f72206e6f6e6578697374656e5f8201527f7420746f6b656e00000000000000000000000000000000000000000000000000602082015250565b5f6131a86027836126f6565b91506131b38261314e565b604082019050919050565b5f6020820190508181035f8301526131d58161319c565b9050919050565b5f81905092915050565b5f6131f0826126ec565b6131fa81856131dc565b935061320a818560208601612706565b80840191505092915050565b5f61322182856131e6565b915061322d82846131e6565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f61325d82613239565b6132678185613243565b9350613277818560208601612706565b6132808161272e565b840191505092915050565b5f60808201905061329e5f8301876127c1565b6132ab60208301866127c1565b6132b86040830185612827565b81810360608301526132ca8184613253565b905095945050505050565b5f815190506132e381612664565b92915050565b5f602082840312156132fe576132fd612554565b5b5f61330b848285016132d5565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61334b826125b6565b9150613356836125b6565b925082820390508181111561336e5761336d612d58565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea26469706673582212208bda047cb690fac5297566fd6b14f63bc272b557796d62850f263509bf1445c264736f6c6343000814003368747470733a2f2f7777772e746f706d696e65722e696e666f2f6e66742f6d657461646174612f
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101ed575f3560e01c806355f804b31161010d57806395d89b41116100a0578063c87b56dd1161006f578063c87b56dd14610563578063d5a172f214610593578063e985e9c5146105b1578063f2fde38b146105e1576101ed565b806395d89b41146104f15780639b5b9b181461050f578063a22cb4651461052b578063b88d4fde14610547576101ed565b806370a08231116100dc57806370a082311461048f578063715018a6146104bf5780638456cb59146104c95780638da5cb5b146104d3576101ed565b806355f804b31461040957806357df110a146104255780635c975abb146104415780636352211e1461045f576101ed565b806323b872dd1161018557806340c10f191161015457806340c10f191461038557806342842e0e146103a157806342966c68146103bd5780634f6ccce7146103d9576101ed565b806323b872dd14610313578063290c292d1461032f5780632f745c591461034b5780633f4ba83a1461037b576101ed565b8063095ea7b3116101c1578063095ea7b31461028b5780630f0beece146102a7578063150b7a02146102c557806318160ddd146102f5576101ed565b8062f2a6ab146101f157806301ffc9a71461020d57806306fdde031461023d578063081812fc1461025b575b5f80fd5b61020b600480360381019061020691906125e9565b6105fd565b005b6102276004803603810190610222919061268e565b610674565b60405161023491906126d3565b60405180910390f35b6102456106ed565b6040516102529190612776565b60405180910390f35b61027560048036038101906102709190612796565b61077d565b60405161028291906127d0565b60405180910390f35b6102a560048036038101906102a091906127e9565b610798565b005b6102af6107ae565b6040516102bc9190612836565b60405180910390f35b6102df60048036038101906102da919061297b565b6107b4565b6040516102ec9190612a0a565b60405180910390f35b6102fd6107c7565b60405161030a9190612836565b60405180910390f35b61032d60048036038101906103289190612a23565b6107d0565b005b610349600480360381019061034491906127e9565b6108cf565b005b610365600480360381019061036091906127e9565b610a17565b6040516103729190612836565b60405180910390f35b610383610abb565b005b61039f600480360381019061039a91906127e9565b610acd565b005b6103bb60048036038101906103b69190612a23565b610aeb565b005b6103d760048036038101906103d29190612796565b610b0a565b005b6103f360048036038101906103ee9190612796565b610b35565b6040516104009190612836565b60405180910390f35b610423600480360381019061041e9190612b11565b610ba7565b005b61043f600480360381019061043a9190612796565b610bc2565b005b610449610be1565b60405161045691906126d3565b60405180910390f35b61047960048036038101906104749190612796565b610bf6565b60405161048691906127d0565b60405180910390f35b6104a960048036038101906104a49190612b58565b610c07565b6040516104b69190612836565b60405180910390f35b6104c7610cbd565b005b6104d1610cd0565b005b6104db610ce2565b6040516104e891906127d0565b60405180910390f35b6104f9610d09565b6040516105069190612776565b60405180910390f35b610529600480360381019061052491906127e9565b610d99565b005b61054560048036038101906105409190612bad565b610e07565b005b610561600480360381019061055c919061297b565b610e1d565b005b61057d60048036038101906105789190612796565b610e42565b60405161058a9190612776565b60405180910390f35b61059b610ef2565b6040516105a891906127d0565b60405180910390f35b6105cb60048036038101906105c69190612beb565b610f17565b6040516105d891906126d3565b60405180910390f35b6105fb60048036038101906105f69190612b58565b610fa5565b005b610605611029565b8273ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b815260040161064293929190612c29565b5f604051808303815f87803b158015610659575f80fd5b505af115801561066b573d5f803e3d5ffd5b50505050505050565b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106e657506106e5826110b0565b5b9050919050565b6060600180546106fc90612c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461072890612c8b565b80156107735780601f1061074a57610100808354040283529160200191610773565b820191905f5260205f20905b81548152906001019060200180831161075657829003601f168201915b5050505050905090565b5f61078782611191565b5061079182611217565b9050919050565b6107aa82826107a5611250565b611257565b5050565b600e5481565b5f63150b7a0260e01b9050949350505050565b5f600d54905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610840575f6040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161083791906127d0565b60405180910390fd5b5f610853838361084e611250565b611269565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108c9578382826040517f64283d7b0000000000000000000000000000000000000000000000000000000081526004016108c093929190612cbb565b60405180910390fd5b50505050565b6108d7611029565b6108df611383565b5f8111610921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091890612d3a565b60405180910390fd5b600e5481600d546109329190612d85565b1115610973576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096a90612e02565b60405180910390fd5b5f5b818110156109c4575f6001600d5461098d9190612d85565b905061099984826113c4565b600d5f8154809291906109ab90612e20565b91905055505080806109bc90612e20565b915050610975565b508173ffffffffffffffffffffffffffffffffffffffff167faa8cea5b9b55c0967a846322a639d3bc70b13695058b5c9cb34928b75b0d20fe82604051610a0b9190612836565b60405180910390a25050565b5f610a2183610c07565b8210610a665782826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610a5d929190612e67565b60405180910390fd5b60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b610ac3611029565b610acb6113e1565b565b610ad5611029565b610add611383565b610ae782826113c4565b5050565b610b0583838360405180602001604052805f815250610e1d565b505050565b610b12611029565b610b1b81611442565b600d5f815480929190610b2d90612e8e565b919050555050565b5f610b3e6107c7565b8210610b83575f826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610b7a929190612e67565b60405180910390fd5b60098281548110610b9757610b96612eb5565b5b905f5260205f2001549050919050565b610baf611029565b80600c9081610bbe919061307f565b5050565b610bca611029565b80600e54610bd89190612d85565b600e8190555050565b5f600b5f9054906101000a900460ff16905090565b5f610c0082611191565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610c78575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610c6f91906127d0565b60405180910390fd5b60045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610cc5611029565b610cce5f6114c4565b565b610cd8611029565b610ce0611585565b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060028054610d1890612c8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4490612c8b565b8015610d8f5780601f10610d6657610100808354040283529160200191610d8f565b820191905f5260205f20905b815481529060010190602001808311610d7257829003601f168201915b5050505050905090565b8173ffffffffffffffffffffffffffffffffffffffff166342842e0e3330846040518463ffffffff1660e01b8152600401610dd693929190612c29565b5f604051808303815f87803b158015610ded575f80fd5b505af1158015610dff573d5f803e3d5ffd5b505050505050565b610e19610e12611250565b83836115e7565b5050565b610e288484846107d0565b610e3c610e33611250565b85858585611750565b50505050565b60605f73ffffffffffffffffffffffffffffffffffffffff16610e64836118fc565b73ffffffffffffffffffffffffffffffffffffffff1603610eba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb1906131be565b60405180910390fd5b610ec2611935565b610ecb836119c5565b604051602001610edc929190613216565b6040516020818303038152906040529050919050565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b610fad611029565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361101d575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161101491906127d0565b60405180910390fd5b611026816114c4565b50565b611031611250565b73ffffffffffffffffffffffffffffffffffffffff1661104f610ce2565b73ffffffffffffffffffffffffffffffffffffffff16146110ae57611072611250565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016110a591906127d0565b60405180910390fd5b565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061117a57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061118a575061118982611a8f565b5b9050919050565b5f8061119c836118fc565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361120e57826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112059190612836565b60405180910390fd5b80915050919050565b5f60055f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b6112648383836001611af8565b505050565b5f80611276858585611cb7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112b9576112b484611ec2565b6112f8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146112f7576112f68185611f06565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113395761133484611fdd565b611378565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461137757611376858561209d565b5b5b809150509392505050565b61138b610be1565b156113c2576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6113dd828260405180602001604052805f815250612121565b5050565b6113e9612144565b5f600b5f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61142b611250565b60405161143891906127d0565b60405180910390a1565b5f61144e5f835f611269565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114c057816040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016114b79190612836565b60405180910390fd5b5050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61158d611383565b6001600b5f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115d0611250565b6040516115dd91906127d0565b60405180910390a1565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361165757816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161164e91906127d0565b60405180910390fd5b8060065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161174391906126d3565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156118f5578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02868685856040518563ffffffff1660e01b81526004016117ae949392919061328b565b6020604051808303815f875af19250505080156117e957506040513d601f19601f820116820180604052508101906117e691906132e9565b60015b61186a573d805f8114611817576040519150601f19603f3d011682016040523d82523d5f602084013e61181c565b606091505b505f81510361186257836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161185991906127d0565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146118f357836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016118ea91906127d0565b60405180910390fd5b505b5050505050565b5f60035f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6060600c805461194490612c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461197090612c8b565b80156119bb5780601f10611992576101008083540402835291602001916119bb565b820191905f5260205f20905b81548152906001019060200180831161199e57829003601f168201915b5050505050905090565b60605f60016119d384612184565b0190505f8167ffffffffffffffff8111156119f1576119f0612857565b5b6040519080825280601f01601f191660200182016040528015611a235781602001600182028036833780820191505090505b5090505f82602001820190505b600115611a84578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611a7957611a78613314565b5b0494505f8503611a30575b819350505050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8080611b3057505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611c62575f611b3f84611191565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611ba957508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611bbc5750611bba8184610f17565b155b15611bfe57826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401611bf591906127d0565b60405180910390fd5b8115611c6057838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360055f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f80611cc2846118fc565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611d0357611d028184866122d5565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d8e57611d425f855f80611af8565b600160045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611e0d57600160045f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460035f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b600980549050600a5f8381526020019081526020015f2081905550600981908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f611f1083610c07565b90505f60085f8481526020019081526020015f205490505f60075f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050828214611faf575f815f8581526020019081526020015f2054905080825f8581526020019081526020015f20819055508260085f8381526020019081526020015f2081905550505b60085f8581526020019081526020015f205f9055805f8481526020019081526020015f205f90555050505050565b5f6001600980549050611ff09190613341565b90505f600a5f8481526020019081526020015f205490505f6009838154811061201c5761201b612eb5565b5b905f5260205f2001549050806009838154811061203c5761203b612eb5565b5b905f5260205f20018190555081600a5f8381526020019081526020015f2081905550600a5f8581526020019081526020015f205f9055600980548061208457612083613374565b5b600190038181905f5260205f20015f9055905550505050565b5f60016120a984610c07565b6120b39190613341565b90508160075f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060085f8481526020019081526020015f2081905550505050565b61212b8383612398565b61213f612136611250565b5f858585611750565b505050565b61214c610be1565b612182576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106121e0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816121d6576121d5613314565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061221d576d04ee2d6d415b85acef8100000000838161221357612212613314565b5b0492506020810190505b662386f26fc10000831061224c57662386f26fc10000838161224257612241613314565b5b0492506010810190505b6305f5e1008310612275576305f5e100838161226b5761226a613314565b5b0492506008810190505b612710831061229a5761271083816122905761228f613314565b5b0492506004810190505b606483106122bd57606483816122b3576122b2613314565b5b0492506002810190505b600a83106122cc576001810190505b80915050919050565b6122e083838361248b565b612393575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361235457806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040161234b9190612836565b60405180910390fd5b81816040517f177e802f00000000000000000000000000000000000000000000000000000000815260040161238a929190612e67565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612408575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016123ff91906127d0565b60405180910390fd5b5f61241483835f611269565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612486575f6040517f73c6ac6e00000000000000000000000000000000000000000000000000000000815260040161247d91906127d0565b60405180910390fd5b505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561254257508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061250357506125028484610f17565b5b8061254157508273ffffffffffffffffffffffffffffffffffffffff1661252983611217565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125858261255c565b9050919050565b6125958161257b565b811461259f575f80fd5b50565b5f813590506125b08161258c565b92915050565b5f819050919050565b6125c8816125b6565b81146125d2575f80fd5b50565b5f813590506125e3816125bf565b92915050565b5f805f60608486031215612600576125ff612554565b5b5f61260d868287016125a2565b935050602061261e868287016125d5565b925050604061262f868287016125a2565b9150509250925092565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61266d81612639565b8114612677575f80fd5b50565b5f8135905061268881612664565b92915050565b5f602082840312156126a3576126a2612554565b5b5f6126b08482850161267a565b91505092915050565b5f8115159050919050565b6126cd816126b9565b82525050565b5f6020820190506126e65f8301846126c4565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612723578082015181840152602081019050612708565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612748826126ec565b61275281856126f6565b9350612762818560208601612706565b61276b8161272e565b840191505092915050565b5f6020820190508181035f83015261278e818461273e565b905092915050565b5f602082840312156127ab576127aa612554565b5b5f6127b8848285016125d5565b91505092915050565b6127ca8161257b565b82525050565b5f6020820190506127e35f8301846127c1565b92915050565b5f80604083850312156127ff576127fe612554565b5b5f61280c858286016125a2565b925050602061281d858286016125d5565b9150509250929050565b612830816125b6565b82525050565b5f6020820190506128495f830184612827565b92915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61288d8261272e565b810181811067ffffffffffffffff821117156128ac576128ab612857565b5b80604052505050565b5f6128be61254b565b90506128ca8282612884565b919050565b5f67ffffffffffffffff8211156128e9576128e8612857565b5b6128f28261272e565b9050602081019050919050565b828183375f83830152505050565b5f61291f61291a846128cf565b6128b5565b90508281526020810184848401111561293b5761293a612853565b5b6129468482856128ff565b509392505050565b5f82601f8301126129625761296161284f565b5b813561297284826020860161290d565b91505092915050565b5f805f806080858703121561299357612992612554565b5b5f6129a0878288016125a2565b94505060206129b1878288016125a2565b93505060406129c2878288016125d5565b925050606085013567ffffffffffffffff8111156129e3576129e2612558565b5b6129ef8782880161294e565b91505092959194509250565b612a0481612639565b82525050565b5f602082019050612a1d5f8301846129fb565b92915050565b5f805f60608486031215612a3a57612a39612554565b5b5f612a47868287016125a2565b9350506020612a58868287016125a2565b9250506040612a69868287016125d5565b9150509250925092565b5f67ffffffffffffffff821115612a8d57612a8c612857565b5b612a968261272e565b9050602081019050919050565b5f612ab5612ab084612a73565b6128b5565b905082815260208101848484011115612ad157612ad0612853565b5b612adc8482856128ff565b509392505050565b5f82601f830112612af857612af761284f565b5b8135612b08848260208601612aa3565b91505092915050565b5f60208284031215612b2657612b25612554565b5b5f82013567ffffffffffffffff811115612b4357612b42612558565b5b612b4f84828501612ae4565b91505092915050565b5f60208284031215612b6d57612b6c612554565b5b5f612b7a848285016125a2565b91505092915050565b612b8c816126b9565b8114612b96575f80fd5b50565b5f81359050612ba781612b83565b92915050565b5f8060408385031215612bc357612bc2612554565b5b5f612bd0858286016125a2565b9250506020612be185828601612b99565b9150509250929050565b5f8060408385031215612c0157612c00612554565b5b5f612c0e858286016125a2565b9250506020612c1f858286016125a2565b9150509250929050565b5f606082019050612c3c5f8301866127c1565b612c4960208301856127c1565b612c566040830184612827565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612ca257607f821691505b602082108103612cb557612cb4612c5e565b5b50919050565b5f606082019050612cce5f8301866127c1565b612cdb6020830185612827565b612ce860408301846127c1565b949350505050565b7f4e46543a207a65726f20636f756e7400000000000000000000000000000000005f82015250565b5f612d24600f836126f6565b9150612d2f82612cf0565b602082019050919050565b5f6020820190508181035f830152612d5181612d18565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612d8f826125b6565b9150612d9a836125b6565b9250828201905080821115612db257612db1612d58565b5b92915050565b7f4e46543a206e6f7420656e6f756768204e4654000000000000000000000000005f82015250565b5f612dec6013836126f6565b9150612df782612db8565b602082019050919050565b5f6020820190508181035f830152612e1981612de0565b9050919050565b5f612e2a826125b6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e5c57612e5b612d58565b5b600182019050919050565b5f604082019050612e7a5f8301856127c1565b612e876020830184612827565b9392505050565b5f612e98826125b6565b91505f8203612eaa57612ea9612d58565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612f3e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612f03565b612f488683612f03565b95508019841693508086168417925050509392505050565b5f819050919050565b5f612f83612f7e612f79846125b6565b612f60565b6125b6565b9050919050565b5f819050919050565b612f9c83612f69565b612fb0612fa882612f8a565b848454612f0f565b825550505050565b5f90565b612fc4612fb8565b612fcf818484612f93565b505050565b5b81811015612ff257612fe75f82612fbc565b600181019050612fd5565b5050565b601f8211156130375761300881612ee2565b61301184612ef4565b81016020851015613020578190505b61303461302c85612ef4565b830182612fd4565b50505b505050565b5f82821c905092915050565b5f6130575f198460080261303c565b1980831691505092915050565b5f61306f8383613048565b9150826002028217905092915050565b613088826126ec565b67ffffffffffffffff8111156130a1576130a0612857565b5b6130ab8254612c8b565b6130b6828285612ff6565b5f60209050601f8311600181146130e7575f84156130d5578287015190505b6130df8582613064565b865550613146565b601f1984166130f586612ee2565b5f5b8281101561311c578489015182556001820191506020850194506020810190506130f7565b868310156131395784890151613135601f891682613048565b8355505b6001600288020188555050505b505050505050565b7f4154504e46543a2055524920717565727920666f72206e6f6e6578697374656e5f8201527f7420746f6b656e00000000000000000000000000000000000000000000000000602082015250565b5f6131a86027836126f6565b91506131b38261314e565b604082019050919050565b5f6020820190508181035f8301526131d58161319c565b9050919050565b5f81905092915050565b5f6131f0826126ec565b6131fa81856131dc565b935061320a818560208601612706565b80840191505092915050565b5f61322182856131e6565b915061322d82846131e6565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f61325d82613239565b6132678185613243565b9350613277818560208601612706565b6132808161272e565b840191505092915050565b5f60808201905061329e5f8301876127c1565b6132ab60208301866127c1565b6132b86040830185612827565b81810360608301526132ca8184613253565b905095945050505050565b5f815190506132e381612664565b92915050565b5f602082840312156132fe576132fd612554565b5b5f61330b848285016132d5565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61334b826125b6565b9150613356836125b6565b925082820390508181111561336e5761336d612d58565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea26469706673582212208bda047cb690fac5297566fd6b14f63bc272b557796d62850f263509bf1445c264736f6c63430008140033
Deployed Bytecode Sourcemap
122596:2518:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124792:172;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112857:224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96094:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97266:158;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97085:115;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;122782:33;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119519:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123178:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97935:588;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124184:431;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113165:260;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125043:65;;;:::i;:::-;;124058:116;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98594:134;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123941:107;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113682:231;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123421:111;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123546:109;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;121532:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95907:120;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95632:213;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3289:103;;;:::i;:::-;;124974:61;;;:::i;:::-;;2614:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96254:95;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124625:157;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97496:146;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98799:236;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123665:266;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122829:88;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97713:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3547:220;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124792:172;2500:13;:11;:13::i;:::-;124899:11:::1;124891:37;;;124937:4;124944:2;124948:7;124891:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;124792:172:::0;;;:::o;112857:224::-;112959:4;112998:35;112983:50;;;:11;:50;;;;:90;;;;113037:36;113061:11;113037:23;:36::i;:::-;112983:90;112976:97;;112857:224;;;:::o;96094:91::-;96139:13;96172:5;96165:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96094:91;:::o;97266:158::-;97333:7;97353:22;97367:7;97353:13;:22::i;:::-;;97395:21;97408:7;97395:12;:21::i;:::-;97388:28;;97266:158;;;:::o;97085:115::-;97157:35;97166:2;97170:7;97179:12;:10;:12::i;:::-;97157:8;:35::i;:::-;97085:115;;:::o;122782:33::-;;;;:::o;119519:155::-;119610:6;119636:30;;;119629:37;;119519:155;;;;;;:::o;123178:100::-;123231:7;123258:11;;123251:18;;123178:100;:::o;97935:588::-;98044:1;98030:16;;:2;:16;;;98026:89;;98100:1;98070:33;;;;;;;;;;;:::i;:::-;;;;;;;;98026:89;98336:21;98360:34;98368:2;98372:7;98381:12;:10;:12::i;:::-;98360:7;:34::i;:::-;98336:58;;98426:4;98409:21;;:13;:21;;;98405:111;;98475:4;98481:7;98490:13;98454:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;98405:111;98015:508;97935:588;;;:::o;124184:431::-;2500:13;:11;:13::i;:::-;121137:19:::1;:17;:19::i;:::-;124288:1:::2;124279:6;:10;124271:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;124352:11;;124342:6;124328:11;;:20;;;;:::i;:::-;:35;;124320:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;124405:9;124400:169;124424:6;124420:1;:10;124400:169;;;124452:15;124484:1;124470:11;;:15;;;;:::i;:::-;124452:33;;124502:22;124512:2;124516:7;124502:9;:22::i;:::-;124541:11;;:13;;;;;;;;;:::i;:::-;;;;;;124437:132;124432:3;;;;;:::i;:::-;;;;124400:169;;;;124595:2;124586:21;;;124600:6;124586:21;;;;;;:::i;:::-;;;;;;;;124184:431:::0;;:::o;113165:260::-;113253:7;113286:16;113296:5;113286:9;:16::i;:::-;113277:5;:25;113273:101;;113349:5;113356;113326:36;;;;;;;;;;;;:::i;:::-;;;;;;;;113273:101;113391:12;:19;113404:5;113391:19;;;;;;;;;;;;;;;:26;113411:5;113391:26;;;;;;;;;;;;113384:33;;113165:260;;;;:::o;125043:65::-;2500:13;:11;:13::i;:::-;125090:10:::1;:8;:10::i;:::-;125043:65::o:0;124058:116::-;2500:13;:11;:13::i;:::-;121137:19:::1;:17;:19::i;:::-;124144:22:::2;124154:2;124158:7;124144:9;:22::i;:::-;124058:116:::0;;:::o;98594:134::-;98681:39;98698:4;98704:2;98708:7;98681:39;;;;;;;;;;;;:16;:39::i;:::-;98594:134;;;:::o;123941:107::-;2500:13;:11;:13::i;:::-;124002:14:::1;124008:7;124002:5;:14::i;:::-;124027:11;;:13;;;;;;;;;:::i;:::-;;;;;;123941:107:::0;:::o;113682:231::-;113748:7;113781:13;:11;:13::i;:::-;113772:5;:22;113768:103;;113849:1;113853:5;113818:41;;;;;;;;;;;;:::i;:::-;;;;;;;;113768:103;113888:10;113899:5;113888:17;;;;;;;;:::i;:::-;;;;;;;;;;113881:24;;113682:231;;;:::o;123421:111::-;2500:13;:11;:13::i;:::-;123514:10:::1;123497:14;:27;;;;;;:::i;:::-;;123421:111:::0;:::o;123546:109::-;2500:13;:11;:13::i;:::-;123642:5:::1;123628:11;;:19;;;;:::i;:::-;123614:11;:33;;;;123546:109:::0;:::o;121532:86::-;121579:4;121603:7;;;;;;;;;;;121596:14;;121532:86;:::o;95907:120::-;95970:7;95997:22;96011:7;95997:13;:22::i;:::-;95990:29;;95907:120;;;:::o;95632:213::-;95695:7;95736:1;95719:19;;:5;:19;;;95715:89;;95789:1;95762:30;;;;;;;;;;;:::i;:::-;;;;;;;;95715:89;95821:9;:16;95831:5;95821:16;;;;;;;;;;;;;;;;95814:23;;95632:213;;;:::o;3289:103::-;2500:13;:11;:13::i;:::-;3354:30:::1;3381:1;3354:18;:30::i;:::-;3289:103::o:0;124974:61::-;2500:13;:11;:13::i;:::-;125019:8:::1;:6;:8::i;:::-;124974:61::o:0;2614:87::-;2660:7;2687:6;;;;;;;;;;;2680:13;;2614:87;:::o;96254:95::-;96301:13;96334:7;96327:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96254:95;:::o;124625:157::-;124709:11;124701:37;;;124739:10;124759:4;124766:7;124701:73;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124625:157;;:::o;97496:146::-;97582:52;97601:12;:10;:12::i;:::-;97615:8;97625;97582:18;:52::i;:::-;97496:146;;:::o;98799:236::-;98913:31;98926:4;98932:2;98936:7;98913:12;:31::i;:::-;98955:72;98989:12;:10;:12::i;:::-;99003:4;99009:2;99013:7;99022:4;98955:33;:72::i;:::-;98799:236;;;;:::o;123665:266::-;123738:13;123802:1;123773:31;;:17;123782:7;123773:8;:17::i;:::-;:31;;;123764:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;123891:10;:8;:10::i;:::-;123903:18;:7;:16;:18::i;:::-;123874:48;;;;;;;;;:::i;:::-;;;;;;;;;;;;;123860:63;;123665:266;;;:::o;122829:88::-;;;;;;;;;;;;;:::o;97713:155::-;97801:4;97825:18;:25;97844:5;97825:25;;;;;;;;;;;;;;;:35;97851:8;97825:35;;;;;;;;;;;;;;;;;;;;;;;;;97818:42;;97713:155;;;;:::o;3547:220::-;2500:13;:11;:13::i;:::-;3652:1:::1;3632:22;;:8;:22;;::::0;3628:93:::1;;3706:1;3678:31;;;;;;;;;;;:::i;:::-;;;;;;;;3628:93;3731:28;3750:8;3731:18;:28::i;:::-;3547:220:::0;:::o;2779:166::-;2850:12;:10;:12::i;:::-;2839:23;;:7;:5;:7::i;:::-;:23;;;2835:103;;2913:12;:10;:12::i;:::-;2886:40;;;;;;;;;;;:::i;:::-;;;;;;;;2835:103;2779:166::o;95263:305::-;95365:4;95417:25;95402:40;;;:11;:40;;;;:105;;;;95474:33;95459:48;;;:11;:48;;;;95402:105;:158;;;;95524:36;95548:11;95524:23;:36::i;:::-;95402:158;95382:178;;95263:305;;;:::o;110317:247::-;110380:7;110400:13;110416:17;110425:7;110416:8;:17::i;:::-;110400:33;;110465:1;110448:19;;:5;:19;;;110444:90;;110514:7;110491:31;;;;;;;;;;;:::i;:::-;;;;;;;;110444:90;110551:5;110544:12;;;110317:247;;;:::o;99798:129::-;99868:7;99895:15;:24;99911:7;99895:24;;;;;;;;;;;;;;;;;;;;;99888:31;;99798:129;;;:::o;672:98::-;725:7;752:10;745:17;;672:98;:::o;108549:122::-;108630:33;108639:2;108643:7;108652:4;108658;108630:8;:33::i;:::-;108549:122;;;:::o;113974:640::-;114069:7;114089:21;114113:32;114127:2;114131:7;114140:4;114113:13;:32::i;:::-;114089:56;;114187:1;114162:27;;:13;:27;;;114158:214;;114206:40;114238:7;114206:31;:40::i;:::-;114158:214;;;114285:2;114268:19;;:13;:19;;;114264:108;;114304:56;114337:13;114352:7;114304:32;:56::i;:::-;114264:108;114158:214;114400:1;114386:16;;:2;:16;;;114382:192;;114419:45;114456:7;114419:36;:45::i;:::-;114382:192;;;114503:2;114486:19;;:13;:19;;;114482:92;;114522:40;114550:2;114554:7;114522:27;:40::i;:::-;114482:92;114382:192;114593:13;114586:20;;;113974:640;;;;;:::o;121691:132::-;121757:8;:6;:8::i;:::-;121753:63;;;121789:15;;;;;;;;;;;;;;121753:63;121691:132::o;104617:102::-;104685:26;104695:2;104699:7;104685:26;;;;;;;;;;;;:9;:26::i;:::-;104617:102;;:::o;122433:120::-;121396:16;:14;:16::i;:::-;122502:5:::1;122492:7;;:15;;;;;;;;;;;;;;;;;;122523:22;122532:12;:10;:12::i;:::-;122523:22;;;;;;:::i;:::-;;;;;;;;122433:120::o:0;105495:232::-;105547:21;105571:40;105587:1;105591:7;105608:1;105571:7;:40::i;:::-;105547:64;;105651:1;105626:27;;:13;:27;;;105622:98;;105700:7;105677:31;;;;;;;;;;;:::i;:::-;;;;;;;;105622:98;105536:191;105495:232;:::o;3927:191::-;4001:16;4020:6;;;;;;;;;;;4001:25;;4046:8;4037:6;;:17;;;;;;;;;;;;;;;;;;4101:8;4070:40;;4091:8;4070:40;;;;;;;;;;;;3990:128;3927:191;:::o;122174:118::-;121137:19;:17;:19::i;:::-;122244:4:::1;122234:7;;:14;;;;;;;;;;;;;;;;;;122264:20;122271:12;:10;:12::i;:::-;122264:20;;;;;;:::i;:::-;;;;;;;;122174:118::o:0;109756:318::-;109884:1;109864:22;;:8;:22;;;109860:93;;109932:8;109910:31;;;;;;;;;;;:::i;:::-;;;;;;;;109860:93;110001:8;109963:18;:25;109982:5;109963:25;;;;;;;;;;;;;;;:35;109989:8;109963:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;110047:8;110025:41;;110040:5;110025:41;;;110057:8;110025:41;;;;;;:::i;:::-;;;;;;;;109756:318;;;:::o;19249:948::-;19453:1;19436:2;:14;;;:18;19432:758;;;19491:2;19475:36;;;19512:8;19522:4;19528:7;19537:4;19475:67;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;19471:708;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19855:1;19838:6;:13;:18;19834:330;;19980:2;19944:39;;;;;;;;;;;:::i;:::-;;;;;;;;19834:330;20114:6;20108:13;20099:6;20095:2;20091:15;20084:38;19471:708;19600:41;;;19590:51;;;:6;:51;;;;19586:185;;19748:2;19712:39;;;;;;;;;;;:::i;:::-;;;;;;;;19586:185;19543:243;19432:758;19249:948;;;;;:::o;99560:117::-;99626:7;99653;:16;99661:7;99653:16;;;;;;;;;;;;;;;;;;;;;99646:23;;99560:117;;;:::o;123292:115::-;123352:13;123385:14;123378:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123292:115;:::o;89818:650::-;89874:13;89925:14;89962:1;89942:17;89953:5;89942:10;:17::i;:::-;:21;89925:38;;89978:20;90012:6;90001:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89978:41;;90034:11;90131:6;90127:2;90123:15;90115:6;90111:28;90104:35;;90168:254;90175:4;90168:254;;;90200:5;;;;;;;;90306:10;90301:2;90294:5;90290:14;90285:32;90280:3;90272:46;90364:2;90355:11;;;;;;:::i;:::-;;;;;90398:1;90389:5;:10;90168:254;90385:21;90168:254;90443:6;90436:13;;;;;89818:650;;;:::o;93929:148::-;94005:4;94044:25;94029:40;;;:11;:40;;;;94022:47;;93929:148;;;:::o;108859:678::-;109021:9;:31;;;;109050:1;109034:18;;:4;:18;;;;109021:31;109017:471;;;109069:13;109085:22;109099:7;109085:13;:22::i;:::-;109069:38;;109254:1;109238:18;;:4;:18;;;;:35;;;;;109269:4;109260:13;;:5;:13;;;;109238:35;:69;;;;;109278:29;109295:5;109302:4;109278:16;:29::i;:::-;109277:30;109238:69;109234:144;;;109357:4;109335:27;;;;;;;;;;;:::i;:::-;;;;;;;;109234:144;109398:9;109394:83;;;109453:7;109449:2;109433:28;;109442:5;109433:28;;;;;;;;;;;;109394:83;109054:434;109017:471;109527:2;109500:15;:24;109516:7;109500:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;108859:678;;;;:::o;102759:824::-;102845:7;102865:12;102880:17;102889:7;102880:8;:17::i;:::-;102865:32;;102976:1;102960:18;;:4;:18;;;102956:88;;102995:37;103012:4;103018;103024:7;102995:16;:37::i;:::-;102956:88;103107:1;103091:18;;:4;:18;;;103087:263;;103209:48;103226:1;103230:7;103247:1;103251:5;103209:8;:48::i;:::-;103322:1;103303:9;:15;103313:4;103303:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;103087:263;103380:1;103366:16;;:2;:16;;;103362:111;;103445:1;103428:9;:13;103438:2;103428:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;103362:111;103504:2;103485:7;:16;103493:7;103485:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;103543:7;103539:2;103524:27;;103533:4;103524:27;;;;;;;;;;;;103571:4;103564:11;;;102759:824;;;;;:::o;115334:164::-;115438:10;:17;;;;115411:15;:24;115427:7;115411:24;;;;;;;;;;;:44;;;;115466:10;115482:7;115466:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;115334:164;:::o;116125:1075::-;116391:22;116416:15;116426:4;116416:9;:15::i;:::-;116391:40;;116442:18;116463:17;:26;116481:7;116463:26;;;;;;;;;;;;116442:47;;116502:61;116566:12;:18;116579:4;116566:18;;;;;;;;;;;;;;;116502:82;;116705:14;116691:10;:28;116687:330;;116736:19;116758;:35;116778:14;116758:35;;;;;;;;;;;;116736:57;;116844:11;116810:19;:31;116830:10;116810:31;;;;;;;;;;;:45;;;;116961:10;116928:17;:30;116946:11;116928:30;;;;;;;;;;;:43;;;;116721:296;116687:330;117113:17;:26;117131:7;117113:26;;;;;;;;;;;117106:33;;;117157:19;:35;117177:14;117157:35;;;;;;;;;;;117150:42;;;116206:994;;;116125:1075;;:::o;117495:1079::-;117748:22;117793:1;117773:10;:17;;;;:21;;;;:::i;:::-;117748:46;;117805:18;117826:15;:24;117842:7;117826:24;;;;;;;;;;;;117805:45;;118177:19;118199:10;118210:14;118199:26;;;;;;;;:::i;:::-;;;;;;;;;;118177:48;;118263:11;118238:10;118249;118238:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;118374:10;118343:15;:28;118359:11;118343:28;;;;;;;;;;;:41;;;;118515:15;:24;118531:7;118515:24;;;;;;;;;;;118508:31;;;118550:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;117566:1008;;;117495:1079;:::o;114915:218::-;115000:14;115033:1;115017:13;115027:2;115017:9;:13::i;:::-;:17;;;;:::i;:::-;115000:34;;115072:7;115045:12;:16;115058:2;115045:16;;;;;;;;;;;;;;;:24;115062:6;115045:24;;;;;;;;;;;:34;;;;115119:6;115090:17;:26;115108:7;115090:26;;;;;;;;;;;:35;;;;114989:144;114915:218;;:::o;104946:210::-;105041:18;105047:2;105051:7;105041:5;:18::i;:::-;105070:78;105104:12;:10;:12::i;:::-;105126:1;105130:2;105134:7;105143:4;105070:33;:78::i;:::-;104946:210;;;:::o;121900:130::-;121964:8;:6;:8::i;:::-;121959:64;;121996:15;;;;;;;;;;;;;;121959:64;121900:130::o;83608:948::-;83661:7;83681:14;83698:1;83681:18;;83748:8;83739:5;:17;83735:106;;83786:8;83777:17;;;;;;:::i;:::-;;;;;83823:2;83813:12;;;;83735:106;83868:8;83859:5;:17;83855:106;;83906:8;83897:17;;;;;;:::i;:::-;;;;;83943:2;83933:12;;;;83855:106;83988:8;83979:5;:17;83975:106;;84026:8;84017:17;;;;;;:::i;:::-;;;;;84063:2;84053:12;;;;83975:106;84108:7;84099:5;:16;84095:103;;84145:7;84136:16;;;;;;:::i;:::-;;;;;84181:1;84171:11;;;;84095:103;84225:7;84216:5;:16;84212:103;;84262:7;84253:16;;;;;;:::i;:::-;;;;;84298:1;84288:11;;;;84212:103;84342:7;84333:5;:16;84329:103;;84379:7;84370:16;;;;;;:::i;:::-;;;;;84415:1;84405:11;;;;84329:103;84459:7;84450:5;:16;84446:68;;84497:1;84487:11;;;;84446:68;84542:6;84535:13;;;83608:948;;;:::o;100966:376::-;101079:38;101093:5;101100:7;101109;101079:13;:38::i;:::-;101074:261;;101155:1;101138:19;;:5;:19;;;101134:190;;101208:7;101185:31;;;;;;;;;;;:::i;:::-;;;;;;;;101134:190;101291:7;101300;101264:44;;;;;;;;;;;;:::i;:::-;;;;;;;;101074:261;100966:376;;;:::o;103919:335::-;104001:1;103987:16;;:2;:16;;;103983:89;;104057:1;104027:33;;;;;;;;;;;:::i;:::-;;;;;;;;103983:89;104082:21;104106:32;104114:2;104118:7;104135:1;104106:7;:32::i;:::-;104082:56;;104178:1;104153:27;;:13;:27;;;104149:98;;104232:1;104204:31;;;;;;;;;;;:::i;:::-;;;;;;;;104149:98;103972:282;103919:335;;:::o;100247:276::-;100350:4;100406:1;100387:21;;:7;:21;;;;:128;;;;;100435:7;100426:16;;:5;:16;;;:52;;;;100446:32;100463:5;100470:7;100446:16;:32::i;:::-;100426:52;:88;;;;100507:7;100482:32;;:21;100495:7;100482:12;:21::i;:::-;:32;;;100426:88;100387:128;100367:148;;100247:276;;;;;:::o;7:75:1:-;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:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:77::-;878:7;907:5;896:16;;841:77;;;:::o;924:122::-;997:24;1015:5;997:24;:::i;:::-;990:5;987:35;977:63;;1036:1;1033;1026:12;977:63;924:122;:::o;1052:139::-;1098:5;1136:6;1123:20;1114:29;;1152:33;1179:5;1152:33;:::i;:::-;1052:139;;;;:::o;1197:619::-;1274:6;1282;1290;1339:2;1327:9;1318:7;1314:23;1310:32;1307:119;;;1345:79;;:::i;:::-;1307:119;1465:1;1490:53;1535:7;1526:6;1515:9;1511:22;1490:53;:::i;:::-;1480:63;;1436:117;1592:2;1618:53;1663:7;1654:6;1643:9;1639:22;1618:53;:::i;:::-;1608:63;;1563:118;1720:2;1746:53;1791:7;1782:6;1771:9;1767:22;1746:53;:::i;:::-;1736:63;;1691:118;1197:619;;;;;:::o;1822:149::-;1858:7;1898:66;1891:5;1887:78;1876:89;;1822:149;;;:::o;1977:120::-;2049:23;2066:5;2049:23;:::i;:::-;2042:5;2039:34;2029:62;;2087:1;2084;2077:12;2029:62;1977:120;:::o;2103:137::-;2148:5;2186:6;2173:20;2164:29;;2202:32;2228:5;2202:32;:::i;:::-;2103:137;;;;:::o;2246:327::-;2304:6;2353:2;2341:9;2332:7;2328:23;2324:32;2321:119;;;2359:79;;:::i;:::-;2321:119;2479:1;2504:52;2548:7;2539:6;2528:9;2524:22;2504:52;:::i;:::-;2494:62;;2450:116;2246:327;;;;:::o;2579:90::-;2613:7;2656:5;2649:13;2642:21;2631:32;;2579:90;;;:::o;2675:109::-;2756:21;2771:5;2756:21;:::i;:::-;2751:3;2744:34;2675:109;;:::o;2790:210::-;2877:4;2915:2;2904:9;2900:18;2892:26;;2928:65;2990:1;2979:9;2975:17;2966:6;2928:65;:::i;:::-;2790:210;;;;:::o;3006:99::-;3058:6;3092:5;3086:12;3076:22;;3006:99;;;:::o;3111:169::-;3195:11;3229:6;3224:3;3217:19;3269:4;3264:3;3260:14;3245:29;;3111:169;;;;:::o;3286:246::-;3367:1;3377:113;3391:6;3388:1;3385:13;3377:113;;;3476:1;3471:3;3467:11;3461:18;3457:1;3452:3;3448:11;3441:39;3413:2;3410:1;3406:10;3401:15;;3377:113;;;3524:1;3515:6;3510:3;3506:16;3499:27;3348:184;3286:246;;;:::o;3538:102::-;3579:6;3630:2;3626:7;3621:2;3614:5;3610:14;3606:28;3596:38;;3538:102;;;:::o;3646:377::-;3734:3;3762:39;3795:5;3762:39;:::i;:::-;3817:71;3881:6;3876:3;3817:71;:::i;:::-;3810:78;;3897:65;3955:6;3950:3;3943:4;3936:5;3932:16;3897:65;:::i;:::-;3987:29;4009:6;3987:29;:::i;:::-;3982:3;3978:39;3971:46;;3738:285;3646:377;;;;:::o;4029:313::-;4142:4;4180:2;4169:9;4165:18;4157:26;;4229:9;4223:4;4219:20;4215:1;4204:9;4200:17;4193:47;4257:78;4330:4;4321:6;4257:78;:::i;:::-;4249:86;;4029:313;;;;:::o;4348:329::-;4407:6;4456:2;4444:9;4435:7;4431:23;4427:32;4424:119;;;4462:79;;:::i;:::-;4424:119;4582:1;4607:53;4652:7;4643:6;4632:9;4628:22;4607:53;:::i;:::-;4597:63;;4553:117;4348:329;;;;:::o;4683:118::-;4770:24;4788:5;4770:24;:::i;:::-;4765:3;4758:37;4683:118;;:::o;4807:222::-;4900:4;4938:2;4927:9;4923:18;4915:26;;4951:71;5019:1;5008:9;5004:17;4995:6;4951:71;:::i;:::-;4807:222;;;;:::o;5035:474::-;5103:6;5111;5160:2;5148:9;5139:7;5135:23;5131:32;5128:119;;;5166:79;;:::i;:::-;5128:119;5286:1;5311:53;5356:7;5347:6;5336:9;5332:22;5311:53;:::i;:::-;5301:63;;5257:117;5413:2;5439:53;5484:7;5475:6;5464:9;5460:22;5439:53;:::i;:::-;5429:63;;5384:118;5035:474;;;;;:::o;5515:118::-;5602:24;5620:5;5602:24;:::i;:::-;5597:3;5590:37;5515:118;;:::o;5639:222::-;5732:4;5770:2;5759:9;5755:18;5747:26;;5783:71;5851:1;5840:9;5836:17;5827:6;5783:71;:::i;:::-;5639:222;;;;:::o;5867:117::-;5976:1;5973;5966:12;5990:117;6099:1;6096;6089:12;6113:180;6161:77;6158:1;6151:88;6258:4;6255:1;6248:15;6282:4;6279:1;6272:15;6299:281;6382:27;6404:4;6382:27;:::i;:::-;6374:6;6370:40;6512:6;6500:10;6497:22;6476:18;6464:10;6461:34;6458:62;6455:88;;;6523:18;;:::i;:::-;6455:88;6563:10;6559:2;6552:22;6342:238;6299:281;;:::o;6586:129::-;6620:6;6647:20;;:::i;:::-;6637:30;;6676:33;6704:4;6696:6;6676:33;:::i;:::-;6586:129;;;:::o;6721:307::-;6782:4;6872:18;6864:6;6861:30;6858:56;;;6894:18;;:::i;:::-;6858:56;6932:29;6954:6;6932:29;:::i;:::-;6924:37;;7016:4;7010;7006:15;6998:23;;6721:307;;;:::o;7034:146::-;7131:6;7126:3;7121;7108:30;7172:1;7163:6;7158:3;7154:16;7147:27;7034:146;;;:::o;7186:423::-;7263:5;7288:65;7304:48;7345:6;7304:48;:::i;:::-;7288:65;:::i;:::-;7279:74;;7376:6;7369:5;7362:21;7414:4;7407:5;7403:16;7452:3;7443:6;7438:3;7434:16;7431:25;7428:112;;;7459:79;;:::i;:::-;7428:112;7549:54;7596:6;7591:3;7586;7549:54;:::i;:::-;7269:340;7186:423;;;;;:::o;7628:338::-;7683:5;7732:3;7725:4;7717:6;7713:17;7709:27;7699:122;;7740:79;;:::i;:::-;7699:122;7857:6;7844:20;7882:78;7956:3;7948:6;7941:4;7933:6;7929:17;7882:78;:::i;:::-;7873:87;;7689:277;7628:338;;;;:::o;7972:943::-;8067:6;8075;8083;8091;8140:3;8128:9;8119:7;8115:23;8111:33;8108:120;;;8147:79;;:::i;:::-;8108:120;8267:1;8292:53;8337:7;8328:6;8317:9;8313:22;8292:53;:::i;:::-;8282:63;;8238:117;8394:2;8420:53;8465:7;8456:6;8445:9;8441:22;8420:53;:::i;:::-;8410:63;;8365:118;8522:2;8548:53;8593:7;8584:6;8573:9;8569:22;8548:53;:::i;:::-;8538:63;;8493:118;8678:2;8667:9;8663:18;8650:32;8709:18;8701:6;8698:30;8695:117;;;8731:79;;:::i;:::-;8695:117;8836:62;8890:7;8881:6;8870:9;8866:22;8836:62;:::i;:::-;8826:72;;8621:287;7972:943;;;;;;;:::o;8921:115::-;9006:23;9023:5;9006:23;:::i;:::-;9001:3;8994:36;8921:115;;:::o;9042:218::-;9133:4;9171:2;9160:9;9156:18;9148:26;;9184:69;9250:1;9239:9;9235:17;9226:6;9184:69;:::i;:::-;9042:218;;;;:::o;9266:619::-;9343:6;9351;9359;9408:2;9396:9;9387:7;9383:23;9379:32;9376:119;;;9414:79;;:::i;:::-;9376:119;9534:1;9559:53;9604:7;9595:6;9584:9;9580:22;9559:53;:::i;:::-;9549:63;;9505:117;9661:2;9687:53;9732:7;9723:6;9712:9;9708:22;9687:53;:::i;:::-;9677:63;;9632:118;9789:2;9815:53;9860:7;9851:6;9840:9;9836:22;9815:53;:::i;:::-;9805:63;;9760:118;9266:619;;;;;:::o;9891:308::-;9953:4;10043:18;10035:6;10032:30;10029:56;;;10065:18;;:::i;:::-;10029:56;10103:29;10125:6;10103:29;:::i;:::-;10095:37;;10187:4;10181;10177:15;10169:23;;9891:308;;;:::o;10205:425::-;10283:5;10308:66;10324:49;10366:6;10324:49;:::i;:::-;10308:66;:::i;:::-;10299:75;;10397:6;10390:5;10383:21;10435:4;10428:5;10424:16;10473:3;10464:6;10459:3;10455:16;10452:25;10449:112;;;10480:79;;:::i;:::-;10449:112;10570:54;10617:6;10612:3;10607;10570:54;:::i;:::-;10289:341;10205:425;;;;;:::o;10650:340::-;10706:5;10755:3;10748:4;10740:6;10736:17;10732:27;10722:122;;10763:79;;:::i;:::-;10722:122;10880:6;10867:20;10905:79;10980:3;10972:6;10965:4;10957:6;10953:17;10905:79;:::i;:::-;10896:88;;10712:278;10650:340;;;;:::o;10996:509::-;11065:6;11114:2;11102:9;11093:7;11089:23;11085:32;11082:119;;;11120:79;;:::i;:::-;11082:119;11268:1;11257:9;11253:17;11240:31;11298:18;11290:6;11287:30;11284:117;;;11320:79;;:::i;:::-;11284:117;11425:63;11480:7;11471:6;11460:9;11456:22;11425:63;:::i;:::-;11415:73;;11211:287;10996:509;;;;:::o;11511:329::-;11570:6;11619:2;11607:9;11598:7;11594:23;11590:32;11587:119;;;11625:79;;:::i;:::-;11587:119;11745:1;11770:53;11815:7;11806:6;11795:9;11791:22;11770:53;:::i;:::-;11760:63;;11716:117;11511:329;;;;:::o;11846:116::-;11916:21;11931:5;11916:21;:::i;:::-;11909:5;11906:32;11896:60;;11952:1;11949;11942:12;11896:60;11846:116;:::o;11968:133::-;12011:5;12049:6;12036:20;12027:29;;12065:30;12089:5;12065:30;:::i;:::-;11968:133;;;;:::o;12107:468::-;12172:6;12180;12229:2;12217:9;12208:7;12204:23;12200:32;12197:119;;;12235:79;;:::i;:::-;12197:119;12355:1;12380:53;12425:7;12416:6;12405:9;12401:22;12380:53;:::i;:::-;12370:63;;12326:117;12482:2;12508:50;12550:7;12541:6;12530:9;12526:22;12508:50;:::i;:::-;12498:60;;12453:115;12107:468;;;;;:::o;12581:474::-;12649:6;12657;12706:2;12694:9;12685:7;12681:23;12677:32;12674:119;;;12712:79;;:::i;:::-;12674:119;12832:1;12857:53;12902:7;12893:6;12882:9;12878:22;12857:53;:::i;:::-;12847:63;;12803:117;12959:2;12985:53;13030:7;13021:6;13010:9;13006:22;12985:53;:::i;:::-;12975:63;;12930:118;12581:474;;;;;:::o;13061:442::-;13210:4;13248:2;13237:9;13233:18;13225:26;;13261:71;13329:1;13318:9;13314:17;13305:6;13261:71;:::i;:::-;13342:72;13410:2;13399:9;13395:18;13386:6;13342:72;:::i;:::-;13424;13492:2;13481:9;13477:18;13468:6;13424:72;:::i;:::-;13061:442;;;;;;:::o;13509:180::-;13557:77;13554:1;13547:88;13654:4;13651:1;13644:15;13678:4;13675:1;13668:15;13695:320;13739:6;13776:1;13770:4;13766:12;13756:22;;13823:1;13817:4;13813:12;13844:18;13834:81;;13900:4;13892:6;13888:17;13878:27;;13834:81;13962:2;13954:6;13951:14;13931:18;13928:38;13925:84;;13981:18;;:::i;:::-;13925:84;13746:269;13695:320;;;:::o;14021:442::-;14170:4;14208:2;14197:9;14193:18;14185:26;;14221:71;14289:1;14278:9;14274:17;14265:6;14221:71;:::i;:::-;14302:72;14370:2;14359:9;14355:18;14346:6;14302:72;:::i;:::-;14384;14452:2;14441:9;14437:18;14428:6;14384:72;:::i;:::-;14021:442;;;;;;:::o;14469:165::-;14609:17;14605:1;14597:6;14593:14;14586:41;14469:165;:::o;14640:366::-;14782:3;14803:67;14867:2;14862:3;14803:67;:::i;:::-;14796:74;;14879:93;14968:3;14879:93;:::i;:::-;14997:2;14992:3;14988:12;14981:19;;14640:366;;;:::o;15012:419::-;15178:4;15216:2;15205:9;15201:18;15193:26;;15265:9;15259:4;15255:20;15251:1;15240:9;15236:17;15229:47;15293:131;15419:4;15293:131;:::i;:::-;15285:139;;15012:419;;;:::o;15437:180::-;15485:77;15482:1;15475:88;15582:4;15579:1;15572:15;15606:4;15603:1;15596:15;15623:191;15663:3;15682:20;15700:1;15682:20;:::i;:::-;15677:25;;15716:20;15734:1;15716:20;:::i;:::-;15711:25;;15759:1;15756;15752:9;15745:16;;15780:3;15777:1;15774:10;15771:36;;;15787:18;;:::i;:::-;15771:36;15623:191;;;;:::o;15820:169::-;15960:21;15956:1;15948:6;15944:14;15937:45;15820:169;:::o;15995:366::-;16137:3;16158:67;16222:2;16217:3;16158:67;:::i;:::-;16151:74;;16234:93;16323:3;16234:93;:::i;:::-;16352:2;16347:3;16343:12;16336:19;;15995:366;;;:::o;16367:419::-;16533:4;16571:2;16560:9;16556:18;16548:26;;16620:9;16614:4;16610:20;16606:1;16595:9;16591:17;16584:47;16648:131;16774:4;16648:131;:::i;:::-;16640:139;;16367:419;;;:::o;16792:233::-;16831:3;16854:24;16872:5;16854:24;:::i;:::-;16845:33;;16900:66;16893:5;16890:77;16887:103;;16970:18;;:::i;:::-;16887:103;17017:1;17010:5;17006:13;16999:20;;16792:233;;;:::o;17031:332::-;17152:4;17190:2;17179:9;17175:18;17167:26;;17203:71;17271:1;17260:9;17256:17;17247:6;17203:71;:::i;:::-;17284:72;17352:2;17341:9;17337:18;17328:6;17284:72;:::i;:::-;17031:332;;;;;:::o;17369:171::-;17408:3;17431:24;17449:5;17431:24;:::i;:::-;17422:33;;17477:4;17470:5;17467:15;17464:41;;17485:18;;:::i;:::-;17464:41;17532:1;17525:5;17521:13;17514:20;;17369:171;;;:::o;17546:180::-;17594:77;17591:1;17584:88;17691:4;17688:1;17681:15;17715:4;17712:1;17705:15;17732:141;17781:4;17804:3;17796:11;;17827:3;17824:1;17817:14;17861:4;17858:1;17848:18;17840:26;;17732:141;;;:::o;17879:93::-;17916:6;17963:2;17958;17951:5;17947:14;17943:23;17933:33;;17879:93;;;:::o;17978:107::-;18022:8;18072:5;18066:4;18062:16;18041:37;;17978:107;;;;:::o;18091:393::-;18160:6;18210:1;18198:10;18194:18;18233:97;18263:66;18252:9;18233:97;:::i;:::-;18351:39;18381:8;18370:9;18351:39;:::i;:::-;18339:51;;18423:4;18419:9;18412:5;18408:21;18399:30;;18472:4;18462:8;18458:19;18451:5;18448:30;18438:40;;18167:317;;18091:393;;;;;:::o;18490:60::-;18518:3;18539:5;18532:12;;18490:60;;;:::o;18556:142::-;18606:9;18639:53;18657:34;18666:24;18684:5;18666:24;:::i;:::-;18657:34;:::i;:::-;18639:53;:::i;:::-;18626:66;;18556:142;;;:::o;18704:75::-;18747:3;18768:5;18761:12;;18704:75;;;:::o;18785:269::-;18895:39;18926:7;18895:39;:::i;:::-;18956:91;19005:41;19029:16;19005:41;:::i;:::-;18997:6;18990:4;18984:11;18956:91;:::i;:::-;18950:4;18943:105;18861:193;18785:269;;;:::o;19060:73::-;19105:3;19060:73;:::o;19139:189::-;19216:32;;:::i;:::-;19257:65;19315:6;19307;19301:4;19257:65;:::i;:::-;19192:136;19139:189;;:::o;19334:186::-;19394:120;19411:3;19404:5;19401:14;19394:120;;;19465:39;19502:1;19495:5;19465:39;:::i;:::-;19438:1;19431:5;19427:13;19418:22;;19394:120;;;19334:186;;:::o;19526:543::-;19627:2;19622:3;19619:11;19616:446;;;19661:38;19693:5;19661:38;:::i;:::-;19745:29;19763:10;19745:29;:::i;:::-;19735:8;19731:44;19928:2;19916:10;19913:18;19910:49;;;19949:8;19934:23;;19910:49;19972:80;20028:22;20046:3;20028:22;:::i;:::-;20018:8;20014:37;20001:11;19972:80;:::i;:::-;19631:431;;19616:446;19526:543;;;:::o;20075:117::-;20129:8;20179:5;20173:4;20169:16;20148:37;;20075:117;;;;:::o;20198:169::-;20242:6;20275:51;20323:1;20319:6;20311:5;20308:1;20304:13;20275:51;:::i;:::-;20271:56;20356:4;20350;20346:15;20336:25;;20249:118;20198:169;;;;:::o;20372:295::-;20448:4;20594:29;20619:3;20613:4;20594:29;:::i;:::-;20586:37;;20656:3;20653:1;20649:11;20643:4;20640:21;20632:29;;20372:295;;;;:::o;20672:1395::-;20789:37;20822:3;20789:37;:::i;:::-;20891:18;20883:6;20880:30;20877:56;;;20913:18;;:::i;:::-;20877:56;20957:38;20989:4;20983:11;20957:38;:::i;:::-;21042:67;21102:6;21094;21088:4;21042:67;:::i;:::-;21136:1;21160:4;21147:17;;21192:2;21184:6;21181:14;21209:1;21204:618;;;;21866:1;21883:6;21880:77;;;21932:9;21927:3;21923:19;21917:26;21908:35;;21880:77;21983:67;22043:6;22036:5;21983:67;:::i;:::-;21977:4;21970:81;21839:222;21174:887;;21204:618;21256:4;21252:9;21244:6;21240:22;21290:37;21322:4;21290:37;:::i;:::-;21349:1;21363:208;21377:7;21374:1;21371:14;21363:208;;;21456:9;21451:3;21447:19;21441:26;21433:6;21426:42;21507:1;21499:6;21495:14;21485:24;;21554:2;21543:9;21539:18;21526:31;;21400:4;21397:1;21393:12;21388:17;;21363:208;;;21599:6;21590:7;21587:19;21584:179;;;21657:9;21652:3;21648:19;21642:26;21700:48;21742:4;21734:6;21730:17;21719:9;21700:48;:::i;:::-;21692:6;21685:64;21607:156;21584:179;21809:1;21805;21797:6;21793:14;21789:22;21783:4;21776:36;21211:611;;;21174:887;;20764:1303;;;20672:1395;;:::o;22073:226::-;22213:34;22209:1;22201:6;22197:14;22190:58;22282:9;22277:2;22269:6;22265:15;22258:34;22073:226;:::o;22305:366::-;22447:3;22468:67;22532:2;22527:3;22468:67;:::i;:::-;22461:74;;22544:93;22633:3;22544:93;:::i;:::-;22662:2;22657:3;22653:12;22646:19;;22305:366;;;:::o;22677:419::-;22843:4;22881:2;22870:9;22866:18;22858:26;;22930:9;22924:4;22920:20;22916:1;22905:9;22901:17;22894:47;22958:131;23084:4;22958:131;:::i;:::-;22950:139;;22677:419;;;:::o;23102:148::-;23204:11;23241:3;23226:18;;23102:148;;;;:::o;23256:390::-;23362:3;23390:39;23423:5;23390:39;:::i;:::-;23445:89;23527:6;23522:3;23445:89;:::i;:::-;23438:96;;23543:65;23601:6;23596:3;23589:4;23582:5;23578:16;23543:65;:::i;:::-;23633:6;23628:3;23624:16;23617:23;;23366:280;23256:390;;;;:::o;23652:435::-;23832:3;23854:95;23945:3;23936:6;23854:95;:::i;:::-;23847:102;;23966:95;24057:3;24048:6;23966:95;:::i;:::-;23959:102;;24078:3;24071:10;;23652:435;;;;;:::o;24093:98::-;24144:6;24178:5;24172:12;24162:22;;24093:98;;;:::o;24197:168::-;24280:11;24314:6;24309:3;24302:19;24354:4;24349:3;24345:14;24330:29;;24197:168;;;;:::o;24371:373::-;24457:3;24485:38;24517:5;24485:38;:::i;:::-;24539:70;24602:6;24597:3;24539:70;:::i;:::-;24532:77;;24618:65;24676:6;24671:3;24664:4;24657:5;24653:16;24618:65;:::i;:::-;24708:29;24730:6;24708:29;:::i;:::-;24703:3;24699:39;24692:46;;24461:283;24371:373;;;;:::o;24750:640::-;24945:4;24983:3;24972:9;24968:19;24960:27;;24997:71;25065:1;25054:9;25050:17;25041:6;24997:71;:::i;:::-;25078:72;25146:2;25135:9;25131:18;25122:6;25078:72;:::i;:::-;25160;25228:2;25217:9;25213:18;25204:6;25160:72;:::i;:::-;25279:9;25273:4;25269:20;25264:2;25253:9;25249:18;25242:48;25307:76;25378:4;25369:6;25307:76;:::i;:::-;25299:84;;24750:640;;;;;;;:::o;25396:141::-;25452:5;25483:6;25477:13;25468:22;;25499:32;25525:5;25499:32;:::i;:::-;25396:141;;;;:::o;25543:349::-;25612:6;25661:2;25649:9;25640:7;25636:23;25632:32;25629:119;;;25667:79;;:::i;:::-;25629:119;25787:1;25812:63;25867:7;25858:6;25847:9;25843:22;25812:63;:::i;:::-;25802:73;;25758:127;25543:349;;;;:::o;25898:180::-;25946:77;25943:1;25936:88;26043:4;26040:1;26033:15;26067:4;26064:1;26057:15;26084:194;26124:4;26144:20;26162:1;26144:20;:::i;:::-;26139:25;;26178:20;26196:1;26178:20;:::i;:::-;26173:25;;26222:1;26219;26215:9;26207:17;;26246:1;26240:4;26237:11;26234:37;;;26251:18;;:::i;:::-;26234:37;26084:194;;;;:::o;26284:180::-;26332:77;26329:1;26322:88;26429:4;26426:1;26419:15;26453:4;26450:1;26443:15
Swarm Source
ipfs://8bda047cb690fac5297566fd6b14f63bc272b557796d62850f263509bf1445c2
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
[ 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.