More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 460 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim Tokens | 19236474 | 346 days ago | IN | 0 ETH | 0.00528156 | ||||
Claim Tokens | 19017899 | 376 days ago | IN | 0 ETH | 0.0034289 | ||||
Turn Off Ico | 18958311 | 385 days ago | IN | 0 ETH | 0.00100557 | ||||
Withdraw Remaine... | 18958308 | 385 days ago | IN | 0 ETH | 0.00474624 | ||||
Claim Tokens | 18958122 | 385 days ago | IN | 0 ETH | 0.00431762 | ||||
Claim Tokens | 18922361 | 390 days ago | IN | 0 ETH | 0.00298748 | ||||
Claim Tokens | 18915254 | 391 days ago | IN | 0 ETH | 0.00192957 | ||||
Claim Tokens | 18915129 | 391 days ago | IN | 0 ETH | 0.00292528 | ||||
Claim Tokens | 18914989 | 391 days ago | IN | 0 ETH | 0.00268501 | ||||
Claim Tokens | 18914281 | 391 days ago | IN | 0 ETH | 0.00227381 | ||||
Claim Tokens | 18913471 | 391 days ago | IN | 0 ETH | 0.00215165 | ||||
Claim Tokens | 18913466 | 391 days ago | IN | 0 ETH | 0.00222946 | ||||
Claim Tokens | 18910165 | 391 days ago | IN | 0 ETH | 0.00147298 | ||||
Claim Tokens | 18909535 | 392 days ago | IN | 0 ETH | 0.00143477 | ||||
Claim Tokens | 18908280 | 392 days ago | IN | 0 ETH | 0.00241994 | ||||
Claim Tokens | 18907582 | 392 days ago | IN | 0 ETH | 0.00185532 | ||||
Claim Tokens | 18907394 | 392 days ago | IN | 0 ETH | 0.00210747 | ||||
Claim Tokens | 18906415 | 392 days ago | IN | 0 ETH | 0.00281444 | ||||
Claim Tokens | 18906090 | 392 days ago | IN | 0 ETH | 0.00256158 | ||||
Claim Tokens | 18905895 | 392 days ago | IN | 0 ETH | 0.00218245 | ||||
Claim Tokens | 18905473 | 392 days ago | IN | 0 ETH | 0.00187861 | ||||
Claim Tokens | 18904913 | 392 days ago | IN | 0 ETH | 0.0020328 | ||||
Claim Tokens | 18904883 | 392 days ago | IN | 0 ETH | 0.00201018 | ||||
Claim Tokens | 18904782 | 392 days ago | IN | 0 ETH | 0.00194574 | ||||
Claim Tokens | 18904643 | 392 days ago | IN | 0 ETH | 0.00189149 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18858202 | 399 days ago | 80 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PhysicsIco
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-12-17 */ // Sources flattened with hardhat v2.19.1 https://hardhat.org // SPDX-License-Identifier: MIT // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/access/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. 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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/token/ERC20/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } // File @openzeppelin/contracts/utils/structs/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } } // File contracts/interfaces/IPhysicsStaking.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.8.19; interface IPhysicsStaking { function users( address account ) external view returns ( uint112 withdrawableTokens, uint112 baseTokensStaked, uint112 holderUnlockTime, uint48 stakingDuration, bool blacklisted ); } // File contracts/ico/PhysicsIco.sol pragma solidity ^0.8.0; // Original license: SPDX_License_Identifier: MIT contract PhysicsIco is Ownable { using SafeERC20 for IERC20; using Address for address payable; using EnumerableSet for EnumerableSet.AddressSet; enum ClaimOption { FULL, // Users can claim 100% tokens at first HALF // Users can claim 50% tokens at first, and then 50% after 24 hours } enum ContributeOption { HOLDING, // contributable because the account has token holdings STAKING // contributable because the account has token staked } struct IcoConf { ClaimOption claimOption; address treasury; // Address where the accumulated funds will be received. address icoToken; // Token to be listed address physicsToken; // Physics token address physicsStaking; // Physics staking string icoTokenSymbol; // Ico token symbol. It is needed on the FE side before ico token is configured uint256 startDate; // Ico start dte uint256 endDate; // Ico end date uint256 hardcap; // Hardcap in ETH bytes32 optMerkleRoot; // Merkle root for the contribution criteria bool isClaimEnabled; // The flag if the claim is enabled for the ICO } struct IcoStats { uint256 accumedFunds; // Total accumlated ETH amount by the users' contribution /** * _filledTokens = _toDistTokens + [amount to distributed to the blocked accounts] */ uint256 filledTokens; // Total filled ICO token amount uint256 toDistTokens; // Total ICO token amount to be distributed uint256 claimedTokens; // Total claimed tokens amount bool isFundsClaimed; // The flag is that the accumulated funds were withdrawn. } struct UserData { uint256 contribAmtWithHoldOpt; // User contributed funds amount with holding option uint256 contribAmtWithStakeOpt; // User contributed funds amount with staking option uint256 disAmtWithHoldOpt; // ICO token amount to be received for the holding option contribution uint256 disAmtWithStakeOpt; // ICO token amount to be received for the staking option contribution uint256 firstClaimedAt; // First claimed time bool claimed; // User claimed tokens or not } uint256 private constant CLAIM_INTERVAL = 24 hours; /// @dev Last ico id uint256 private _lastIcoId; /// @dev Flag to show if any ico is opened or not bool private _icoOpened; /// @dev Ico configuration data mapping(uint256 => IcoConf) private _icoConfData; /// @dev Ico live stats data mapping(uint256 => IcoStats) private _icoStatsData; /// @notice User contribution data for the ico /// @dev Key is the hash value of user address & ico id mapping(bytes32 => UserData) private _userData; /// @notice Claim blacklist /// @dev Key is the hash value of user address & ico id mapping(bytes32 => bool) private _blacklist; event AccountBlacklisted(uint256 icoId, address account, bool blacklisted); event Claimed(uint256 icoId, address account, uint256 amount); event Contributed( uint256 icoId, address account, ContributeOption option, uint256 fundAmount, uint256 tokenAmount ); event Finalized(uint256 icoId); event HardcapUpdated(uint256 icoId, uint256 hardcap); event IcoOpened(uint256 icoId); event IcoTrunedOff(); function openNewIco( ClaimOption option_, address treasury_, address physicsToken_, address physicsStaking_, string calldata icoTokenSymbol_, uint256 startDate_, uint256 endDate_, uint256 hardcap_, bytes32 optMerkleRoot_ ) external onlyOwner { require(treasury_ != address(0), "invalid treasury"); IPhysicsStaking(physicsStaking_).users(address(0)); // To check the Physics staking contract IERC20(physicsToken_).balanceOf(address(this)); // To check the IERC20 contract require(!_icoOpened, "close opened ico"); require(block.timestamp < startDate_, "must be future time"); require(startDate_ < endDate_, "startDate must before endDate"); IcoConf memory conf = IcoConf({ claimOption: option_, treasury: treasury_, physicsToken: physicsToken_, physicsStaking: physicsStaking_, icoTokenSymbol: icoTokenSymbol_, startDate: startDate_, endDate: endDate_, hardcap: hardcap_, optMerkleRoot: optMerkleRoot_, icoToken: address(0), isClaimEnabled: false }); uint256 icoId = _lastIcoId; ++icoId; _lastIcoId = icoId; _icoConfData[icoId] = conf; _icoOpened = true; emit IcoOpened(icoId); } /// @notice Contribute in the ICO /// @dev Holding option or Staking option are available /// @param option_ One of contribution options: holding or staking /// @param icoId_ Current opened ico /// @param crtAmt_ Criteria amount (this can be holding criteria amount or staking criteria amount) /// @param crtPeriod_ Criteria period (use only for the staking option. default 0 for the holding option) /// @param maxFundAmt_ Max contributable funds amount with the option and the criteria /// @param fundAmt_ Current contribution fund amount /// @param tokenAmt_ ICO token amount to be received from the current contribution /// @param proof_ Proof data to validate the given parameters by using merkle root function contribute( ContributeOption option_, uint256 icoId_, uint256 crtAmt_, uint256 crtPeriod_, uint256 maxFundAmt_, uint256 fundAmt_, uint256 tokenAmt_, bytes32[] calldata proof_ ) external payable { address caller = _msgSender(); bytes32 key = _hash2(icoId_, caller); IcoStats storage icoStats = _icoStatsData[icoId_]; IcoConf memory icoConf = _icoConfData[icoId_]; require( block.timestamp >= icoConf.startDate && block.timestamp < icoConf.endDate, "ico not opened" ); require(msg.value >= fundAmt_, "less funds"); require( MerkleProof.verify( proof_, icoConf.optMerkleRoot, keccak256( bytes.concat( keccak256( abi.encodePacked( option_, crtAmt_, crtPeriod_, maxFundAmt_, fundAmt_, tokenAmt_ ) ) ) ) ), "proof failed" ); _validateCriteria( option_, icoConf.physicsToken, icoConf.physicsStaking, crtAmt_, crtPeriod_ ); _validateContribLimit( icoId_, option_, maxFundAmt_, fundAmt_, tokenAmt_ ); icoStats.accumedFunds += fundAmt_; icoStats.filledTokens += tokenAmt_; // The distributable token amount only accumulates when the account is not blacklisted. if (!_blacklist[key]) icoStats.toDistTokens += tokenAmt_; require(icoStats.accumedFunds <= icoConf.hardcap, "reached hardcap"); emit Contributed(icoId_, caller, option_, fundAmt_, tokenAmt_); } /// @notice Validate whether the account is eligible for the ICO using the provided option. /// @dev ContributeOption.HOLDING checks the hold amount of Physics token /// @dev ContributeOption.STAKING checks the staked amount and duration in the Physics staking contract function _validateCriteria( ContributeOption option_, address physicsToken_, address physicsStaking_, uint256 crtAmt_, uint256 crtPeriod_ ) internal view { address caller = _msgSender(); if (option_ == ContributeOption.HOLDING) { uint256 holdingBalance = IERC20Metadata(physicsToken_).balanceOf( caller ); require(holdingBalance >= crtAmt_, "unmeet holding criteria"); } else { ( uint256 withdrawableTokens, , , uint48 stakingDuration, bool blacklisted ) = IPhysicsStaking(physicsStaking_).users(caller); require( !blacklisted && withdrawableTokens >= crtAmt_ && stakingDuration >= crtPeriod_, "unmeet staking criteria" ); } } /// @notice Validate the contribution limit when using the provided option. function _validateContribLimit( uint256 icoId_, ContributeOption option_, uint256 maxFundAmt_, uint256 fundAmt_, uint256 tokenAmt_ ) internal { bytes32 key = _hash2(icoId_, _msgSender()); UserData storage userData = _userData[key]; if (option_ == ContributeOption.HOLDING) { uint256 contribAmtWithHoldOpt_ = userData.contribAmtWithHoldOpt + fundAmt_; require( contribAmtWithHoldOpt_ <= maxFundAmt_, "hold opt contribution limit" ); userData.contribAmtWithHoldOpt = contribAmtWithHoldOpt_; userData.disAmtWithHoldOpt += tokenAmt_; } else { uint256 contribAmtWithStakeOpt_ = userData.contribAmtWithStakeOpt + fundAmt_; require( contribAmtWithStakeOpt_ <= maxFundAmt_, "stake opt contribution limit" ); userData.contribAmtWithStakeOpt = contribAmtWithStakeOpt_; userData.disAmtWithStakeOpt += tokenAmt_; } } /// @notice Claim ICO tokens for the contributions already made. /// @dev There are two types of ICO. One offers a 100% claim, while the other offers a 50% / 50% claim. /// In the case of the second option, users can only claim the second 50% after 24 hours from the first claim. function claimTokens(uint256 icoId_) external { address caller = _msgSender(); bytes32 key = _hash2(icoId_, caller); IcoConf memory icoConf = _icoConfData[icoId_]; require(icoConf.endDate < block.timestamp, "not finished"); require(icoConf.isClaimEnabled, "claim disabled"); UserData memory userData = _userData[key]; require(!_blacklist[key], "blacklisted"); require(!userData.claimed, "already claimed"); uint256 claimableAmt = userData.disAmtWithHoldOpt + userData.disAmtWithStakeOpt; require(claimableAmt != 0, "nothing claimable"); if (icoConf.claimOption == ClaimOption.FULL) { _userData[key].claimed = true; } else { claimableAmt /= 2; if (userData.firstClaimedAt > 0) { require( block.timestamp >= userData.firstClaimedAt + CLAIM_INTERVAL, "wait more" ); _userData[key].claimed = true; } } IERC20(icoConf.icoToken).safeTransfer(caller, claimableAmt); _userData[key].firstClaimedAt = block.timestamp; _icoStatsData[icoId_].claimedTokens += claimableAmt; emit Claimed(icoId_, caller, claimableAmt); } /// @notice Finalize ICO when it was filled or by some reasons /// @dev Only owner can call this function /// @dev It should indicate the new claim date function finalizeIco(uint256 icoId_) external onlyOwner { IcoConf storage icoConf = _icoConfData[icoId_]; require( block.timestamp > icoConf.startDate && block.timestamp < icoConf.endDate, "ico not opened" ); icoConf.endDate = block.timestamp; emit Finalized(icoId_); } /// @notice Turn ICO off /// @dev icoOpened flag turned to false function turnOffIco(uint256 icoId_) external onlyOwner { IcoConf storage icoConf = _icoConfData[icoId_]; require(block.timestamp > icoConf.endDate, "ico not finished"); require(_icoOpened, "already turned off"); _icoOpened = false; emit IcoTrunedOff(); } /// @notice Withdraw remained ICO tokens after ICO finished /// @dev Only owner can call this function function withdrawRemainedTokens(uint256 icoId_) external onlyOwner { IcoStats memory icoStats = _icoStatsData[icoId_]; IcoConf memory icoConf = _icoConfData[icoId_]; require(block.timestamp >= icoConf.endDate, "ico not finished"); IERC20 icoToken = IERC20(icoConf.icoToken); uint256 contractTokens = icoToken.balanceOf(address(this)) + icoStats.claimedTokens; uint256 toDistTokens = icoStats.toDistTokens; require(contractTokens >= toDistTokens, "insufficient amount"); icoToken.safeTransfer(_msgSender(), contractTokens - toDistTokens); } /// @notice Withdraw accumlated funds in the contract /// @dev Only owner can call this function function withdrawFunds(uint256 icoId_) external onlyOwner { IcoStats memory icoStats = _icoStatsData[icoId_]; IcoConf memory icoConf = _icoConfData[icoId_]; require(block.timestamp >= icoConf.endDate, "ico not finished"); require(!icoStats.isFundsClaimed, "already withdrawn"); uint256 accumendFunds = icoStats.accumedFunds; require(accumendFunds > 0, "nothing to withdraw"); address payable treasury = payable(icoConf.treasury); treasury.sendValue(accumendFunds); _icoStatsData[icoId_].isFundsClaimed = true; } /// @notice Batch blacklist account or recover from the blacklist /// @dev Only owner can call this function function batchBlacklistAccount( uint256 icoId_, address[] calldata accounts_, bool flag_ ) external onlyOwner { uint256 len = accounts_.length; for (uint256 i; i < len; ) { blacklistAccount(icoId_, accounts_[i], flag_); unchecked { ++i; } } } /// @notice Blacklist account or recover from the blacklist /// @dev Only owner can call this function function blacklistAccount( uint256 icoId_, address account_, bool flag_ ) public onlyOwner { bytes32 key = _hash2(icoId_, account_); if (_blacklist[key] == flag_) return; // Nothing change for this conf _blacklist[key] = flag_; UserData memory userData = _userData[key]; uint256 changeAmount = userData.disAmtWithHoldOpt + userData.disAmtWithStakeOpt; // When an account is blacklisted, the distributable token amount decreases. // When removed from the blacklist, the distributable token amount increases. if (flag_) _icoStatsData[icoId_].toDistTokens -= changeAmount; else _icoStatsData[icoId_].toDistTokens += changeAmount; emit AccountBlacklisted(icoId_, account_, flag_); } /// @notice Check if the provided account is blacklisted. function isBlacklisted( uint256 icoId_, address account_ ) external view returns (bool) { bytes32 key = _hash2(icoId_, account_); return _blacklist[key]; } /// @notice View the ico configuration data for the given ico id function viewIcoConf( uint256 icoId_ ) external view returns (IcoConf memory) { return _icoConfData[icoId_]; } /// @notice View the ico live stats data for the given ico id function viewIcoStats( uint256 icoId_ ) external view returns (IcoStats memory) { return _icoStatsData[icoId_]; } /// @notice Update ICO start / end / claim date /// @dev Only owner can call this function function updateIcoDates( uint256 icoId_, uint256 startDate_, uint256 endDate_ ) external onlyOwner { IcoConf storage icoConf = _icoConfData[icoId_]; require(block.timestamp < icoConf.startDate, "ico already started"); require(block.timestamp < startDate_, "must be future time"); require(startDate_ < endDate_, "startDate must before endDate"); icoConf.startDate = startDate_; icoConf.endDate = endDate_; } /// @notice Enable claim for the ico /// @dev Only owner can call this function function enableIcoClaim(uint256 icoId_) external onlyOwner { IcoConf storage icoConf = _icoConfData[icoId_]; require(icoConf.startDate > 0, "invalid ico id"); require(icoConf.icoToken != address(0), "ico token not set"); icoConf.isClaimEnabled = true; } /// @notice Update ico token /// @dev Only owner can call this function function updateIcoToken( uint256 icoId_, address icoToken_ ) external onlyOwner { IcoConf storage icoConf = _icoConfData[icoId_]; require(icoConf.startDate > 0, "invalid ico id"); IERC20(icoToken_).balanceOf(address(this)); // To check the IERC20 contract icoConf.icoToken = icoToken_; } /// @notice Update ICO hardcap /// @dev Only owner can call this function function updateHardcap( uint256 icoId_, uint256 hardcap_ ) external onlyOwner { require( hardcap_ >= _icoStatsData[icoId_].accumedFunds, "more accumlated" ); _icoConfData[icoId_].hardcap = hardcap_; emit HardcapUpdated(icoId_, hardcap_); } /// @notice Update the contribute option merkle root /// @dev Only owner can call this function function updateOptMerkleRoot( uint256 icoId_, bytes32 merkleRoot_ ) external onlyOwner { IcoConf storage icoConf = _icoConfData[icoId_]; require(icoConf.optMerkleRoot != merkleRoot_, "nothing changed"); icoConf.optMerkleRoot = merkleRoot_; } /// @notice View user contribution data function viewUserData( uint256 icoId_, address account_ ) external view returns (UserData memory) { bytes32 key = _hash2(icoId_, account_); return _userData[key]; } /// @notice View the last ico id function lastIcoId() external view returns (uint256) { return _lastIcoId; } /// @notice Get hash value from (address, uint256) function _hash2( uint256 param1_, address param2_ ) private pure returns (bytes32) { return keccak256(abi.encode(param1_, param2_)); } /// @notice It allows the admin to recover tokens sent to the contract /// @param token_: the address of the token to withdraw /// @param amount_: the number of tokens to withdraw /// @dev Only owner can call this function function recoverToken(address token_, uint256 amount_) external onlyOwner { IERC20(token_).safeTransfer(_msgSender(), amount_); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"icoId","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"blacklisted","type":"bool"}],"name":"AccountBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"icoId","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"icoId","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"enum PhysicsIco.ContributeOption","name":"option","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"fundAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"Contributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"icoId","type":"uint256"}],"name":"Finalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"icoId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"hardcap","type":"uint256"}],"name":"HardcapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"icoId","type":"uint256"}],"name":"IcoOpened","type":"event"},{"anonymous":false,"inputs":[],"name":"IcoTrunedOff","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"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"address[]","name":"accounts_","type":"address[]"},{"internalType":"bool","name":"flag_","type":"bool"}],"name":"batchBlacklistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"address","name":"account_","type":"address"},{"internalType":"bool","name":"flag_","type":"bool"}],"name":"blacklistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"}],"name":"claimTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum PhysicsIco.ContributeOption","name":"option_","type":"uint8"},{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"uint256","name":"crtAmt_","type":"uint256"},{"internalType":"uint256","name":"crtPeriod_","type":"uint256"},{"internalType":"uint256","name":"maxFundAmt_","type":"uint256"},{"internalType":"uint256","name":"fundAmt_","type":"uint256"},{"internalType":"uint256","name":"tokenAmt_","type":"uint256"},{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"}],"name":"contribute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"}],"name":"enableIcoClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"}],"name":"finalizeIco","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"address","name":"account_","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastIcoId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum PhysicsIco.ClaimOption","name":"option_","type":"uint8"},{"internalType":"address","name":"treasury_","type":"address"},{"internalType":"address","name":"physicsToken_","type":"address"},{"internalType":"address","name":"physicsStaking_","type":"address"},{"internalType":"string","name":"icoTokenSymbol_","type":"string"},{"internalType":"uint256","name":"startDate_","type":"uint256"},{"internalType":"uint256","name":"endDate_","type":"uint256"},{"internalType":"uint256","name":"hardcap_","type":"uint256"},{"internalType":"bytes32","name":"optMerkleRoot_","type":"bytes32"}],"name":"openNewIco","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"recoverToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"}],"name":"turnOffIco","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"uint256","name":"hardcap_","type":"uint256"}],"name":"updateHardcap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"uint256","name":"startDate_","type":"uint256"},{"internalType":"uint256","name":"endDate_","type":"uint256"}],"name":"updateIcoDates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"address","name":"icoToken_","type":"address"}],"name":"updateIcoToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"name":"updateOptMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"}],"name":"viewIcoConf","outputs":[{"components":[{"internalType":"enum PhysicsIco.ClaimOption","name":"claimOption","type":"uint8"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"icoToken","type":"address"},{"internalType":"address","name":"physicsToken","type":"address"},{"internalType":"address","name":"physicsStaking","type":"address"},{"internalType":"string","name":"icoTokenSymbol","type":"string"},{"internalType":"uint256","name":"startDate","type":"uint256"},{"internalType":"uint256","name":"endDate","type":"uint256"},{"internalType":"uint256","name":"hardcap","type":"uint256"},{"internalType":"bytes32","name":"optMerkleRoot","type":"bytes32"},{"internalType":"bool","name":"isClaimEnabled","type":"bool"}],"internalType":"struct PhysicsIco.IcoConf","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"}],"name":"viewIcoStats","outputs":[{"components":[{"internalType":"uint256","name":"accumedFunds","type":"uint256"},{"internalType":"uint256","name":"filledTokens","type":"uint256"},{"internalType":"uint256","name":"toDistTokens","type":"uint256"},{"internalType":"uint256","name":"claimedTokens","type":"uint256"},{"internalType":"bool","name":"isFundsClaimed","type":"bool"}],"internalType":"struct PhysicsIco.IcoStats","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"},{"internalType":"address","name":"account_","type":"address"}],"name":"viewUserData","outputs":[{"components":[{"internalType":"uint256","name":"contribAmtWithHoldOpt","type":"uint256"},{"internalType":"uint256","name":"contribAmtWithStakeOpt","type":"uint256"},{"internalType":"uint256","name":"disAmtWithHoldOpt","type":"uint256"},{"internalType":"uint256","name":"disAmtWithStakeOpt","type":"uint256"},{"internalType":"uint256","name":"firstClaimedAt","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"internalType":"struct PhysicsIco.UserData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"icoId_","type":"uint256"}],"name":"withdrawRemainedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b613215806200007f6000396000f3fe6080604052600436106101405760003560e01c8063a03df5e5116100b6578063d285e33f1161006f578063d285e33f146103d8578063d32531741461043c578063d5a788ce1461044f578063f2fde38b1461046d578063f775e5041461048d578063fff24d19146104ad57600080fd5b8063a03df5e51461030b578063a0de6f351461032b578063a839eae61461034b578063b0dcb0a31461036b578063b29a814014610398578063b8bec6cc146103b857600080fd5b80634350cd93116101085780634350cd931461023e57806346e04a2f1461025e5780634ae001d81461027e5780635c3c9734146102ae578063715018a6146102ce5780638da5cb5b146102e357600080fd5b8063155dd5ee146101455780632143a50f146101675780632344091e14610187578063338531c9146101fe5780633dd2e3291461021e575b600080fd5b34801561015157600080fd5b506101656101603660046129a3565b6104cd565b005b34801561017357600080fd5b506101656101823660046129a3565b610766565b34801561019357600080fd5b506101a76101a23660046129d8565b610a26565b6040516101f59190600060c082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015292915050565b60405180910390f35b34801561020a57600080fd5b50610165610219366004612a04565b610ace565b34801561022a57600080fd5b50610165610239366004612a04565b610b79565b34801561024a57600080fd5b506101656102593660046129a3565b610bdc565b34801561026a57600080fd5b506101656102793660046129a3565b610c93565b34801561028a57600080fd5b5061029e6102993660046129d8565b61111c565b60405190151581526020016101f5565b3480156102ba57600080fd5b506101656102c9366004612a80565b611143565b3480156102da57600080fd5b50610165611190565b3480156102ef57600080fd5b506000546040516001600160a01b0390911681526020016101f5565b34801561031757600080fd5b50610165610326366004612adf565b6111a4565b34801561033757600080fd5b50610165610346366004612b2c565b611300565b34801561035757600080fd5b506101656103663660046129d8565b611728565b34801561037757600080fd5b5061038b6103863660046129a3565b61180d565b6040516101f59190612c98565b3480156103a457600080fd5b506101656103b3366004612d6a565b6119b9565b3480156103c457600080fd5b506101656103d33660046129a3565b6119d9565b3480156103e457600080fd5b506103f86103f33660046129a3565b611a90565b6040516101f59190600060a0820190508251825260208301516020830152604083015160408301526060830151606083015260808301511515608083015292915050565b61016561044a366004612d94565b611b15565b34801561045b57600080fd5b506001546040519081526020016101f5565b34801561047957600080fd5b50610165610488366004612e27565b611f0a565b34801561049957600080fd5b506101656104a83660046129a3565b611f83565b3480156104b957600080fd5b506101656104c8366004612e42565b612022565b6104d5612126565b6000818152600460208181526040808420815160a08101835281548152600180830154828601526002830154828501526003808401546060840152929095015460ff9081161515608083015287875291909352818520825161016081019093528054939594929390928492919091169081111561055457610554612c07565b600181111561056557610565612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a0909201916105b690612e6e565b80601f01602080910402602001604051908101604052809291908181526020018280546105e290612e6e565b801561062f5780601f106106045761010080835404028352916020019161062f565b820191906000526020600020905b81548152906001019060200180831161061257829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015260e08101519091504210156106a05760405162461bcd60e51b815260040161069790612ea8565b60405180910390fd5b8160800151156106e65760405162461bcd60e51b815260206004820152601160248201527030b63932b0b23c903bb4ba34323930bbb760791b6044820152606401610697565b81518061072b5760405162461bcd60e51b81526020600482015260136024820152726e6f7468696e6720746f20776974686472617760681b6044820152606401610697565b60208201516107436001600160a01b03821683612180565b50505060009182525060046020819052604090912001805460ff19166001179055565b61076e612126565b6000818152600460208181526040808420815160a08101835281548152600180830154828601526002830154828501526003808401546060840152929095015460ff908116151560808301528787529190935281852082516101608101909352805493959492939092849291909116908111156107ed576107ed612c07565b60018111156107fe576107fe612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a09092019161084f90612e6e565b80601f016020809104026020016040519081016040528092919081815260200182805461087b90612e6e565b80156108c85780601f1061089d576101008083540402835291602001916108c8565b820191906000526020600020905b8154815290600101906020018083116108ab57829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015260e08101519091504210156109305760405162461bcd60e51b815260040161069790612ea8565b604081810151606084015191516370a0823160e01b815230600482015290916000916001600160a01b038416906370a0823190602401602060405180830381865afa158015610983573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a79190612ed2565b6109b19190612f01565b6040850151909150808210156109ff5760405162461bcd60e51b81526020600482015260136024820152721a5b9cdd59999a58da595b9d08185b5bdd5b9d606a1b6044820152606401610697565b610a1e33610a0d8385612f14565b6001600160a01b0386169190612299565b505050505050565b610a616040518060c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6000610a6d84846122eb565b600090815260056020818152604092839020835160c08101855281548152600182015492810192909252600281015493820193909352600383015460608201526004830154608082015291015460ff16151560a08201529150505b92915050565b610ad6612126565b600082815260046020526040902054811015610b265760405162461bcd60e51b815260206004820152600f60248201526e1b5bdc99481858d8dd5b5b185d1959608a1b6044820152606401610697565b60008281526003602090815260409182902060070183905581518481529081018390527f63afb649c3004190251012cbd8328870222bc5975be8fdb3d9b3d4094c04832f91015b60405180910390a15050565b610b81612126565b60008281526003602052604090206008810154829003610bd55760405162461bcd60e51b815260206004820152600f60248201526e1b9bdd1a1a5b99c818da185b99d959608a1b6044820152606401610697565b6008015550565b610be4612126565b60008181526003602052604090206005810154610c345760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a59081a58dbc81a5960921b6044820152606401610697565b60018101546001600160a01b0316610c825760405162461bcd60e51b81526020600482015260116024820152701a58dbc81d1bdad95b881b9bdd081cd95d607a1b6044820152606401610697565b600901805460ff1916600117905550565b336000610ca083836122eb565b6000848152600360205260408082208151610160810190925280549394509192909190829060ff166001811115610cd957610cd9612c07565b6001811115610cea57610cea612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a090920191610d3b90612e6e565b80601f0160208091040260200160405190810160405280929190818152602001828054610d6790612e6e565b8015610db45780601f10610d8957610100808354040283529160200191610db4565b820191906000526020600020905b815481529060010190602001808311610d9757829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015260e08101519091504211610e3a5760405162461bcd60e51b815260206004820152600c60248201526b1b9bdd08199a5b9a5cda195960a21b6044820152606401610697565b806101400151610e7d5760405162461bcd60e51b815260206004820152600e60248201526d18db185a5b48191a5cd8589b195960921b6044820152606401610697565b6000828152600560208181526040808420815160c08101835281548152600182015481850152600282015481840152600382015460608201526004820154608082015293015460ff908116151560a085015286855260069092529092205490911615610f195760405162461bcd60e51b815260206004820152600b60248201526a189b1858dadb1a5cdd195960aa1b6044820152606401610697565b8060a0015115610f5d5760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b6044820152606401610697565b600081606001518260400151610f739190612f01565b905080600003610fb95760405162461bcd60e51b81526020600482015260116024820152706e6f7468696e6720636c61696d61626c6560781b6044820152606401610697565b600083516001811115610fce57610fce612c07565b03610ff557600084815260056020819052604090912001805460ff19166001179055611079565b611000600282612f27565b608083015190915015611079576201518082608001516110209190612f01565b42101561105b5760405162461bcd60e51b815260206004820152600960248201526877616974206d6f726560b81b6044820152606401610697565b600084815260056020819052604090912001805460ff191660011790555b6040830151611092906001600160a01b03168683612299565b600084815260056020908152604080832042600491820155898452909152812060030180548392906110c5908490612f01565b9091555050604080518781526001600160a01b03871660208201529081018290527f4ec90e965519d92681267467f775ada5bd214aa92c0dc93d90a5e880ce9ed026906060015b60405180910390a1505050505050565b60008061112984846122eb565b60009081526006602052604090205460ff16949350505050565b61114b612126565b8160005b81811015610a1e576111888686868481811061116d5761116d612f49565b90506020020160208101906111829190612e27565b856111a4565b60010161114f565b611198612126565b6111a26000612330565b565b6111ac612126565b60006111b884846122eb565b60008181526006602052604090205490915082151560ff9091161515036111df5750505050565b6000818152600660209081526040808320805460ff19168615151790556005808352818420825160c0810184528154815260018201549481019490945260028101549284018390526003810154606085018190526004820154608086015291015460ff16151560a084015291929161125691612f01565b9050831561128a576000868152600460205260408120600201805483929061127f908490612f14565b909155506112b19050565b600086815260046020526040812060020180548392906112ab908490612f01565b90915550505b604080518781526001600160a01b0387166020820152851515918101919091527f2db3614065e8970939807c373f1f9e7b2a066e8d30b7bdec226123ce1675d37c9060600161110c565b505050565b611308612126565b6001600160a01b0389166113515760405162461bcd60e51b815260206004820152601060248201526f696e76616c696420747265617375727960801b6044820152606401610697565b60405163543a185d60e11b8152600060048201526001600160a01b0388169063a87430ba9060240160a060405180830381865afa158015611396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ba9190612f76565b50506040516370a0823160e01b81523060048201526001600160a01b038c1693506370a0823192506024019050602060405180830381865afa158015611404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114289190612ed2565b5060025460ff161561146f5760405162461bcd60e51b815260206004820152601060248201526f636c6f7365206f70656e65642069636f60801b6044820152606401610697565b8342106114b45760405162461bcd60e51b81526020600482015260136024820152726d757374206265206675747572652074696d6560681b6044820152606401610697565b8284106115035760405162461bcd60e51b815260206004820152601d60248201527f737461727444617465206d757374206265666f726520656e64446174650000006044820152606401610697565b60006040518061016001604052808c600181111561152357611523612c07565b81526020018b6001600160a01b0316815260200160006001600160a01b031681526020018a6001600160a01b03168152602001896001600160a01b0316815260200188888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050506020820188905260408201879052606082018690526080820185905260a0909101526001549091506115ce81612fed565b6001818155600082815260036020526040902084518154939450859391929091839160ff1990911690838181111561160857611608612c07565b0217905550602082015181546001600160a01b0391821661010002610100600160a81b031990911617825560408301516001830180549183166001600160a01b03199283161790556060840151600284018054918416918316919091179055608084015160038401805491909316911617905560a0820151600482019061168f9082613062565b5060c0820151600582015560e0820151600682015561010082015160078201556101208201516008820155610140909101516009909101805491151560ff199283161790556002805490911660011790556040517f8b002cb4c916c04e43329d1c0e03784c1a5aa2dc49caf95224aae4fca1fa896c906117129083815260200190565b60405180910390a1505050505050505050505050565b611730612126565b600082815260036020526040902060058101546117805760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a59081a58dbc81a5960921b6044820152606401610697565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa1580156117c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e89190612ed2565b5060010180546001600160a01b0319166001600160a01b039290921691909117905550565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a082015260c0810182905260e081018290526101008101829052610120810182905261014081019190915260008281526003602052604090819020815161016081019092528054829060ff16600181111561189757611897612c07565b60018111156118a8576118a8612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a0909201916118f990612e6e565b80601f016020809104026020016040519081016040528092919081815260200182805461192590612e6e565b80156119725780601f1061194757610100808354040283529160200191611972565b820191906000526020600020905b81548152906001019060200180831161195557829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015292915050565b6119c1612126565b6119d56001600160a01b0383163383612299565b5050565b6119e1612126565b600081815260036020526040902060068101544211611a125760405162461bcd60e51b815260040161069790612ea8565b60025460ff16611a595760405162461bcd60e51b815260206004820152601260248201527130b63932b0b23c903a3ab93732b21037b33360711b6044820152606401610697565b6002805460ff191690556040517f985fcc741e81f00ad7a35e096d9082cef5563b2c67effcdec4a438da5ae419c790600090a15050565b611ac46040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b50600090815260046020818152604092839020835160a081018552815481526001820154928101929092526002810154938201939093526003830154606082015291015460ff161515608082015290565b336000611b228a836122eb565b60008b815260046020908152604080832060039092528083208151610160810190925280549495509193909190829060ff166001811115611b6557611b65612c07565b6001811115611b7657611b76612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a090920191611bc790612e6e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf390612e6e565b8015611c405780601f10611c1557610100808354040283529160200191611c40565b820191906000526020600020905b815481529060010190602001808311611c2357829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015260c08101519091504210801590611c9b57508060e0015142105b611cd85760405162461bcd60e51b815260206004820152600e60248201526d1a58dbc81b9bdd081bdc195b995960921b6044820152606401610697565b87341015611d155760405162461bcd60e51b815260206004820152600a6024820152696c6573732066756e647360b01b6044820152606401610697565b611db3868680806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508261012001518f8e8e8e8e8e604051602001611d7b96959493929190613122565b60408051601f198184030181528282528051602091820120908301520160405160208183030381529060405280519060200120612380565b611dee5760405162461bcd60e51b815260206004820152600c60248201526b1c1c9bdbd98819985a5b195960a21b6044820152606401610697565b611e038d826060015183608001518e8e612396565b611e108c8e8b8b8b612572565b87826000016000828254611e249190612f01565b9250508190555086826001016000828254611e3f9190612f01565b909155505060008381526006602052604090205460ff16611e745786826002016000828254611e6e9190612f01565b90915550505b61010081015182541115611ebc5760405162461bcd60e51b815260206004820152600f60248201526e072656163686564206861726463617608c1b6044820152606401610697565b7fcce9dcaf129f1357203918bd0fea386caf9679f9513a13a6081dec19de1658738c858f8b8b604051611ef3959493929190613158565b60405180910390a150505050505050505050505050565b611f12612126565b6001600160a01b038116611f775760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610697565b611f8081612330565b50565b611f8b612126565b6000818152600360205260409020600581015442118015611faf5750806006015442105b611fec5760405162461bcd60e51b815260206004820152600e60248201526d1a58dbc81b9bdd081bdc195b995960921b6044820152606401610697565b4260068201556040518281527f839cf22e1ba87ce2f5b9bbf46cf0175a09eed52febdfaac8852478e68203c76390602001610b6d565b61202a612126565b6000838152600360205260409020600581015442106120815760405162461bcd60e51b81526020600482015260136024820152721a58dbc8185b1c9958591e481cdd185c9d1959606a1b6044820152606401610697565b8242106120c65760405162461bcd60e51b81526020600482015260136024820152726d757374206265206675747572652074696d6560681b6044820152606401610697565b8183106121155760405162461bcd60e51b815260206004820152601d60248201527f737461727444617465206d757374206265666f726520656e64446174650000006044820152606401610697565b600581019290925560069091015550565b6000546001600160a01b031633146111a25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b804710156121d05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610697565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461221d576040519150601f19603f3d011682016040523d82523d6000602084013e612222565b606091505b50509050806112fb5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610697565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526112fb9084906126bf565b600082826040516020016123129291909182526001600160a01b0316602082015260400190565b60405160208183030381529060405280519060200120905092915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008261238d8584612794565b14949350505050565b3360008660018111156123ab576123ab612c07565b03612476576040516370a0823160e01b81526001600160a01b038281166004830152600091908716906370a0823190602401602060405180830381865afa1580156123fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241e9190612ed2565b9050838110156124705760405162461bcd60e51b815260206004820152601760248201527f756e6d65657420686f6c64696e672063726974657269610000000000000000006044820152606401610697565b50610a1e565b60405163543a185d60e11b81526001600160a01b038281166004830152600091829182919088169063a87430ba9060240160a060405180830381865afa1580156124c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e89190612f76565b9450945050506001600160701b03169250801580156125075750858310155b801561251b5750848265ffffffffffff1610155b6125675760405162461bcd60e51b815260206004820152601760248201527f756e6d656574207374616b696e672063726974657269610000000000000000006044820152606401610697565b505050505050505050565b600061257e86336122eb565b60008181526005602052604081209192508660018111156125a1576125a1612c07565b0361262e5780546000906125b6908690612f01565b9050858111156126085760405162461bcd60e51b815260206004820152601b60248201527f686f6c64206f707420636f6e747269627574696f6e206c696d697400000000006044820152606401610697565b808255600282018054859190600090612622908490612f01565b909155506126b6915050565b60008482600101546126409190612f01565b9050858111156126925760405162461bcd60e51b815260206004820152601c60248201527f7374616b65206f707420636f6e747269627574696f6e206c696d6974000000006044820152606401610697565b808260010181905550838260030160008282546126af9190612f01565b9091555050505b50505050505050565b6000612714826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166127e19092919063ffffffff16565b90508051600014806127355750808060200190518101906127359190613193565b6112fb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610697565b600081815b84518110156127d9576127c5828683815181106127b8576127b8612f49565b60200260200101516127f8565b9150806127d181612fed565b915050612799565b509392505050565b60606127f0848460008561282a565b949350505050565b6000818310612814576000828152602084905260409020612823565b60008381526020839052604090205b9392505050565b60608247101561288b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610697565b600080866001600160a01b031685876040516128a791906131b0565b60006040518083038185875af1925050503d80600081146128e4576040519150601f19603f3d011682016040523d82523d6000602084013e6128e9565b606091505b50915091506128fa87838387612905565b979650505050505050565b6060831561297457825160000361296d576001600160a01b0385163b61296d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610697565b50816127f0565b6127f083838151156129895781518083602001fd5b8060405162461bcd60e51b815260040161069791906131cc565b6000602082840312156129b557600080fd5b5035919050565b80356001600160a01b03811681146129d357600080fd5b919050565b600080604083850312156129eb57600080fd5b823591506129fb602084016129bc565b90509250929050565b60008060408385031215612a1757600080fd5b50508035926020909101359150565b60008083601f840112612a3857600080fd5b50813567ffffffffffffffff811115612a5057600080fd5b6020830191508360208260051b8501011115612a6b57600080fd5b9250929050565b8015158114611f8057600080fd5b60008060008060608587031215612a9657600080fd5b84359350602085013567ffffffffffffffff811115612ab457600080fd5b612ac087828801612a26565b9094509250506040850135612ad481612a72565b939692955090935050565b600080600060608486031215612af457600080fd5b83359250612b04602085016129bc565b91506040840135612b1481612a72565b809150509250925092565b60028110611f8057600080fd5b6000806000806000806000806000806101208b8d031215612b4c57600080fd5b8a35612b5781612b1f565b9950612b6560208c016129bc565b9850612b7360408c016129bc565b9750612b8160608c016129bc565b965060808b013567ffffffffffffffff80821115612b9e57600080fd5b818d0191508d601f830112612bb257600080fd5b813581811115612bc157600080fd5b8e6020828501011115612bd357600080fd5b9b9e9a9d50989b979a6020919091019990985060a08801359760c0810135975060e081013596506101000135945092505050565b634e487b7160e01b600052602160045260246000fd5b60028110611f8057634e487b7160e01b600052602160045260246000fd5b612c4481612c1d565b9052565b60005b83811015612c63578181015183820152602001612c4b565b50506000910152565b60008151808452612c84816020860160208601612c48565b601f01601f19169290920160200192915050565b60208152612caa602082018351612c3b565b60006020830151612cc660408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b03811660808401525060808301516001600160a01b03811660a08401525060a08301516101608060c0850152612d22610180850183612c6c565b60c086015160e0868101919091528601516101008087019190915286015161012080870191909152860151610140808701919091529095015115159301929092525090919050565b60008060408385031215612d7d57600080fd5b612d86836129bc565b946020939093013593505050565b60008060008060008060008060006101008a8c031215612db357600080fd5b8935612dbe81612b1f565b985060208a0135975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a013567ffffffffffffffff811115612e0457600080fd5b612e108c828d01612a26565b915080935050809150509295985092959850929598565b600060208284031215612e3957600080fd5b612823826129bc565b600080600060608486031215612e5757600080fd5b505081359360208301359350604090920135919050565b600181811c90821680612e8257607f821691505b602082108103612ea257634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526010908201526f1a58dbc81b9bdd08199a5b9a5cda195960821b604082015260600190565b600060208284031215612ee457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ac857610ac8612eeb565b81810381811115610ac857610ac8612eeb565b600082612f4457634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160701b03811681146129d357600080fd5b600080600080600060a08688031215612f8e57600080fd5b612f9786612f5f565b9450612fa560208701612f5f565b9350612fb360408701612f5f565b9250606086015165ffffffffffff81168114612fce57600080fd5b6080870151909250612fdf81612a72565b809150509295509295909350565b600060018201612fff57612fff612eeb565b5060010190565b634e487b7160e01b600052604160045260246000fd5b601f8211156112fb57600081815260208120601f850160051c810160208610156130435750805b601f850160051c820191505b81811015610a1e5782815560010161304f565b815167ffffffffffffffff81111561307c5761307c613006565b6130908161308a8454612e6e565b8461301c565b602080601f8311600181146130c557600084156130ad5750858301515b600019600386901b1c1916600185901b178555610a1e565b600085815260208120601f198616915b828110156130f4578886015182559484019460019091019084016130d5565b50858210156131125787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61312b87612c1d565b60f89690961b86526001860194909452602185019290925260418401526061830152608182015260a10190565b8581526001600160a01b038516602082015260a0810161317785612c1d565b8460408301528360608301528260808301529695505050505050565b6000602082840312156131a557600080fd5b815161282381612a72565b600082516131c2818460208701612c48565b9190910192915050565b6020815260006128236020830184612c6c56fea2646970667358221220ac627b9534c0d8cf9190fb05d1bda002f0534e9779e7a718b41f9a5a652c2f2a64736f6c63430008130033
Deployed Bytecode
0x6080604052600436106101405760003560e01c8063a03df5e5116100b6578063d285e33f1161006f578063d285e33f146103d8578063d32531741461043c578063d5a788ce1461044f578063f2fde38b1461046d578063f775e5041461048d578063fff24d19146104ad57600080fd5b8063a03df5e51461030b578063a0de6f351461032b578063a839eae61461034b578063b0dcb0a31461036b578063b29a814014610398578063b8bec6cc146103b857600080fd5b80634350cd93116101085780634350cd931461023e57806346e04a2f1461025e5780634ae001d81461027e5780635c3c9734146102ae578063715018a6146102ce5780638da5cb5b146102e357600080fd5b8063155dd5ee146101455780632143a50f146101675780632344091e14610187578063338531c9146101fe5780633dd2e3291461021e575b600080fd5b34801561015157600080fd5b506101656101603660046129a3565b6104cd565b005b34801561017357600080fd5b506101656101823660046129a3565b610766565b34801561019357600080fd5b506101a76101a23660046129d8565b610a26565b6040516101f59190600060c082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015292915050565b60405180910390f35b34801561020a57600080fd5b50610165610219366004612a04565b610ace565b34801561022a57600080fd5b50610165610239366004612a04565b610b79565b34801561024a57600080fd5b506101656102593660046129a3565b610bdc565b34801561026a57600080fd5b506101656102793660046129a3565b610c93565b34801561028a57600080fd5b5061029e6102993660046129d8565b61111c565b60405190151581526020016101f5565b3480156102ba57600080fd5b506101656102c9366004612a80565b611143565b3480156102da57600080fd5b50610165611190565b3480156102ef57600080fd5b506000546040516001600160a01b0390911681526020016101f5565b34801561031757600080fd5b50610165610326366004612adf565b6111a4565b34801561033757600080fd5b50610165610346366004612b2c565b611300565b34801561035757600080fd5b506101656103663660046129d8565b611728565b34801561037757600080fd5b5061038b6103863660046129a3565b61180d565b6040516101f59190612c98565b3480156103a457600080fd5b506101656103b3366004612d6a565b6119b9565b3480156103c457600080fd5b506101656103d33660046129a3565b6119d9565b3480156103e457600080fd5b506103f86103f33660046129a3565b611a90565b6040516101f59190600060a0820190508251825260208301516020830152604083015160408301526060830151606083015260808301511515608083015292915050565b61016561044a366004612d94565b611b15565b34801561045b57600080fd5b506001546040519081526020016101f5565b34801561047957600080fd5b50610165610488366004612e27565b611f0a565b34801561049957600080fd5b506101656104a83660046129a3565b611f83565b3480156104b957600080fd5b506101656104c8366004612e42565b612022565b6104d5612126565b6000818152600460208181526040808420815160a08101835281548152600180830154828601526002830154828501526003808401546060840152929095015460ff9081161515608083015287875291909352818520825161016081019093528054939594929390928492919091169081111561055457610554612c07565b600181111561056557610565612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a0909201916105b690612e6e565b80601f01602080910402602001604051908101604052809291908181526020018280546105e290612e6e565b801561062f5780601f106106045761010080835404028352916020019161062f565b820191906000526020600020905b81548152906001019060200180831161061257829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015260e08101519091504210156106a05760405162461bcd60e51b815260040161069790612ea8565b60405180910390fd5b8160800151156106e65760405162461bcd60e51b815260206004820152601160248201527030b63932b0b23c903bb4ba34323930bbb760791b6044820152606401610697565b81518061072b5760405162461bcd60e51b81526020600482015260136024820152726e6f7468696e6720746f20776974686472617760681b6044820152606401610697565b60208201516107436001600160a01b03821683612180565b50505060009182525060046020819052604090912001805460ff19166001179055565b61076e612126565b6000818152600460208181526040808420815160a08101835281548152600180830154828601526002830154828501526003808401546060840152929095015460ff908116151560808301528787529190935281852082516101608101909352805493959492939092849291909116908111156107ed576107ed612c07565b60018111156107fe576107fe612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a09092019161084f90612e6e565b80601f016020809104026020016040519081016040528092919081815260200182805461087b90612e6e565b80156108c85780601f1061089d576101008083540402835291602001916108c8565b820191906000526020600020905b8154815290600101906020018083116108ab57829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015260e08101519091504210156109305760405162461bcd60e51b815260040161069790612ea8565b604081810151606084015191516370a0823160e01b815230600482015290916000916001600160a01b038416906370a0823190602401602060405180830381865afa158015610983573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a79190612ed2565b6109b19190612f01565b6040850151909150808210156109ff5760405162461bcd60e51b81526020600482015260136024820152721a5b9cdd59999a58da595b9d08185b5bdd5b9d606a1b6044820152606401610697565b610a1e33610a0d8385612f14565b6001600160a01b0386169190612299565b505050505050565b610a616040518060c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6000610a6d84846122eb565b600090815260056020818152604092839020835160c08101855281548152600182015492810192909252600281015493820193909352600383015460608201526004830154608082015291015460ff16151560a08201529150505b92915050565b610ad6612126565b600082815260046020526040902054811015610b265760405162461bcd60e51b815260206004820152600f60248201526e1b5bdc99481858d8dd5b5b185d1959608a1b6044820152606401610697565b60008281526003602090815260409182902060070183905581518481529081018390527f63afb649c3004190251012cbd8328870222bc5975be8fdb3d9b3d4094c04832f91015b60405180910390a15050565b610b81612126565b60008281526003602052604090206008810154829003610bd55760405162461bcd60e51b815260206004820152600f60248201526e1b9bdd1a1a5b99c818da185b99d959608a1b6044820152606401610697565b6008015550565b610be4612126565b60008181526003602052604090206005810154610c345760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a59081a58dbc81a5960921b6044820152606401610697565b60018101546001600160a01b0316610c825760405162461bcd60e51b81526020600482015260116024820152701a58dbc81d1bdad95b881b9bdd081cd95d607a1b6044820152606401610697565b600901805460ff1916600117905550565b336000610ca083836122eb565b6000848152600360205260408082208151610160810190925280549394509192909190829060ff166001811115610cd957610cd9612c07565b6001811115610cea57610cea612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a090920191610d3b90612e6e565b80601f0160208091040260200160405190810160405280929190818152602001828054610d6790612e6e565b8015610db45780601f10610d8957610100808354040283529160200191610db4565b820191906000526020600020905b815481529060010190602001808311610d9757829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015260e08101519091504211610e3a5760405162461bcd60e51b815260206004820152600c60248201526b1b9bdd08199a5b9a5cda195960a21b6044820152606401610697565b806101400151610e7d5760405162461bcd60e51b815260206004820152600e60248201526d18db185a5b48191a5cd8589b195960921b6044820152606401610697565b6000828152600560208181526040808420815160c08101835281548152600182015481850152600282015481840152600382015460608201526004820154608082015293015460ff908116151560a085015286855260069092529092205490911615610f195760405162461bcd60e51b815260206004820152600b60248201526a189b1858dadb1a5cdd195960aa1b6044820152606401610697565b8060a0015115610f5d5760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b6044820152606401610697565b600081606001518260400151610f739190612f01565b905080600003610fb95760405162461bcd60e51b81526020600482015260116024820152706e6f7468696e6720636c61696d61626c6560781b6044820152606401610697565b600083516001811115610fce57610fce612c07565b03610ff557600084815260056020819052604090912001805460ff19166001179055611079565b611000600282612f27565b608083015190915015611079576201518082608001516110209190612f01565b42101561105b5760405162461bcd60e51b815260206004820152600960248201526877616974206d6f726560b81b6044820152606401610697565b600084815260056020819052604090912001805460ff191660011790555b6040830151611092906001600160a01b03168683612299565b600084815260056020908152604080832042600491820155898452909152812060030180548392906110c5908490612f01565b9091555050604080518781526001600160a01b03871660208201529081018290527f4ec90e965519d92681267467f775ada5bd214aa92c0dc93d90a5e880ce9ed026906060015b60405180910390a1505050505050565b60008061112984846122eb565b60009081526006602052604090205460ff16949350505050565b61114b612126565b8160005b81811015610a1e576111888686868481811061116d5761116d612f49565b90506020020160208101906111829190612e27565b856111a4565b60010161114f565b611198612126565b6111a26000612330565b565b6111ac612126565b60006111b884846122eb565b60008181526006602052604090205490915082151560ff9091161515036111df5750505050565b6000818152600660209081526040808320805460ff19168615151790556005808352818420825160c0810184528154815260018201549481019490945260028101549284018390526003810154606085018190526004820154608086015291015460ff16151560a084015291929161125691612f01565b9050831561128a576000868152600460205260408120600201805483929061127f908490612f14565b909155506112b19050565b600086815260046020526040812060020180548392906112ab908490612f01565b90915550505b604080518781526001600160a01b0387166020820152851515918101919091527f2db3614065e8970939807c373f1f9e7b2a066e8d30b7bdec226123ce1675d37c9060600161110c565b505050565b611308612126565b6001600160a01b0389166113515760405162461bcd60e51b815260206004820152601060248201526f696e76616c696420747265617375727960801b6044820152606401610697565b60405163543a185d60e11b8152600060048201526001600160a01b0388169063a87430ba9060240160a060405180830381865afa158015611396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ba9190612f76565b50506040516370a0823160e01b81523060048201526001600160a01b038c1693506370a0823192506024019050602060405180830381865afa158015611404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114289190612ed2565b5060025460ff161561146f5760405162461bcd60e51b815260206004820152601060248201526f636c6f7365206f70656e65642069636f60801b6044820152606401610697565b8342106114b45760405162461bcd60e51b81526020600482015260136024820152726d757374206265206675747572652074696d6560681b6044820152606401610697565b8284106115035760405162461bcd60e51b815260206004820152601d60248201527f737461727444617465206d757374206265666f726520656e64446174650000006044820152606401610697565b60006040518061016001604052808c600181111561152357611523612c07565b81526020018b6001600160a01b0316815260200160006001600160a01b031681526020018a6001600160a01b03168152602001896001600160a01b0316815260200188888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050506020820188905260408201879052606082018690526080820185905260a0909101526001549091506115ce81612fed565b6001818155600082815260036020526040902084518154939450859391929091839160ff1990911690838181111561160857611608612c07565b0217905550602082015181546001600160a01b0391821661010002610100600160a81b031990911617825560408301516001830180549183166001600160a01b03199283161790556060840151600284018054918416918316919091179055608084015160038401805491909316911617905560a0820151600482019061168f9082613062565b5060c0820151600582015560e0820151600682015561010082015160078201556101208201516008820155610140909101516009909101805491151560ff199283161790556002805490911660011790556040517f8b002cb4c916c04e43329d1c0e03784c1a5aa2dc49caf95224aae4fca1fa896c906117129083815260200190565b60405180910390a1505050505050505050505050565b611730612126565b600082815260036020526040902060058101546117805760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a59081a58dbc81a5960921b6044820152606401610697565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa1580156117c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e89190612ed2565b5060010180546001600160a01b0319166001600160a01b039290921691909117905550565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a082015260c0810182905260e081018290526101008101829052610120810182905261014081019190915260008281526003602052604090819020815161016081019092528054829060ff16600181111561189757611897612c07565b60018111156118a8576118a8612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a0909201916118f990612e6e565b80601f016020809104026020016040519081016040528092919081815260200182805461192590612e6e565b80156119725780601f1061194757610100808354040283529160200191611972565b820191906000526020600020905b81548152906001019060200180831161195557829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015292915050565b6119c1612126565b6119d56001600160a01b0383163383612299565b5050565b6119e1612126565b600081815260036020526040902060068101544211611a125760405162461bcd60e51b815260040161069790612ea8565b60025460ff16611a595760405162461bcd60e51b815260206004820152601260248201527130b63932b0b23c903a3ab93732b21037b33360711b6044820152606401610697565b6002805460ff191690556040517f985fcc741e81f00ad7a35e096d9082cef5563b2c67effcdec4a438da5ae419c790600090a15050565b611ac46040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b50600090815260046020818152604092839020835160a081018552815481526001820154928101929092526002810154938201939093526003830154606082015291015460ff161515608082015290565b336000611b228a836122eb565b60008b815260046020908152604080832060039092528083208151610160810190925280549495509193909190829060ff166001811115611b6557611b65612c07565b6001811115611b7657611b76612c07565b815281546001600160a01b0361010090910481166020830152600183015481166040830152600283015481166060830152600383015416608082015260048201805460a090920191611bc790612e6e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf390612e6e565b8015611c405780601f10611c1557610100808354040283529160200191611c40565b820191906000526020600020905b815481529060010190602001808311611c2357829003601f168201915b50505091835250506005820154602082015260068201546040820152600782015460608201526008820154608082015260099091015460ff16151560a09091015260c08101519091504210801590611c9b57508060e0015142105b611cd85760405162461bcd60e51b815260206004820152600e60248201526d1a58dbc81b9bdd081bdc195b995960921b6044820152606401610697565b87341015611d155760405162461bcd60e51b815260206004820152600a6024820152696c6573732066756e647360b01b6044820152606401610697565b611db3868680806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508261012001518f8e8e8e8e8e604051602001611d7b96959493929190613122565b60408051601f198184030181528282528051602091820120908301520160405160208183030381529060405280519060200120612380565b611dee5760405162461bcd60e51b815260206004820152600c60248201526b1c1c9bdbd98819985a5b195960a21b6044820152606401610697565b611e038d826060015183608001518e8e612396565b611e108c8e8b8b8b612572565b87826000016000828254611e249190612f01565b9250508190555086826001016000828254611e3f9190612f01565b909155505060008381526006602052604090205460ff16611e745786826002016000828254611e6e9190612f01565b90915550505b61010081015182541115611ebc5760405162461bcd60e51b815260206004820152600f60248201526e072656163686564206861726463617608c1b6044820152606401610697565b7fcce9dcaf129f1357203918bd0fea386caf9679f9513a13a6081dec19de1658738c858f8b8b604051611ef3959493929190613158565b60405180910390a150505050505050505050505050565b611f12612126565b6001600160a01b038116611f775760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610697565b611f8081612330565b50565b611f8b612126565b6000818152600360205260409020600581015442118015611faf5750806006015442105b611fec5760405162461bcd60e51b815260206004820152600e60248201526d1a58dbc81b9bdd081bdc195b995960921b6044820152606401610697565b4260068201556040518281527f839cf22e1ba87ce2f5b9bbf46cf0175a09eed52febdfaac8852478e68203c76390602001610b6d565b61202a612126565b6000838152600360205260409020600581015442106120815760405162461bcd60e51b81526020600482015260136024820152721a58dbc8185b1c9958591e481cdd185c9d1959606a1b6044820152606401610697565b8242106120c65760405162461bcd60e51b81526020600482015260136024820152726d757374206265206675747572652074696d6560681b6044820152606401610697565b8183106121155760405162461bcd60e51b815260206004820152601d60248201527f737461727444617465206d757374206265666f726520656e64446174650000006044820152606401610697565b600581019290925560069091015550565b6000546001600160a01b031633146111a25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b804710156121d05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610697565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461221d576040519150601f19603f3d011682016040523d82523d6000602084013e612222565b606091505b50509050806112fb5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610697565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526112fb9084906126bf565b600082826040516020016123129291909182526001600160a01b0316602082015260400190565b60405160208183030381529060405280519060200120905092915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008261238d8584612794565b14949350505050565b3360008660018111156123ab576123ab612c07565b03612476576040516370a0823160e01b81526001600160a01b038281166004830152600091908716906370a0823190602401602060405180830381865afa1580156123fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241e9190612ed2565b9050838110156124705760405162461bcd60e51b815260206004820152601760248201527f756e6d65657420686f6c64696e672063726974657269610000000000000000006044820152606401610697565b50610a1e565b60405163543a185d60e11b81526001600160a01b038281166004830152600091829182919088169063a87430ba9060240160a060405180830381865afa1580156124c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e89190612f76565b9450945050506001600160701b03169250801580156125075750858310155b801561251b5750848265ffffffffffff1610155b6125675760405162461bcd60e51b815260206004820152601760248201527f756e6d656574207374616b696e672063726974657269610000000000000000006044820152606401610697565b505050505050505050565b600061257e86336122eb565b60008181526005602052604081209192508660018111156125a1576125a1612c07565b0361262e5780546000906125b6908690612f01565b9050858111156126085760405162461bcd60e51b815260206004820152601b60248201527f686f6c64206f707420636f6e747269627574696f6e206c696d697400000000006044820152606401610697565b808255600282018054859190600090612622908490612f01565b909155506126b6915050565b60008482600101546126409190612f01565b9050858111156126925760405162461bcd60e51b815260206004820152601c60248201527f7374616b65206f707420636f6e747269627574696f6e206c696d6974000000006044820152606401610697565b808260010181905550838260030160008282546126af9190612f01565b9091555050505b50505050505050565b6000612714826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166127e19092919063ffffffff16565b90508051600014806127355750808060200190518101906127359190613193565b6112fb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610697565b600081815b84518110156127d9576127c5828683815181106127b8576127b8612f49565b60200260200101516127f8565b9150806127d181612fed565b915050612799565b509392505050565b60606127f0848460008561282a565b949350505050565b6000818310612814576000828152602084905260409020612823565b60008381526020839052604090205b9392505050565b60608247101561288b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610697565b600080866001600160a01b031685876040516128a791906131b0565b60006040518083038185875af1925050503d80600081146128e4576040519150601f19603f3d011682016040523d82523d6000602084013e6128e9565b606091505b50915091506128fa87838387612905565b979650505050505050565b6060831561297457825160000361296d576001600160a01b0385163b61296d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610697565b50816127f0565b6127f083838151156129895781518083602001fd5b8060405162461bcd60e51b815260040161069791906131cc565b6000602082840312156129b557600080fd5b5035919050565b80356001600160a01b03811681146129d357600080fd5b919050565b600080604083850312156129eb57600080fd5b823591506129fb602084016129bc565b90509250929050565b60008060408385031215612a1757600080fd5b50508035926020909101359150565b60008083601f840112612a3857600080fd5b50813567ffffffffffffffff811115612a5057600080fd5b6020830191508360208260051b8501011115612a6b57600080fd5b9250929050565b8015158114611f8057600080fd5b60008060008060608587031215612a9657600080fd5b84359350602085013567ffffffffffffffff811115612ab457600080fd5b612ac087828801612a26565b9094509250506040850135612ad481612a72565b939692955090935050565b600080600060608486031215612af457600080fd5b83359250612b04602085016129bc565b91506040840135612b1481612a72565b809150509250925092565b60028110611f8057600080fd5b6000806000806000806000806000806101208b8d031215612b4c57600080fd5b8a35612b5781612b1f565b9950612b6560208c016129bc565b9850612b7360408c016129bc565b9750612b8160608c016129bc565b965060808b013567ffffffffffffffff80821115612b9e57600080fd5b818d0191508d601f830112612bb257600080fd5b813581811115612bc157600080fd5b8e6020828501011115612bd357600080fd5b9b9e9a9d50989b979a6020919091019990985060a08801359760c0810135975060e081013596506101000135945092505050565b634e487b7160e01b600052602160045260246000fd5b60028110611f8057634e487b7160e01b600052602160045260246000fd5b612c4481612c1d565b9052565b60005b83811015612c63578181015183820152602001612c4b565b50506000910152565b60008151808452612c84816020860160208601612c48565b601f01601f19169290920160200192915050565b60208152612caa602082018351612c3b565b60006020830151612cc660408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b03811660808401525060808301516001600160a01b03811660a08401525060a08301516101608060c0850152612d22610180850183612c6c565b60c086015160e0868101919091528601516101008087019190915286015161012080870191909152860151610140808701919091529095015115159301929092525090919050565b60008060408385031215612d7d57600080fd5b612d86836129bc565b946020939093013593505050565b60008060008060008060008060006101008a8c031215612db357600080fd5b8935612dbe81612b1f565b985060208a0135975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a013567ffffffffffffffff811115612e0457600080fd5b612e108c828d01612a26565b915080935050809150509295985092959850929598565b600060208284031215612e3957600080fd5b612823826129bc565b600080600060608486031215612e5757600080fd5b505081359360208301359350604090920135919050565b600181811c90821680612e8257607f821691505b602082108103612ea257634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526010908201526f1a58dbc81b9bdd08199a5b9a5cda195960821b604082015260600190565b600060208284031215612ee457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ac857610ac8612eeb565b81810381811115610ac857610ac8612eeb565b600082612f4457634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160701b03811681146129d357600080fd5b600080600080600060a08688031215612f8e57600080fd5b612f9786612f5f565b9450612fa560208701612f5f565b9350612fb360408701612f5f565b9250606086015165ffffffffffff81168114612fce57600080fd5b6080870151909250612fdf81612a72565b809150509295509295909350565b600060018201612fff57612fff612eeb565b5060010190565b634e487b7160e01b600052604160045260246000fd5b601f8211156112fb57600081815260208120601f850160051c810160208610156130435750805b601f850160051c820191505b81811015610a1e5782815560010161304f565b815167ffffffffffffffff81111561307c5761307c613006565b6130908161308a8454612e6e565b8461301c565b602080601f8311600181146130c557600084156130ad5750858301515b600019600386901b1c1916600185901b178555610a1e565b600085815260208120601f198616915b828110156130f4578886015182559484019460019091019084016130d5565b50858210156131125787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61312b87612c1d565b60f89690961b86526001860194909452602185019290925260418401526061830152608182015260a10190565b8581526001600160a01b038516602082015260a0810161317785612c1d565b8460408301528360608301528260808301529695505050505050565b6000602082840312156131a557600080fd5b815161282381612a72565b600082516131c2818460208701612c48565b9190910192915050565b6020815260006128236020830184612c6c56fea2646970667358221220ac627b9534c0d8cf9190fb05d1bda002f0534e9779e7a718b41f9a5a652c2f2a64736f6c63430008130033
Deployed Bytecode Sourcemap
50659:19811:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64423:603;;;;;;;;;;-1:-1:-1;64423:603:0;;;;;:::i;:::-;;:::i;:::-;;63675:633;;;;;;;;;;-1:-1:-1;63675:633:0;;;;;:::i;:::-;;:::i;69493:210::-;;;;;;;;;;-1:-1:-1;69493:210:0;;;;;:::i;:::-;;:::i;:::-;;;;;;876:4:1;918:3;907:9;903:19;895:27;;955:6;949:13;938:9;931:32;1019:4;1011:6;1007:17;1001:24;994:4;983:9;979:20;972:54;1082:4;1074:6;1070:17;1064:24;1057:4;1046:9;1042:20;1035:54;1145:4;1137:6;1133:17;1127:24;1120:4;1109:9;1105:20;1098:54;1208:4;1200:6;1196:17;1190:24;1183:4;1172:9;1168:20;1161:54;1285:4;1277:6;1273:17;1267:24;1260:32;1253:40;1246:4;1235:9;1231:20;1224:70;732:568;;;;;69493:210:0;;;;;;;;68697:331;;;;;;;;;;-1:-1:-1;68697:331:0;;;;;:::i;:::-;;:::i;69142:298::-;;;;;;;;;;-1:-1:-1;69142:298:0;;;;;:::i;:::-;;:::i;67870:294::-;;;;;;;;;;-1:-1:-1;67870:294:0;;;;;:::i;:::-;;:::i;61291:1330::-;;;;;;;;;;-1:-1:-1;61291:1330:0;;;;;:::i;:::-;;:::i;66531:201::-;;;;;;;;;;-1:-1:-1;66531:201:0;;;;;:::i;:::-;;:::i;:::-;;;1976:14:1;;1969:22;1951:41;;1939:2;1924:18;66531:201:0;1811:187:1;65153:362:0;;;;;;;;;;-1:-1:-1;65153:362:0;;;;;:::i;:::-;;:::i;2979:103::-;;;;;;;;;;;;;:::i;2338:87::-;;;;;;;;;;-1:-1:-1;2384:7:0;2411:6;2338:87;;-1:-1:-1;;;;;2411:6:0;;;3392:51:1;;3380:2;3365:18;2338:87:0;3246:203:1;65636:824:0;;;;;;;;;;-1:-1:-1;65636:824:0;;;;;:::i;:::-;;:::i;54134:1442::-;;;;;;;;;;-1:-1:-1;54134:1442:0;;;;;:::i;:::-;;:::i;68254:351::-;;;;;;;;;;-1:-1:-1;68254:351:0;;;;;:::i;:::-;;:::i;66810:138::-;;;;;;;;;;-1:-1:-1;66810:138:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;70324:143::-;;;;;;;;;;-1:-1:-1;70324:143:0;;;;;:::i;:::-;;:::i;63246:308::-;;;;;;;;;;-1:-1:-1;63246:308:0;;;;;:::i;:::-;;:::i;67023:141::-;;;;;;;;;;-1:-1:-1;67023:141:0;;;;;:::i;:::-;;:::i;:::-;;;;;;8066:4:1;8108:3;8097:9;8093:19;8085:27;;8145:6;8139:13;8128:9;8121:32;8209:4;8201:6;8197:17;8191:24;8184:4;8173:9;8169:20;8162:54;8272:4;8264:6;8260:17;8254:24;8247:4;8236:9;8232:20;8225:54;8335:4;8327:6;8323:17;8317:24;8310:4;8299:9;8295:20;8288:54;8412:4;8404:6;8400:17;8394:24;8387:32;8380:40;8373:4;8362:9;8358:20;8351:70;7922:505;;;;;56340:2144:0;;;;;;:::i;:::-;;:::i;69749:89::-;;;;;;;;;;-1:-1:-1;69820:10:0;;69749:89;;9598:25:1;;;9586:2;9571:18;69749:89:0;9452:177:1;3237:201:0;;;;;;;;;;-1:-1:-1;3237:201:0;;;;;:::i;:::-;;:::i;62797:366::-;;;;;;;;;;-1:-1:-1;62797:366:0;;;;;:::i;:::-;;:::i;67273:499::-;;;;;;;;;;-1:-1:-1;67273:499:0;;;;;:::i;:::-;;:::i;64423:603::-;2224:13;:11;:13::i;:::-;64492:24:::1;64519:21:::0;;;:13:::1;:21;::::0;;;;;;;64492:48;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;::::1;;;::::0;;;;64576:20;;;;;;;;;;64551:45;;::::1;::::0;::::1;::::0;;;;;64492:48;;:24;64551:45;;64576:20;;64551:45;;;;;::::1;::::0;;::::1;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;::::0;;;;-1:-1:-1;;;;;64551:45:0::1;::::0;;::::1;::::0;::::1;;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;64551:45:0;;;-1:-1:-1;;64551:45:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;::::1;;;;::::0;;;;;64636:15:::1;::::0;::::1;::::0;64551:45;;-1:-1:-1;64617:15:0::1;:34;;64609:63;;;;-1:-1:-1::0;;;64609:63:0::1;;;;;;;:::i;:::-;;;;;;;;;64692:8;:23;;;64691:24;64683:54;;;::::0;-1:-1:-1;;;64683:54:0;;11078:2:1;64683:54:0::1;::::0;::::1;11060:21:1::0;11117:2;11097:18;;;11090:30;-1:-1:-1;;;11136:18:1;;;11129:47;11193:18;;64683:54:0::1;10876:341:1::0;64683:54:0::1;64772:21:::0;;64812:17;64804:49:::1;;;::::0;-1:-1:-1;;;64804:49:0;;11424:2:1;64804:49:0::1;::::0;::::1;11406:21:1::0;11463:2;11443:18;;;11436:30;-1:-1:-1;;;11482:18:1;;;11475:49;11541:18;;64804:49:0::1;11222:343:1::0;64804:49:0::1;64901:16;::::0;::::1;::::0;64929:33:::1;-1:-1:-1::0;;;;;64929:18:0;::::1;64948:13:::0;64929:18:::1;:33::i;:::-;-1:-1:-1::0;;;64975:21:0::1;::::0;;;-1:-1:-1;64975:13:0::1;:21;::::0;;;;;;;:36:::1;:43:::0;;-1:-1:-1;;64975:43:0::1;65014:4;64975:43;::::0;;64423:603::o;63675:633::-;2224:13;:11;:13::i;:::-;63753:24:::1;63780:21:::0;;;:13:::1;:21;::::0;;;;;;;63753:48;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;::::1;;;::::0;;;;63837:20;;;;;;;;;;63812:45;;::::1;::::0;::::1;::::0;;;;;63753:48;;:24;63812:45;;63837:20;;63812:45;;;;;::::1;::::0;;::::1;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;::::0;;;;-1:-1:-1;;;;;63812:45:0::1;::::0;;::::1;::::0;::::1;;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;63812:45:0;;;-1:-1:-1;;63812:45:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;::::1;;;;::::0;;;;;63895:15:::1;::::0;::::1;::::0;63812:45;;-1:-1:-1;63876:15:0::1;:34;;63868:63;;;;-1:-1:-1::0;;;63868:63:0::1;;;;;;;:::i;:::-;63969:16;::::0;;::::1;::::0;64071:22:::1;::::0;::::1;::::0;64022:33;;-1:-1:-1;;;64022:33:0;;64049:4:::1;64022:33;::::0;::::1;3392:51:1::0;63969:16:0;;63944:15:::1;::::0;-1:-1:-1;;;;;64022:18:0;::::1;::::0;::::1;::::0;3365::1;;64022:33:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:71;;;;:::i;:::-;64127:21;::::0;::::1;::::0;63997:96;;-1:-1:-1;64167:30:0;;::::1;;64159:62;;;::::0;-1:-1:-1;;;64159:62:0;;12223:2:1;64159:62:0::1;::::0;::::1;12205:21:1::0;12262:2;12242:18;;;12235:30;-1:-1:-1;;;12281:18:1;;;12274:49;12340:18;;64159:62:0::1;12021:343:1::0;64159:62:0::1;64234:66;914:10:::0;64270:29:::1;64287:12:::0;64270:14;:29:::1;:::i;:::-;-1:-1:-1::0;;;;;64234:21:0;::::1;::::0;:66;:21:::1;:66::i;:::-;63742:566;;;;;63675:633:::0;:::o;69493:210::-;69597:15;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69597:15:0;69625:11;69639:24;69646:6;69654:8;69639:6;:24::i;:::-;69681:14;;;;:9;:14;;;;;;;;;69674:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;69493:210:0;;;;;:::o;68697:331::-;2224:13;:11;:13::i;:::-;68843:21:::1;::::0;;;:13:::1;:21;::::0;;;;:34;68831:46;::::1;;68809:111;;;::::0;-1:-1:-1;;;68809:111:0;;12704:2:1;68809:111:0::1;::::0;::::1;12686:21:1::0;12743:2;12723:18;;;12716:30;-1:-1:-1;;;12762:18:1;;;12755:45;12817:18;;68809:111:0::1;12502:339:1::0;68809:111:0::1;68931:20;::::0;;;:12:::1;:20;::::0;;;;;;;;:28:::1;;:39:::0;;;68988:32;;13020:25:1;;;13061:18;;;13054:34;;;68988:32:0::1;::::0;12993:18:1;68988:32:0::1;;;;;;;;68697:331:::0;;:::o;69142:298::-;2224:13;:11;:13::i;:::-;69263:23:::1;69289:20:::0;;;:12:::1;:20;::::0;;;;69328:21:::1;::::0;::::1;::::0;:36;;;69320:64:::1;;;::::0;-1:-1:-1;;;69320:64:0;;13301:2:1;69320:64:0::1;::::0;::::1;13283:21:1::0;13340:2;13320:18;;;13313:30;-1:-1:-1;;;13359:18:1;;;13352:45;13414:18;;69320:64:0::1;13099:339:1::0;69320:64:0::1;69397:21;;:35:::0;-1:-1:-1;69142:298:0:o;67870:294::-;2224:13;:11;:13::i;:::-;67940:23:::1;67966:20:::0;;;:12:::1;:20;::::0;;;;68005:17:::1;::::0;::::1;::::0;67997:48:::1;;;::::0;-1:-1:-1;;;67997:48:0;;13645:2:1;67997:48:0::1;::::0;::::1;13627:21:1::0;13684:2;13664:18;;;13657:30;-1:-1:-1;;;13703:18:1;;;13696:44;13757:18;;67997:48:0::1;13443:338:1::0;67997:48:0::1;68064:16;::::0;::::1;::::0;-1:-1:-1;;;;;68064:16:0::1;68056:60;;;::::0;-1:-1:-1;;;68056:60:0;;13988:2:1;68056:60:0::1;::::0;::::1;13970:21:1::0;14027:2;14007:18;;;14000:30;-1:-1:-1;;;14046:18:1;;;14039:47;14103:18;;68056:60:0::1;13786:341:1::0;68056:60:0::1;68127:22;;:29:::0;;-1:-1:-1;;68127:29:0::1;68152:4;68127:29;::::0;;-1:-1:-1;67870:294:0:o;61291:1330::-;914:10;61348:14;61402:22;61409:6;914:10;61402:6;:22::i;:::-;61435;61460:20;;;:12;:20;;;;;;61435:45;;;;;;;;;;61388:36;;-1:-1:-1;61435:22:0;;:45;;61460:20;61435:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;61435:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;61435:45:0;;;-1:-1:-1;;61435:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61499:15;;;;61435:45;;-1:-1:-1;61517:15:0;-1:-1:-1;61491:58:0;;;;-1:-1:-1;;;61491:58:0;;14334:2:1;61491:58:0;;;14316:21:1;14373:2;14353:18;;;14346:30;-1:-1:-1;;;14392:18:1;;;14385:42;14444:18;;61491:58:0;14132:336:1;61491:58:0;61568:7;:22;;;61560:49;;;;-1:-1:-1;;;61560:49:0;;14675:2:1;61560:49:0;;;14657:21:1;14714:2;14694:18;;;14687:30;-1:-1:-1;;;14733:18:1;;;14726:44;14787:18;;61560:49:0;14473:338:1;61560:49:0;61622:24;61649:14;;;:9;:14;;;;;;;;61622:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61683:15;;;:10;:15;;;;;;;61622:41;;61683:15;61682:16;61674:40;;;;-1:-1:-1;;;61674:40:0;;15018:2:1;61674:40:0;;;15000:21:1;15057:2;15037:18;;;15030:30;-1:-1:-1;;;15076:18:1;;;15069:41;15127:18;;61674:40:0;14816:335:1;61674:40:0;61734:8;:16;;;61733:17;61725:45;;;;-1:-1:-1;;;61725:45:0;;15358:2:1;61725:45:0;;;15340:21:1;15397:2;15377:18;;;15370:30;-1:-1:-1;;;15416:18:1;;;15409:45;15471:18;;61725:45:0;15156:339:1;61725:45:0;61783:20;61848:8;:27;;;61806:8;:26;;;:69;;;;:::i;:::-;61783:92;;61894:12;61910:1;61894:17;61886:47;;;;-1:-1:-1;;;61886:47:0;;15702:2:1;61886:47:0;;;15684:21:1;15741:2;15721:18;;;15714:30;-1:-1:-1;;;15760:18:1;;;15753:47;15817:18;;61886:47:0;15500:341:1;61886:47:0;61973:16;61950:19;;:39;;;;;;;;:::i;:::-;;61946:423;;62006:14;;;;:9;:14;;;;;;;;:22;:29;;-1:-1:-1;;62006:29:0;62031:4;62006:29;;;61946:423;;;62068:17;62084:1;62068:17;;:::i;:::-;62104:23;;;;62068:17;;-1:-1:-1;62104:27:0;62100:258;;52989:8;62201;:23;;;:40;;;;:::i;:::-;62182:15;:59;;62152:142;;;;-1:-1:-1;;;62152:142:0;;16270:2:1;62152:142:0;;;16252:21:1;16309:1;16289:18;;;16282:29;-1:-1:-1;;;16327:18:1;;;16320:39;16376:18;;62152:142:0;16068:332:1;62152:142:0;62313:14;;;;:9;:14;;;;;;;;:22;:29;;-1:-1:-1;;62313:29:0;62338:4;62313:29;;;62100:258;62388:16;;;;62381:59;;-1:-1:-1;;;;;62381:37:0;62419:6;62427:12;62381:37;:59::i;:::-;62451:14;;;;:9;:14;;;;;;;;62483:15;62451:29;;;;:47;62509:21;;;;;;;;:35;;:51;;62548:12;;62451:14;62509:51;;62548:12;;62509:51;:::i;:::-;;;;-1:-1:-1;;62576:37:0;;;16607:25:1;;;-1:-1:-1;;;;;16668:32:1;;16663:2;16648:18;;16641:60;16717:18;;;16710:34;;;62576:37:0;;16595:2:1;16580:18;62576:37:0;;;;;;;;61337:1284;;;;;61291:1330;:::o;66531:201::-;66636:4;66653:11;66667:24;66674:6;66682:8;66667:6;:24::i;:::-;66709:15;;;;:10;:15;;;;;;;;;66531:201;-1:-1:-1;;;;66531:201:0:o;65153:362::-;2224:13;:11;:13::i;:::-;65320:9;65306:11:::1;65347:161;65367:3;65363:1;:7;65347:161;;;65389:45;65406:6;65414:9;;65424:1;65414:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;65428:5;65389:16;:45::i;:::-;65478:3;;65347:161;;2979:103:::0;2224:13;:11;:13::i;:::-;3044:30:::1;3071:1;3044:18;:30::i;:::-;2979:103::o:0;65636:824::-;2224:13;:11;:13::i;:::-;65770:11:::1;65784:24;65791:6;65799:8;65784:6;:24::i;:::-;65823:15;::::0;;;:10:::1;:15;::::0;;;;;65770:38;;-1:-1:-1;65823:24:0;::::1;;:15;::::0;;::::1;:24;;::::0;65819:37:::1;;65849:7;65636:824:::0;;;:::o;65819:37::-:1;65898:15;::::0;;;:10:::1;:15;::::0;;;;;;;:23;;-1:-1:-1;;65898:23:0::1;::::0;::::1;;;::::0;;65961:9:::1;:14:::0;;;;;;65934:41;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;65934:41:0;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;65898:23:::1;65934:41;;;::::0;;;;;;65898:15;66009:69:::1;::::0;::::1;:::i;:::-;65986:92;;66268:5;66264:127;;;66275:21;::::0;;;:13:::1;:21;::::0;;;;:34:::1;;:50:::0;;66313:12;;66275:21;:50:::1;::::0;66313:12;;66275:50:::1;:::i;:::-;::::0;;;-1:-1:-1;66264:127:0::1;::::0;-1:-1:-1;66264:127:0::1;;66341:21;::::0;;;:13:::1;:21;::::0;;;;:34:::1;;:50:::0;;66379:12;;66341:21;:50:::1;::::0;66379:12;;66341:50:::1;:::i;:::-;::::0;;;-1:-1:-1;;66264:127:0::1;66409:43;::::0;;17083:25:1;;;-1:-1:-1;;;;;17144:32:1;;17139:2;17124:18;;17117:60;17220:14;;17213:22;17193:18;;;17186:50;;;;66409:43:0::1;::::0;17071:2:1;17056:18;66409:43:0::1;16887:355:1::0;2248:1:0::1;65636:824:::0;;;:::o;54134:1442::-;2224:13;:11;:13::i;:::-;-1:-1:-1;;;;;54481:23:0;::::1;54473:52;;;::::0;-1:-1:-1;;;54473:52:0;;17449:2:1;54473:52:0::1;::::0;::::1;17431:21:1::0;17488:2;17468:18;;;17461:30;-1:-1:-1;;;17507:18:1;;;17500:46;17563:18;;54473:52:0::1;17247:340:1::0;54473:52:0::1;54536:50;::::0;-1:-1:-1;;;54536:50:0;;54583:1:::1;54536:50;::::0;::::1;3392:51:1::0;-1:-1:-1;;;;;54536:38:0;::::1;::::0;::::1;::::0;3365:18:1;;54536:50:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;54638:46:0::1;::::0;-1:-1:-1;;;54638:46:0;;54678:4:::1;54638:46;::::0;::::1;3392:51:1::0;-1:-1:-1;;;;;54638:31:0;::::1;::::0;-1:-1:-1;54638:31:0::1;::::0;-1:-1:-1;3365:18:1;;;-1:-1:-1;54638:46:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;54736:10:0::1;::::0;::::1;;54735:11;54727:40;;;::::0;-1:-1:-1;;;54727:40:0;;18661:2:1;54727:40:0::1;::::0;::::1;18643:21:1::0;18700:2;18680:18;;;18673:30;-1:-1:-1;;;18719:18:1;;;18712:46;18775:18;;54727:40:0::1;18459:340:1::0;54727:40:0::1;54804:10;54786:15;:28;54778:60;;;::::0;-1:-1:-1;;;54778:60:0;;19006:2:1;54778:60:0::1;::::0;::::1;18988:21:1::0;19045:2;19025:18;;;19018:30;-1:-1:-1;;;19064:18:1;;;19057:49;19123:18;;54778:60:0::1;18804:343:1::0;54778:60:0::1;54870:8;54857:10;:21;54849:63;;;::::0;-1:-1:-1;;;54849:63:0;;19354:2:1;54849:63:0::1;::::0;::::1;19336:21:1::0;19393:2;19373:18;;;19366:30;19432:31;19412:18;;;19405:59;19481:18;;54849:63:0::1;19152:353:1::0;54849:63:0::1;54925:19;54947:438;;;;;;;;54983:7;54947:438;;;;;;;;:::i;:::-;;;;;55015:9;-1:-1:-1::0;;;;;54947:438:0::1;;;;;55335:1;-1:-1:-1::0;;;;;54947:438:0::1;;;;;55053:13;-1:-1:-1::0;;;;;54947:438:0::1;;;;;55097:15;-1:-1:-1::0;;;;;54947:438:0::1;;;;;55143:15;;54947:438;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;-1:-1:-1;54947:438:0;;;-1:-1:-1;;;54947:438:0::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;55412:10;54925:460;;-1:-1:-1;55433:7:0::1;55412:10:::0;55433:7:::1;:::i;:::-;55451:10;:18:::0;;;55480:19:::1;::::0;;;:12:::1;:19;::::0;;;;:26;;;;55433:7;;-1:-1:-1;55502:4:0;;55480:19;;:26;;:19;;-1:-1:-1;;55480:26:0;;::::1;::::0;;;;::::1;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;55480:26:0::1;::::0;::::1;::::0;;;-1:-1:-1;;;;;55480:26:0;;::::1;;;-1:-1:-1::0;;;;;;55480:26:0;;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;::::1;-1:-1:-1::0;;;;;;55480:26:0;;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;55480:26:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;55480:26:0;;::::1;;::::0;;55517:10:::1;:17:::0;;;;::::1;55480:26:::0;55517:17:::1;::::0;;55552:16:::1;::::0;::::1;::::0;::::1;::::0;55562:5;9598:25:1;;9586:2;9571:18;;9452:177;55552:16:0::1;;;;;;;;54462:1114;;54134:1442:::0;;;;;;;;;;:::o;68254:351::-;2224:13;:11;:13::i;:::-;68368:23:::1;68394:20:::0;;;:12:::1;:20;::::0;;;;68433:17:::1;::::0;::::1;::::0;68425:48:::1;;;::::0;-1:-1:-1;;;68425:48:0;;13645:2:1;68425:48:0::1;::::0;::::1;13627:21:1::0;13684:2;13664:18;;;13657:30;-1:-1:-1;;;13703:18:1;;;13696:44;13757:18;;68425:48:0::1;13443:338:1::0;68425:48:0::1;68484:42;::::0;-1:-1:-1;;;68484:42:0;;68520:4:::1;68484:42;::::0;::::1;3392:51:1::0;-1:-1:-1;;;;;68484:27:0;::::1;::::0;::::1;::::0;3365:18:1;;68484:42:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;68569:16:0::1;;:28:::0;;-1:-1:-1;;;;;;68569:28:0::1;-1:-1:-1::0;;;;;68569:28:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;68254:351:0:o;66810:138::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66920:20:0;;;;:12;:20;;;;;;;66913:27;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;66913:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;66913:27:0;;;-1:-1:-1;;66913:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66810:138;-1:-1:-1;;66810:138:0:o;70324:143::-;2224:13;:11;:13::i;:::-;70409:50:::1;-1:-1:-1::0;;;;;70409:27:0;::::1;914:10:::0;70451:7;70409:27:::1;:50::i;:::-;70324:143:::0;;:::o;63246:308::-;2224:13;:11;:13::i;:::-;63312:23:::1;63338:20:::0;;;:12:::1;:20;::::0;;;;63395:15:::1;::::0;::::1;::::0;63377::::1;:33;63369:62;;;;-1:-1:-1::0;;;63369:62:0::1;;;;;;;:::i;:::-;63450:10;::::0;::::1;;63442:41;;;::::0;-1:-1:-1;;;63442:41:0;;22188:2:1;63442:41:0::1;::::0;::::1;22170:21:1::0;22227:2;22207:18;;;22200:30;-1:-1:-1;;;22246:18:1;;;22239:48;22304:18;;63442:41:0::1;21986:342:1::0;63442:41:0::1;63496:10;:18:::0;;-1:-1:-1;;63496:18:0::1;::::0;;63532:14:::1;::::0;::::1;::::0;63509:5:::1;::::0;63532:14:::1;63301:253;63246:308:::0;:::o;67023:141::-;67100:15;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67100:15:0;-1:-1:-1;67135:21:0;;;;:13;:21;;;;;;;;;67128:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67023:141::o;56340:2144::-;914:10;56631:14;56685:22;56692:6;914:10;56685:6;:22::i;:::-;56718:25;56746:21;;;:13;:21;;;;;;;;56803:12;:20;;;;;;56778:45;;;;;;;;;;56671:36;;-1:-1:-1;56746:21:0;;56778:45;;56803:20;56778:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;56778:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;56778:45:0;;;-1:-1:-1;;56778:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56875:17;;;;56778:45;;-1:-1:-1;56856:15:0;:36;;;;:90;;;56931:7;:15;;;56913;:33;56856:90;56834:154;;;;-1:-1:-1;;;56834:154:0;;22535:2:1;56834:154:0;;;22517:21:1;22574:2;22554:18;;;22547:30;-1:-1:-1;;;22593:18:1;;;22586:44;22647:18;;56834:154:0;22333:338:1;56834:154:0;57020:8;57007:9;:21;;56999:44;;;;-1:-1:-1;;;56999:44:0;;22878:2:1;56999:44:0;;;22860:21:1;22917:2;22897:18;;;22890:30;-1:-1:-1;;;22936:18:1;;;22929:40;22986:18;;56999:44:0;22676:334:1;56999:44:0;57078:606;57115:6;;57078:606;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57140:7;:21;;;57342:7;57384;57426:10;57471:11;57517:8;57560:9;57291:309;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;57291:309:0;;;;;;;;;57251:376;;57291:309;57251:376;;;;57212:438;;;23736:19:1;23771:12;57212:438:0;;;;;;;;;;;;57180:489;;;;;;57078:18;:606::i;:::-;57056:668;;;;-1:-1:-1;;;57056:668:0;;23996:2:1;57056:668:0;;;23978:21:1;24035:2;24015:18;;;24008:30;-1:-1:-1;;;24054:18:1;;;24047:42;24106:18;;57056:668:0;23794:336:1;57056:668:0;57737:169;57769:7;57791;:20;;;57826:7;:22;;;57863:7;57885:10;57737:17;:169::i;:::-;57917:148;57953:6;57974:7;57996:11;58022:8;58045:9;57917:21;:148::i;:::-;58103:8;58078;:21;;;:33;;;;;;;:::i;:::-;;;;;;;;58147:9;58122:8;:21;;;:34;;;;;;;:::i;:::-;;;;-1:-1:-1;;58269:15:0;;;;:10;:15;;;;;;;;58264:56;;58311:9;58286:8;:21;;;:34;;;;;;;:::i;:::-;;;;-1:-1:-1;;58264:56:0;58366:15;;;;58341:21;;:40;;58333:68;;;;-1:-1:-1;;;58333:68:0;;24337:2:1;58333:68:0;;;24319:21:1;24376:2;24356:18;;;24349:30;-1:-1:-1;;;24395:18:1;;;24388:45;24450:18;;58333:68:0;24135:339:1;58333:68:0;58419:57;58431:6;58439;58447:7;58456:8;58466:9;58419:57;;;;;;;;;;:::i;:::-;;;;;;;;56620:1864;;;;56340:2144;;;;;;;;;:::o;3237:201::-;2224:13;:11;:13::i;:::-;-1:-1:-1;;;;;3326:22:0;::::1;3318:73;;;::::0;-1:-1:-1;;;3318:73:0;;25244:2:1;3318:73:0::1;::::0;::::1;25226:21:1::0;25283:2;25263:18;;;25256:30;25322:34;25302:18;;;25295:62;-1:-1:-1;;;25373:18:1;;;25366:36;25419:19;;3318:73:0::1;25042:402:1::0;3318:73:0::1;3402:28;3421:8;3402:18;:28::i;:::-;3237:201:::0;:::o;62797:366::-;2224:13;:11;:13::i;:::-;62864:23:::1;62890:20:::0;;;:12:::1;:20;::::0;;;;62961:17:::1;::::0;::::1;::::0;62943:15:::1;:35;:89:::0;::::1;;;;63017:7;:15;;;62999;:33;62943:89;62921:153;;;::::0;-1:-1:-1;;;62921:153:0;;22535:2:1;62921:153:0::1;::::0;::::1;22517:21:1::0;22574:2;22554:18;;;22547:30;-1:-1:-1;;;22593:18:1;;;22586:44;22647:18;;62921:153:0::1;22333:338:1::0;62921:153:0::1;63105:15;63087;::::0;::::1;:33:::0;63138:17:::1;::::0;9598:25:1;;;63138:17:0::1;::::0;9586:2:1;9571:18;63138:17:0::1;9452:177:1::0;67273:499:0;2224:13;:11;:13::i;:::-;67415:23:::1;67441:20:::0;;;:12:::1;:20;::::0;;;;67498:17:::1;::::0;::::1;::::0;67480:15:::1;:35;67472:67;;;::::0;-1:-1:-1;;;67472:67:0;;25651:2:1;67472:67:0::1;::::0;::::1;25633:21:1::0;25690:2;25670:18;;;25663:30;-1:-1:-1;;;25709:18:1;;;25702:49;25768:18;;67472:67:0::1;25449:343:1::0;67472:67:0::1;67576:10;67558:15;:28;67550:60;;;::::0;-1:-1:-1;;;67550:60:0;;19006:2:1;67550:60:0::1;::::0;::::1;18988:21:1::0;19045:2;19025:18;;;19018:30;-1:-1:-1;;;19064:18:1;;;19057:49;19123:18;;67550:60:0::1;18804:343:1::0;67550:60:0::1;67642:8;67629:10;:21;67621:63;;;::::0;-1:-1:-1;;;67621:63:0;;19354:2:1;67621:63:0::1;::::0;::::1;19336:21:1::0;19393:2;19373:18;;;19366:30;19432:31;19412:18;;;19405:59;19481:18;;67621:63:0::1;19152:353:1::0;67621:63:0::1;67697:17;::::0;::::1;:30:::0;;;;67738:15:::1;::::0;;::::1;:26:::0;-1:-1:-1;67273:499:0:o;2503:132::-;2384:7;2411:6;-1:-1:-1;;;;;2411:6:0;914:10;2567:23;2559:68;;;;-1:-1:-1;;;2559:68:0;;25999:2:1;2559:68:0;;;25981:21:1;;;26018:18;;;26011:30;26077:34;26057:18;;;26050:62;26129:18;;2559:68:0;25797:356:1;12703:317:0;12818:6;12793:21;:31;;12785:73;;;;-1:-1:-1;;;12785:73:0;;26360:2:1;12785:73:0;;;26342:21:1;26399:2;26379:18;;;26372:30;26438:31;26418:18;;;26411:59;26487:18;;12785:73:0;26158:353:1;12785:73:0;12872:12;12890:9;-1:-1:-1;;;;;12890:14:0;12912:6;12890:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12871:52;;;12942:7;12934:78;;;;-1:-1:-1;;;12934:78:0;;26928:2:1;12934:78:0;;;26910:21:1;26967:2;26947:18;;;26940:30;27006:34;26986:18;;;26979:62;27077:28;27057:18;;;27050:56;27123:19;;12934:78:0;26726:422:1;20560:177:0;20670:58;;;-1:-1:-1;;;;;27345:32:1;;20670:58:0;;;27327:51:1;27394:18;;;;27387:34;;;20670:58:0;;;;;;;;;;27300:18:1;;;;20670:58:0;;;;;;;;-1:-1:-1;;;;;20670:58:0;-1:-1:-1;;;20670:58:0;;;20643:86;;20663:5;;20643:19;:86::i;69902:171::-;69999:7;70047;70056;70036:28;;;;;;;;27606:25:1;;;-1:-1:-1;;;;;27667:32:1;27662:2;27647:18;;27640:60;27594:2;27579:18;;27432:274;70036:28:0;;;;;;;;;;;;;70026:39;;;;;;70019:46;;69902:171;;;;:::o;3598:191::-;3672:16;3691:6;;-1:-1:-1;;;;;3708:17:0;;;-1:-1:-1;;;;;;3708:17:0;;;;;;3741:40;;3691:6;;;;;;;3741:40;;3672:16;3741:40;3661:128;3598:191;:::o;27954:156::-;28045:4;28098;28069:25;28082:5;28089:4;28069:12;:25::i;:::-;:33;;27954:156;-1:-1:-1;;;;27954:156:0:o;58777:986::-;914:10;58992:14;59036:7;:35;;;;;;;;:::i;:::-;;59032:724;;59113:79;;-1:-1:-1;;;59113:79:0;;-1:-1:-1;;;;;3410:32:1;;;59113:79:0;;;3392:51:1;59088:22:0;;59113:39;;;;;;3365:18:1;;59113:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59088:104;;59233:7;59215:14;:25;;59207:61;;;;-1:-1:-1;;;59207:61:0;;27913:2:1;59207:61:0;;;27895:21:1;27952:2;27932:18;;;27925:30;27991:25;27971:18;;;27964:53;28034:18;;59207:61:0;27711:347:1;59207:61:0;59073:207;59032:724;;;59478:46;;-1:-1:-1;;;59478:46:0;;-1:-1:-1;;;;;3410:32:1;;;59478:46:0;;;3392:51:1;59320:26:0;;;;;;59478:38;;;;;;3365:18:1;;59478:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59301:223;;;;;;-1:-1:-1;;;;;59301:223:0;;;59566:11;59565:12;:66;;;;;59624:7;59602:18;:29;;59565:66;:120;;;;;59675:10;59656:15;:29;;;;59565:120;59539:205;;;;-1:-1:-1;;;59539:205:0;;28265:2:1;59539:205:0;;;28247:21:1;28304:2;28284:18;;;28277:30;28343:25;28323:18;;;28316:53;28386:18;;59539:205:0;28063:347:1;59539:205:0;59286:470;;;58981:782;58777:986;;;;;:::o;59852:1136::-;60055:11;60069:28;60076:6;914:10;60069:6;:28::i;:::-;60108:25;60136:14;;;:9;:14;;;;;60055:42;;-1:-1:-1;60165:7:0;:35;;;;;;;;:::i;:::-;;60161:820;;60250:30;;60217;;60250:58;;60300:8;;60250:58;:::i;:::-;60217:91;;60375:11;60349:22;:37;;60323:126;;;;-1:-1:-1;;;60323:126:0;;28617:2:1;60323:126:0;;;28599:21:1;28656:2;28636:18;;;28629:30;28695:29;28675:18;;;28668:57;28742:18;;60323:126:0;28415:351:1;60323:126:0;60464:55;;;60534:26;;;:39;;60564:9;;60534:26;60464:30;;60534:39;;60564:9;;60534:39;:::i;:::-;;;;-1:-1:-1;60161:820:0;;-1:-1:-1;;60161:820:0;;60606:31;60691:8;60640;:31;;;:59;;;;:::i;:::-;60606:93;;60767:11;60740:23;:38;;60714:128;;;;-1:-1:-1;;;60714:128:0;;28973:2:1;60714:128:0;;;28955:21:1;29012:2;28992:18;;;28985:30;29051;29031:18;;;29024:58;29099:18;;60714:128:0;28771:352:1;60714:128:0;60891:23;60857:8;:31;;:57;;;;60960:9;60929:8;:27;;;:40;;;;;;;:::i;:::-;;;;-1:-1:-1;;;60161:820:0;60044:944;;59852:1136;;;;;:::o;24906:649::-;25330:23;25356:69;25384:4;25356:69;;;;;;;;;;;;;;;;;25364:5;-1:-1:-1;;;;;25356:27:0;;;:69;;;;;:::i;:::-;25330:95;;25444:10;:17;25465:1;25444:22;:56;;;;25481:10;25470:30;;;;;;;;;;;;:::i;:::-;25436:111;;;;-1:-1:-1;;;25436:111:0;;29580:2:1;25436:111:0;;;29562:21:1;29619:2;29599:18;;;29592:30;29658:34;29638:18;;;29631:62;-1:-1:-1;;;29709:18:1;;;29702:40;29759:19;;25436:111:0;29378:406:1;28753:296:0;28836:7;28879:4;28836:7;28894:118;28918:5;:12;28914:1;:16;28894:118;;;28967:33;28977:12;28991:5;28997:1;28991:8;;;;;;;;:::i;:::-;;;;;;;28967:9;:33::i;:::-;28952:48;-1:-1:-1;28932:3:0;;;;:::i;:::-;;;;28894:118;;;-1:-1:-1;29029:12:0;28753:296;-1:-1:-1;;;28753:296:0:o;14199:229::-;14336:12;14368:52;14390:6;14398:4;14404:1;14407:12;14368:21;:52::i;:::-;14361:59;14199:229;-1:-1:-1;;;;14199:229:0:o;36191:149::-;36254:7;36285:1;36281;:5;:51;;36416:13;36510:15;;;36546:4;36539:15;;;36593:4;36577:21;;36281:51;;;36416:13;36510:15;;;36546:4;36539:15;;;36593:4;36577:21;;36289:20;36274:58;36191:149;-1:-1:-1;;;36191:149:0:o;15285:455::-;15455:12;15513:5;15488:21;:30;;15480:81;;;;-1:-1:-1;;;15480:81:0;;29991:2:1;15480:81:0;;;29973:21:1;30030:2;30010:18;;;30003:30;30069:34;30049:18;;;30042:62;-1:-1:-1;;;30120:18:1;;;30113:36;30166:19;;15480:81:0;29789:402:1;15480:81:0;15573:12;15587:23;15614:6;-1:-1:-1;;;;;15614:11:0;15633:5;15640:4;15614:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15572:73;;;;15663:69;15690:6;15698:7;15707:10;15719:12;15663:26;:69::i;:::-;15656:76;15285:455;-1:-1:-1;;;;;;;15285:455:0:o;17858:644::-;18043:12;18072:7;18068:427;;;18100:10;:17;18121:1;18100:22;18096:290;;-1:-1:-1;;;;;11739:19:0;;;18310:60;;;;-1:-1:-1;;;18310:60:0;;30690:2:1;18310:60:0;;;30672:21:1;30729:2;30709:18;;;30702:30;30768:31;30748:18;;;30741:59;30817:18;;18310:60:0;30488:353:1;18310:60:0;-1:-1:-1;18407:10:0;18400:17;;18068:427;18450:33;18458:10;18470:12;19205:17;;:21;19201:388;;19437:10;19431:17;19494:15;19481:10;19477:2;19473:19;19466:44;19201:388;19564:12;19557:20;;-1:-1:-1;;;19557:20:0;;;;;;;;:::i;14:180:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;199:173::-;267:20;;-1:-1:-1;;;;;316:31:1;;306:42;;296:70;;362:1;359;352:12;296:70;199:173;;;:::o;377:254::-;445:6;453;506:2;494:9;485:7;481:23;477:32;474:52;;;522:1;519;512:12;474:52;558:9;545:23;535:33;;587:38;621:2;610:9;606:18;587:38;:::i;:::-;577:48;;377:254;;;;;:::o;1305:248::-;1373:6;1381;1434:2;1422:9;1413:7;1409:23;1405:32;1402:52;;;1450:1;1447;1440:12;1402:52;-1:-1:-1;;1473:23:1;;;1543:2;1528:18;;;1515:32;;-1:-1:-1;1305:248:1:o;2003:367::-;2066:8;2076:6;2130:3;2123:4;2115:6;2111:17;2107:27;2097:55;;2148:1;2145;2138:12;2097:55;-1:-1:-1;2171:20:1;;2214:18;2203:30;;2200:50;;;2246:1;2243;2236:12;2200:50;2283:4;2275:6;2271:17;2259:29;;2343:3;2336:4;2326:6;2323:1;2319:14;2311:6;2307:27;2303:38;2300:47;2297:67;;;2360:1;2357;2350:12;2297:67;2003:367;;;;;:::o;2375:118::-;2461:5;2454:13;2447:21;2440:5;2437:32;2427:60;;2483:1;2480;2473:12;2498:634;2599:6;2607;2615;2623;2676:2;2664:9;2655:7;2651:23;2647:32;2644:52;;;2692:1;2689;2682:12;2644:52;2728:9;2715:23;2705:33;;2789:2;2778:9;2774:18;2761:32;2816:18;2808:6;2805:30;2802:50;;;2848:1;2845;2838:12;2802:50;2887:70;2949:7;2940:6;2929:9;2925:22;2887:70;:::i;:::-;2976:8;;-1:-1:-1;2861:96:1;-1:-1:-1;;3061:2:1;3046:18;;3033:32;3074:28;3033:32;3074:28;:::i;:::-;2498:634;;;;-1:-1:-1;2498:634:1;;-1:-1:-1;;2498:634:1:o;3454:383::-;3528:6;3536;3544;3597:2;3585:9;3576:7;3572:23;3568:32;3565:52;;;3613:1;3610;3603:12;3565:52;3649:9;3636:23;3626:33;;3678:38;3712:2;3701:9;3697:18;3678:38;:::i;:::-;3668:48;;3766:2;3755:9;3751:18;3738:32;3779:28;3801:5;3779:28;:::i;:::-;3826:5;3816:15;;;3454:383;;;;;:::o;3842:110::-;3926:1;3919:5;3916:12;3906:40;;3942:1;3939;3932:12;3957:1252;4116:6;4124;4132;4140;4148;4156;4164;4172;4180;4188;4241:3;4229:9;4220:7;4216:23;4212:33;4209:53;;;4258:1;4255;4248:12;4209:53;4297:9;4284:23;4316:40;4350:5;4316:40;:::i;:::-;4375:5;-1:-1:-1;4399:38:1;4433:2;4418:18;;4399:38;:::i;:::-;4389:48;;4456:38;4490:2;4479:9;4475:18;4456:38;:::i;:::-;4446:48;;4513:38;4547:2;4536:9;4532:18;4513:38;:::i;:::-;4503:48;;4602:3;4591:9;4587:19;4574:33;4626:18;4667:2;4659:6;4656:14;4653:34;;;4683:1;4680;4673:12;4653:34;4721:6;4710:9;4706:22;4696:32;;4766:7;4759:4;4755:2;4751:13;4747:27;4737:55;;4788:1;4785;4778:12;4737:55;4828:2;4815:16;4854:2;4846:6;4843:14;4840:34;;;4870:1;4867;4860:12;4840:34;4915:7;4910:2;4901:6;4897:2;4893:15;4889:24;4886:37;4883:57;;;4936:1;4933;4926:12;4883:57;3957:1252;;;;-1:-1:-1;3957:1252:1;;;;4967:2;4959:11;;;;;4989:6;;-1:-1:-1;5042:3:1;5027:19;;5014:33;;5094:3;5079:19;;5066:33;;-1:-1:-1;5146:3:1;5131:19;;5118:33;;-1:-1:-1;5198:3:1;5183:19;5170:33;;-1:-1:-1;3957:1252:1;-1:-1:-1;;;3957:1252:1:o;5214:127::-;5275:10;5270:3;5266:20;5263:1;5256:31;5306:4;5303:1;5296:15;5330:4;5327:1;5320:15;5346:213;5430:1;5423:5;5420:12;5410:143;;5475:10;5470:3;5466:20;5463:1;5456:31;5510:4;5507:1;5500:15;5538:4;5535:1;5528:15;5564:136;5627:40;5661:5;5627:40;:::i;:::-;5676:18;;5564:136::o;5705:250::-;5790:1;5800:113;5814:6;5811:1;5808:13;5800:113;;;5890:11;;;5884:18;5871:11;;;5864:39;5836:2;5829:10;5800:113;;;-1:-1:-1;;5947:1:1;5929:16;;5922:27;5705:250::o;5960:271::-;6002:3;6040:5;6034:12;6067:6;6062:3;6055:19;6083:76;6152:6;6145:4;6140:3;6136:14;6129:4;6122:5;6118:16;6083:76;:::i;:::-;6213:2;6192:15;-1:-1:-1;;6188:29:1;6179:39;;;;6220:4;6175:50;;5960:271;-1:-1:-1;;5960:271:1:o;6236:1422::-;6415:2;6404:9;6397:21;6427:62;6485:2;6474:9;6470:18;6461:6;6455:13;6427:62;:::i;:::-;6378:4;6536:2;6528:6;6524:15;6518:22;6549:52;6597:2;6586:9;6582:18;6568:12;-1:-1:-1;;;;;3203:31:1;3191:44;;3137:104;6549:52;-1:-1:-1;6650:2:1;6638:15;;6632:22;-1:-1:-1;;;;;3203:31:1;;6713:2;6698:18;;3191:44;-1:-1:-1;6766:2:1;6754:15;;6748:22;-1:-1:-1;;;;;3203:31:1;;6829:3;6814:19;;3191:44;-1:-1:-1;6883:3:1;6871:16;;6865:23;-1:-1:-1;;;;;3203:31:1;;6947:3;6932:19;;3191:44;6897:55;7001:3;6993:6;6989:16;6983:23;7025:6;7068:2;7062:3;7051:9;7047:19;7040:31;7094:54;7143:3;7132:9;7128:19;7112:14;7094:54;:::i;:::-;7203:3;7191:16;;7185:23;7179:3;7164:19;;;7157:52;;;;7234:16;;7228:23;7270:3;7289:18;;;7282:30;;;;7337:15;;7331:22;7372:3;7391:18;;;7384:30;;;;7439:15;;7433:22;7474:3;7493:18;;;7486:30;;;;7553:15;;;7547:22;706:13;699:21;7610:18;;687:34;;;;-1:-1:-1;7080:68:1;;7646:6;-1:-1:-1;6236:1422:1:o;7663:254::-;7731:6;7739;7792:2;7780:9;7771:7;7767:23;7763:32;7760:52;;;7808:1;7805;7798:12;7760:52;7831:29;7850:9;7831:29;:::i;:::-;7821:39;7907:2;7892:18;;;;7879:32;;-1:-1:-1;;;7663:254:1:o;8432:1015::-;8602:6;8610;8618;8626;8634;8642;8650;8658;8666;8719:3;8707:9;8698:7;8694:23;8690:33;8687:53;;;8736:1;8733;8726:12;8687:53;8775:9;8762:23;8794:40;8828:5;8794:40;:::i;:::-;8853:5;-1:-1:-1;8905:2:1;8890:18;;8877:32;;-1:-1:-1;8956:2:1;8941:18;;8928:32;;-1:-1:-1;9007:2:1;8992:18;;8979:32;;-1:-1:-1;9058:3:1;9043:19;;9030:33;;-1:-1:-1;9110:3:1;9095:19;;9082:33;;-1:-1:-1;9162:3:1;9147:19;;9134:33;;-1:-1:-1;9218:3:1;9203:19;;9190:33;9246:18;9235:30;;9232:50;;;9278:1;9275;9268:12;9232:50;9317:70;9379:7;9370:6;9359:9;9355:22;9317:70;:::i;:::-;9291:96;;9406:8;9396:18;;;9433:8;9423:18;;;8432:1015;;;;;;;;;;;:::o;9634:186::-;9693:6;9746:2;9734:9;9725:7;9721:23;9717:32;9714:52;;;9762:1;9759;9752:12;9714:52;9785:29;9804:9;9785:29;:::i;9825:316::-;9902:6;9910;9918;9971:2;9959:9;9950:7;9946:23;9942:32;9939:52;;;9987:1;9984;9977:12;9939:52;-1:-1:-1;;10010:23:1;;;10080:2;10065:18;;10052:32;;-1:-1:-1;10131:2:1;10116:18;;;10103:32;;9825:316;-1:-1:-1;9825:316:1:o;10146:380::-;10225:1;10221:12;;;;10268;;;10289:61;;10343:4;10335:6;10331:17;10321:27;;10289:61;10396:2;10388:6;10385:14;10365:18;10362:38;10359:161;;10442:10;10437:3;10433:20;10430:1;10423:31;10477:4;10474:1;10467:15;10505:4;10502:1;10495:15;10359:161;;10146:380;;;:::o;10531:340::-;10733:2;10715:21;;;10772:2;10752:18;;;10745:30;-1:-1:-1;;;10806:2:1;10791:18;;10784:46;10862:2;10847:18;;10531:340::o;11570:184::-;11640:6;11693:2;11681:9;11672:7;11668:23;11664:32;11661:52;;;11709:1;11706;11699:12;11661:52;-1:-1:-1;11732:16:1;;11570:184;-1:-1:-1;11570:184:1:o;11759:127::-;11820:10;11815:3;11811:20;11808:1;11801:31;11851:4;11848:1;11841:15;11875:4;11872:1;11865:15;11891:125;11956:9;;;11977:10;;;11974:36;;;11990:18;;:::i;12369:128::-;12436:9;;;12457:11;;;12454:37;;;12471:18;;:::i;15846:217::-;15886:1;15912;15902:132;;15956:10;15951:3;15947:20;15944:1;15937:31;15991:4;15988:1;15981:15;16019:4;16016:1;16009:15;15902:132;-1:-1:-1;16048:9:1;;15846:217::o;16755:127::-;16816:10;16811:3;16807:20;16804:1;16797:31;16847:4;16844:1;16837:15;16871:4;16868:1;16861:15;17592:188;17671:13;;-1:-1:-1;;;;;17713:42:1;;17703:53;;17693:81;;17770:1;17767;17760:12;17785:669;17887:6;17895;17903;17911;17919;17972:3;17960:9;17951:7;17947:23;17943:33;17940:53;;;17989:1;17986;17979:12;17940:53;18012:40;18042:9;18012:40;:::i;:::-;18002:50;;18071:49;18116:2;18105:9;18101:18;18071:49;:::i;:::-;18061:59;;18139:49;18184:2;18173:9;18169:18;18139:49;:::i;:::-;18129:59;;18231:2;18220:9;18216:18;18210:25;18275:14;18268:5;18264:26;18257:5;18254:37;18244:65;;18305:1;18302;18295:12;18244:65;18378:3;18363:19;;18357:26;18328:5;;-1:-1:-1;18392:30:1;18357:26;18392:30;:::i;:::-;18441:7;18431:17;;;17785:669;;;;;;;;:::o;19510:135::-;19549:3;19570:17;;;19567:43;;19590:18;;:::i;:::-;-1:-1:-1;19637:1:1;19626:13;;19510:135::o;19650:127::-;19711:10;19706:3;19702:20;19699:1;19692:31;19742:4;19739:1;19732:15;19766:4;19763:1;19756:15;19908:545;20010:2;20005:3;20002:11;19999:448;;;20046:1;20071:5;20067:2;20060:17;20116:4;20112:2;20102:19;20186:2;20174:10;20170:19;20167:1;20163:27;20157:4;20153:38;20222:4;20210:10;20207:20;20204:47;;;-1:-1:-1;20245:4:1;20204:47;20300:2;20295:3;20291:12;20288:1;20284:20;20278:4;20274:31;20264:41;;20355:82;20373:2;20366:5;20363:13;20355:82;;;20418:17;;;20399:1;20388:13;20355:82;;20629:1352;20755:3;20749:10;20782:18;20774:6;20771:30;20768:56;;;20804:18;;:::i;:::-;20833:97;20923:6;20883:38;20915:4;20909:11;20883:38;:::i;:::-;20877:4;20833:97;:::i;:::-;20985:4;;21049:2;21038:14;;21066:1;21061:663;;;;21768:1;21785:6;21782:89;;;-1:-1:-1;21837:19:1;;;21831:26;21782:89;-1:-1:-1;;20586:1:1;20582:11;;;20578:24;20574:29;20564:40;20610:1;20606:11;;;20561:57;21884:81;;21031:944;;21061:663;19855:1;19848:14;;;19892:4;19879:18;;-1:-1:-1;;21097:20:1;;;21215:236;21229:7;21226:1;21223:14;21215:236;;;21318:19;;;21312:26;21297:42;;21410:27;;;;21378:1;21366:14;;;;21245:19;;21215:236;;;21219:3;21479:6;21470:7;21467:19;21464:201;;;21540:19;;;21534:26;-1:-1:-1;;21623:1:1;21619:14;;;21635:3;21615:24;21611:37;21607:42;21592:58;21577:74;;21464:201;-1:-1:-1;;;;;21711:1:1;21695:14;;;21691:22;21678:36;;-1:-1:-1;20629:1352:1:o;23015:587::-;23303:41;23337:6;23303:41;:::i;:::-;23369:3;23365:16;;;;23353:29;;23407:1;23398:11;;23391:27;;;;23443:2;23434:12;;23427:28;;;;23480:2;23471:12;;23464:28;23517:2;23508:12;;23501:28;23554:3;23545:13;;23538:29;23592:3;23583:13;;23015:587::o;24479:558::-;24757:25;;;-1:-1:-1;;;;;24818:32:1;;24813:2;24798:18;;24791:60;24744:3;24729:19;;24860:41;24894:6;24860:41;:::i;:::-;24937:6;24932:2;24921:9;24917:18;24910:34;24980:6;24975:2;24964:9;24960:18;24953:34;25024:6;25018:3;25007:9;25003:19;24996:35;24479:558;;;;;;;;:::o;29128:245::-;29195:6;29248:2;29236:9;29227:7;29223:23;29219:32;29216:52;;;29264:1;29261;29254:12;29216:52;29296:9;29290:16;29315:28;29337:5;29315:28;:::i;30196:287::-;30325:3;30363:6;30357:13;30379:66;30438:6;30433:3;30426:4;30418:6;30414:17;30379:66;:::i;:::-;30461:16;;;;;30196:287;-1:-1:-1;;30196:287:1:o;30846:220::-;30995:2;30984:9;30977:21;30958:4;31015:45;31056:2;31045:9;31041:18;31033:6;31015:45;:::i
Swarm Source
ipfs://ac627b9534c0d8cf9190fb05d1bda002f0534e9779e7a718b41f9a5a652c2f2a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | <$0.000001 | 134,000,000 | $17.68 |
Loading...
Loading
[ Download: CSV Export ]
[ 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.