Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 12729845 | 1003 days ago | IN | Create: NFTXVaultUpgradeable | 0 ETH | 0.15153648 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
NFTXVaultUpgradeable
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-06-29 */ // Sources flattened with hardhat v2.0.11 https://hardhat.org // File contracts/solidity/interface/INFTXEligibility.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface INFTXEligibility { // Read functions. function name() external pure returns (string memory); function finalized() external view returns (bool); function targetAsset() external pure returns (address); function checkAllEligible(uint256[] calldata tokenIds) external view returns (bool); function checkEligible(uint256[] calldata tokenIds) external view returns (bool[] memory); function checkAllIneligible(uint256[] calldata tokenIds) external view returns (bool); function checkIsEligible(uint256 tokenId) external view returns (bool); // Write functions. function __NFTXEligibility_init_bytes(bytes calldata configData) external; function beforeMintHook(uint256[] calldata tokenIds) external; function afterMintHook(uint256[] calldata tokenIds) external; function beforeRedeemHook(uint256[] calldata tokenIds) external; function afterRedeemHook(uint256[] calldata tokenIds) external; } // File contracts/solidity/proxy/IBeacon.sol pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function childImplementation() external view returns (address); function upgradeChildTo(address newImplementation) external; } // File contracts/solidity/interface/INFTXVaultFactory.sol pragma solidity ^0.8.0; interface INFTXVaultFactory is IBeacon { // Read functions. function numVaults() external view returns (uint256); function zapContract() external view returns (address); function feeDistributor() external view returns (address); function eligibilityManager() external view returns (address); function vault(uint256 vaultId) external view returns (address); function vaultsForAsset(address asset) external view returns (address[] memory); function isLocked(uint256 id) external view returns (bool); event NewFeeDistributor(address oldDistributor, address newDistributor); event NewZapContract(address oldZap, address newZap); event NewEligibilityManager(address oldEligManager, address newEligManager); event NewVault(uint256 indexed vaultId, address vaultAddress, address assetAddress); // Write functions. function __NFTXVaultFactory_init(address _vaultImpl, address _feeDistributor) external; function createVault( string calldata name, string calldata symbol, address _assetAddress, bool is1155, bool allowAllItems ) external returns (uint256); function setFeeDistributor(address _feeDistributor) external; function setEligibilityManager(address _eligibilityManager) external; function setZapContract(address _zapContract) external; } // File contracts/solidity/interface/INFTXVault.sol pragma solidity ^0.8.0; interface INFTXVault { function manager() external returns (address); function assetAddress() external returns (address); function vaultFactory() external returns (INFTXVaultFactory); function eligibilityStorage() external returns (INFTXEligibility); function is1155() external returns (bool); function allowAllItems() external returns (bool); function enableMint() external returns (bool); function enableRandomRedeem() external returns (bool); function enableTargetRedeem() external returns (bool); function vaultId() external returns (uint256); function nftIdAt(uint256 holdingsIndex) external view returns (uint256); function mintFee() external returns (uint256); function randomRedeemFee() external returns (uint256); function targetRedeemFee() external returns (uint256); event VaultInit( uint256 indexed vaultId, address assetAddress, bool is1155, bool allowAllItems ); event ManagerSet(address manager); event EligibilityDeployed(uint256 moduleIndex, address eligibilityAddr); // event CustomEligibilityDeployed(address eligibilityAddr); event EnableMintUpdated(bool enabled); event EnableRandomRedeemUpdated(bool enabled); event EnableTargetRedeemUpdated(bool enabled); event MintFeeUpdated(uint256 mintFee); event RandomRedeemFeeUpdated(uint256 randomRedeemFee); event TargetRedeemFeeUpdated(uint256 targetRedeemFee); event Minted(uint256[] nftIds, uint256[] amounts, address to); event Redeemed(uint256[] nftIds, uint256[] specificIds, address to); event Swapped( uint256[] nftIds, uint256[] amounts, uint256[] specificIds, uint256[] redeemedIds, address to ); function __NFTXVault_init( string calldata _name, string calldata _symbol, address _assetAddress, bool _is1155, bool _allowAllItems ) external; function finalizeVault() external; function setVaultFeatures( bool _enableMint, bool _enableRandomRedeem, bool _enableTargetRedeem ) external; function setFees( uint256 _mintFee, uint256 _randomRedeemFee, uint256 _targetRedeemFee ) external; // This function allows for an easy setup of any eligibility module contract from the EligibilityManager. // It takes in ABI encoded parameters for the desired module. This is to make sure they can all follow // a similar interface. function deployEligibilityStorage( uint256 moduleIndex, bytes calldata initData ) external returns (address); // The manager has control over options like fees and features function setManager(address _manager) external; function mint( uint256[] calldata tokenIds, uint256[] calldata amounts /* ignored for ERC721 vaults */ ) external returns (uint256); function mintTo( uint256[] calldata tokenIds, uint256[] calldata amounts, /* ignored for ERC721 vaults */ address to ) external returns (uint256); function redeem(uint256 amount, uint256[] calldata specificIds) external returns (uint256[] calldata); function redeemTo( uint256 amount, uint256[] calldata specificIds, address to ) external returns (uint256[] calldata); function swap( uint256[] calldata tokenIds, uint256[] calldata amounts, /* ignored for ERC721 vaults */ uint256[] calldata specificIds ) external returns (uint256[] calldata); function swapTo( uint256[] calldata tokenIds, uint256[] calldata amounts, /* ignored for ERC721 vaults */ uint256[] calldata specificIds, address to ) external returns (uint256[] calldata); function allValidNFTs(uint256[] calldata tokenIds) external view returns (bool); } // File contracts/solidity/interface/INFTXEligibilityManager.sol pragma solidity ^0.8.0; interface INFTXEligibilityManager { function nftxVaultFactory() external returns (address); function eligibilityImpl() external returns (address); function deployEligibility(uint256 vaultId, bytes calldata initData) external returns (address); } // File contracts/solidity/interface/INFTXFeeDistributor.sol pragma solidity ^0.8.0; interface INFTXFeeDistributor { struct FeeReceiver { uint256 allocPoint; address receiver; bool isContract; } function nftxVaultFactory() external returns (address); function lpStaking() external returns (address); function treasury() external returns (address); function defaultTreasuryAlloc() external returns (uint256); function defaultLPAlloc() external returns (uint256); function allocTotal(uint256 vaultId) external returns (uint256); function specificTreasuryAlloc(uint256 vaultId) external returns (uint256); // Write functions. function __FeeDistributor__init__(address _lpStaking, address _treasury) external; function rescueTokens(address token) external; function distribute(uint256 vaultId) external; function addReceiver(uint256 _vaultId, uint256 _allocPoint, address _receiver, bool _isContract) external; function initializeVaultReceivers(uint256 _vaultId) external; function changeMultipleReceiverAlloc( uint256[] memory _vaultIds, uint256[] memory _receiverIdxs, uint256[] memory allocPoints ) external; function changeMultipleReceiverAddress( uint256[] memory _vaultIds, uint256[] memory _receiverIdxs, address[] memory addresses, bool[] memory isContracts ) external; function changeReceiverAlloc(uint256 _vaultId, uint256 _idx, uint256 _allocPoint) external; function changeReceiverAddress(uint256 _vaultId, uint256 _idx, address _address, bool _isContract) external; function removeReceiver(uint256 _vaultId, uint256 _receiverIdx) external; // Configuration functions. function setTreasuryAddress(address _treasury) external; function setDefaultTreasuryAlloc(uint256 _allocPoint) external; function setSpecificTreasuryAlloc(uint256 _vaultId, uint256 _allocPoint) external; function setLPStakingAddress(address _lpStaking) external; function setNFTXVaultFactory(address _factory) external; function setDefaultLPAlloc(uint256 _allocPoint) external; } // File contracts/solidity/interface/IERC165Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File contracts/solidity/interface/IERC3156Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Interface of the ERC3156 FlashBorrower, as defined in * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. */ interface IERC3156FlashBorrowerUpgradeable { /** * @dev Receive a flash loan. * @param initiator The initiator of the loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @param fee The additional amount of tokens to repay. * @param data Arbitrary data structure, intended to contain user-defined parameters. * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" */ function onFlashLoan( address initiator, address token, uint256 amount, uint256 fee, bytes calldata data ) external returns (bytes32); } /** * @dev Interface of the ERC3156 FlashLender, as defined in * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. */ interface IERC3156FlashLenderUpgradeable { /** * @dev The amount of currency available to be lended. * @param token The loan currency. * @return The amount of `token` that can be borrowed. */ function maxFlashLoan( address token ) external view returns (uint256); /** * @dev The fee to be charged for a given loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @return The amount of `token` to be charged for the loan, on top of the returned principal. */ function flashFee( address token, uint256 amount ) external view returns (uint256); /** * @dev Initiate a flash loan. * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. * @param token The loan currency. * @param amount The amount of tokens lent. * @param data Arbitrary data structure, intended to contain user-defined parameters. */ function flashLoan( IERC3156FlashBorrowerUpgradeable receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); } // File contracts/solidity/token/IERC20Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); } // File contracts/solidity/token/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 IERC20Upgradeable { /** * @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 contracts/solidity/proxy/Initializable.sol // solhint-disable-next-line compiler-version pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } } // File contracts/solidity/util/ContextUpgradeable.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 ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; } // File contracts/solidity/token/ERC20Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20Metadata { mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); _approve(sender, _msgSender(), currentAllowance - amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); _approve(_msgSender(), spender, currentAllowance - subtractedValue); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); _balances[sender] = senderBalance - amount; _balances[recipient] += amount; emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); _balances[account] = accountBalance - amount; _totalSupply -= amount; emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } uint256[45] private __gap; } // File contracts/solidity/token/ERC20FlashMintUpgradeable.sol pragma solidity ^0.8.0; /** * @dev Implementation of the ERC3156 Flash loans extension, as defined in * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. * * Adds the {flashLoan} method, which provides flash loan support at the token * level. By default there is no fee, but this can be changed by overriding {flashFee}. */ abstract contract ERC20FlashMintUpgradeable is Initializable, ERC20Upgradeable, IERC3156FlashLenderUpgradeable { function __ERC20FlashMint_init() internal initializer { __Context_init_unchained(); __ERC20FlashMint_init_unchained(); } function __ERC20FlashMint_init_unchained() internal initializer { } bytes32 constant private RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan"); /** * @dev Returns the maximum amount of tokens available for loan. * @param token The address of the token that is requested. * @return The amont of token that can be loaned. */ function maxFlashLoan(address token) public view override returns (uint256) { return token == address(this) ? type(uint256).max - totalSupply() : 0; } /** * @dev Returns the fee applied when doing flash loans. By default this * implementation has 0 fees. This function can be overloaded to make * the flash loan mechanism deflationary. * @param token The token to be flash loaned. * @param amount The amount of tokens to be loaned. * @return The fees applied to the corresponding flash loan. */ function flashFee(address token, uint256 amount) public view virtual override returns (uint256) { require(token == address(this), "ERC20FlashMint: wrong token"); // silence warning about unused variable without the addition of bytecode. amount; return 0; } /** * @dev Performs a flash loan. New tokens are minted and sent to the * `receiver`, who is required to implement the {IERC3156FlashBorrower} * interface. By the end of the flash loan, the receiver is expected to own * amount + fee tokens and have them approved back to the token contract itself so * they can be burned. * @param receiver The receiver of the flash loan. Should implement the * {IERC3156FlashBorrower.onFlashLoan} interface. * @param token The token to be flash loaned. Only `address(this)` is * supported. * @param amount The amount of tokens to be loaned. * @param data An arbitrary datafield that is passed to the receiver. * @return `true` is the flash loan was successfull. */ function flashLoan( IERC3156FlashBorrowerUpgradeable receiver, address token, uint256 amount, bytes memory data ) public virtual override returns (bool) { uint256 fee = flashFee(token, amount); _mint(address(receiver), amount); require(receiver.onFlashLoan(msg.sender, token, amount, fee, data) == RETURN_VALUE, "ERC20FlashMint: invalid return value"); uint256 currentAllowance = allowance(address(receiver), address(this)); require(currentAllowance >= amount + fee, "ERC20FlashMint: allowance does not allow refund"); _approve(address(receiver), address(this), currentAllowance - amount - fee); _burn(address(receiver), amount + fee); return true; } uint256[50] private __gap; } // File contracts/solidity/token/IERC721ReceiverUpgradeable.sol pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); } // File contracts/solidity/token/ERC721HolderUpgradeable.sol pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721HolderUpgradeable is IERC721ReceiverUpgradeable { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } } // File contracts/solidity/token/IERC1155ReceiverUpgradeable.sol pragma solidity ^0.8.0; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** @dev Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61, or its own function selector). @param operator The address which initiated the transfer (i.e. msg.sender) @param from The address which previously owned the token @param id The ID of the token being transferred @param value The amount of tokens being transferred @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns(bytes4); /** @dev Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81, or its own function selector). @param operator The address which initiated the batch transfer (i.e. msg.sender) @param from The address which previously owned the token @param ids An array containing ids of each token being transferred (order and length must match values array) @param values An array containing amounts of each token being transferred (order and length must match ids array) @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns(bytes4); } // File contracts/solidity/util/ERC165Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is IERC165Upgradeable { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } } // File contracts/solidity/token/ERC1155ReceiverUpgradeable.sol pragma solidity ^0.8.0; /** * @dev _Available since v3.1._ */ abstract contract ERC1155ReceiverUpgradeable is ERC165Upgradeable, IERC1155ReceiverUpgradeable { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId); } } // File contracts/solidity/token/ERC1155HolderUpgradeable.sol pragma solidity ^0.8.0; /** * @dev _Available since v3.1._ */ abstract contract ERC1155HolderUpgradeable is ERC1155ReceiverUpgradeable { function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } } // File contracts/solidity/token/IERC721Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; } // File contracts/solidity/token/IERC1155Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; } // File contracts/solidity/util/OwnableUpgradeable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; } // File contracts/solidity/util/ReentrancyGuardUpgradeable.sol pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } uint256[49] private __gap; } // File contracts/solidity/util/EnumerableSetUpgradeable.sol 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. * * ``` * 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. */ library EnumerableSetUpgradeable { // 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]; } // 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); } // 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)))); } // 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 on 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)); } } // File contracts/solidity/NFTXVaultUpgradeable.sol pragma solidity ^0.8.0; // Authors: @0xKiwi_ and @alexgausman. contract NFTXVaultUpgradeable is OwnableUpgradeable, ERC20FlashMintUpgradeable, ReentrancyGuardUpgradeable, ERC721HolderUpgradeable, ERC1155HolderUpgradeable, INFTXVault { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet; uint256 constant base = 10**18; uint256 public override vaultId; address public override manager; address public override assetAddress; INFTXVaultFactory public override vaultFactory; INFTXEligibility public override eligibilityStorage; uint256 randNonce; uint256 public override mintFee; uint256 public override randomRedeemFee; uint256 public override targetRedeemFee; bool public override is1155; bool public override allowAllItems; bool public override enableMint; bool public override enableRandomRedeem; bool public override enableTargetRedeem; EnumerableSetUpgradeable.UintSet holdings; mapping(uint256 => uint256) quantity1155; function __NFTXVault_init( string memory _name, string memory _symbol, address _assetAddress, bool _is1155, bool _allowAllItems ) public override virtual initializer { __Ownable_init(); __ERC20_init(_name, _symbol); require(_assetAddress != address(0), "Asset != address(0)"); assetAddress = _assetAddress; vaultFactory = INFTXVaultFactory(msg.sender); vaultId = vaultFactory.numVaults(); is1155 = _is1155; allowAllItems = _allowAllItems; emit VaultInit(vaultId, _assetAddress, _is1155, _allowAllItems); setVaultFeatures(true /*enableMint*/, true /*enableRandomRedeem*/, true /*enableTargetRedeem*/); setFees(0.01 ether /*mintFee*/, 0 /*randomRedeemFee*/, 0.05 ether /*targetRedeemFee*/); } function finalizeVault() external override virtual { setManager(address(0)); } function setVaultFeatures( bool _enableMint, bool _enableRandomRedeem, bool _enableTargetRedeem ) public override virtual { onlyPrivileged(); enableMint = _enableMint; enableRandomRedeem = _enableRandomRedeem; enableTargetRedeem = _enableTargetRedeem; emit EnableMintUpdated(_enableMint); emit EnableRandomRedeemUpdated(_enableRandomRedeem); emit EnableTargetRedeemUpdated(_enableTargetRedeem); } function setFees( uint256 _mintFee, uint256 _randomRedeemFee, uint256 _targetRedeemFee ) public override virtual { onlyPrivileged(); require(_mintFee <= base, "Cannot > 1 ether"); require(_randomRedeemFee <= base, "Cannot > 1 ether"); require(_targetRedeemFee <= base, "Cannot > 1 ether"); mintFee = _mintFee; randomRedeemFee = _randomRedeemFee; targetRedeemFee = _targetRedeemFee; emit MintFeeUpdated(_mintFee); emit RandomRedeemFeeUpdated(_randomRedeemFee); emit TargetRedeemFeeUpdated(_targetRedeemFee); } // This function allows for an easy setup of any eligibility module contract from the EligibilityManager. // It takes in ABI encoded parameters for the desired module. This is to make sure they can all follow // a similar interface. function deployEligibilityStorage( uint256 moduleIndex, bytes calldata initData ) external override virtual returns (address) { onlyPrivileged(); require( address(eligibilityStorage) == address(0), "NFTXVault: eligibility already set" ); INFTXEligibilityManager eligManager = INFTXEligibilityManager( vaultFactory.eligibilityManager() ); address _eligibility = eligManager.deployEligibility( moduleIndex, initData ); eligibilityStorage = INFTXEligibility(_eligibility); // Toggle this to let the contract know to check eligibility now. allowAllItems = false; emit EligibilityDeployed(moduleIndex, _eligibility); return _eligibility; } // // This function allows for the manager to set their own arbitrary eligibility contract. // // Once eligiblity is set, it cannot be unset or changed. // Disabled for launch. // function setEligibilityStorage(address _newEligibility) public virtual { // onlyPrivileged(); // require( // address(eligibilityStorage) == address(0), // "NFTXVault: eligibility already set" // ); // eligibilityStorage = INFTXEligibility(_newEligibility); // // Toggle this to let the contract know to check eligibility now. // allowAllItems = false; // emit CustomEligibilityDeployed(address(_newEligibility)); // } // The manager has control over options like fees and features function setManager(address _manager) public override virtual { onlyPrivileged(); manager = _manager; emit ManagerSet(_manager); } function mint( uint256[] calldata tokenIds, uint256[] calldata amounts /* ignored for ERC721 vaults */ ) external override virtual returns (uint256) { return mintTo(tokenIds, amounts, msg.sender); } function mintTo( uint256[] memory tokenIds, uint256[] memory amounts, /* ignored for ERC721 vaults */ address to ) public override virtual nonReentrant returns (uint256) { onlyOwnerIfPaused(1); require(enableMint, "Minting not enabled"); // Take the NFTs. uint256 count = receiveNFTs(tokenIds, amounts); // Mint to the user. _mint(to, base * count); uint256 totalFee = mintFee * count; _chargeAndDistributeFees(totalFee); emit Minted(tokenIds, amounts, to); return count; } function redeem(uint256 amount, uint256[] calldata specificIds) external override virtual returns (uint256[] memory) { return redeemTo(amount, specificIds, msg.sender); } function redeemTo(uint256 amount, uint256[] memory specificIds, address to) public override virtual nonReentrant returns (uint256[] memory) { onlyOwnerIfPaused(2); require(enableRandomRedeem || enableTargetRedeem, "Redeeming not enabled"); // We burn all from sender and mint to fee receiver to reduce costs. _burn(msg.sender, base * amount); // Pay the tokens + toll. uint256 totalFee = (targetRedeemFee * specificIds.length) + ( randomRedeemFee * (amount - specificIds.length) ); _chargeAndDistributeFees(totalFee); // Withdraw from vault. uint256[] memory redeemedIds = withdrawNFTsTo(amount, specificIds, to); emit Redeemed(redeemedIds, specificIds, to); return redeemedIds; } function swap( uint256[] calldata tokenIds, uint256[] calldata amounts, /* ignored for ERC721 vaults */ uint256[] calldata specificIds ) external override virtual returns (uint256[] memory) { return swapTo(tokenIds, amounts, specificIds, msg.sender); } function swapTo( uint256[] memory tokenIds, uint256[] memory amounts, /* ignored for ERC721 vaults */ uint256[] memory specificIds, address to ) public override virtual nonReentrant returns (uint256[] memory) { onlyOwnerIfPaused(3); require(enableMint && (enableRandomRedeem || enableTargetRedeem), "NFTXVault: Mint & Redeem enabled"); // Take the NFTs first, so the user has a chance of rerolling the same. // This is intentional so this action mirrors how minting/redeeming manually would work. uint256 count = receiveNFTs(tokenIds, amounts); // Pay the toll. Mint and Redeem fees here since its a swap. // We burn all from sender and mint to fee receiver to reduce costs. uint256 redeemFee = (targetRedeemFee * specificIds.length) + ( randomRedeemFee * (count - specificIds.length) ); uint256 totalFee = (mintFee * count) + redeemFee; _chargeAndDistributeFees(totalFee); // Withdraw from vault. uint256[] memory ids = withdrawNFTsTo(count, specificIds, to); emit Swapped(tokenIds, amounts, specificIds, ids, to); return ids; } function flashLoan( IERC3156FlashBorrowerUpgradeable receiver, address token, uint256 amount, bytes memory data ) public override virtual returns (bool) { onlyOwnerIfPaused(4); return super.flashLoan(receiver, token, amount, data); } function allValidNFTs(uint256[] memory tokenIds) public view override virtual returns (bool) { if (allowAllItems) { return true; } INFTXEligibility _eligibilityStorage = eligibilityStorage; if (address(_eligibilityStorage) == address(0)) { return false; } return _eligibilityStorage.checkAllEligible(tokenIds); } function nftIdAt(uint256 holdingsIndex) external view override virtual returns (uint256) { return holdings.at(holdingsIndex); } // We set a hook to the eligibility module (if it exists) after redeems in case anything needs to be modified. function afterRedeemHook(uint256[] memory tokenIds) internal virtual { INFTXEligibility _eligibilityStorage = eligibilityStorage; if (address(_eligibilityStorage) == address(0)) { return; } _eligibilityStorage.afterRedeemHook(tokenIds); } function receiveNFTs(uint256[] memory tokenIds, uint256[] memory amounts) internal virtual returns (uint256) { require(allValidNFTs(tokenIds), "NFTXVault: not eligible"); if (is1155) { // This is technically a check, so placing it before the effect. IERC1155Upgradeable(assetAddress).safeBatchTransferFrom( msg.sender, address(this), tokenIds, amounts, "" ); uint256 count; for (uint256 i = 0; i < tokenIds.length; i++) { uint256 tokenId = tokenIds[i]; uint256 amount = amounts[i]; require(amount > 0, "NFTXVault: transferring < 1"); if (quantity1155[tokenId] == 0) { holdings.add(tokenId); } quantity1155[tokenId] += amount; count += amount; } return count; } else { address _assetAddress = assetAddress; for (uint256 i = 0; i < tokenIds.length; i++) { uint256 tokenId = tokenIds[i]; transferFromERC721(_assetAddress, tokenId); holdings.add(tokenId); } return tokenIds.length; } } function withdrawNFTsTo( uint256 amount, uint256[] memory specificIds, address to ) internal virtual returns (uint256[] memory) { require( amount == specificIds.length || enableRandomRedeem, "NFTXVault: Random redeem not enabled" ); require( specificIds.length == 0 || enableTargetRedeem, "NFTXVault: Target redeem not enabled" ); bool _is1155 = is1155; address _assetAddress = assetAddress; uint256[] memory redeemedIds = new uint256[](amount); for (uint256 i = 0; i < amount; i++) { // This will always be fine considering the validations made above. uint256 tokenId = i < specificIds.length ? specificIds[i] : getRandomTokenIdFromVault(); redeemedIds[i] = tokenId; if (_is1155) { quantity1155[tokenId] -= 1; if (quantity1155[tokenId] == 0) { holdings.remove(tokenId); } IERC1155Upgradeable(_assetAddress).safeTransferFrom( address(this), to, tokenId, 1, "" ); } else { holdings.remove(tokenId); transferERC721(_assetAddress, to, tokenId); } } afterRedeemHook(redeemedIds); return redeemedIds; } function _chargeAndDistributeFees(uint256 amount) internal virtual { // Mint fees directly to the distributor and distribute. if (amount > 0) { _burn(msg.sender, amount); address feeDistributor = vaultFactory.feeDistributor(); _mint(feeDistributor, amount); INFTXFeeDistributor(feeDistributor).distribute(vaultId); } } function transferERC721(address assetAddr, address to, uint256 tokenId) internal virtual { address kitties = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d; address punks = 0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB; bytes memory data; if (assetAddr == kitties) { data = abi.encodeWithSignature("transferFrom(address,address,uint256)", address(this), to, tokenId); } else if (assetAddr == punks) { // CryptoPunks. data = abi.encodeWithSignature("transferPunk(address,uint256)", to, tokenId); } else { // Default. data = abi.encodeWithSignature("safeTransferFrom(address,address,uint256)", address(this), to, tokenId); } (bool success,) = address(assetAddr).call(data); require(success); } function transferFromERC721(address assetAddr, uint256 tokenId) internal virtual { address kitties = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d; address punks = 0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB; bytes memory data; if (assetAddr == kitties) { // Cryptokitties. data = abi.encodeWithSignature("transferFrom(address,address,uint256)", msg.sender, address(this), tokenId); } else if (assetAddr == punks) { // CryptoPunks. bytes memory punkIndexToAddress = abi.encodeWithSignature("punkIndexToAddress(uint256)", tokenId); (bool checkSuccess, bytes memory result) = address(assetAddr).staticcall(punkIndexToAddress); (address owner) = abi.decode(result, (address)); require(checkSuccess && owner == msg.sender, "Not the owner"); data = abi.encodeWithSignature("buyPunk(uint256)", tokenId); } else { // Default. data = abi.encodeWithSignature("safeTransferFrom(address,address,uint256)", msg.sender, address(this), tokenId); } (bool success, bytes memory resultData) = address(assetAddr).call(data); require(success, string(resultData)); } function getRandomTokenIdFromVault() internal virtual returns (uint256) { uint256 randomIndex = uint256( keccak256( abi.encodePacked( blockhash(block.number - 1), randNonce, block.coinbase, block.difficulty, block.timestamp ) ) ) % holdings.length(); randNonce += 1; return holdings.at(randomIndex); } function onlyPrivileged() internal view { if (manager == address(0)) { require(msg.sender == owner(), "Not owner"); } else { require(msg.sender == manager, "Not manager"); } } function onlyOwnerIfPaused(uint256 lockId) internal view { require(!vaultFactory.isLocked(lockId) || msg.sender == owner(), "Paused"); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"moduleIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"eligibilityAddr","type":"address"}],"name":"EligibilityDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"EnableMintUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"EnableRandomRedeemUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"EnableTargetRedeemUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"manager","type":"address"}],"name":"ManagerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mintFee","type":"uint256"}],"name":"MintFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"nftIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"randomRedeemFee","type":"uint256"}],"name":"RandomRedeemFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"nftIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Redeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"nftIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"redeemedIds","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Swapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"targetRedeemFee","type":"uint256"}],"name":"TargetRedeemFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"address","name":"assetAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"is1155","type":"bool"},{"indexed":false,"internalType":"bool","name":"allowAllItems","type":"bool"}],"name":"VaultInit","type":"event"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_assetAddress","type":"address"},{"internalType":"bool","name":"_is1155","type":"bool"},{"internalType":"bool","name":"_allowAllItems","type":"bool"}],"name":"__NFTXVault_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"allValidNFTs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowAllItems","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"assetAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"moduleIndex","type":"uint256"},{"internalType":"bytes","name":"initData","type":"bytes"}],"name":"deployEligibilityStorage","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eligibilityStorage","outputs":[{"internalType":"contract INFTXEligibility","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableRandomRedeem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTargetRedeem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalizeVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrowerUpgradeable","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"is1155","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"mintTo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"holdingsIndex","type":"uint256"}],"name":"nftIdAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomRedeemFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"}],"name":"redeem","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"redeemTo","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintFee","type":"uint256"},{"internalType":"uint256","name":"_randomRedeemFee","type":"uint256"},{"internalType":"uint256","name":"_targetRedeemFee","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enableMint","type":"bool"},{"internalType":"bool","name":"_enableRandomRedeem","type":"bool"},{"internalType":"bool","name":"_enableTargetRedeem","type":"bool"}],"name":"setVaultFeatures","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"}],"name":"swap","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"specificIds","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"swapTo","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetRedeemFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultFactory","outputs":[{"internalType":"contract INFTXVaultFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506143c8806100206000396000f3fe608060405234801561001057600080fd5b50600436106103205760003560e01c80638c850814116101a7578063d0ebdbe7116100ee578063f1d20dd411610097578063f7fce33411610071578063f7fce33414610745578063fcc0e3811461074f578063feb8eba51461076457600080fd5b8063f1d20dd4146106e7578063f23a6e61146106fa578063f2fde38b1461073257600080fd5b8063d9d98ce4116100c8578063d9d98ce414610688578063dd62ed3e1461069b578063e78458c4146106d457600080fd5b8063d0ebdbe71461064f578063d6ee4a9314610662578063d8a06f731461067557600080fd5b8063a9059cbb11610150578063c3cb8c141161012a578063c3cb8c1414610621578063c4a0db9614610629578063cec10c111461063c57600080fd5b8063a9059cbb146105c3578063b10402ea146105d6578063bc197c81146105e957600080fd5b806395d89b411161018157806395d89b41146105955780639d54def61461059d578063a457c2d7146105b057600080fd5b80638c850814146105515780638da5cb5b146105715780638f878a431461058257600080fd5b80633d5d190c1161026b5780635cffe9de1161021457806370a08231116101ee57806370a082311461050a578063715018a614610533578063793096581461053b57600080fd5b80635cffe9de146104d1578063613255ab146104e45780636b948a35146104f757600080fd5b8063481c6a7511610245578063481c6a751461049657806354f78d7f146104a95780635877aee6146104be57600080fd5b80633d5d190c1461045c57806344b28d591461046f57806345a0b6521461048357600080fd5b806318160ddd116102cd578063313ce567116102a7578063313ce5671461043157806333194c0a14610440578063395093511461044957600080fd5b806318160ddd146103eb5780631ba46cfd146103f357806323b872dd1461041e57600080fd5b8063095ea7b3116102fe578063095ea7b31461037057806313966db514610383578063150b7a021461039b57600080fd5b806301ffc9a71461032557806306f26dc21461034d57806306fdde031461035b575b600080fd5b610338610333366004613def565b61076e565b60405190151581526020015b60405180910390f35b610104546103389060ff1681565b6103636107d7565b60405161034491906141d5565b61033861037e366004613b13565b610869565b61038d6101015481565b604051908152602001610344565b6103d26103a9366004613a42565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040516001600160e01b03199091168152602001610344565b60675461038d565b60fd54610406906001600160a01b031681565b6040516001600160a01b039091168152602001610344565b61033861042c366004613a02565b61087f565b60405160128152602001610344565b61038d60fb5481565b610338610457366004613b13565b61094a565b61038d61046a366004613b3e565b610981565b610104546103389062010000900460ff1681565b61038d610491366004613ec7565b6109fb565b60fc54610406906001600160a01b031681565b6104bc6104b7366004613d98565b610a09565b005b6104066104cc366004613f66565b610af5565b6103386104df366004613e17565b610d0a565b61038d6104f23660046138e8565b610d22565b6101045461033890610100900460ff1681565b61038d6105183660046138e8565b6001600160a01b031660009081526065602052604090205490565b6104bc610d4a565b6101045461033890640100000000900460ff1681565b61056461055f366004613ce5565b610dee565b604051610344919061411a565b6033546001600160a01b0316610406565b60ff54610406906001600160a01b031681565b610363610fa3565b6105646105ab366004613f29565b610fb2565b6103386105be366004613b13565b61113c565b6103386105d1366004613b13565b6111ef565b61038d6105e4366004613c70565b6111fc565b6103d26105f7366004613958565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b6104bc611347565b610564610637366004613edf565b611353565b6104bc61064a366004613fdd565b61139c565b6104bc61065d3660046138e8565b61152d565b610564610670366004613ba7565b611589565b60fe54610406906001600160a01b031681565b61038d610696366004613b13565b611636565b61038d6106a9366004613920565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b6104bc6106e2366004613e2c565b611699565b6103386106f5366004613c3d565b611906565b6103d2610708366004613aac565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b6104bc6107403660046138e8565b6119d8565b61038d6101025481565b61010454610338906301000000900460ff1681565b61038d6101035481565b60006001600160e01b031982167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d157507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b6060606880546107e6906142cd565b80601f0160208091040260200160405190810160405280929190818152602001828054610812906142cd565b801561085f5780601f106108345761010080835404028352916020019161085f565b820191906000526020600020905b81548152906001019060200180831161084257829003601f168201915b5050505050905090565b6000610876338484611b0a565b50600192915050565b600061088c848484611c63565b6001600160a01b03841660009081526066602090815260408083203384529091529020548281101561092b5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61093f853361093a8685614286565b611b0a565b506001949350505050565b3360008181526066602090815260408083206001600160a01b0387168452909152812054909161087691859061093a90869061424f565b60006109f2858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208089028281018201909352888252909350889250879182918501908490808284376000920191909152503392506111fc915050565b95945050505050565b60006107d161010583611e84565b610a11611e90565b610104805463ffff000019166201000085151590810263ff0000001916919091176301000000851515021764ff00000000191664010000000084151502179091556040519081527fc604be2f834727754dc1ec1225c14d1ecde48e7d12fa7b745dfb137a3db998bd9060200160405180910390a160405182151581527f835d9397f97f5df575f718046bb3e918f911d39d7edfa79aa8d40ddc7d5ce2a59060200160405180910390a160405181151581527f64b60f32742df47d4ccb5b31ca12fee1bc20695467bfe8fa058b00ec446c1563906020015b60405180910390a1505050565b6000610aff611e90565b60ff546001600160a01b031615610b7e5760405162461bcd60e51b815260206004820152602260248201527f4e4654585661756c743a20656c69676962696c69747920616c7265616479207360448201527f65740000000000000000000000000000000000000000000000000000000000006064820152608401610922565b60fe54604080517f14c77faa00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916314c77faa916004808301926020929190829003018186803b158015610bdc57600080fd5b505afa158015610bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c149190613904565b90506000816001600160a01b031663576ff9088787876040518463ffffffff1660e01b8152600401610c48939291906141e8565b602060405180830381600087803b158015610c6257600080fd5b505af1158015610c76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9a9190613904565b60ff80546001600160a01b0319166001600160a01b038316908117909155610104805461ff00191690556040805189815260208101929092529192507fe14c63b3d4272158635bee1d1b95b51bb8de042ee95a15cbfaf2865b4d0af811910160405180910390a195945050505050565b6000610d166004611f54565b6109f28585858561204e565b60006001600160a01b0382163014610d3b5760006107d1565b6067546107d190600019614286565b6033546001600160a01b03163314610da45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610922565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6060600260c9541415610e435760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610922565b600260c955610e526003611f54565b6101045462010000900460ff168015610e8a5750610104546301000000900460ff1680610e8a575061010454640100000000900460ff165b610ed65760405162461bcd60e51b815260206004820181905260248201527f4e4654585661756c743a204d696e7420262052656465656d20656e61626c65646044820152606401610922565b6000610ee28686612272565b90506000845182610ef39190614286565b61010254610f019190614267565b855161010354610f119190614267565b610f1b919061424f565b90506000818361010154610f2f9190614267565b610f39919061424f565b9050610f44816124f7565b6000610f5184888861261d565b90507f66982ed4a058811a8004bdcec9adcb3671f2b4f1a788667a3a74959d7c09af3c898989848a604051610f8a95949392919061416c565b60405180910390a1600160c95598975050505050505050565b6060606980546107e6906142cd565b6060600260c95414156110075760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610922565b600260c981905561101790611f54565b610104546301000000900460ff168061103b575061010454640100000000900460ff165b6110875760405162461bcd60e51b815260206004820152601560248201527f52656465656d696e67206e6f7420656e61626c656400000000000000000000006044820152606401610922565b6110a23361109d86670de0b6b3a7640000614267565b61290d565b60008351856110b19190614286565b610102546110bf9190614267565b8451610103546110cf9190614267565b6110d9919061424f565b90506110e4816124f7565b60006110f186868661261d565b90507f63b13f6307f284441e029836b0c22eb91eb62a7ad555670061157930ce884f4e8186866040516111269392919061412d565b60405180910390a1600160c95595945050505050565b3360009081526066602090815260408083206001600160a01b0386168452909152812054828110156111d65760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610922565b6111e5338561093a8685614286565b5060019392505050565b6000610876338484611c63565b6000600260c95414156112515760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610922565b600260c9556112606001611f54565b6101045462010000900460ff166112b95760405162461bcd60e51b815260206004820152601360248201527f4d696e74696e67206e6f7420656e61626c6564000000000000000000000000006044820152606401610922565b60006112c58585612272565b90506112e2836112dd83670de0b6b3a7640000614267565b612a93565b600081610101546112f39190614267565b90506112fe816124f7565b7f1f72ad2a14447fa756b6f5aca53504645af79813493aca2d906b69e4aaeb94928686866040516113319392919061412d565b60405180910390a150600160c955949350505050565b611351600061152d565b565b606061139484848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250339250610fb2915050565b949350505050565b6113a4611e90565b670de0b6b3a76400008311156113ef5760405162461bcd60e51b815260206004820152601060248201526f21b0b73737ba101f10189032ba3432b960811b6044820152606401610922565b670de0b6b3a764000082111561143a5760405162461bcd60e51b815260206004820152601060248201526f21b0b73737ba101f10189032ba3432b960811b6044820152606401610922565b670de0b6b3a76400008111156114855760405162461bcd60e51b815260206004820152601060248201526f21b0b73737ba101f10189032ba3432b960811b6044820152606401610922565b6101018390556101028290556101038190556040518381527f38fbb1c8b109c430f0c030e7ed076cf5611a307773a4e8e365601e8f8bceaec69060200160405180910390a16040518281527fba745d4fd094af690af401897448edc81084d2a0f10fd90cd608be663c68905f9060200160405180910390a16040518181527fb9941a503692be6effbff47d4a5c63e74d003c710f0e4d5bd6ccc552ec9c7e4390602001610ae8565b611535611e90565b60fc80546001600160a01b0319166001600160a01b0383169081179091556040519081527f60a0f5b9f9e81e98216071b85826681c796256fe3d1354ecb675580fba64fa699060200160405180910390a150565b606061162b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a92508991829185019084908082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092019190915250339250610dee915050565b979650505050505050565b60006001600160a01b03831630146116905760405162461bcd60e51b815260206004820152601b60248201527f4552433230466c6173684d696e743a2077726f6e6720746f6b656e00000000006044820152606401610922565b50600092915050565b600054610100900460ff16806116b2575060005460ff16155b6117155760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015611737576000805461ffff19166101011790555b61173f612b72565b6117498686612c34565b6001600160a01b03841661179f5760405162461bcd60e51b815260206004820152601360248201527f417373657420213d2061646472657373283029000000000000000000000000006044820152606401610922565b60fd80546001600160a01b03199081166001600160a01b0387161790915560fe805433921682179055604080517f264a6208000000000000000000000000000000000000000000000000000000008152905163264a620891600480820192602092909190829003018186803b15801561181757600080fd5b505afa15801561182b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184f9190613dd7565b60fb8190556101048054841515610100810261ff001988151590811661ffff199094169390931717909255604080516001600160a01b038916815260208101929092528101919091527f18ecce5c418b882a3d89e5b6cc8100dc3383309b8e78525266fe1283a7f934d69060600160405180910390a26118d26001806001610a09565b6118ec662386f26fc10000600066b1a2bc2ec5000061139c565b80156118fe576000805461ff00191690555b505050505050565b61010454600090610100900460ff161561192257506001919050565b60ff546001600160a01b03168061193c5750600092915050565b6040517f84ca9f850000000000000000000000000000000000000000000000000000000081526001600160a01b038216906384ca9f859061198190869060040161411a565b60206040518083038186803b15801561199957600080fd5b505afa1580156119ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119d19190613d7c565b9392505050565b6033546001600160a01b03163314611a325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610922565b6001600160a01b038116611aae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610922565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038316611b855760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b038216611c015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316611cdf5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b038216611d5b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b03831660009081526065602052604090205481811015611dea5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610922565b611df48282614286565b6001600160a01b038086166000908152606560205260408082209390935590851681529081208054849290611e2a90849061424f565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611e7691815260200190565b60405180910390a350505050565b60006119d18383612cfb565b60fc546001600160a01b0316611efa576033546001600160a01b031633146113515760405162461bcd60e51b815260206004820152600960248201527f4e6f74206f776e657200000000000000000000000000000000000000000000006044820152606401610922565b60fc546001600160a01b031633146113515760405162461bcd60e51b815260206004820152600b60248201527f4e6f74206d616e616765720000000000000000000000000000000000000000006044820152606401610922565b60fe546040517ff6aacfb1000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b039091169063f6aacfb19060240160206040518083038186803b158015611fb157600080fd5b505afa158015611fc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe99190613d7c565b1580611fff57506033546001600160a01b031633145b61204b5760405162461bcd60e51b815260206004820152600660248201527f50617573656400000000000000000000000000000000000000000000000000006044820152606401610922565b50565b60008061205b8585611636565b90506120678685612a93565b6040517f23e30c8b0000000000000000000000000000000000000000000000000000000081527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038816906323e30c8b906120d69033908a908a9088908b906004016140e2565b602060405180830381600087803b1580156120f057600080fd5b505af1158015612104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121289190613dd7565b1461219a5760405162461bcd60e51b8152602060048201526024808201527f4552433230466c6173684d696e743a20696e76616c69642072657475726e207660448201527f616c7565000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b03861660009081526066602090815260408083203084529091529020546121c8828661424f565b81101561223d5760405162461bcd60e51b815260206004820152602f60248201527f4552433230466c6173684d696e743a20616c6c6f77616e636520646f6573206e60448201527f6f7420616c6c6f7720726566756e6400000000000000000000000000000000006064820152608401610922565b61225787308461224d8986614286565b61093a9190614286565b6122658761109d848861424f565b5060019695505050505050565b600061227d83611906565b6122c95760405162461bcd60e51b815260206004820152601760248201527f4e4654585661756c743a206e6f7420656c696769626c650000000000000000006044820152606401610922565b6101045460ff161561247d5760fd546040517f2eb2c2d60000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632eb2c2d69061232490339030908890889060040161408a565b600060405180830381600087803b15801561233e57600080fd5b505af1158015612352573d6000803e3d6000fd5b5060009250829150505b845181101561247557600085828151811061238757634e487b7160e01b600052603260045260246000fd5b6020026020010151905060008583815181106123b357634e487b7160e01b600052603260045260246000fd5b602002602001015190506000811161240d5760405162461bcd60e51b815260206004820152601b60248201527f4e4654585661756c743a207472616e7366657272696e67203c203100000000006044820152606401610922565b6000828152610107602052604090205461242f5761242d61010583612d33565b505b600082815261010760205260408120805483929061244e90849061424f565b9091555061245e9050818561424f565b93505050808061246d90614308565b91505061235c565b5090506107d1565b60fd546001600160a01b031660005b84518110156124ec5760008582815181106124b757634e487b7160e01b600052603260045260246000fd5b602002602001015190506124cb8382612d3f565b6124d761010582612d33565b505080806124e490614308565b91505061248c565b5083519150506107d1565b801561204b57612507338261290d565b60fe54604080517f0d43e8ad00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b031691630d43e8ad916004808301926020929190829003018186803b15801561256557600080fd5b505afa158015612579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259d9190613904565b90506125a98183612a93565b60fb546040517f91c05b0b00000000000000000000000000000000000000000000000000000000815260048101919091526001600160a01b038216906391c05b0b906024015b600060405180830381600087803b15801561260957600080fd5b505af11580156118fe573d6000803e3d6000fd5b606082518414806126385750610104546301000000900460ff165b6126905760405162461bcd60e51b8152602060048201526024808201527f4e4654585661756c743a2052616e646f6d2072656465656d206e6f7420656e61604482015263189b195960e21b6064820152608401610922565b825115806126a9575061010454640100000000900460ff165b6127015760405162461bcd60e51b8152602060048201526024808201527f4e4654585661756c743a205461726765742072656465656d206e6f7420656e61604482015263189b195960e21b6064820152608401610922565b6101045460fd5460ff909116906001600160a01b031660008667ffffffffffffffff81111561274057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612769578160200160208202803683370190505b50905060005b878110156128f95760008751821061278e57612789613043565b6127b7565b8782815181106127ae57634e487b7160e01b600052603260045260246000fd5b60200260200101515b9050808383815181106127da57634e487b7160e01b600052603260045260246000fd5b60200260200101818152505084156128ce5760008181526101076020526040812080546001929061280c908490614286565b90915550506000818152610107602052604090205461283357612831610105826130e7565b505b6040517ff242432a0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038881166024830152604482018390526001606483015260a06084830152600060a483015285169063f242432a9060c401600060405180830381600087803b1580156128b157600080fd5b505af11580156128c5573d6000803e3d6000fd5b505050506128e6565b6128da610105826130e7565b506128e68488836130f3565b50806128f181614308565b91505061276f565b50612903816132c5565b9695505050505050565b6001600160a01b0382166129895760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b03821660009081526065602052604090205481811015612a185760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610922565b612a228282614286565b6001600160a01b03841660009081526065602052604081209190915560678054849290612a50908490614286565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001611c56565b6001600160a01b038216612ae95760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610922565b8060676000828254612afb919061424f565b90915550506001600160a01b03821660009081526065602052604081208054839290612b2890849061424f565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600054610100900460ff1680612b8b575060005460ff16155b612bee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015612c10576000805461ffff19166101011790555b612c1861331f565b612c206133d0565b801561204b576000805461ff001916905550565b600054610100900460ff1680612c4d575060005460ff16155b612cb05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015612cd2576000805461ffff19166101011790555b612cda61331f565b612ce483836134c5565b8015612cf6576000805461ff00191690555b505050565b6000826000018281548110612d2057634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b60006119d183836135a1565b7306012c8cf97bead5deae237070f9587f8e7a266d73b47e3cd837ddf8e4c57f05d70ab865de6e193bbb60606001600160a01b038516831415612dc6576040513360248201523060448201526064810185905260840160408051601f198184030181529190526020810180516001600160e01b03166323b872dd60e01b1790529050612fb7565b816001600160a01b0316856001600160a01b03161415612f7157600084604051602401612df591815260200190565b60408051601f198184030181529181526020820180516001600160e01b03167f58178168000000000000000000000000000000000000000000000000000000001790525190915060009081906001600160a01b03891690612e5790859061406e565b600060405180830381855afa9150503d8060008114612e92576040519150601f19603f3d011682016040523d82523d6000602084013e612e97565b606091505b5091509150600081806020019051810190612eb29190613904565b9050828015612ec957506001600160a01b03811633145b612f155760405162461bcd60e51b815260206004820152600d60248201527f4e6f7420746865206f776e6572000000000000000000000000000000000000006044820152606401610922565b6040516024810189905260440160408051601f198184030181529190526020810180516001600160e01b03167f8264fe98000000000000000000000000000000000000000000000000000000001790529450612fb79350505050565b6040513360248201523060448201526064810185905260840160408051601f198184030181529190526020810180516001600160e01b0316632142170760e11b17905290505b600080866001600160a01b031683604051612fd2919061406e565b6000604051808303816000865af19150503d806000811461300f576040519150601f19603f3d011682016040523d82523d6000602084013e613014565b606091505b50915091508181906130395760405162461bcd60e51b815260040161092291906141d5565b5050505050505050565b6000806130516101056135f0565b61305c600143614286565b61010054604080519240602084015282015241606090811b6bffffffffffffffffffffffff19169082015244607482015242609482015260b4016040516020818303038152906040528051906020012060001c6130b99190614323565b9050600161010060008282546130cf919061424f565b909155506130e1905061010582611e84565b91505090565b60006119d183836135fa565b7306012c8cf97bead5deae237070f9587f8e7a266d73b47e3cd837ddf8e4c57f05d70ab865de6e193bbb60606001600160a01b038616831415613183576040513060248201526001600160a01b03861660448201526064810185905260840160408051601f198184030181529190526020810180516001600160e01b03166323b872dd60e01b1790529050613252565b816001600160a01b0316866001600160a01b03161415613203576040516001600160a01b03861660248201526044810185905260640160408051601f198184030181529190526020810180516001600160e01b03167f8b72a2ec000000000000000000000000000000000000000000000000000000001790529050613252565b6040513060248201526001600160a01b03861660448201526064810185905260840160408051601f198184030181529190526020810180516001600160e01b0316632142170760e11b17905290505b6000866001600160a01b03168260405161326c919061406e565b6000604051808303816000865af19150503d80600081146132a9576040519150601f19603f3d011682016040523d82523d6000602084013e6132ae565b606091505b50509050806132bc57600080fd5b50505050505050565b60ff546001600160a01b0316806132da575050565b6040517f5e2f9b520000000000000000000000000000000000000000000000000000000081526001600160a01b03821690635e2f9b52906125ef90859060040161411a565b600054610100900460ff1680613338575060005460ff16155b61339b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015612c20576000805461ffff1916610101179055801561204b576000805461ff001916905550565b600054610100900460ff16806133e9575060005460ff16155b61344c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff1615801561346e576000805461ffff19166101011790555b603380546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350801561204b576000805461ff001916905550565b600054610100900460ff16806134de575060005460ff16155b6135415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015613563576000805461ffff19166101011790555b8251613576906068906020860190613717565b50815161358a906069906020850190613717565b508015612cf6576000805461ff0019169055505050565b60008181526001830160205260408120546135e8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556107d1565b5060006107d1565b60006107d1825490565b6000818152600183016020526040812054801561370d57600061361e600183614286565b855490915060009061363290600190614286565b90508181146136b357600086600001828154811061366057634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061369157634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b85548690806136d257634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506107d1565b60009150506107d1565b828054613723906142cd565b90600052602060002090601f016020900481019282613745576000855561378b565b82601f1061375e57805160ff191683800117855561378b565b8280016001018555821561378b579182015b8281111561378b578251825591602001919060010190613770565b5061379792915061379b565b5090565b5b80821115613797576000815560010161379c565b60008083601f8401126137c1578182fd5b50813567ffffffffffffffff8111156137d8578182fd5b6020830191508360208260051b85010111156137f357600080fd5b9250929050565b600082601f83011261380a578081fd5b8135602067ffffffffffffffff82111561382657613826614359565b8160051b61383582820161421e565b83815282810190868401838801850189101561384f578687fd5b8693505b85841015613871578035835260019390930192918401918401613853565b50979650505050505050565b600082601f83011261388d578081fd5b813567ffffffffffffffff8111156138a7576138a7614359565b6138ba601f8201601f191660200161421e565b8181528460208386010111156138ce578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156138f9578081fd5b81356119d18161436f565b600060208284031215613915578081fd5b81516119d18161436f565b60008060408385031215613932578081fd5b823561393d8161436f565b9150602083013561394d8161436f565b809150509250929050565b600080600080600060a0868803121561396f578081fd5b853561397a8161436f565b9450602086013561398a8161436f565b9350604086013567ffffffffffffffff808211156139a6578283fd5b6139b289838a016137fa565b945060608801359150808211156139c7578283fd5b6139d389838a016137fa565b935060808801359150808211156139e8578283fd5b506139f58882890161387d565b9150509295509295909350565b600080600060608486031215613a16578283fd5b8335613a218161436f565b92506020840135613a318161436f565b929592945050506040919091013590565b60008060008060808587031215613a57578384fd5b8435613a628161436f565b93506020850135613a728161436f565b925060408501359150606085013567ffffffffffffffff811115613a94578182fd5b613aa08782880161387d565b91505092959194509250565b600080600080600060a08688031215613ac3578283fd5b8535613ace8161436f565b94506020860135613ade8161436f565b93506040860135925060608601359150608086013567ffffffffffffffff811115613b07578182fd5b6139f58882890161387d565b60008060408385031215613b25578182fd5b8235613b308161436f565b946020939093013593505050565b60008060008060408587031215613b53578182fd5b843567ffffffffffffffff80821115613b6a578384fd5b613b76888389016137b0565b90965094506020870135915080821115613b8e578384fd5b50613b9b878288016137b0565b95989497509550505050565b60008060008060008060608789031215613bbf578384fd5b863567ffffffffffffffff80821115613bd6578586fd5b613be28a838b016137b0565b90985096506020890135915080821115613bfa578586fd5b613c068a838b016137b0565b90965094506040890135915080821115613c1e578283fd5b50613c2b89828a016137b0565b979a9699509497509295939492505050565b600060208284031215613c4e578081fd5b813567ffffffffffffffff811115613c64578182fd5b611394848285016137fa565b600080600060608486031215613c84578081fd5b833567ffffffffffffffff80821115613c9b578283fd5b613ca7878388016137fa565b94506020860135915080821115613cbc578283fd5b50613cc9868287016137fa565b9250506040840135613cda8161436f565b809150509250925092565b60008060008060808587031215613cfa578182fd5b843567ffffffffffffffff80821115613d11578384fd5b613d1d888389016137fa565b95506020870135915080821115613d32578384fd5b613d3e888389016137fa565b94506040870135915080821115613d53578384fd5b50613d60878288016137fa565b9250506060850135613d718161436f565b939692955090935050565b600060208284031215613d8d578081fd5b81516119d181614384565b600080600060608486031215613dac578081fd5b8335613db781614384565b92506020840135613dc781614384565b91506040840135613cda81614384565b600060208284031215613de8578081fd5b5051919050565b600060208284031215613e00578081fd5b81356001600160e01b0319811681146119d1578182fd5b60008060008060808587031215613a57578182fd5b600080600080600060a08688031215613e43578283fd5b853567ffffffffffffffff80821115613e5a578485fd5b613e6689838a0161387d565b96506020880135915080821115613e7b578485fd5b50613e888882890161387d565b9450506040860135613e998161436f565b92506060860135613ea981614384565b91506080860135613eb981614384565b809150509295509295909350565b600060208284031215613ed8578081fd5b5035919050565b600080600060408486031215613ef3578081fd5b83359250602084013567ffffffffffffffff811115613f10578182fd5b613f1c868287016137b0565b9497909650939450505050565b600080600060608486031215613f3d578081fd5b83359250602084013567ffffffffffffffff811115613f5a578182fd5b613cc9868287016137fa565b600080600060408486031215613f7a578081fd5b83359250602084013567ffffffffffffffff80821115613f98578283fd5b818601915086601f830112613fab578283fd5b813581811115613fb9578384fd5b876020828501011115613fca578384fd5b6020830194508093505050509250925092565b600080600060608486031215613ff1578081fd5b505081359360208301359350604090920135919050565b6000815180845260208085019450808401835b838110156140375781518752958201959082019060010161401b565b509495945050505050565b6000815180845261405a81602086016020860161429d565b601f01601f19169290920160200192915050565b6000825161408081846020870161429d565b9190910192915050565b60006001600160a01b03808716835280861660208401525060a060408301526140b660a0830185614008565b82810360608401526140c88185614008565b838103608090940193909352508152602001949350505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a0608083015261162b60a0830184614042565b6020815260006119d16020830184614008565b6060815260006141406060830186614008565b82810360208401526141528186614008565b9150506001600160a01b0383166040830152949350505050565b60a08152600061417f60a0830188614008565b82810360208401526141918188614008565b905082810360408401526141a58187614008565b905082810360608401526141b98186614008565b9150506001600160a01b03831660808301529695505050505050565b6020815260006119d16020830184614042565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561424757614247614359565b604052919050565b6000821982111561426257614262614343565b500190565b600081600019048311821515161561428157614281614343565b500290565b60008282101561429857614298614343565b500390565b60005b838110156142b85781810151838201526020016142a0565b838111156142c7576000848401525b50505050565b600181811c908216806142e157607f821691505b6020821081141561430257634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561431c5761431c614343565b5060010190565b60008261433e57634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461204b57600080fd5b801515811461204b57600080fdfea264697066735822122066d13754c3f5ee2f66bfd0b735a8e31c909f6b3e8b095d8563ba67bcaf44833964736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103205760003560e01c80638c850814116101a7578063d0ebdbe7116100ee578063f1d20dd411610097578063f7fce33411610071578063f7fce33414610745578063fcc0e3811461074f578063feb8eba51461076457600080fd5b8063f1d20dd4146106e7578063f23a6e61146106fa578063f2fde38b1461073257600080fd5b8063d9d98ce4116100c8578063d9d98ce414610688578063dd62ed3e1461069b578063e78458c4146106d457600080fd5b8063d0ebdbe71461064f578063d6ee4a9314610662578063d8a06f731461067557600080fd5b8063a9059cbb11610150578063c3cb8c141161012a578063c3cb8c1414610621578063c4a0db9614610629578063cec10c111461063c57600080fd5b8063a9059cbb146105c3578063b10402ea146105d6578063bc197c81146105e957600080fd5b806395d89b411161018157806395d89b41146105955780639d54def61461059d578063a457c2d7146105b057600080fd5b80638c850814146105515780638da5cb5b146105715780638f878a431461058257600080fd5b80633d5d190c1161026b5780635cffe9de1161021457806370a08231116101ee57806370a082311461050a578063715018a614610533578063793096581461053b57600080fd5b80635cffe9de146104d1578063613255ab146104e45780636b948a35146104f757600080fd5b8063481c6a7511610245578063481c6a751461049657806354f78d7f146104a95780635877aee6146104be57600080fd5b80633d5d190c1461045c57806344b28d591461046f57806345a0b6521461048357600080fd5b806318160ddd116102cd578063313ce567116102a7578063313ce5671461043157806333194c0a14610440578063395093511461044957600080fd5b806318160ddd146103eb5780631ba46cfd146103f357806323b872dd1461041e57600080fd5b8063095ea7b3116102fe578063095ea7b31461037057806313966db514610383578063150b7a021461039b57600080fd5b806301ffc9a71461032557806306f26dc21461034d57806306fdde031461035b575b600080fd5b610338610333366004613def565b61076e565b60405190151581526020015b60405180910390f35b610104546103389060ff1681565b6103636107d7565b60405161034491906141d5565b61033861037e366004613b13565b610869565b61038d6101015481565b604051908152602001610344565b6103d26103a9366004613a42565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040516001600160e01b03199091168152602001610344565b60675461038d565b60fd54610406906001600160a01b031681565b6040516001600160a01b039091168152602001610344565b61033861042c366004613a02565b61087f565b60405160128152602001610344565b61038d60fb5481565b610338610457366004613b13565b61094a565b61038d61046a366004613b3e565b610981565b610104546103389062010000900460ff1681565b61038d610491366004613ec7565b6109fb565b60fc54610406906001600160a01b031681565b6104bc6104b7366004613d98565b610a09565b005b6104066104cc366004613f66565b610af5565b6103386104df366004613e17565b610d0a565b61038d6104f23660046138e8565b610d22565b6101045461033890610100900460ff1681565b61038d6105183660046138e8565b6001600160a01b031660009081526065602052604090205490565b6104bc610d4a565b6101045461033890640100000000900460ff1681565b61056461055f366004613ce5565b610dee565b604051610344919061411a565b6033546001600160a01b0316610406565b60ff54610406906001600160a01b031681565b610363610fa3565b6105646105ab366004613f29565b610fb2565b6103386105be366004613b13565b61113c565b6103386105d1366004613b13565b6111ef565b61038d6105e4366004613c70565b6111fc565b6103d26105f7366004613958565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b6104bc611347565b610564610637366004613edf565b611353565b6104bc61064a366004613fdd565b61139c565b6104bc61065d3660046138e8565b61152d565b610564610670366004613ba7565b611589565b60fe54610406906001600160a01b031681565b61038d610696366004613b13565b611636565b61038d6106a9366004613920565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b6104bc6106e2366004613e2c565b611699565b6103386106f5366004613c3d565b611906565b6103d2610708366004613aac565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b6104bc6107403660046138e8565b6119d8565b61038d6101025481565b61010454610338906301000000900460ff1681565b61038d6101035481565b60006001600160e01b031982167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d157507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b6060606880546107e6906142cd565b80601f0160208091040260200160405190810160405280929190818152602001828054610812906142cd565b801561085f5780601f106108345761010080835404028352916020019161085f565b820191906000526020600020905b81548152906001019060200180831161084257829003601f168201915b5050505050905090565b6000610876338484611b0a565b50600192915050565b600061088c848484611c63565b6001600160a01b03841660009081526066602090815260408083203384529091529020548281101561092b5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61093f853361093a8685614286565b611b0a565b506001949350505050565b3360008181526066602090815260408083206001600160a01b0387168452909152812054909161087691859061093a90869061424f565b60006109f2858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208089028281018201909352888252909350889250879182918501908490808284376000920191909152503392506111fc915050565b95945050505050565b60006107d161010583611e84565b610a11611e90565b610104805463ffff000019166201000085151590810263ff0000001916919091176301000000851515021764ff00000000191664010000000084151502179091556040519081527fc604be2f834727754dc1ec1225c14d1ecde48e7d12fa7b745dfb137a3db998bd9060200160405180910390a160405182151581527f835d9397f97f5df575f718046bb3e918f911d39d7edfa79aa8d40ddc7d5ce2a59060200160405180910390a160405181151581527f64b60f32742df47d4ccb5b31ca12fee1bc20695467bfe8fa058b00ec446c1563906020015b60405180910390a1505050565b6000610aff611e90565b60ff546001600160a01b031615610b7e5760405162461bcd60e51b815260206004820152602260248201527f4e4654585661756c743a20656c69676962696c69747920616c7265616479207360448201527f65740000000000000000000000000000000000000000000000000000000000006064820152608401610922565b60fe54604080517f14c77faa00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916314c77faa916004808301926020929190829003018186803b158015610bdc57600080fd5b505afa158015610bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c149190613904565b90506000816001600160a01b031663576ff9088787876040518463ffffffff1660e01b8152600401610c48939291906141e8565b602060405180830381600087803b158015610c6257600080fd5b505af1158015610c76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9a9190613904565b60ff80546001600160a01b0319166001600160a01b038316908117909155610104805461ff00191690556040805189815260208101929092529192507fe14c63b3d4272158635bee1d1b95b51bb8de042ee95a15cbfaf2865b4d0af811910160405180910390a195945050505050565b6000610d166004611f54565b6109f28585858561204e565b60006001600160a01b0382163014610d3b5760006107d1565b6067546107d190600019614286565b6033546001600160a01b03163314610da45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610922565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6060600260c9541415610e435760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610922565b600260c955610e526003611f54565b6101045462010000900460ff168015610e8a5750610104546301000000900460ff1680610e8a575061010454640100000000900460ff165b610ed65760405162461bcd60e51b815260206004820181905260248201527f4e4654585661756c743a204d696e7420262052656465656d20656e61626c65646044820152606401610922565b6000610ee28686612272565b90506000845182610ef39190614286565b61010254610f019190614267565b855161010354610f119190614267565b610f1b919061424f565b90506000818361010154610f2f9190614267565b610f39919061424f565b9050610f44816124f7565b6000610f5184888861261d565b90507f66982ed4a058811a8004bdcec9adcb3671f2b4f1a788667a3a74959d7c09af3c898989848a604051610f8a95949392919061416c565b60405180910390a1600160c95598975050505050505050565b6060606980546107e6906142cd565b6060600260c95414156110075760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610922565b600260c981905561101790611f54565b610104546301000000900460ff168061103b575061010454640100000000900460ff165b6110875760405162461bcd60e51b815260206004820152601560248201527f52656465656d696e67206e6f7420656e61626c656400000000000000000000006044820152606401610922565b6110a23361109d86670de0b6b3a7640000614267565b61290d565b60008351856110b19190614286565b610102546110bf9190614267565b8451610103546110cf9190614267565b6110d9919061424f565b90506110e4816124f7565b60006110f186868661261d565b90507f63b13f6307f284441e029836b0c22eb91eb62a7ad555670061157930ce884f4e8186866040516111269392919061412d565b60405180910390a1600160c95595945050505050565b3360009081526066602090815260408083206001600160a01b0386168452909152812054828110156111d65760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610922565b6111e5338561093a8685614286565b5060019392505050565b6000610876338484611c63565b6000600260c95414156112515760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610922565b600260c9556112606001611f54565b6101045462010000900460ff166112b95760405162461bcd60e51b815260206004820152601360248201527f4d696e74696e67206e6f7420656e61626c6564000000000000000000000000006044820152606401610922565b60006112c58585612272565b90506112e2836112dd83670de0b6b3a7640000614267565b612a93565b600081610101546112f39190614267565b90506112fe816124f7565b7f1f72ad2a14447fa756b6f5aca53504645af79813493aca2d906b69e4aaeb94928686866040516113319392919061412d565b60405180910390a150600160c955949350505050565b611351600061152d565b565b606061139484848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250339250610fb2915050565b949350505050565b6113a4611e90565b670de0b6b3a76400008311156113ef5760405162461bcd60e51b815260206004820152601060248201526f21b0b73737ba101f10189032ba3432b960811b6044820152606401610922565b670de0b6b3a764000082111561143a5760405162461bcd60e51b815260206004820152601060248201526f21b0b73737ba101f10189032ba3432b960811b6044820152606401610922565b670de0b6b3a76400008111156114855760405162461bcd60e51b815260206004820152601060248201526f21b0b73737ba101f10189032ba3432b960811b6044820152606401610922565b6101018390556101028290556101038190556040518381527f38fbb1c8b109c430f0c030e7ed076cf5611a307773a4e8e365601e8f8bceaec69060200160405180910390a16040518281527fba745d4fd094af690af401897448edc81084d2a0f10fd90cd608be663c68905f9060200160405180910390a16040518181527fb9941a503692be6effbff47d4a5c63e74d003c710f0e4d5bd6ccc552ec9c7e4390602001610ae8565b611535611e90565b60fc80546001600160a01b0319166001600160a01b0383169081179091556040519081527f60a0f5b9f9e81e98216071b85826681c796256fe3d1354ecb675580fba64fa699060200160405180910390a150565b606061162b87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a92508991829185019084908082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092019190915250339250610dee915050565b979650505050505050565b60006001600160a01b03831630146116905760405162461bcd60e51b815260206004820152601b60248201527f4552433230466c6173684d696e743a2077726f6e6720746f6b656e00000000006044820152606401610922565b50600092915050565b600054610100900460ff16806116b2575060005460ff16155b6117155760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015611737576000805461ffff19166101011790555b61173f612b72565b6117498686612c34565b6001600160a01b03841661179f5760405162461bcd60e51b815260206004820152601360248201527f417373657420213d2061646472657373283029000000000000000000000000006044820152606401610922565b60fd80546001600160a01b03199081166001600160a01b0387161790915560fe805433921682179055604080517f264a6208000000000000000000000000000000000000000000000000000000008152905163264a620891600480820192602092909190829003018186803b15801561181757600080fd5b505afa15801561182b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184f9190613dd7565b60fb8190556101048054841515610100810261ff001988151590811661ffff199094169390931717909255604080516001600160a01b038916815260208101929092528101919091527f18ecce5c418b882a3d89e5b6cc8100dc3383309b8e78525266fe1283a7f934d69060600160405180910390a26118d26001806001610a09565b6118ec662386f26fc10000600066b1a2bc2ec5000061139c565b80156118fe576000805461ff00191690555b505050505050565b61010454600090610100900460ff161561192257506001919050565b60ff546001600160a01b03168061193c5750600092915050565b6040517f84ca9f850000000000000000000000000000000000000000000000000000000081526001600160a01b038216906384ca9f859061198190869060040161411a565b60206040518083038186803b15801561199957600080fd5b505afa1580156119ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119d19190613d7c565b9392505050565b6033546001600160a01b03163314611a325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610922565b6001600160a01b038116611aae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610922565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038316611b855760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b038216611c015760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316611cdf5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b038216611d5b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b03831660009081526065602052604090205481811015611dea5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610922565b611df48282614286565b6001600160a01b038086166000908152606560205260408082209390935590851681529081208054849290611e2a90849061424f565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611e7691815260200190565b60405180910390a350505050565b60006119d18383612cfb565b60fc546001600160a01b0316611efa576033546001600160a01b031633146113515760405162461bcd60e51b815260206004820152600960248201527f4e6f74206f776e657200000000000000000000000000000000000000000000006044820152606401610922565b60fc546001600160a01b031633146113515760405162461bcd60e51b815260206004820152600b60248201527f4e6f74206d616e616765720000000000000000000000000000000000000000006044820152606401610922565b60fe546040517ff6aacfb1000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b039091169063f6aacfb19060240160206040518083038186803b158015611fb157600080fd5b505afa158015611fc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe99190613d7c565b1580611fff57506033546001600160a01b031633145b61204b5760405162461bcd60e51b815260206004820152600660248201527f50617573656400000000000000000000000000000000000000000000000000006044820152606401610922565b50565b60008061205b8585611636565b90506120678685612a93565b6040517f23e30c8b0000000000000000000000000000000000000000000000000000000081527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038816906323e30c8b906120d69033908a908a9088908b906004016140e2565b602060405180830381600087803b1580156120f057600080fd5b505af1158015612104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121289190613dd7565b1461219a5760405162461bcd60e51b8152602060048201526024808201527f4552433230466c6173684d696e743a20696e76616c69642072657475726e207660448201527f616c7565000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b03861660009081526066602090815260408083203084529091529020546121c8828661424f565b81101561223d5760405162461bcd60e51b815260206004820152602f60248201527f4552433230466c6173684d696e743a20616c6c6f77616e636520646f6573206e60448201527f6f7420616c6c6f7720726566756e6400000000000000000000000000000000006064820152608401610922565b61225787308461224d8986614286565b61093a9190614286565b6122658761109d848861424f565b5060019695505050505050565b600061227d83611906565b6122c95760405162461bcd60e51b815260206004820152601760248201527f4e4654585661756c743a206e6f7420656c696769626c650000000000000000006044820152606401610922565b6101045460ff161561247d5760fd546040517f2eb2c2d60000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632eb2c2d69061232490339030908890889060040161408a565b600060405180830381600087803b15801561233e57600080fd5b505af1158015612352573d6000803e3d6000fd5b5060009250829150505b845181101561247557600085828151811061238757634e487b7160e01b600052603260045260246000fd5b6020026020010151905060008583815181106123b357634e487b7160e01b600052603260045260246000fd5b602002602001015190506000811161240d5760405162461bcd60e51b815260206004820152601b60248201527f4e4654585661756c743a207472616e7366657272696e67203c203100000000006044820152606401610922565b6000828152610107602052604090205461242f5761242d61010583612d33565b505b600082815261010760205260408120805483929061244e90849061424f565b9091555061245e9050818561424f565b93505050808061246d90614308565b91505061235c565b5090506107d1565b60fd546001600160a01b031660005b84518110156124ec5760008582815181106124b757634e487b7160e01b600052603260045260246000fd5b602002602001015190506124cb8382612d3f565b6124d761010582612d33565b505080806124e490614308565b91505061248c565b5083519150506107d1565b801561204b57612507338261290d565b60fe54604080517f0d43e8ad00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b031691630d43e8ad916004808301926020929190829003018186803b15801561256557600080fd5b505afa158015612579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259d9190613904565b90506125a98183612a93565b60fb546040517f91c05b0b00000000000000000000000000000000000000000000000000000000815260048101919091526001600160a01b038216906391c05b0b906024015b600060405180830381600087803b15801561260957600080fd5b505af11580156118fe573d6000803e3d6000fd5b606082518414806126385750610104546301000000900460ff165b6126905760405162461bcd60e51b8152602060048201526024808201527f4e4654585661756c743a2052616e646f6d2072656465656d206e6f7420656e61604482015263189b195960e21b6064820152608401610922565b825115806126a9575061010454640100000000900460ff165b6127015760405162461bcd60e51b8152602060048201526024808201527f4e4654585661756c743a205461726765742072656465656d206e6f7420656e61604482015263189b195960e21b6064820152608401610922565b6101045460fd5460ff909116906001600160a01b031660008667ffffffffffffffff81111561274057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612769578160200160208202803683370190505b50905060005b878110156128f95760008751821061278e57612789613043565b6127b7565b8782815181106127ae57634e487b7160e01b600052603260045260246000fd5b60200260200101515b9050808383815181106127da57634e487b7160e01b600052603260045260246000fd5b60200260200101818152505084156128ce5760008181526101076020526040812080546001929061280c908490614286565b90915550506000818152610107602052604090205461283357612831610105826130e7565b505b6040517ff242432a0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038881166024830152604482018390526001606483015260a06084830152600060a483015285169063f242432a9060c401600060405180830381600087803b1580156128b157600080fd5b505af11580156128c5573d6000803e3d6000fd5b505050506128e6565b6128da610105826130e7565b506128e68488836130f3565b50806128f181614308565b91505061276f565b50612903816132c5565b9695505050505050565b6001600160a01b0382166129895760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610922565b6001600160a01b03821660009081526065602052604090205481811015612a185760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610922565b612a228282614286565b6001600160a01b03841660009081526065602052604081209190915560678054849290612a50908490614286565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001611c56565b6001600160a01b038216612ae95760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610922565b8060676000828254612afb919061424f565b90915550506001600160a01b03821660009081526065602052604081208054839290612b2890849061424f565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600054610100900460ff1680612b8b575060005460ff16155b612bee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015612c10576000805461ffff19166101011790555b612c1861331f565b612c206133d0565b801561204b576000805461ff001916905550565b600054610100900460ff1680612c4d575060005460ff16155b612cb05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015612cd2576000805461ffff19166101011790555b612cda61331f565b612ce483836134c5565b8015612cf6576000805461ff00191690555b505050565b6000826000018281548110612d2057634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b60006119d183836135a1565b7306012c8cf97bead5deae237070f9587f8e7a266d73b47e3cd837ddf8e4c57f05d70ab865de6e193bbb60606001600160a01b038516831415612dc6576040513360248201523060448201526064810185905260840160408051601f198184030181529190526020810180516001600160e01b03166323b872dd60e01b1790529050612fb7565b816001600160a01b0316856001600160a01b03161415612f7157600084604051602401612df591815260200190565b60408051601f198184030181529181526020820180516001600160e01b03167f58178168000000000000000000000000000000000000000000000000000000001790525190915060009081906001600160a01b03891690612e5790859061406e565b600060405180830381855afa9150503d8060008114612e92576040519150601f19603f3d011682016040523d82523d6000602084013e612e97565b606091505b5091509150600081806020019051810190612eb29190613904565b9050828015612ec957506001600160a01b03811633145b612f155760405162461bcd60e51b815260206004820152600d60248201527f4e6f7420746865206f776e6572000000000000000000000000000000000000006044820152606401610922565b6040516024810189905260440160408051601f198184030181529190526020810180516001600160e01b03167f8264fe98000000000000000000000000000000000000000000000000000000001790529450612fb79350505050565b6040513360248201523060448201526064810185905260840160408051601f198184030181529190526020810180516001600160e01b0316632142170760e11b17905290505b600080866001600160a01b031683604051612fd2919061406e565b6000604051808303816000865af19150503d806000811461300f576040519150601f19603f3d011682016040523d82523d6000602084013e613014565b606091505b50915091508181906130395760405162461bcd60e51b815260040161092291906141d5565b5050505050505050565b6000806130516101056135f0565b61305c600143614286565b61010054604080519240602084015282015241606090811b6bffffffffffffffffffffffff19169082015244607482015242609482015260b4016040516020818303038152906040528051906020012060001c6130b99190614323565b9050600161010060008282546130cf919061424f565b909155506130e1905061010582611e84565b91505090565b60006119d183836135fa565b7306012c8cf97bead5deae237070f9587f8e7a266d73b47e3cd837ddf8e4c57f05d70ab865de6e193bbb60606001600160a01b038616831415613183576040513060248201526001600160a01b03861660448201526064810185905260840160408051601f198184030181529190526020810180516001600160e01b03166323b872dd60e01b1790529050613252565b816001600160a01b0316866001600160a01b03161415613203576040516001600160a01b03861660248201526044810185905260640160408051601f198184030181529190526020810180516001600160e01b03167f8b72a2ec000000000000000000000000000000000000000000000000000000001790529050613252565b6040513060248201526001600160a01b03861660448201526064810185905260840160408051601f198184030181529190526020810180516001600160e01b0316632142170760e11b17905290505b6000866001600160a01b03168260405161326c919061406e565b6000604051808303816000865af19150503d80600081146132a9576040519150601f19603f3d011682016040523d82523d6000602084013e6132ae565b606091505b50509050806132bc57600080fd5b50505050505050565b60ff546001600160a01b0316806132da575050565b6040517f5e2f9b520000000000000000000000000000000000000000000000000000000081526001600160a01b03821690635e2f9b52906125ef90859060040161411a565b600054610100900460ff1680613338575060005460ff16155b61339b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015612c20576000805461ffff1916610101179055801561204b576000805461ff001916905550565b600054610100900460ff16806133e9575060005460ff16155b61344c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff1615801561346e576000805461ffff19166101011790555b603380546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350801561204b576000805461ff001916905550565b600054610100900460ff16806134de575060005460ff16155b6135415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610922565b600054610100900460ff16158015613563576000805461ffff19166101011790555b8251613576906068906020860190613717565b50815161358a906069906020850190613717565b508015612cf6576000805461ff0019169055505050565b60008181526001830160205260408120546135e8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556107d1565b5060006107d1565b60006107d1825490565b6000818152600183016020526040812054801561370d57600061361e600183614286565b855490915060009061363290600190614286565b90508181146136b357600086600001828154811061366057634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061369157634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b85548690806136d257634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506107d1565b60009150506107d1565b828054613723906142cd565b90600052602060002090601f016020900481019282613745576000855561378b565b82601f1061375e57805160ff191683800117855561378b565b8280016001018555821561378b579182015b8281111561378b578251825591602001919060010190613770565b5061379792915061379b565b5090565b5b80821115613797576000815560010161379c565b60008083601f8401126137c1578182fd5b50813567ffffffffffffffff8111156137d8578182fd5b6020830191508360208260051b85010111156137f357600080fd5b9250929050565b600082601f83011261380a578081fd5b8135602067ffffffffffffffff82111561382657613826614359565b8160051b61383582820161421e565b83815282810190868401838801850189101561384f578687fd5b8693505b85841015613871578035835260019390930192918401918401613853565b50979650505050505050565b600082601f83011261388d578081fd5b813567ffffffffffffffff8111156138a7576138a7614359565b6138ba601f8201601f191660200161421e565b8181528460208386010111156138ce578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156138f9578081fd5b81356119d18161436f565b600060208284031215613915578081fd5b81516119d18161436f565b60008060408385031215613932578081fd5b823561393d8161436f565b9150602083013561394d8161436f565b809150509250929050565b600080600080600060a0868803121561396f578081fd5b853561397a8161436f565b9450602086013561398a8161436f565b9350604086013567ffffffffffffffff808211156139a6578283fd5b6139b289838a016137fa565b945060608801359150808211156139c7578283fd5b6139d389838a016137fa565b935060808801359150808211156139e8578283fd5b506139f58882890161387d565b9150509295509295909350565b600080600060608486031215613a16578283fd5b8335613a218161436f565b92506020840135613a318161436f565b929592945050506040919091013590565b60008060008060808587031215613a57578384fd5b8435613a628161436f565b93506020850135613a728161436f565b925060408501359150606085013567ffffffffffffffff811115613a94578182fd5b613aa08782880161387d565b91505092959194509250565b600080600080600060a08688031215613ac3578283fd5b8535613ace8161436f565b94506020860135613ade8161436f565b93506040860135925060608601359150608086013567ffffffffffffffff811115613b07578182fd5b6139f58882890161387d565b60008060408385031215613b25578182fd5b8235613b308161436f565b946020939093013593505050565b60008060008060408587031215613b53578182fd5b843567ffffffffffffffff80821115613b6a578384fd5b613b76888389016137b0565b90965094506020870135915080821115613b8e578384fd5b50613b9b878288016137b0565b95989497509550505050565b60008060008060008060608789031215613bbf578384fd5b863567ffffffffffffffff80821115613bd6578586fd5b613be28a838b016137b0565b90985096506020890135915080821115613bfa578586fd5b613c068a838b016137b0565b90965094506040890135915080821115613c1e578283fd5b50613c2b89828a016137b0565b979a9699509497509295939492505050565b600060208284031215613c4e578081fd5b813567ffffffffffffffff811115613c64578182fd5b611394848285016137fa565b600080600060608486031215613c84578081fd5b833567ffffffffffffffff80821115613c9b578283fd5b613ca7878388016137fa565b94506020860135915080821115613cbc578283fd5b50613cc9868287016137fa565b9250506040840135613cda8161436f565b809150509250925092565b60008060008060808587031215613cfa578182fd5b843567ffffffffffffffff80821115613d11578384fd5b613d1d888389016137fa565b95506020870135915080821115613d32578384fd5b613d3e888389016137fa565b94506040870135915080821115613d53578384fd5b50613d60878288016137fa565b9250506060850135613d718161436f565b939692955090935050565b600060208284031215613d8d578081fd5b81516119d181614384565b600080600060608486031215613dac578081fd5b8335613db781614384565b92506020840135613dc781614384565b91506040840135613cda81614384565b600060208284031215613de8578081fd5b5051919050565b600060208284031215613e00578081fd5b81356001600160e01b0319811681146119d1578182fd5b60008060008060808587031215613a57578182fd5b600080600080600060a08688031215613e43578283fd5b853567ffffffffffffffff80821115613e5a578485fd5b613e6689838a0161387d565b96506020880135915080821115613e7b578485fd5b50613e888882890161387d565b9450506040860135613e998161436f565b92506060860135613ea981614384565b91506080860135613eb981614384565b809150509295509295909350565b600060208284031215613ed8578081fd5b5035919050565b600080600060408486031215613ef3578081fd5b83359250602084013567ffffffffffffffff811115613f10578182fd5b613f1c868287016137b0565b9497909650939450505050565b600080600060608486031215613f3d578081fd5b83359250602084013567ffffffffffffffff811115613f5a578182fd5b613cc9868287016137fa565b600080600060408486031215613f7a578081fd5b83359250602084013567ffffffffffffffff80821115613f98578283fd5b818601915086601f830112613fab578283fd5b813581811115613fb9578384fd5b876020828501011115613fca578384fd5b6020830194508093505050509250925092565b600080600060608486031215613ff1578081fd5b505081359360208301359350604090920135919050565b6000815180845260208085019450808401835b838110156140375781518752958201959082019060010161401b565b509495945050505050565b6000815180845261405a81602086016020860161429d565b601f01601f19169290920160200192915050565b6000825161408081846020870161429d565b9190910192915050565b60006001600160a01b03808716835280861660208401525060a060408301526140b660a0830185614008565b82810360608401526140c88185614008565b838103608090940193909352508152602001949350505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a0608083015261162b60a0830184614042565b6020815260006119d16020830184614008565b6060815260006141406060830186614008565b82810360208401526141528186614008565b9150506001600160a01b0383166040830152949350505050565b60a08152600061417f60a0830188614008565b82810360208401526141918188614008565b905082810360408401526141a58187614008565b905082810360608401526141b98186614008565b9150506001600160a01b03831660808301529695505050505050565b6020815260006119d16020830184614042565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561424757614247614359565b604052919050565b6000821982111561426257614262614343565b500190565b600081600019048311821515161561428157614281614343565b500290565b60008282101561429857614298614343565b500390565b60005b838110156142b85781810151838201526020016142a0565b838111156142c7576000848401525b50505050565b600181811c908216806142e157607f821691505b6020821081141561430257634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561431c5761431c614343565b5060010190565b60008261433e57634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461204b57600080fd5b801515811461204b57600080fdfea264697066735822122066d13754c3f5ee2f66bfd0b735a8e31c909f6b3e8b095d8563ba67bcaf44833964736f6c63430008040033
Deployed Bytecode Sourcemap
64317:16368:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39624:269;;;;;;:::i;:::-;;:::i;:::-;;;22989:14:1;;22982:22;22964:41;;22952:2;22937:18;39624:269:0;;;;;;;;65028:27;;;;;;;;;21793:100;;;:::i;:::-;;;;;;;:::i;23960:169::-;;;;;;:::i;:::-;;:::i;64896:31::-;;;;;;;;;35900:25:1;;;35888:2;35873:18;64896:31:0;35855:76:1;35624:207:0;;;;;;:::i;:::-;35793:30;35624:207;;;;;;;;;;-1:-1:-1;;;;;;23178:79:1;;;23160:98;;23148:2;23133:18;35624:207:0;23115:149:1;22913:108:0;23001:12;;22913:108;;64716:36;;;;;-1:-1:-1;;;;;64716:36:0;;;;;;-1:-1:-1;;;;;17628:55:1;;;17610:74;;17598:2;17583:18;64716:36:0;17565:125:1;24611:422:0;;;;;;:::i;:::-;;:::i;22755:93::-;;;22838:2;36847:36:1;;36835:2;36820:18;22755:93:0;36802:87:1;64640:31:0;;;;;;25442:215;;;;;;:::i;:::-;;:::i;69479:235::-;;;;;;:::i;:::-;;:::i;65103:31::-;;;;;;;;;;;;73767:141;;;;;;:::i;:::-;;:::i;64678:31::-;;;;;-1:-1:-1;;;;;64678:31:0;;;66284:498;;;;;;:::i;:::-;;:::i;:::-;;67684:835;;;;;;:::i;:::-;;:::i;73005:297::-;;;;;;:::i;:::-;;:::i;31667:164::-;;;;;;:::i;:::-;;:::i;65062:34::-;;;;;;;;;;;;23084:127;;;;;;:::i;:::-;-1:-1:-1;;;;;23185:18:0;23158:7;23185:18;;;:9;:18;;;;;;;23084:127;51149:148;;;:::i;65187:39::-;;;;;;;;;;;;71753:1244;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;50498:87::-;50571:6;;-1:-1:-1;;;;;50571:6:0;50498:87;;64812:51;;;;;-1:-1:-1;;;;;64812:51:0;;;22012:104;;;:::i;70567:868::-;;;;;;:::i;:::-;;:::i;26160:377::-;;;;;;:::i;:::-;;:::i;23424:175::-;;;;;;:::i;:::-;;:::i;69722:604::-;;;;;;:::i;:::-;;:::i;40304:203::-;;;;;;:::i;:::-;40463:36;40304:203;;;;;;;;66184:92;;;:::i;70334:225::-;;;;;;:::i;:::-;;:::i;66790:637::-;;;;;;:::i;:::-;;:::i;69309:162::-;;;;;;:::i;:::-;;:::i;71447:298::-;;;;;;:::i;:::-;;:::i;64759:46::-;;;;;-1:-1:-1;;;;;64759:46:0;;;32230:297;;;;;;:::i;:::-;;:::i;23662:151::-;;;;;;:::i;:::-;-1:-1:-1;;;;;23778:18:0;;;23751:7;23778:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;23662:151;65332:844;;;;;;:::i;:::-;;:::i;73310:449::-;;;;;;:::i;:::-;;:::i;40121:175::-;;;;;;:::i;:::-;40257:31;40121:175;;;;;;;;51452:244;;;;;;:::i;:::-;;:::i;64934:39::-;;;;;;65141;;;;;;;;;;;;64980;;;;;;39624:269;39748:4;-1:-1:-1;;;;;;39772:60:0;;39787:45;39772:60;;:113;;-1:-1:-1;39262:36:0;-1:-1:-1;;;;;;39247:51:0;;;39849:36;39765:120;39624:269;-1:-1:-1;;39624:269:0:o;21793:100::-;21847:13;21880:5;21873:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21793:100;:::o;23960:169::-;24043:4;24060:39;19149:10;24083:7;24092:6;24060:8;:39::i;:::-;-1:-1:-1;24117:4:0;23960:169;;;;:::o;24611:422::-;24717:4;24734:36;24744:6;24752:9;24763:6;24734:9;:36::i;:::-;-1:-1:-1;;;;;24810:19:0;;24783:24;24810:19;;;:11;:19;;;;;;;;19149:10;24810:33;;;;;;;;24862:26;;;;24854:79;;;;-1:-1:-1;;;24854:79:0;;30591:2:1;24854:79:0;;;30573:21:1;30630:2;30610:18;;;30603:30;30669:34;30649:18;;;30642:62;30740:10;30720:18;;;30713:38;30768:19;;24854:79:0;;;;;;;;;24944:57;24953:6;19149:10;24975:25;24994:6;24975:16;:25;:::i;:::-;24944:8;:57::i;:::-;-1:-1:-1;25021:4:0;;24611:422;-1:-1:-1;;;;24611:422:0:o;25442:215::-;19149:10;25530:4;25579:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;25579:34:0;;;;;;;;;;25530:4;;25547:80;;25570:7;;25579:47;;25616:10;;25579:47;:::i;69479:235::-;69642:7;69669:37;69676:8;;69669:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;69669:37:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;69686:7:0;;-1:-1:-1;69686:7:0;;;;69669:37;;;69686:7;;69669:37;69686:7;69669:37;;;;;;;;;-1:-1:-1;69695:10:0;;-1:-1:-1;69669:6:0;;-1:-1:-1;;69669:37:0:i;:::-;69662:44;69479:235;-1:-1:-1;;;;;69479:235:0:o;73767:141::-;73847:7;73874:26;:8;73886:13;73874:11;:26::i;66284:498::-;66449:16;:14;:16::i;:::-;66476:10;:24;;-1:-1:-1;;66511:40:0;66476:24;;;;;;;-1:-1:-1;;66511:40:0;;;;;;;;;;;-1:-1:-1;;66562:40:0;;;;;;;;;;66620:30;;22964:41:1;;;66620:30:0;;22952:2:1;22937:18;66620:30:0;;;;;;;66666:46;;22989:14:1;;22982:22;22964:41;;66666:46:0;;22952:2:1;22937:18;66666:46:0;;;;;;;66728;;22989:14:1;;22982:22;22964:41;;66728:46:0;;22952:2:1;22937:18;66728:46:0;;;;;;;;66284:498;;;:::o;67684:835::-;67824:7;67844:16;:14;:16::i;:::-;67901:18;;-1:-1:-1;;;;;67901:18:0;67893:41;67871:125;;;;-1:-1:-1;;;67871:125:0;;29417:2:1;67871:125:0;;;29399:21:1;29456:2;29436:18;;;29429:30;29495:34;29475:18;;;29468:62;29566:4;29546:18;;;29539:32;29588:19;;67871:125:0;29389:224:1;67871:125:0;68083:12;;:33;;;;;;;;68007:35;;-1:-1:-1;;;;;68083:12:0;;:31;;:33;;;;;;;;;;;;;;:12;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68007:120;;68138:20;68161:11;-1:-1:-1;;;;;68161:29:0;;68205:11;68231:8;;68161:89;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68261:18;:51;;-1:-1:-1;;;;;;68261:51:0;-1:-1:-1;;;;;68261:51:0;;;;;;;;68398:13;:21;;-1:-1:-1;;68398:21:0;;;68435:46;;;36110:25:1;;;36166:2;36151:18;;36144:83;;;;68261:51:0;;-1:-1:-1;68435:46:0;;36083:18:1;68435:46:0;;;;;;;68499:12;67684:835;-1:-1:-1;;;;;67684:835:0:o;73005:297::-;73193:4;73210:20;73228:1;73210:17;:20::i;:::-;73248:46;73264:8;73274:5;73281:6;73289:4;73248:15;:46::i;31667:164::-;31734:7;-1:-1:-1;;;;;31761:22:0;;31778:4;31761:22;:62;;31822:1;31761:62;;;23001:12;;31786:33;;-1:-1:-1;;31786:33:0;:::i;51149:148::-;50571:6;;-1:-1:-1;;;;;50571:6:0;19149:10;50718:23;50710:68;;;;-1:-1:-1;;;50710:68:0;;31345:2:1;50710:68:0;;;31327:21:1;;;31364:18;;;31357:30;31423:34;31403:18;;;31396:62;31475:18;;50710:68:0;31317:182:1;50710:68:0;51240:6:::1;::::0;51219:40:::1;::::0;51256:1:::1;::::0;-1:-1:-1;;;;;51240:6:0::1;::::0;51219:40:::1;::::0;51256:1;;51219:40:::1;51270:6;:19:::0;;-1:-1:-1;;;;;;51270:19:0::1;::::0;;51149:148::o;71753:1244::-;71985:16;53513:1;54276:7;;:19;;54268:63;;;;-1:-1:-1;;;54268:63:0;;34009:2:1;54268:63:0;;;33991:21:1;34048:2;34028:18;;;34021:30;34087:33;34067:18;;;34060:61;34138:18;;54268:63:0;33981:181:1;54268:63:0;53513:1;54409:7;:18;72014:20:::1;72032:1;72014:17;:20::i;:::-;72053:10;::::0;;;::::1;;;:56:::0;::::1;;;-1:-1:-1::0;72068:18:0::1;::::0;;;::::1;;;::::0;:40:::1;;-1:-1:-1::0;72090:18:0::1;::::0;;;::::1;;;72068:40;72045:101;;;::::0;-1:-1:-1;;;72045:101:0;;29056:2:1;72045:101:0::1;::::0;::::1;29038:21:1::0;;;29075:18;;;29068:30;29134:34;29114:18;;;29107:62;29186:18;;72045:101:0::1;29028:182:1::0;72045:101:0::1;72337:13;72353:30;72365:8;72375:7;72353:11;:30::i;:::-;72337:46;;72552:17;72655:11;:18;72647:5;:26;;;;:::i;:::-;72628:15;;:46;;;;:::i;:::-;72591:11;:18;72573:15;;:36;;;;:::i;:::-;72572:113;;;;:::i;:::-;72552:133;;72696:16;72735:9;72726:5;72716:7;;:15;;;;:::i;:::-;72715:29;;;;:::i;:::-;72696:48;;72755:34;72780:8;72755:24;:34::i;:::-;72843:20;72866:38;72881:5;72888:11;72901:2;72866:14;:38::i;:::-;72843:61;;72920:48;72928:8;72938:7;72947:11;72960:3;72965:2;72920:48;;;;;;;;;;:::i;:::-;;;;;;;;53469:1:::0;54588:7;:22;72986:3;71753:1244;-1:-1:-1;;;;;;;;71753:1244:0:o;22012:104::-;22068:13;22101:7;22094:14;;;;;:::i;70567:868::-;70734:16;53513:1;54276:7;;:19;;54268:63;;;;-1:-1:-1;;;54268:63:0;;34009:2:1;54268:63:0;;;33991:21:1;34048:2;34028:18;;;34021:30;34087:33;34067:18;;;34060:61;34138:18;;54268:63:0;33981:181:1;54268:63:0;53513:1;54409:7;:18;;;70768:20:::1;::::0;:17:::1;:20::i;:::-;70807:18;::::0;;;::::1;;;::::0;:40:::1;;-1:-1:-1::0;70829:18:0::1;::::0;;;::::1;;;70807:40;70799:74;;;::::0;-1:-1:-1;;;70799:74:0;;28364:2:1;70799:74:0::1;::::0;::::1;28346:21:1::0;28403:2;28383:18;;;28376:30;28442:23;28422:18;;;28415:51;28483:18;;70799:74:0::1;28336:171:1::0;70799:74:0::1;70972:32;70978:10;70990:13;70997:6:::0;64625::::1;70990:13;:::i;:::-;70972:5;:32::i;:::-;71050:16;71153:11;:18;71144:6;:27;;;;:::i;:::-;71125:15;;:47;;;;:::i;:::-;71088:11;:18;71070:15;;:36;;;;:::i;:::-;71069:114;;;;:::i;:::-;71050:133;;71194:34;71219:8;71194:24;:34::i;:::-;71274:28;71305:39;71320:6;71328:11;71341:2;71305:14;:39::i;:::-;71274:70;;71360:38;71369:11;71382;71395:2;71360:38;;;;;;;;:::i;:::-;;;;;;;;53469:1:::0;54588:7;:22;71416:11;70567:868;-1:-1:-1;;;;;70567:868:0:o;26160:377::-;19149:10;26253:4;26297:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;26297:34:0;;;;;;;;;;26350:35;;;;26342:85;;;;-1:-1:-1;;;26342:85:0;;34785:2:1;26342:85:0;;;34767:21:1;34824:2;34804:18;;;34797:30;34863:34;34843:18;;;34836:62;34934:7;34914:18;;;34907:35;34959:19;;26342:85:0;34757:227:1;26342:85:0;26438:67;19149:10;26461:7;26470:34;26489:15;26470:16;:34;:::i;26438:67::-;-1:-1:-1;26525:4:0;;26160:377;-1:-1:-1;;;26160:377:0:o;23424:175::-;23510:4;23527:42;19149:10;23551:9;23562:6;23527:9;:42::i;69722:604::-;69915:7;53513:1;54276:7;;:19;;54268:63;;;;-1:-1:-1;;;54268:63:0;;34009:2:1;54268:63:0;;;33991:21:1;34048:2;34028:18;;;34021:30;34087:33;34067:18;;;34060:61;34138:18;;54268:63:0;33981:181:1;54268:63:0;53513:1;54409:7;:18;69935:20:::1;69953:1;69935:17;:20::i;:::-;69974:10;::::0;;;::::1;;;69966:42;;;::::0;-1:-1:-1;;;69966:42:0;;31706:2:1;69966:42:0::1;::::0;::::1;31688:21:1::0;31745:2;31725:18;;;31718:30;31784:21;31764:18;;;31757:49;31823:18;;69966:42:0::1;31678:169:1::0;69966:42:0::1;70046:13;70062:30;70074:8;70084:7;70062:11;:30::i;:::-;70046:46:::0;-1:-1:-1;70135:23:0::1;70141:2:::0;70145:12:::1;70046:46:::0;64625:6:::1;70145:12;:::i;:::-;70135:5;:23::i;:::-;70169:16;70198:5;70188:7;;:15;;;;:::i;:::-;70169:34;;70214;70239:8;70214:24;:34::i;:::-;70266:29;70273:8;70283:7;70292:2;70266:29;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;53469:1:0;54588:7;:22;70313:5;69722:604;-1:-1:-1;;;;69722:604:0:o;66184:92::-;66246:22;66265:1;66246:10;:22::i;:::-;66184:92::o;70334:225::-;70469:16;70510:41;70519:6;70527:11;;70510:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70540:10:0;;-1:-1:-1;70510:8:0;;-1:-1:-1;;70510:41:0:i;:::-;70503:48;70334:225;-1:-1:-1;;;;70334:225:0:o;66790:637::-;66946:16;:14;:16::i;:::-;64625:6;66981:8;:16;;66973:45;;;;-1:-1:-1;;;66973:45:0;;31000:2:1;66973:45:0;;;30982:21:1;31039:2;31019:18;;;31012:30;-1:-1:-1;;;31058:18:1;;;31051:46;31114:18;;66973:45:0;30972:166:1;66973:45:0;64625:6;67037:16;:24;;67029:53;;;;-1:-1:-1;;;67029:53:0;;31000:2:1;67029:53:0;;;30982:21:1;31039:2;31019:18;;;31012:30;-1:-1:-1;;;31058:18:1;;;31051:46;31114:18;;67029:53:0;30972:166:1;67029:53:0;64625:6;67101:16;:24;;67093:53;;;;-1:-1:-1;;;67093:53:0;;31000:2:1;67093:53:0;;;30982:21:1;31039:2;31019:18;;;31012:30;-1:-1:-1;;;31058:18:1;;;31051:46;31114:18;;67093:53:0;30972:166:1;67093:53:0;67157:7;:18;;;67186:15;:34;;;67231:15;:34;;;67283:24;;35900:25:1;;;67283:24:0;;35888:2:1;35873:18;67283:24:0;;;;;;;67323:40;;35900:25:1;;;67323:40:0;;35888:2:1;35873:18;67323:40:0;;;;;;;67379;;35900:25:1;;;67379:40:0;;35888:2:1;35873:18;67379:40:0;35855:76:1;69309:162:0;69382:16;:14;:16::i;:::-;69409:7;:18;;-1:-1:-1;;;;;;69409:18:0;-1:-1:-1;;;;;69409:18:0;;;;;;;;69443:20;;17610:74:1;;;69443:20:0;;17598:2:1;17583:18;69443:20:0;;;;;;;69309:162;:::o;71447:298::-;71651:16;71687:50;71694:8;;71687:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;71687:50:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71704:7:0;;-1:-1:-1;71704:7:0;;;;71687:50;;;71704:7;;71687:50;71704:7;71687:50;;;;;;;;;-1:-1:-1;;71687:50:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71713:11:0;;-1:-1:-1;71713:11:0;;;;71687:50;;;71713:11;;71687:50;71713:11;71687:50;;;;;;;;;-1:-1:-1;71726:10:0;;-1:-1:-1;71687:6:0;;-1:-1:-1;;71687:50:0:i;:::-;71680:57;71447:298;-1:-1:-1;;;;;;;71447:298:0:o;32230:297::-;32317:7;-1:-1:-1;;;;;32345:22:0;;32362:4;32345:22;32337:62;;;;-1:-1:-1;;;32337:62:0;;30235:2:1;32337:62:0;;;30217:21:1;30274:2;30254:18;;;30247:30;30313:29;30293:18;;;30286:57;30360:18;;32337:62:0;30207:177:1;32337:62:0;-1:-1:-1;32518:1:0;32230:297;;;;:::o;65332:844::-;17890:13;;;;;;;;:30;;-1:-1:-1;17908:12:0;;;;17907:13;17890:30;17882:89;;;;-1:-1:-1;;;17882:89:0;;29820:2:1;17882:89:0;;;29802:21:1;29859:2;29839:18;;;29832:30;29898:34;29878:18;;;29871:62;-1:-1:-1;;;29949:18:1;;;29942:44;30003:19;;17882:89:0;29792:236:1;17882:89:0;17984:19;18007:13;;;;;;18006:14;18031:101;;;;18066:13;:20;;-1:-1:-1;;18101:19:0;;;;;18031:101;65559:16:::1;:14;:16::i;:::-;65586:28;65599:5;65606:7;65586:12;:28::i;:::-;-1:-1:-1::0;;;;;65633:27:0;::::1;65625:59;;;::::0;-1:-1:-1;;;65625:59:0;;27255:2:1;65625:59:0::1;::::0;::::1;27237:21:1::0;27294:2;27274:18;;;27267:30;27333:21;27313:18;;;27306:49;27372:18;;65625:59:0::1;27227:169:1::0;65625:59:0::1;65695:12;:28:::0;;-1:-1:-1;;;;;;65695:28:0;;::::1;-1:-1:-1::0;;;;;65695:28:0;::::1;;::::0;;;65734:12:::1;:44:::0;;65767:10:::1;65734:44:::0;::::1;::::0;::::1;::::0;;65799:24:::1;::::0;;;;;;;:22:::1;::::0;:24:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;65767:10;65799:24;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65789:7;:34:::0;;;65834:6:::1;:16:::0;;65861:30;::::1;;65834:16;65861:30:::0;::::1;-1:-1:-1::0;;65834:16:0;::::1;;65861:30:::0;;;-1:-1:-1;;65861:30:0;;;;;;;::::1;::::0;;;65907:58:::1;::::0;;-1:-1:-1;;;;;20480:55:1;;20462:74;;20567:2;20552:18;;20545:50;;;;20611:18;;20604:50;;;;65907:58:0::1;::::0;20450:2:1;20435:18;65907:58:0::1;;;;;;;65976:95;65993:4;66014::::0;66043::::1;65976:16;:95::i;:::-;66082:86;66090:10;66114:1;66137:10;66082:7;:86::i;:::-;18162:14:::0;18158:68;;;18209:5;18193:21;;-1:-1:-1;;18193:21:0;;;18158:68;65332:844;;;;;;:::o;73310:449::-;73468:13;;73442:4;;73468:13;;;;;73464:57;;;-1:-1:-1;73505:4:0;;73310:449;-1:-1:-1;73310:449:0:o;73464:57::-;73572:18;;-1:-1:-1;;;;;73572:18:0;73605:42;73601:87;;-1:-1:-1;73671:5:0;;73310:449;-1:-1:-1;;73310:449:0:o;73601:87::-;73705:46;;;;;-1:-1:-1;;;;;73705:36:0;;;;;:46;;73742:8;;73705:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73698:53;73310:449;-1:-1:-1;;;73310:449:0:o;51452:244::-;50571:6;;-1:-1:-1;;;;;50571:6:0;19149:10;50718:23;50710:68;;;;-1:-1:-1;;;50710:68:0;;31345:2:1;50710:68:0;;;31327:21:1;;;31364:18;;;31357:30;31423:34;31403:18;;;31396:62;31475:18;;50710:68:0;31317:182:1;50710:68:0;-1:-1:-1;;;;;51541:22:0;::::1;51533:73;;;::::0;-1:-1:-1;;;51533:73:0;;25686:2:1;51533:73:0::1;::::0;::::1;25668:21:1::0;25725:2;25705:18;;;25698:30;25764:34;25744:18;;;25737:62;25835:8;25815:18;;;25808:36;25861:19;;51533:73:0::1;25658:228:1::0;51533:73:0::1;51643:6;::::0;51622:38:::1;::::0;-1:-1:-1;;;;;51622:38:0;;::::1;::::0;51643:6:::1;::::0;51622:38:::1;::::0;51643:6:::1;::::0;51622:38:::1;51671:6;:17:::0;;-1:-1:-1;;;;;;51671:17:0::1;-1:-1:-1::0;;;;;51671:17:0;;;::::1;::::0;;;::::1;::::0;;51452:244::o;29521:346::-;-1:-1:-1;;;;;29623:19:0;;29615:68;;;;-1:-1:-1;;;29615:68:0;;33604:2:1;29615:68:0;;;33586:21:1;33643:2;33623:18;;;33616:30;33682:34;33662:18;;;33655:62;33753:6;33733:18;;;33726:34;33777:19;;29615:68:0;33576:226:1;29615:68:0;-1:-1:-1;;;;;29702:21:0;;29694:68;;;;-1:-1:-1;;;29694:68:0;;26093:2:1;29694:68:0;;;26075:21:1;26132:2;26112:18;;;26105:30;26171:34;26151:18;;;26144:62;26242:4;26222:18;;;26215:32;26264:19;;29694:68:0;26065:224:1;29694:68:0;-1:-1:-1;;;;;29775:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;29827:32;;35900:25:1;;;29827:32:0;;35873:18:1;29827:32:0;;;;;;;;29521:346;;;:::o;27027:604::-;-1:-1:-1;;;;;27133:20:0;;27125:70;;;;-1:-1:-1;;;27125:70:0;;32861:2:1;27125:70:0;;;32843:21:1;32900:2;32880:18;;;32873:30;32939:34;32919:18;;;32912:62;33010:7;32990:18;;;32983:35;33035:19;;27125:70:0;32833:227:1;27125:70:0;-1:-1:-1;;;;;27214:23:0;;27206:71;;;;-1:-1:-1;;;27206:71:0;;24205:2:1;27206:71:0;;;24187:21:1;24244:2;24224:18;;;24217:30;24283:34;24263:18;;;24256:62;24354:5;24334:18;;;24327:33;24377:19;;27206:71:0;24177:225:1;27206:71:0;-1:-1:-1;;;;;27374:17:0;;27350:21;27374:17;;;:9;:17;;;;;;27410:23;;;;27402:74;;;;-1:-1:-1;;;27402:74:0;;26496:2:1;27402:74:0;;;26478:21:1;26535:2;26515:18;;;26508:30;26574:34;26554:18;;;26547:62;26645:8;26625:18;;;26618:36;26671:19;;27402:74:0;26468:228:1;27402:74:0;27507:22;27523:6;27507:13;:22;:::i;:::-;-1:-1:-1;;;;;27487:17:0;;;;;;;:9;:17;;;;;;:42;;;;27540:20;;;;;;;;:30;;27564:6;;27487:17;27540:30;;27564:6;;27540:30;:::i;:::-;;;;;;;;27605:9;-1:-1:-1;;;;;27588:35:0;27597:6;-1:-1:-1;;;;;27588:35:0;;27616:6;27588:35;;;;35900:25:1;;35888:2;35873:18;;35855:76;27588:35:0;;;;;;;;27027:604;;;;:::o;64017:137::-;64088:7;64123:22;64127:3;64139:5;64123:3;:22::i;80291:233::-;80346:7;;-1:-1:-1;;;;;80346:7:0;80342:175;;50571:6;;-1:-1:-1;;;;;50571:6:0;80392:10;:21;80384:43;;;;-1:-1:-1;;;80384:43:0;;33267:2:1;80384:43:0;;;33249:21:1;33306:1;33286:18;;;33279:29;33344:11;33324:18;;;33317:39;33373:18;;80384:43:0;33239:158:1;80342:175:0;80482:7;;-1:-1:-1;;;;;80482:7:0;80468:10;:21;80460:45;;;;-1:-1:-1;;;80460:45:0;;24609:2:1;80460:45:0;;;24591:21:1;24648:2;24628:18;;;24621:30;24687:13;24667:18;;;24660:41;24718:18;;80460:45:0;24581:161:1;80532:150:0;80609:12;;:29;;;;;;;;35900:25:1;;;-1:-1:-1;;;;;80609:12:0;;;;:21;;35873:18:1;;80609:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80608:30;:55;;;-1:-1:-1;50571:6:0;;-1:-1:-1;;;;;50571:6:0;80642:10;:21;80608:55;80600:74;;;;-1:-1:-1;;;80600:74:0;;24949:2:1;80600:74:0;;;24931:21:1;24988:1;24968:18;;;24961:29;25026:8;25006:18;;;24999:36;25052:18;;80600:74:0;24921:155:1;80600:74:0;80532:150;:::o;33317:782::-;33514:4;33536:11;33550:23;33559:5;33566:6;33550:8;:23::i;:::-;33536:37;;33584:32;33598:8;33609:6;33584:5;:32::i;:::-;33635:58;;;;;31405:45;;-1:-1:-1;;;;;33635:20:0;;;;;:58;;33656:10;;33668:5;;33675:6;;33683:3;;33688:4;;33635:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:74;33627:123;;;;-1:-1:-1;;;33627:123:0;;27959:2:1;33627:123:0;;;27941:21:1;27998:2;27978:18;;;27971:30;28037:34;28017:18;;;28010:62;28108:6;28088:18;;;28081:34;28132:19;;33627:123:0;27931:226:1;33627:123:0;-1:-1:-1;;;;;23778:18:0;;33761:24;23778:18;;;:11;:18;;;;;;;;33825:4;23778:27;;;;;;;;33870:12;33879:3;33870:6;:12;:::i;:::-;33850:16;:32;;33842:92;;;;-1:-1:-1;;;33842:92:0;;34369:2:1;33842:92:0;;;34351:21:1;34408:2;34388:18;;;34381:30;34447:34;34427:18;;;34420:62;34518:17;34498:18;;;34491:45;34553:19;;33842:92:0;34341:237:1;33842:92:0;33945:75;33962:8;33981:4;34016:3;33988:25;34007:6;33988:16;:25;:::i;:::-;:31;;;;:::i;33945:75::-;34031:38;34045:8;34056:12;34065:3;34056:6;:12;:::i;34031:38::-;-1:-1:-1;34087:4:0;;33317:782;-1:-1:-1;;;;;;33317:782:0:o;74332:1375::-;74459:7;74492:22;74505:8;74492:12;:22::i;:::-;74484:58;;;;-1:-1:-1;;;74484:58:0;;26903:2:1;74484:58:0;;;26885:21:1;26942:2;26922:18;;;26915:30;26981:25;26961:18;;;26954:53;27024:18;;74484:58:0;26875:173:1;74484:58:0;74557:6;;;;74553:1147;;;74678:12;;74658:205;;;;;-1:-1:-1;;;;;74678:12:0;;;;74658:55;;:205;;74732:10;;74769:4;;74793:8;;74820:7;;74658:205;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74880:13:0;;-1:-1:-1;74880:13:0;;-1:-1:-1;;74908:423:0;74932:8;:15;74928:1;:19;74908:423;;;74973:15;74991:8;75000:1;74991:11;;;;;;-1:-1:-1;;;74991:11:0;;;;;;;;;;;;;;;74973:29;;75021:14;75038:7;75046:1;75038:10;;;;;;-1:-1:-1;;;75038:10:0;;;;;;;;;;;;;;;75021:27;;75084:1;75075:6;:10;75067:50;;;;-1:-1:-1;;;75067:50:0;;27603:2:1;75067:50:0;;;27585:21:1;27642:2;27622:18;;;27615:30;27681:29;27661:18;;;27654:57;27728:18;;75067:50:0;27575:177:1;75067:50:0;75140:21;;;;:12;:21;;;;;;75136:96;;75191:21;:8;75204:7;75191:12;:21::i;:::-;;75136:96;75250:21;;;;:12;:21;;;;;:31;;75275:6;;75250:21;:31;;75275:6;;75250:31;:::i;:::-;;;;-1:-1:-1;75300:15:0;;-1:-1:-1;75309:6:0;75300:15;;:::i;:::-;;;74908:423;;74949:3;;;;;:::i;:::-;;;;74908:423;;;-1:-1:-1;75352:5:0;-1:-1:-1;75345:12:0;;74553:1147;75414:12;;-1:-1:-1;;;;;75414:12:0;75390:21;75441:211;75465:8;:15;75461:1;:19;75441:211;;;75506:15;75524:8;75533:1;75524:11;;;;;;-1:-1:-1;;;75524:11:0;;;;;;;;;;;;;;;75506:29;;75554:42;75573:13;75588:7;75554:18;:42::i;:::-;75615:21;:8;75628:7;75615:12;:21::i;:::-;;75441:211;75482:3;;;;;:::i;:::-;;;;75441:211;;;;75673:8;:15;75666:22;;;;;77256:402;77404:10;;77400:251;;77431:25;77437:10;77449:6;77431:5;:25::i;:::-;77496:12;;:29;;;;;;;;77471:22;;-1:-1:-1;;;;;77496:12:0;;:27;;:29;;;;;;;;;;;;;;:12;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77471:54;;77540:29;77546:14;77562:6;77540:5;:29::i;:::-;77631:7;;77584:55;;;;;;;;35900:25:1;;;;-1:-1:-1;;;;;77584:46:0;;;;;35873:18:1;;77584:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75715:1533;75857:16;75918:11;:18;75908:6;:28;:50;;;-1:-1:-1;75940:18:0;;;;;;;75908:50;75886:136;;;;-1:-1:-1;;;75886:136:0;;32456:2:1;75886:136:0;;;32438:21:1;32495:2;32475:18;;;32468:30;32534:34;32514:18;;;32507:62;-1:-1:-1;;;32585:18:1;;;32578:34;32629:19;;75886:136:0;32428:226:1;75886:136:0;76055:18;;:23;;:45;;-1:-1:-1;76082:18:0;;;;;;;76055:45;76033:131;;;;-1:-1:-1;;;76033:131:0;;35551:2:1;76033:131:0;;;35533:21:1;35590:2;35570:18;;;35563:30;35629:34;35609:18;;;35602:62;-1:-1:-1;;;35680:18:1;;;35673:34;35724:19;;76033:131:0;35523:226:1;76033:131:0;76192:6;;76233:12;;76192:6;;;;;-1:-1:-1;;;;;76233:12:0;76177;76301:6;76287:21;;;;;;-1:-1:-1;;;76287:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76287:21:0;;76256:52;;76324:9;76319:854;76343:6;76339:1;:10;76319:854;;;76453:15;76475:11;:18;76471:1;:22;:87;;76531:27;:25;:27::i;:::-;76471:87;;;76514:11;76526:1;76514:14;;;;;;-1:-1:-1;;;76514:14:0;;;;;;;;;;;;;;;76471:87;76453:105;;76590:7;76573:11;76585:1;76573:14;;;;;;-1:-1:-1;;;76573:14:0;;;;;;;;;;;;;;:24;;;;;76618:7;76614:548;;;76646:21;;;;:12;:21;;;;;:26;;76671:1;;76646:21;:26;;76671:1;;76646:26;:::i;:::-;;;;-1:-1:-1;;76695:21:0;;;;:12;:21;;;;;;76691:99;;76746:24;:8;76762:7;76746:15;:24::i;:::-;;76691:99;76810:210;;;;;76892:4;76810:210;;;19382:34:1;-1:-1:-1;;;;;19452:15:1;;;19432:18;;;19425:43;19484:18;;;19477:34;;;76975:1:0;19527:18:1;;;19520:34;19591:3;19570:19;;;19563:32;-1:-1:-1;19611:19:1;;;19604:33;76810:51:0;;;;;19654:19:1;;76810:210:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76614:548;;;77061:24;:8;77077:7;77061:15;:24::i;:::-;;77104:42;77119:13;77134:2;77138:7;77104:14;:42::i;:::-;-1:-1:-1;76351:3:0;;;;:::i;:::-;;;;76319:854;;;;77183:28;77199:11;77183:15;:28::i;:::-;77229:11;75715:1533;-1:-1:-1;;;;;;75715:1533:0:o;28589:494::-;-1:-1:-1;;;;;28673:21:0;;28665:67;;;;-1:-1:-1;;;28665:67:0;;32054:2:1;28665:67:0;;;32036:21:1;32093:2;32073:18;;;32066:30;32132:34;32112:18;;;32105:62;32203:3;32183:18;;;32176:31;32224:19;;28665:67:0;32026:223:1;28665:67:0;-1:-1:-1;;;;;28832:18:0;;28807:22;28832:18;;;:9;:18;;;;;;28869:24;;;;28861:71;;;;-1:-1:-1;;;28861:71:0;;25283:2:1;28861:71:0;;;25265:21:1;25322:2;25302:18;;;25295:30;25361:34;25341:18;;;25334:62;25432:4;25412:18;;;25405:32;25454:19;;28861:71:0;25255:224:1;28861:71:0;28964:23;28981:6;28964:14;:23;:::i;:::-;-1:-1:-1;;;;;28943:18:0;;;;;;:9;:18;;;;;:44;;;;28998:12;:22;;29014:6;;28943:18;28998:22;;29014:6;;28998:22;:::i;:::-;;;;-1:-1:-1;;29038:37:0;;35900:25:1;;;29064:1:0;;-1:-1:-1;;;;;29038:37:0;;;;;35888:2:1;35873:18;29038:37:0;35855:76:1;27918:338:0;-1:-1:-1;;;;;28002:21:0;;27994:65;;;;-1:-1:-1;;;27994:65:0;;35191:2:1;27994:65:0;;;35173:21:1;35230:2;35210:18;;;35203:30;35269:33;35249:18;;;35242:61;35320:18;;27994:65:0;35163:181:1;27994:65:0;28150:6;28134:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;28167:18:0;;;;;;:9;:18;;;;;:28;;28189:6;;28167:18;:28;;28189:6;;28167:28;:::i;:::-;;;;-1:-1:-1;;28211:37:0;;35900:25:1;;;-1:-1:-1;;;;;28211:37:0;;;28228:1;;28211:37;;35888:2:1;35873:18;28211:37:0;;;;;;;27918:338;;:::o;50084:129::-;17890:13;;;;;;;;:30;;-1:-1:-1;17908:12:0;;;;17907:13;17890:30;17882:89;;;;-1:-1:-1;;;17882:89:0;;29820:2:1;17882:89:0;;;29802:21:1;29859:2;29839:18;;;29832:30;29898:34;29878:18;;;29871:62;-1:-1:-1;;;29949:18:1;;;29942:44;30003:19;;17882:89:0;29792:236:1;17882:89:0;17984:19;18007:13;;;;;;18006:14;18031:101;;;;18066:13;:20;;-1:-1:-1;;18101:19:0;;;;;18031:101;50142:26:::1;:24;:26::i;:::-;50179;:24;:26::i;:::-;18162:14:::0;18158:68;;;18209:5;18193:21;;-1:-1:-1;;18193:21:0;;;50084:129;:::o;21377:181::-;17890:13;;;;;;;;:30;;-1:-1:-1;17908:12:0;;;;17907:13;17890:30;17882:89;;;;-1:-1:-1;;;17882:89:0;;29820:2:1;17882:89:0;;;29802:21:1;29859:2;29839:18;;;29832:30;29898:34;29878:18;;;29871:62;-1:-1:-1;;;29949:18:1;;;29942:44;30003:19;;17882:89:0;29792:236:1;17882:89:0;17984:19;18007:13;;;;;;18006:14;18031:101;;;;18066:13;:20;;-1:-1:-1;;18101:19:0;;;;;18031:101;21475:26:::1;:24;:26::i;:::-;21512:38;21535:5;21542:7;21512:22;:38::i;:::-;18162:14:::0;18158:68;;;18209:5;18193:21;;-1:-1:-1;;18193:21:0;;;18158:68;21377:181;;;:::o;59139:120::-;59206:7;59233:3;:11;;59245:5;59233:18;;;;;;-1:-1:-1;;;59233:18:0;;;;;;;;;;;;;;;;;59226:25;;59139:120;;;;:::o;62797:131::-;62864:4;62888:32;62893:3;62913:5;62888:4;:32::i;78509:1258::-;78619:42;78688;78741:17;-1:-1:-1;;;;;78773:20:0;;;;78769:862;;;78848:100;;78913:10;78848:100;;;18878:34:1;78933:4:0;18928:18:1;;;18921:43;18980:18;;;18973:34;;;18790:18;;78848:100:0;;;-1:-1:-1;;78848:100:0;;;;;;;;;;;;;;-1:-1:-1;;;;;78848:100:0;-1:-1:-1;;;78848:100:0;;;;-1:-1:-1;78769:862:0;;;78983:5;-1:-1:-1;;;;;78970:18:0;:9;-1:-1:-1;;;;;78970:18:0;;78966:665;;;79034:31;79123:7;79068:63;;;;;;35900:25:1;;35888:2;35873:18;;35855:76;79068:63:0;;;;-1:-1:-1;;79068:63:0;;;;;;;;;;;;;;-1:-1:-1;;;;;79068:63:0;;;;;79189:49;79068:63;;-1:-1:-1;;;;;;;;;;79189:29:0;;;:49;;79068:63;;79189:49;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79146:92;;;;79254:13;79282:6;79271:29;;;;;;;;;;;;:::i;:::-;79253:47;;79323:12;:35;;;;-1:-1:-1;;;;;;79339:19:0;;79348:10;79339:19;79323:35;79315:61;;;;-1:-1:-1;;;79315:61:0;;28714:2:1;79315:61:0;;;28696:21:1;28753:2;28733:18;;;28726:30;28792:15;28772:18;;;28765:43;28825:18;;79315:61:0;28686:163:1;79315:61:0;79398:52;;;;;35900:25:1;;;35873:18;;79398:52:0;;;-1:-1:-1;;79398:52:0;;;;;;;;;;;;;;-1:-1:-1;;;;;79398:52:0;;;;;;-1:-1:-1;78966:665:0;;-1:-1:-1;;;;78966:665:0;;79515:104;;79584:10;79515:104;;;18878:34:1;79604:4:0;18928:18:1;;;18921:43;18980:18;;;18973:34;;;18790:18;;79515:104:0;;;-1:-1:-1;;79515:104:0;;;;;;;;;;;;;;-1:-1:-1;;;;;79515:104:0;-1:-1:-1;;;79515:104:0;;;;-1:-1:-1;78966:665:0;79642:12;79656:23;79691:9;-1:-1:-1;;;;;79683:23:0;79707:4;79683:29;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79641:71;;;;79731:7;79747:10;79723:36;;;;;-1:-1:-1;;;79723:36:0;;;;;;;;:::i;:::-;;78509:1258;;;;;;;:::o;79775:508::-;79838:7;79858:19;80191:17;:8;:15;:17::i;:::-;79979:16;79994:1;79979:12;:16;:::i;:::-;80020:9;;79930:232;;;79969:27;;79930:232;;;16930:19:1;16965:12;;16958:28;80052:14:0;17024:2:1;17020:15;;;-1:-1:-1;;17016:53:1;17002:12;;;16995:75;80089:16:0;17086:12:1;;;17079:28;80128:15:0;17123:13:1;;;17116:29;17161:13;;79930:232:0;;;;;;;;;;;;79902:275;;;;;;79880:308;;:328;;;;:::i;:::-;79858:350;;80232:1;80219:9;;:14;;;;;;;:::i;:::-;;;;-1:-1:-1;80251:24:0;;-1:-1:-1;80251:8:0;80263:11;80251;:24::i;:::-;80244:31;;;79775:508;:::o;63104:137::-;63174:4;63198:35;63206:3;63226:5;63198:7;:35::i;77666:835::-;77784:42;77853;77906:17;-1:-1:-1;;;;;77938:20:0;;;;77934:475;;;77982:92;;78055:4;77982:92;;;18878:34:1;-1:-1:-1;;;;;18948:15:1;;18928:18;;;18921:43;18980:18;;;18973:34;;;18790:18;;77982:92:0;;;-1:-1:-1;;77982:92:0;;;;;;;;;;;;;;-1:-1:-1;;;;;77982:92:0;-1:-1:-1;;;77982:92:0;;;;-1:-1:-1;77934:475:0;;;78109:5;-1:-1:-1;;;;;78096:18:0;:9;-1:-1:-1;;;;;78096:18:0;;78092:317;;;78167:69;;-1:-1:-1;;;;;20857:55:1;;78167:69:0;;;20839:74:1;20929:18;;;20922:34;;;20812:18;;78167:69:0;;;-1:-1:-1;;78167:69:0;;;;;;;;;;;;;;-1:-1:-1;;;;;78167:69:0;;;;;;-1:-1:-1;78092:317:0;;;78301:96;;78378:4;78301:96;;;18878:34:1;-1:-1:-1;;;;;18948:15:1;;18928:18;;;18921:43;18980:18;;;18973:34;;;18790:18;;78301:96:0;;;-1:-1:-1;;78301:96:0;;;;;;;;;;;;;;-1:-1:-1;;;;;78301:96:0;-1:-1:-1;;;78301:96:0;;;;-1:-1:-1;78092:317:0;78420:12;78445:9;-1:-1:-1;;;;;78437:23:0;78461:4;78437:29;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78419:47;;;78485:7;78477:16;;;;;;77666:835;;;;;;;:::o;74032:292::-;74151:18;;-1:-1:-1;;;;;74151:18:0;74184:42;74180:81;;74243:7;74032:292;:::o;74180:81::-;74271:45;;;;;-1:-1:-1;;;;;74271:35:0;;;;;:45;;74307:8;;74271:45;;;:::i;18998:65::-;17890:13;;;;;;;;:30;;-1:-1:-1;17908:12:0;;;;17907:13;17890:30;17882:89;;;;-1:-1:-1;;;17882:89:0;;29820:2:1;17882:89:0;;;29802:21:1;29859:2;29839:18;;;29832:30;29898:34;29878:18;;;29871:62;-1:-1:-1;;;29949:18:1;;;29942:44;30003:19;;17882:89:0;29792:236:1;17882:89:0;17984:19;18007:13;;;;;;18006:14;18031:101;;;;18066:13;:20;;-1:-1:-1;;18101:19:0;;;;;18158:68;;;;18209:5;18193:21;;-1:-1:-1;;18193:21:0;;;18998:65;:::o;50221:196::-;17890:13;;;;;;;;:30;;-1:-1:-1;17908:12:0;;;;17907:13;17890:30;17882:89;;;;-1:-1:-1;;;17882:89:0;;29820:2:1;17882:89:0;;;29802:21:1;29859:2;29839:18;;;29832:30;29898:34;29878:18;;;29871:62;-1:-1:-1;;;29949:18:1;;;29942:44;30003:19;;17882:89:0;29792:236:1;17882:89:0;17984:19;18007:13;;;;;;18006:14;18031:101;;;;18066:13;:20;;-1:-1:-1;;18101:19:0;;;;;18031:101;50332:6:::1;:18:::0;;-1:-1:-1;;;;;;50332:18:0::1;19149:10:::0;50332:18;;::::1;::::0;;;50366:43:::1;::::0;19149:10;;50289:17:::1;::::0;50366:43:::1;::::0;50289:17;;50366:43:::1;18144:1;18162:14:::0;18158:68;;;18209:5;18193:21;;-1:-1:-1;;18193:21:0;;;50221:196;:::o;21566:157::-;17890:13;;;;;;;;:30;;-1:-1:-1;17908:12:0;;;;17907:13;17890:30;17882:89;;;;-1:-1:-1;;;17882:89:0;;29820:2:1;17882:89:0;;;29802:21:1;29859:2;29839:18;;;29832:30;29898:34;29878:18;;;29871:62;-1:-1:-1;;;29949:18:1;;;29942:44;30003:19;;17882:89:0;29792:236:1;17882:89:0;17984:19;18007:13;;;;;;18006:14;18031:101;;;;18066:13;:20;;-1:-1:-1;;18101:19:0;;;;;18031:101;21674:13;;::::1;::::0;:5:::1;::::0;:13:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;21698:17:0;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;:::-;;18162:14:::0;18158:68;;;18209:5;18193:21;;-1:-1:-1;;18193:21:0;;;21566:157;;;:::o;56388:414::-;56451:4;58568:19;;;:12;;;:19;;;;;;56468:327;;-1:-1:-1;56511:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;56694:18;;56672:19;;;:12;;;:19;;;;;;:40;;;;56727:11;;56468:327;-1:-1:-1;56778:5:0;56771:12;;63559:114;63619:7;63646:19;63654:3;58769:18;;58686:109;56978:1407;57044:4;57183:19;;;:12;;;:19;;;;;;57219:15;;57215:1163;;57581:21;57605:14;57618:1;57605:10;:14;:::i;:::-;57654:18;;57581:38;;-1:-1:-1;57634:17:0;;57654:22;;57675:1;;57654:22;:::i;:::-;57634:42;;57710:13;57697:9;:26;57693:405;;57744:17;57764:3;:11;;57776:9;57764:22;;;;;;-1:-1:-1;;;57764:22:0;;;;;;;;;;;;;;;;;57744:42;;57918:9;57889:3;:11;;57901:13;57889:26;;;;;;-1:-1:-1;;;57889:26:0;;;;;;;;;;;;;;;;;;;;:38;;;;58003:23;;;:12;;;:23;;;;;:36;;;57693:405;58179:17;;:3;;:17;;;-1:-1:-1;;;58179:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;58274:3;:12;;:19;58287:5;58274:19;;;;;;;;;;;58267:26;;;58317:4;58310:11;;;;;;;57215:1163;58361:5;58354:12;;;;;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:395:1;77:8;87:6;141:3;134:4;126:6;122:17;118:27;108:2;;166:8;156;149:26;108:2;-1:-1:-1;196:20:1;;239:18;228:30;;225:2;;;278:8;268;261:26;225:2;322:4;314:6;310:17;298:29;;382:3;375:4;365:6;362:1;358:14;350:6;346:27;342:38;339:47;336:2;;;399:1;396;389:12;336:2;98:311;;;;;:::o;414:743::-;468:5;521:3;514:4;506:6;502:17;498:27;488:2;;543:5;536;529:20;488:2;583:6;570:20;609:4;632:18;628:2;625:26;622:2;;;654:18;;:::i;:::-;700:2;697:1;693:10;723:28;747:2;743;739:11;723:28;:::i;:::-;785:15;;;816:12;;;;848:15;;;882;;;878:24;;875:33;-1:-1:-1;872:2:1;;;925:5;918;911:20;872:2;951:5;942:14;;965:163;979:2;976:1;973:9;965:163;;;1036:17;;1024:30;;997:1;990:9;;;;;1074:12;;;;1106;;965:163;;;-1:-1:-1;1146:5:1;478:679;-1:-1:-1;;;;;;;478:679:1:o;1162:550::-;1204:5;1257:3;1250:4;1242:6;1238:17;1234:27;1224:2;;1279:5;1272;1265:20;1224:2;1319:6;1306:20;1345:18;1341:2;1338:26;1335:2;;;1367:18;;:::i;:::-;1411:55;1454:2;1435:13;;-1:-1:-1;;1431:27:1;1460:4;1427:38;1411:55;:::i;:::-;1491:2;1482:7;1475:19;1537:3;1530:4;1525:2;1517:6;1513:15;1509:26;1506:35;1503:2;;;1558:5;1551;1544:20;1503:2;1627;1620:4;1612:6;1608:17;1601:4;1592:7;1588:18;1575:55;1650:16;;;1668:4;1646:27;1639:42;;;;1654:7;1214:498;-1:-1:-1;;1214:498:1:o;1717:257::-;1776:6;1829:2;1817:9;1808:7;1804:23;1800:32;1797:2;;;1850:6;1842;1835:22;1797:2;1894:9;1881:23;1913:31;1938:5;1913:31;:::i;1979:261::-;2049:6;2102:2;2090:9;2081:7;2077:23;2073:32;2070:2;;;2123:6;2115;2108:22;2070:2;2160:9;2154:16;2179:31;2204:5;2179:31;:::i;2519:398::-;2587:6;2595;2648:2;2636:9;2627:7;2623:23;2619:32;2616:2;;;2669:6;2661;2654:22;2616:2;2713:9;2700:23;2732:31;2757:5;2732:31;:::i;:::-;2782:5;-1:-1:-1;2839:2:1;2824:18;;2811:32;2852:33;2811:32;2852:33;:::i;:::-;2904:7;2894:17;;;2606:311;;;;;:::o;2922:1111::-;3076:6;3084;3092;3100;3108;3161:3;3149:9;3140:7;3136:23;3132:33;3129:2;;;3183:6;3175;3168:22;3129:2;3227:9;3214:23;3246:31;3271:5;3246:31;:::i;:::-;3296:5;-1:-1:-1;3353:2:1;3338:18;;3325:32;3366:33;3325:32;3366:33;:::i;:::-;3418:7;-1:-1:-1;3476:2:1;3461:18;;3448:32;3499:18;3529:14;;;3526:2;;;3561:6;3553;3546:22;3526:2;3589:61;3642:7;3633:6;3622:9;3618:22;3589:61;:::i;:::-;3579:71;;3703:2;3692:9;3688:18;3675:32;3659:48;;3732:2;3722:8;3719:16;3716:2;;;3753:6;3745;3738:22;3716:2;3781:63;3836:7;3825:8;3814:9;3810:24;3781:63;:::i;:::-;3771:73;;3897:3;3886:9;3882:19;3869:33;3853:49;;3927:2;3917:8;3914:16;3911:2;;;3948:6;3940;3933:22;3911:2;;3976:51;4019:7;4008:8;3997:9;3993:24;3976:51;:::i;:::-;3966:61;;;3119:914;;;;;;;;:::o;4038:466::-;4115:6;4123;4131;4184:2;4172:9;4163:7;4159:23;4155:32;4152:2;;;4205:6;4197;4190:22;4152:2;4249:9;4236:23;4268:31;4293:5;4268:31;:::i;:::-;4318:5;-1:-1:-1;4375:2:1;4360:18;;4347:32;4388:33;4347:32;4388:33;:::i;:::-;4142:362;;4440:7;;-1:-1:-1;;;4494:2:1;4479:18;;;;4466:32;;4142:362::o;4509:685::-;4604:6;4612;4620;4628;4681:3;4669:9;4660:7;4656:23;4652:33;4649:2;;;4703:6;4695;4688:22;4649:2;4747:9;4734:23;4766:31;4791:5;4766:31;:::i;:::-;4816:5;-1:-1:-1;4873:2:1;4858:18;;4845:32;4886:33;4845:32;4886:33;:::i;:::-;4938:7;-1:-1:-1;4992:2:1;4977:18;;4964:32;;-1:-1:-1;5047:2:1;5032:18;;5019:32;5074:18;5063:30;;5060:2;;;5111:6;5103;5096:22;5060:2;5139:49;5180:7;5171:6;5160:9;5156:22;5139:49;:::i;:::-;5129:59;;;4639:555;;;;;;;:::o;5199:754::-;5303:6;5311;5319;5327;5335;5388:3;5376:9;5367:7;5363:23;5359:33;5356:2;;;5410:6;5402;5395:22;5356:2;5454:9;5441:23;5473:31;5498:5;5473:31;:::i;:::-;5523:5;-1:-1:-1;5580:2:1;5565:18;;5552:32;5593:33;5552:32;5593:33;:::i;:::-;5645:7;-1:-1:-1;5699:2:1;5684:18;;5671:32;;-1:-1:-1;5750:2:1;5735:18;;5722:32;;-1:-1:-1;5805:3:1;5790:19;;5777:33;5833:18;5822:30;;5819:2;;;5870:6;5862;5855:22;5819:2;5898:49;5939:7;5930:6;5919:9;5915:22;5898:49;:::i;5958:325::-;6026:6;6034;6087:2;6075:9;6066:7;6062:23;6058:32;6055:2;;;6108:6;6100;6093:22;6055:2;6152:9;6139:23;6171:31;6196:5;6171:31;:::i;:::-;6221:5;6273:2;6258:18;;;;6245:32;;-1:-1:-1;;;6045:238:1:o;6288:803::-;6410:6;6418;6426;6434;6487:2;6475:9;6466:7;6462:23;6458:32;6455:2;;;6508:6;6500;6493:22;6455:2;6553:9;6540:23;6582:18;6623:2;6615:6;6612:14;6609:2;;;6644:6;6636;6629:22;6609:2;6688:70;6750:7;6741:6;6730:9;6726:22;6688:70;:::i;:::-;6777:8;;-1:-1:-1;6662:96:1;-1:-1:-1;6865:2:1;6850:18;;6837:32;;-1:-1:-1;6881:16:1;;;6878:2;;;6915:6;6907;6900:22;6878:2;;6959:72;7023:7;7012:8;7001:9;6997:24;6959:72;:::i;:::-;6445:646;;;;-1:-1:-1;7050:8:1;-1:-1:-1;;;;6445:646:1:o;7096:1128::-;7254:6;7262;7270;7278;7286;7294;7347:2;7335:9;7326:7;7322:23;7318:32;7315:2;;;7368:6;7360;7353:22;7315:2;7413:9;7400:23;7442:18;7483:2;7475:6;7472:14;7469:2;;;7504:6;7496;7489:22;7469:2;7548:70;7610:7;7601:6;7590:9;7586:22;7548:70;:::i;:::-;7637:8;;-1:-1:-1;7522:96:1;-1:-1:-1;7725:2:1;7710:18;;7697:32;;-1:-1:-1;7741:16:1;;;7738:2;;;7775:6;7767;7760:22;7738:2;7819:72;7883:7;7872:8;7861:9;7857:24;7819:72;:::i;:::-;7910:8;;-1:-1:-1;7793:98:1;-1:-1:-1;7998:2:1;7983:18;;7970:32;;-1:-1:-1;8014:16:1;;;8011:2;;;8048:6;8040;8033:22;8011:2;;8092:72;8156:7;8145:8;8134:9;8130:24;8092:72;:::i;:::-;7305:919;;;;-1:-1:-1;7305:919:1;;-1:-1:-1;7305:919:1;;8183:8;;7305:919;-1:-1:-1;;;7305:919:1:o;8229:368::-;8313:6;8366:2;8354:9;8345:7;8341:23;8337:32;8334:2;;;8387:6;8379;8372:22;8334:2;8432:9;8419:23;8465:18;8457:6;8454:30;8451:2;;;8502:6;8494;8487:22;8451:2;8530:61;8583:7;8574:6;8563:9;8559:22;8530:61;:::i;8602:760::-;8729:6;8737;8745;8798:2;8786:9;8777:7;8773:23;8769:32;8766:2;;;8819:6;8811;8804:22;8766:2;8864:9;8851:23;8893:18;8934:2;8926:6;8923:14;8920:2;;;8955:6;8947;8940:22;8920:2;8983:61;9036:7;9027:6;9016:9;9012:22;8983:61;:::i;:::-;8973:71;;9097:2;9086:9;9082:18;9069:32;9053:48;;9126:2;9116:8;9113:16;9110:2;;;9147:6;9139;9132:22;9110:2;;9175:63;9230:7;9219:8;9208:9;9204:24;9175:63;:::i;:::-;9165:73;;;9288:2;9277:9;9273:18;9260:32;9301:31;9326:5;9301:31;:::i;:::-;9351:5;9341:15;;;8756:606;;;;;:::o;9367:997::-;9528:6;9536;9544;9552;9605:3;9593:9;9584:7;9580:23;9576:33;9573:2;;;9627:6;9619;9612:22;9573:2;9672:9;9659:23;9701:18;9742:2;9734:6;9731:14;9728:2;;;9763:6;9755;9748:22;9728:2;9791:61;9844:7;9835:6;9824:9;9820:22;9791:61;:::i;:::-;9781:71;;9905:2;9894:9;9890:18;9877:32;9861:48;;9934:2;9924:8;9921:16;9918:2;;;9955:6;9947;9940:22;9918:2;9983:63;10038:7;10027:8;10016:9;10012:24;9983:63;:::i;:::-;9973:73;;10099:2;10088:9;10084:18;10071:32;10055:48;;10128:2;10118:8;10115:16;10112:2;;;10149:6;10141;10134:22;10112:2;;10177:63;10232:7;10221:8;10210:9;10206:24;10177:63;:::i;:::-;10167:73;;;10290:2;10279:9;10275:18;10262:32;10303:31;10328:5;10303:31;:::i;:::-;9563:801;;;;-1:-1:-1;9563:801:1;;-1:-1:-1;;9563:801:1:o;10369:255::-;10436:6;10489:2;10477:9;10468:7;10464:23;10460:32;10457:2;;;10510:6;10502;10495:22;10457:2;10547:9;10541:16;10566:28;10588:5;10566:28;:::i;10629:521::-;10697:6;10705;10713;10766:2;10754:9;10745:7;10741:23;10737:32;10734:2;;;10787:6;10779;10772:22;10734:2;10831:9;10818:23;10850:28;10872:5;10850:28;:::i;:::-;10897:5;-1:-1:-1;10954:2:1;10939:18;;10926:32;10967:30;10926:32;10967:30;:::i;:::-;11016:7;-1:-1:-1;11075:2:1;11060:18;;11047:32;11088:30;11047:32;11088:30;:::i;11155:194::-;11225:6;11278:2;11266:9;11257:7;11253:23;11249:32;11246:2;;;11299:6;11291;11284:22;11246:2;-1:-1:-1;11327:16:1;;11236:113;-1:-1:-1;11236:113:1:o;11354:352::-;11412:6;11465:2;11453:9;11444:7;11440:23;11436:32;11433:2;;;11486:6;11478;11471:22;11433:2;11530:9;11517:23;-1:-1:-1;;;;;;11573:5:1;11569:78;11562:5;11559:89;11549:2;;11667:6;11659;11652:22;11711:725;11846:6;11854;11862;11870;11923:3;11911:9;11902:7;11898:23;11894:33;11891:2;;;11945:6;11937;11930:22;12441:978;12550:6;12558;12566;12574;12582;12635:3;12623:9;12614:7;12610:23;12606:33;12603:2;;;12657:6;12649;12642:22;12603:2;12702:9;12689:23;12731:18;12772:2;12764:6;12761:14;12758:2;;;12793:6;12785;12778:22;12758:2;12821:49;12862:7;12853:6;12842:9;12838:22;12821:49;:::i;:::-;12811:59;;12923:2;12912:9;12908:18;12895:32;12879:48;;12952:2;12942:8;12939:16;12936:2;;;12973:6;12965;12958:22;12936:2;;13001:51;13044:7;13033:8;13022:9;13018:24;13001:51;:::i;:::-;12991:61;;;13102:2;13091:9;13087:18;13074:32;13115:31;13140:5;13115:31;:::i;:::-;13165:5;-1:-1:-1;13222:2:1;13207:18;;13194:32;13235:30;13194:32;13235:30;:::i;:::-;13284:7;-1:-1:-1;13343:3:1;13328:19;;13315:33;13357:30;13315:33;13357:30;:::i;:::-;13406:7;13396:17;;;12593:826;;;;;;;;:::o;13424:190::-;13483:6;13536:2;13524:9;13515:7;13511:23;13507:32;13504:2;;;13557:6;13549;13542:22;13504:2;-1:-1:-1;13585:23:1;;13494:120;-1:-1:-1;13494:120:1:o;13818:525::-;13913:6;13921;13929;13982:2;13970:9;13961:7;13957:23;13953:32;13950:2;;;14003:6;13995;13988:22;13950:2;14044:9;14031:23;14021:33;;14105:2;14094:9;14090:18;14077:32;14132:18;14124:6;14121:30;14118:2;;;14169:6;14161;14154:22;14118:2;14213:70;14275:7;14266:6;14255:9;14251:22;14213:70;:::i;:::-;13940:403;;14302:8;;-1:-1:-1;14187:96:1;;-1:-1:-1;;;;13940:403:1:o;14348:571::-;14450:6;14458;14466;14519:2;14507:9;14498:7;14494:23;14490:32;14487:2;;;14540:6;14532;14525:22;14487:2;14581:9;14568:23;14558:33;;14642:2;14631:9;14627:18;14614:32;14669:18;14661:6;14658:30;14655:2;;;14706:6;14698;14691:22;14655:2;14734:61;14787:7;14778:6;14767:9;14763:22;14734:61;:::i;14924:709::-;15003:6;15011;15019;15072:2;15060:9;15051:7;15047:23;15043:32;15040:2;;;15093:6;15085;15078:22;15040:2;15134:9;15121:23;15111:33;;15195:2;15184:9;15180:18;15167:32;15218:18;15259:2;15251:6;15248:14;15245:2;;;15280:6;15272;15265:22;15245:2;15323:6;15312:9;15308:22;15298:32;;15368:7;15361:4;15357:2;15353:13;15349:27;15339:2;;15395:6;15387;15380:22;15339:2;15440;15427:16;15466:2;15458:6;15455:14;15452:2;;;15487:6;15479;15472:22;15452:2;15537:7;15532:2;15523:6;15519:2;15515:15;15511:24;15508:37;15505:2;;;15563:6;15555;15548:22;15505:2;15599;15595;15591:11;15581:21;;15621:6;15611:16;;;;;15030:603;;;;;:::o;15638:326::-;15715:6;15723;15731;15784:2;15772:9;15763:7;15759:23;15755:32;15752:2;;;15805:6;15797;15790:22;15752:2;-1:-1:-1;;15833:23:1;;;15903:2;15888:18;;15875:32;;-1:-1:-1;15954:2:1;15939:18;;;15926:32;;15742:222;-1:-1:-1;15742:222:1:o;15969:437::-;16022:3;16060:5;16054:12;16087:6;16082:3;16075:19;16113:4;16142:2;16137:3;16133:12;16126:19;;16179:2;16172:5;16168:14;16200:3;16212:169;16226:6;16223:1;16220:13;16212:169;;;16287:13;;16275:26;;16321:12;;;;16356:15;;;;16248:1;16241:9;16212:169;;;-1:-1:-1;16397:3:1;;16030:376;-1:-1:-1;;;;;16030:376:1:o;16411:257::-;16452:3;16490:5;16484:12;16517:6;16512:3;16505:19;16533:63;16589:6;16582:4;16577:3;16573:14;16566:4;16559:5;16555:16;16533:63;:::i;:::-;16650:2;16629:15;-1:-1:-1;;16625:29:1;16616:39;;;;16657:4;16612:50;;16460:208;-1:-1:-1;;16460:208:1:o;17185:274::-;17314:3;17352:6;17346:13;17368:53;17414:6;17409:3;17402:4;17394:6;17390:17;17368:53;:::i;:::-;17437:16;;;;;17322:137;-1:-1:-1;;17322:137:1:o;17695:915::-;18071:4;-1:-1:-1;;;;;18181:2:1;18173:6;18169:15;18158:9;18151:34;18233:2;18225:6;18221:15;18216:2;18205:9;18201:18;18194:43;;18273:3;18268:2;18257:9;18253:18;18246:31;18300:57;18352:3;18341:9;18337:19;18329:6;18300:57;:::i;:::-;18405:9;18397:6;18393:22;18388:2;18377:9;18373:18;18366:50;18439:44;18476:6;18468;18439:44;:::i;:::-;18520:22;;;18514:3;18499:19;;;18492:51;;;;-1:-1:-1;18552:20:1;;18601:2;18589:15;;18080:530;-1:-1:-1;;;;18080:530:1:o;19684:583::-;19906:4;-1:-1:-1;;;;;20016:2:1;20008:6;20004:15;19993:9;19986:34;20068:2;20060:6;20056:15;20051:2;20040:9;20036:18;20029:43;;20108:6;20103:2;20092:9;20088:18;20081:34;20151:6;20146:2;20135:9;20131:18;20124:34;20195:3;20189;20178:9;20174:19;20167:32;20216:45;20256:3;20245:9;20241:19;20233:6;20216:45;:::i;20967:261::-;21146:2;21135:9;21128:21;21109:4;21166:56;21218:2;21207:9;21203:18;21195:6;21166:56;:::i;21233:585::-;21518:2;21507:9;21500:21;21481:4;21544:56;21596:2;21585:9;21581:18;21573:6;21544:56;:::i;:::-;21648:9;21640:6;21636:22;21631:2;21620:9;21616:18;21609:50;21676:44;21713:6;21705;21676:44;:::i;:::-;21668:52;;;-1:-1:-1;;;;;21760:6:1;21756:55;21751:2;21740:9;21736:18;21729:83;21490:328;;;;;;:::o;21823:996::-;22264:3;22253:9;22246:22;22227:4;22291:57;22343:3;22332:9;22328:19;22320:6;22291:57;:::i;:::-;22396:9;22388:6;22384:22;22379:2;22368:9;22364:18;22357:50;22430:44;22467:6;22459;22430:44;:::i;:::-;22416:58;;22522:9;22514:6;22510:22;22505:2;22494:9;22490:18;22483:50;22556:44;22593:6;22585;22556:44;:::i;:::-;22542:58;;22648:9;22640:6;22636:22;22631:2;22620:9;22616:18;22609:50;22676:44;22713:6;22705;22676:44;:::i;:::-;22668:52;;;-1:-1:-1;;;;;22761:6:1;22757:55;22751:3;22740:9;22736:19;22729:84;22236:583;;;;;;;;:::o;23779:219::-;23928:2;23917:9;23910:21;23891:4;23948:44;23988:2;23977:9;23973:18;23965:6;23948:44;:::i;36238:462::-;36423:6;36412:9;36405:25;36466:2;36461;36450:9;36446:18;36439:30;36505:6;36500:2;36489:9;36485:18;36478:34;36562:6;36554;36549:2;36538:9;36534:18;36521:48;36386:4;36589:22;;;36613:2;36585:31;;;36578:45;;;;36684:2;36663:15;;;-1:-1:-1;;36659:29:1;36644:45;36640:54;;36395:305;-1:-1:-1;;36395:305:1:o;36894:275::-;36965:2;36959:9;37030:2;37011:13;;-1:-1:-1;;37007:27:1;36995:40;;37065:18;37050:34;;37086:22;;;37047:62;37044:2;;;37112:18;;:::i;:::-;37148:2;37141:22;36939:230;;-1:-1:-1;36939:230:1:o;37174:128::-;37214:3;37245:1;37241:6;37238:1;37235:13;37232:2;;;37251:18;;:::i;:::-;-1:-1:-1;37287:9:1;;37222:80::o;37307:168::-;37347:7;37413:1;37409;37405:6;37401:14;37398:1;37395:21;37390:1;37383:9;37376:17;37372:45;37369:2;;;37420:18;;:::i;:::-;-1:-1:-1;37460:9:1;;37359:116::o;37480:125::-;37520:4;37548:1;37545;37542:8;37539:2;;;37553:18;;:::i;:::-;-1:-1:-1;37590:9:1;;37529:76::o;37610:258::-;37682:1;37692:113;37706:6;37703:1;37700:13;37692:113;;;37782:11;;;37776:18;37763:11;;;37756:39;37728:2;37721:10;37692:113;;;37823:6;37820:1;37817:13;37814:2;;;37858:1;37849:6;37844:3;37840:16;37833:27;37814:2;;37663:205;;;:::o;37873:437::-;37952:1;37948:12;;;;37995;;;38016:2;;38070:4;38062:6;38058:17;38048:27;;38016:2;38123;38115:6;38112:14;38092:18;38089:38;38086:2;;;-1:-1:-1;;;38157:1:1;38150:88;38261:4;38258:1;38251:15;38289:4;38286:1;38279:15;38086:2;;37928:382;;;:::o;38315:135::-;38354:3;-1:-1:-1;;38375:17:1;;38372:2;;;38395:18;;:::i;:::-;-1:-1:-1;38442:1:1;38431:13;;38362:88::o;38455:266::-;38487:1;38513;38503:2;;-1:-1:-1;;;38545:1:1;38538:88;38649:4;38646:1;38639:15;38677:4;38674:1;38667:15;38503:2;-1:-1:-1;38706:9:1;;38493:228::o;38726:184::-;-1:-1:-1;;;38775:1:1;38768:88;38875:4;38872:1;38865:15;38899:4;38896:1;38889:15;38915:184;-1:-1:-1;;;38964:1:1;38957:88;39064:4;39061:1;39054:15;39088:4;39085:1;39078:15;39104:154;-1:-1:-1;;;;;39183:5:1;39179:54;39172:5;39169:65;39159:2;;39248:1;39245;39238:12;39263:118;39349:5;39342:13;39335:21;39328:5;39325:32;39315:2;;39371:1;39368;39361:12
Swarm Source
ipfs://66d13754c3f5ee2f66bfd0b735a8e31c909f6b3e8b095d8563ba67bcaf448339
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 24 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.