Source Code
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
KashiPairMediumRiskV1
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)Audit Report
/** *Submitted for verification at Etherscan.io on 2021-03-23 */ // SPDX-License-Identifier: UNLICENSED // Kashi Lending Medium Risk // __ __ __ __ _____ __ __ // | |/ .---.-.-----| |--|__| | |_.-----.-----.--| |__.-----.-----. // | <| _ |__ --| | | | | -__| | _ | | | _ | // |__|\__|___._|_____|__|__|__| |_______|_____|__|__|_____|__|__|__|___ | // |_____| // Copyright (c) 2021 BoringCrypto - All rights reserved // Twitter: @Boring_Crypto // Special thanks to: // @0xKeno - for all his invaluable contributions // @burger_crypto - for the idea of trying to let the LPs benefit from liquidations // Version: 22-Feb-2021 pragma solidity 0.6.12; pragma experimental ABIEncoderV2; // solhint-disable avoid-low-level-calls // solhint-disable no-inline-assembly // solhint-disable not-rely-on-time // File @boringcrypto/boring-solidity/contracts/libraries/[email protected] // License-Identifier: MIT /// @notice A library for performing overflow-/underflow-safe math, /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). library BoringMath { function add(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function to128(uint256 a) internal pure returns (uint128 c) { require(a <= uint128(-1), "BoringMath: uint128 Overflow"); c = uint128(a); } function to64(uint256 a) internal pure returns (uint64 c) { require(a <= uint64(-1), "BoringMath: uint64 Overflow"); c = uint64(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= uint32(-1), "BoringMath: uint32 Overflow"); c = uint32(a); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint128. library BoringMath128 { function add(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } // File @boringcrypto/boring-solidity/contracts/[email protected] // License-Identifier: MIT // Audit on 5-Jan-2021 by Keno and BoringCrypto // Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol + Claimable.sol // Edited by BoringCrypto contract BoringOwnableData { address public owner; address public pendingOwner; } contract BoringOwnable is BoringOwnableData { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice `owner` defaults to msg.sender on construction. constructor() public { owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } /// @notice Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner. /// Can only be invoked by the current `owner`. /// @param newOwner Address of the new owner. /// @param direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`. /// @param renounce Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise. function transferOwnership( address newOwner, bool direct, bool renounce ) public onlyOwner { if (direct) { // Checks require(newOwner != address(0) || renounce, "Ownable: zero address"); // Effects emit OwnershipTransferred(owner, newOwner); owner = newOwner; pendingOwner = address(0); } else { // Effects pendingOwner = newOwner; } } /// @notice Needs to be called by `pendingOwner` to claim ownership. function claimOwnership() public { address _pendingOwner = pendingOwner; // Checks require(msg.sender == _pendingOwner, "Ownable: caller != pending owner"); // Effects emit OwnershipTransferred(owner, _pendingOwner); owner = _pendingOwner; pendingOwner = address(0); } /// @notice Only allows the `owner` to execute the function. modifier onlyOwner() { require(msg.sender == owner, "Ownable: caller is not the owner"); _; } } // File @boringcrypto/boring-solidity/contracts/[email protected] // License-Identifier: MIT // Based on code and smartness by Ross Campbell and Keno // Uses immutable to store the domain separator to reduce gas usage // If the chain id changes due to a fork, the forked chain will calculate on the fly. contract Domain { bytes32 private constant DOMAIN_SEPARATOR_SIGNATURE_HASH = keccak256("EIP712Domain(uint256 chainId,address verifyingContract)"); // See https://eips.ethereum.org/EIPS/eip-191 string private constant EIP191_PREFIX_FOR_EIP712_STRUCTURED_DATA = "\x19\x01"; // solhint-disable var-name-mixedcase bytes32 private immutable _DOMAIN_SEPARATOR; uint256 private immutable DOMAIN_SEPARATOR_CHAIN_ID; /// @dev Calculate the DOMAIN_SEPARATOR function _calculateDomainSeparator(uint256 chainId) private view returns (bytes32) { return keccak256(abi.encode(DOMAIN_SEPARATOR_SIGNATURE_HASH, chainId, address(this))); } constructor() public { uint256 chainId; assembly { chainId := chainid() } _DOMAIN_SEPARATOR = _calculateDomainSeparator(DOMAIN_SEPARATOR_CHAIN_ID = chainId); } /// @dev Return the DOMAIN_SEPARATOR // It's named internal to allow making it public from the contract that uses it by creating a simple view function // with the desired public name, such as DOMAIN_SEPARATOR or domainSeparator. // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() public view returns (bytes32) { uint256 chainId; assembly { chainId := chainid() } return chainId == DOMAIN_SEPARATOR_CHAIN_ID ? _DOMAIN_SEPARATOR : _calculateDomainSeparator(chainId); } function _getDigest(bytes32 dataHash) internal view returns (bytes32 digest) { digest = keccak256(abi.encodePacked(EIP191_PREFIX_FOR_EIP712_STRUCTURED_DATA, DOMAIN_SEPARATOR(), dataHash)); } } // File @boringcrypto/boring-solidity/contracts/[email protected] // License-Identifier: MIT // solhint-disable no-inline-assembly // solhint-disable not-rely-on-time // Data part taken out for building of contracts that receive delegate calls contract ERC20Data { /// @notice owner > balance mapping. mapping(address => uint256) public balanceOf; /// @notice owner > spender > allowance mapping. mapping(address => mapping(address => uint256)) public allowance; /// @notice owner > nonce mapping. Used in `permit`. mapping(address => uint256) public nonces; } contract ERC20 is ERC20Data, Domain { event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @notice Transfers `amount` tokens from `msg.sender` to `to`. /// @param to The address to move the tokens. /// @param amount of the tokens to move. /// @return (bool) Returns True if succeeded. function transfer(address to, uint256 amount) public returns (bool) { // If `amount` is 0, or `msg.sender` is `to` nothing happens if (amount != 0) { uint256 srcBalance = balanceOf[msg.sender]; require(srcBalance >= amount, "ERC20: balance too low"); if (msg.sender != to) { require(to != address(0), "ERC20: no zero address"); // Moved down so low balance calls safe some gas balanceOf[msg.sender] = srcBalance - amount; // Underflow is checked balanceOf[to] += amount; // Can't overflow because totalSupply would be greater than 2^256-1 } } emit Transfer(msg.sender, to, amount); return true; } /// @notice Transfers `amount` tokens from `from` to `to`. Caller needs approval for `from`. /// @param from Address to draw tokens from. /// @param to The address to move the tokens. /// @param amount The token amount to move. /// @return (bool) Returns True if succeeded. function transferFrom( address from, address to, uint256 amount ) public returns (bool) { // If `amount` is 0, or `from` is `to` nothing happens if (amount != 0) { uint256 srcBalance = balanceOf[from]; require(srcBalance >= amount, "ERC20: balance too low"); if (from != to) { uint256 spenderAllowance = allowance[from][msg.sender]; // If allowance is infinite, don't decrease it to save on gas (breaks with EIP-20). if (spenderAllowance != type(uint256).max) { require(spenderAllowance >= amount, "ERC20: allowance too low"); allowance[from][msg.sender] = spenderAllowance - amount; // Underflow is checked } require(to != address(0), "ERC20: no zero address"); // Moved down so other failed calls safe some gas balanceOf[from] = srcBalance - amount; // Underflow is checked balanceOf[to] += amount; // Can't overflow because totalSupply would be greater than 2^256-1 } } emit Transfer(from, to, amount); return true; } /// @notice Approves `amount` from sender to be spend by `spender`. /// @param spender Address of the party that can draw from msg.sender's account. /// @param amount The maximum collective amount that `spender` can draw. /// @return (bool) Returns True if approved. function approve(address spender, uint256 amount) public returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 private constant PERMIT_SIGNATURE_HASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; /// @notice Approves `value` from `owner_` to be spend by `spender`. /// @param owner_ Address of the owner. /// @param spender The address of the spender that gets approved to draw from `owner_`. /// @param value The maximum collective amount that `spender` can draw. /// @param deadline This permit must be redeemed before this deadline (UTC timestamp in seconds). function permit( address owner_, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external { require(owner_ != address(0), "ERC20: Owner cannot be 0"); require(block.timestamp < deadline, "ERC20: Expired"); require( ecrecover(_getDigest(keccak256(abi.encode(PERMIT_SIGNATURE_HASH, owner_, spender, value, nonces[owner_]++, deadline))), v, r, s) == owner_, "ERC20: Invalid Signature" ); allowance[owner_][spender] = value; emit Approval(owner_, spender, value); } } // File @boringcrypto/boring-solidity/contracts/interfaces/[email protected] // License-Identifier: MIT interface IMasterContract { /// @notice Init function that gets called from `BoringFactory.deploy`. /// Also kown as the constructor for cloned contracts. /// Any ETH send to `BoringFactory.deploy` ends up here. /// @param data Can be abi encoded arguments or anything else. function init(bytes calldata data) external payable; } // File @boringcrypto/boring-solidity/contracts/libraries/[email protected] // License-Identifier: MIT struct Rebase { uint128 elastic; uint128 base; } /// @notice A rebasing library using overflow-/underflow-safe math. library RebaseLibrary { using BoringMath for uint256; using BoringMath128 for uint128; /// @notice Calculates the base value in relationship to `elastic` and `total`. function toBase( Rebase memory total, uint256 elastic, bool roundUp ) internal pure returns (uint256 base) { if (total.elastic == 0) { base = elastic; } else { base = elastic.mul(total.base) / total.elastic; if (roundUp && base.mul(total.elastic) / total.base < elastic) { base = base.add(1); } } } /// @notice Calculates the elastic value in relationship to `base` and `total`. function toElastic( Rebase memory total, uint256 base, bool roundUp ) internal pure returns (uint256 elastic) { if (total.base == 0) { elastic = base; } else { elastic = base.mul(total.elastic) / total.base; if (roundUp && elastic.mul(total.base) / total.elastic < base) { elastic = elastic.add(1); } } } /// @notice Add `elastic` to `total` and doubles `total.base`. /// @return (Rebase) The new total. /// @return base in relationship to `elastic`. function add( Rebase memory total, uint256 elastic, bool roundUp ) internal pure returns (Rebase memory, uint256 base) { base = toBase(total, elastic, roundUp); total.elastic = total.elastic.add(elastic.to128()); total.base = total.base.add(base.to128()); return (total, base); } /// @notice Sub `base` from `total` and update `total.elastic`. /// @return (Rebase) The new total. /// @return elastic in relationship to `base`. function sub( Rebase memory total, uint256 base, bool roundUp ) internal pure returns (Rebase memory, uint256 elastic) { elastic = toElastic(total, base, roundUp); total.elastic = total.elastic.sub(elastic.to128()); total.base = total.base.sub(base.to128()); return (total, elastic); } /// @notice Add `elastic` and `base` to `total`. function add( Rebase memory total, uint256 elastic, uint256 base ) internal pure returns (Rebase memory) { total.elastic = total.elastic.add(elastic.to128()); total.base = total.base.add(base.to128()); return total; } /// @notice Subtract `elastic` and `base` to `total`. function sub( Rebase memory total, uint256 elastic, uint256 base ) internal pure returns (Rebase memory) { total.elastic = total.elastic.sub(elastic.to128()); total.base = total.base.sub(base.to128()); return total; } } // File @boringcrypto/boring-solidity/contracts/interfaces/[email protected] // License-Identifier: MIT interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); /// @notice EIP 2612 function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; } // File @boringcrypto/boring-solidity/contracts/libraries/[email protected] // License-Identifier: MIT library BoringERC20 { bytes4 private constant SIG_SYMBOL = 0x95d89b41; // symbol() bytes4 private constant SIG_NAME = 0x06fdde03; // name() bytes4 private constant SIG_DECIMALS = 0x313ce567; // decimals() bytes4 private constant SIG_TRANSFER = 0xa9059cbb; // transfer(address,uint256) bytes4 private constant SIG_TRANSFER_FROM = 0x23b872dd; // transferFrom(address,address,uint256) function returnDataToString(bytes memory data) internal pure returns (string memory) { if (data.length >= 64) { return abi.decode(data, (string)); } else if (data.length == 32) { uint8 i = 0; while (i < 32 && data[i] != 0) { i++; } bytes memory bytesArray = new bytes(i); for (i = 0; i < 32 && data[i] != 0; i++) { bytesArray[i] = data[i]; } return string(bytesArray); } else { return "???"; } } /// @notice Provides a safe ERC20.symbol version which returns '???' as fallback string. /// @param token The address of the ERC-20 token contract. /// @return (string) Token symbol. function safeSymbol(IERC20 token) internal view returns (string memory) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_SYMBOL)); return success ? returnDataToString(data) : "???"; } /// @notice Provides a safe ERC20.name version which returns '???' as fallback string. /// @param token The address of the ERC-20 token contract. /// @return (string) Token name. function safeName(IERC20 token) internal view returns (string memory) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_NAME)); return success ? returnDataToString(data) : "???"; } /// @notice Provides a safe ERC20.decimals version which returns '18' as fallback value. /// @param token The address of the ERC-20 token contract. /// @return (uint8) Token decimals. function safeDecimals(IERC20 token) internal view returns (uint8) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_DECIMALS)); return success && data.length == 32 ? abi.decode(data, (uint8)) : 18; } } // File @sushiswap/bentobox-sdk/contracts/[email protected] // License-Identifier: MIT interface IBatchFlashBorrower { function onBatchFlashLoan( address sender, IERC20[] calldata tokens, uint256[] calldata amounts, uint256[] calldata fees, bytes calldata data ) external; } // File @sushiswap/bentobox-sdk/contracts/[email protected] // License-Identifier: MIT interface IFlashBorrower { function onFlashLoan( address sender, IERC20 token, uint256 amount, uint256 fee, bytes calldata data ) external; } // File @sushiswap/bentobox-sdk/contracts/[email protected] // License-Identifier: MIT interface IStrategy { // Send the assets to the Strategy and call skim to invest them function skim(uint256 amount) external; // Harvest any profits made converted to the asset and pass them to the caller function harvest(uint256 balance, address sender) external returns (int256 amountAdded); // Withdraw assets. The returned amount can differ from the requested amount due to rounding. // The actualAmount should be very close to the amount. The difference should NOT be used to report a loss. That's what harvest is for. function withdraw(uint256 amount) external returns (uint256 actualAmount); // Withdraw all assets in the safest way possible. This shouldn't fail. function exit(uint256 balance) external returns (int256 amountAdded); } // File @sushiswap/bentobox-sdk/contracts/[email protected] // License-Identifier: MIT interface IBentoBoxV1 { event LogDeploy(address indexed masterContract, bytes data, address indexed cloneAddress); event LogDeposit(address indexed token, address indexed from, address indexed to, uint256 amount, uint256 share); event LogFlashLoan(address indexed borrower, address indexed token, uint256 amount, uint256 feeAmount, address indexed receiver); event LogRegisterProtocol(address indexed protocol); event LogSetMasterContractApproval(address indexed masterContract, address indexed user, bool approved); event LogStrategyDivest(address indexed token, uint256 amount); event LogStrategyInvest(address indexed token, uint256 amount); event LogStrategyLoss(address indexed token, uint256 amount); event LogStrategyProfit(address indexed token, uint256 amount); event LogStrategyQueued(address indexed token, address indexed strategy); event LogStrategySet(address indexed token, address indexed strategy); event LogStrategyTargetPercentage(address indexed token, uint256 targetPercentage); event LogTransfer(address indexed token, address indexed from, address indexed to, uint256 share); event LogWhiteListMasterContract(address indexed masterContract, bool approved); event LogWithdraw(address indexed token, address indexed from, address indexed to, uint256 amount, uint256 share); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function balanceOf(IERC20, address) external view returns (uint256); function batch(bytes[] calldata calls, bool revertOnFail) external payable returns (bool[] memory successes, bytes[] memory results); function batchFlashLoan( IBatchFlashBorrower borrower, address[] calldata receivers, IERC20[] calldata tokens, uint256[] calldata amounts, bytes calldata data ) external; function claimOwnership() external; function deploy( address masterContract, bytes calldata data, bool useCreate2 ) external payable; function deposit( IERC20 token_, address from, address to, uint256 amount, uint256 share ) external payable returns (uint256 amountOut, uint256 shareOut); function flashLoan( IFlashBorrower borrower, address receiver, IERC20 token, uint256 amount, bytes calldata data ) external; function harvest( IERC20 token, bool balance, uint256 maxChangeAmount ) external; function masterContractApproved(address, address) external view returns (bool); function masterContractOf(address) external view returns (address); function nonces(address) external view returns (uint256); function owner() external view returns (address); function pendingOwner() external view returns (address); function pendingStrategy(IERC20) external view returns (IStrategy); function permitToken( IERC20 token, address from, address to, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function registerProtocol() external; function setMasterContractApproval( address user, address masterContract, bool approved, uint8 v, bytes32 r, bytes32 s ) external; function setStrategy(IERC20 token, IStrategy newStrategy) external; function setStrategyTargetPercentage(IERC20 token, uint64 targetPercentage_) external; function strategy(IERC20) external view returns (IStrategy); function strategyData(IERC20) external view returns ( uint64 strategyStartDate, uint64 targetPercentage, uint128 balance ); function toAmount( IERC20 token, uint256 share, bool roundUp ) external view returns (uint256 amount); function toShare( IERC20 token, uint256 amount, bool roundUp ) external view returns (uint256 share); function totals(IERC20) external view returns (Rebase memory totals_); function transfer( IERC20 token, address from, address to, uint256 share ) external; function transferMultiple( IERC20 token, address from, address[] calldata tos, uint256[] calldata shares ) external; function transferOwnership( address newOwner, bool direct, bool renounce ) external; function whitelistMasterContract(address masterContract, bool approved) external; function whitelistedMasterContracts(address) external view returns (bool); function withdraw( IERC20 token_, address from, address to, uint256 amount, uint256 share ) external returns (uint256 amountOut, uint256 shareOut); } // File contracts/interfaces/IOracle.sol // License-Identifier: MIT interface IOracle { /// @notice Get the latest exchange rate. /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return success if no valid (recent) rate is available, return false else true. /// @return rate The rate of the requested asset / pair / pool. function get(bytes calldata data) external returns (bool success, uint256 rate); /// @notice Check the last exchange rate without any state changes. /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return success if no valid (recent) rate is available, return false else true. /// @return rate The rate of the requested asset / pair / pool. function peek(bytes calldata data) external view returns (bool success, uint256 rate); /// @notice Check the current spot exchange rate without any state changes. For oracles like TWAP this will be different from peek(). /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return rate The rate of the requested asset / pair / pool. function peekSpot(bytes calldata data) external view returns (uint256 rate); /// @notice Returns a human readable (short) name about this oracle. /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return (string) A human readable symbol name about this oracle. function symbol(bytes calldata data) external view returns (string memory); /// @notice Returns a human readable name about this oracle. /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return (string) A human readable name about this oracle. function name(bytes calldata data) external view returns (string memory); } // File contracts/interfaces/ISwapper.sol // License-Identifier: MIT interface ISwapper { /// @notice Withdraws 'amountFrom' of token 'from' from the BentoBox account for this swapper. /// Swaps it for at least 'amountToMin' of token 'to'. /// Transfers the swapped tokens of 'to' into the BentoBox using a plain ERC20 transfer. /// Returns the amount of tokens 'to' transferred to BentoBox. /// (The BentoBox skim function will be used by the caller to get the swapped funds). function swap( IERC20 fromToken, IERC20 toToken, address recipient, uint256 shareToMin, uint256 shareFrom ) external returns (uint256 extraShare, uint256 shareReturned); /// @notice Calculates the amount of token 'from' needed to complete the swap (amountFrom), /// this should be less than or equal to amountFromMax. /// Withdraws 'amountFrom' of token 'from' from the BentoBox account for this swapper. /// Swaps it for exactly 'exactAmountTo' of token 'to'. /// Transfers the swapped tokens of 'to' into the BentoBox using a plain ERC20 transfer. /// Transfers allocated, but unused 'from' tokens within the BentoBox to 'refundTo' (amountFromMax - amountFrom). /// Returns the amount of 'from' tokens withdrawn from BentoBox (amountFrom). /// (The BentoBox skim function will be used by the caller to get the swapped funds). function swapExact( IERC20 fromToken, IERC20 toToken, address recipient, address refundTo, uint256 shareFromSupplied, uint256 shareToExact ) external returns (uint256 shareUsed, uint256 shareReturned); } // File contracts/KashiPair.sol // License-Identifier: UNLICENSED // Kashi Lending Medium Risk /// @title KashiPair /// @dev This contract allows contract calls to any contract (except BentoBox) /// from arbitrary callers thus, don't trust calls from this contract in any circumstances. contract KashiPairMediumRiskV1 is ERC20, BoringOwnable, IMasterContract { using BoringMath for uint256; using BoringMath128 for uint128; using RebaseLibrary for Rebase; using BoringERC20 for IERC20; event LogExchangeRate(uint256 rate); event LogAccrue(uint256 accruedAmount, uint256 feeFraction, uint64 rate, uint256 utilization); event LogAddCollateral(address indexed from, address indexed to, uint256 share); event LogAddAsset(address indexed from, address indexed to, uint256 share, uint256 fraction); event LogRemoveCollateral(address indexed from, address indexed to, uint256 share); event LogRemoveAsset(address indexed from, address indexed to, uint256 share, uint256 fraction); event LogBorrow(address indexed from, address indexed to, uint256 amount, uint256 feeAmount, uint256 part); event LogRepay(address indexed from, address indexed to, uint256 amount, uint256 part); event LogFeeTo(address indexed newFeeTo); event LogWithdrawFees(address indexed feeTo, uint256 feesEarnedFraction); // Immutables (for MasterContract and all clones) IBentoBoxV1 public immutable bentoBox; KashiPairMediumRiskV1 public immutable masterContract; // MasterContract variables address public feeTo; mapping(ISwapper => bool) public swappers; // Per clone variables // Clone init settings IERC20 public collateral; IERC20 public asset; IOracle public oracle; bytes public oracleData; // Total amounts uint256 public totalCollateralShare; // Total collateral supplied Rebase public totalAsset; // elastic = BentoBox shares held by the KashiPair, base = Total fractions held by asset suppliers Rebase public totalBorrow; // elastic = Total token amount to be repayed by borrowers, base = Total parts of the debt held by borrowers // User balances mapping(address => uint256) public userCollateralShare; // userAssetFraction is called balanceOf for ERC20 compatibility (it's in ERC20.sol) mapping(address => uint256) public userBorrowPart; /// @notice Exchange and interest rate tracking. /// This is 'cached' here because calls to Oracles can be very expensive. uint256 public exchangeRate; struct AccrueInfo { uint64 interestPerSecond; uint64 lastAccrued; uint128 feesEarnedFraction; } AccrueInfo public accrueInfo; // ERC20 'variables' function symbol() external view returns (string memory) { return string(abi.encodePacked("km", collateral.safeSymbol(), "/", asset.safeSymbol(), "-", oracle.symbol(oracleData))); } function name() external view returns (string memory) { return string(abi.encodePacked("Kashi Medium Risk ", collateral.safeName(), "/", asset.safeName(), "-", oracle.name(oracleData))); } function decimals() external view returns (uint8) { return asset.safeDecimals(); } // totalSupply for ERC20 compatibility function totalSupply() public view returns (uint256) { return totalAsset.base; } // Settings for the Medium Risk KashiPair uint256 private constant CLOSED_COLLATERIZATION_RATE = 75000; // 75% uint256 private constant OPEN_COLLATERIZATION_RATE = 77000; // 77% uint256 private constant COLLATERIZATION_RATE_PRECISION = 1e5; // Must be less than EXCHANGE_RATE_PRECISION (due to optimization in math) uint256 private constant MINIMUM_TARGET_UTILIZATION = 7e17; // 70% uint256 private constant MAXIMUM_TARGET_UTILIZATION = 8e17; // 80% uint256 private constant UTILIZATION_PRECISION = 1e18; uint256 private constant FULL_UTILIZATION = 1e18; uint256 private constant FULL_UTILIZATION_MINUS_MAX = FULL_UTILIZATION - MAXIMUM_TARGET_UTILIZATION; uint256 private constant FACTOR_PRECISION = 1e18; uint64 private constant STARTING_INTEREST_PER_SECOND = 317097920; // approx 1% APR uint64 private constant MINIMUM_INTEREST_PER_SECOND = 79274480; // approx 0.25% APR uint64 private constant MAXIMUM_INTEREST_PER_SECOND = 317097920000; // approx 1000% APR uint256 private constant INTEREST_ELASTICITY = 28800e36; // Half or double in 28800 seconds (8 hours) if linear uint256 private constant EXCHANGE_RATE_PRECISION = 1e18; uint256 private constant LIQUIDATION_MULTIPLIER = 112000; // add 12% uint256 private constant LIQUIDATION_MULTIPLIER_PRECISION = 1e5; // Fees uint256 private constant PROTOCOL_FEE = 10000; // 10% uint256 private constant PROTOCOL_FEE_DIVISOR = 1e5; uint256 private constant BORROW_OPENING_FEE = 50; // 0.05% uint256 private constant BORROW_OPENING_FEE_PRECISION = 1e5; /// @notice The constructor is only used for the initial master contract. Subsequent clones are initialised via `init`. constructor(IBentoBoxV1 bentoBox_) public { bentoBox = bentoBox_; masterContract = this; feeTo = msg.sender; } /// @notice Serves as the constructor for clones, as clones can't have a regular constructor /// @dev `data` is abi encoded in the format: (IERC20 collateral, IERC20 asset, IOracle oracle, bytes oracleData) function init(bytes calldata data) public payable override { require(address(collateral) == address(0), "KashiPair: already initialized"); (collateral, asset, oracle, oracleData) = abi.decode(data, (IERC20, IERC20, IOracle, bytes)); require(address(collateral) != address(0), "KashiPair: bad pair"); accrueInfo.interestPerSecond = uint64(STARTING_INTEREST_PER_SECOND); // 1% APR, with 1e18 being 100% } /// @notice Accrues the interest on the borrowed tokens and handles the accumulation of fees. function accrue() public { AccrueInfo memory _accrueInfo = accrueInfo; // Number of seconds since accrue was called uint256 elapsedTime = block.timestamp - _accrueInfo.lastAccrued; if (elapsedTime == 0) { return; } _accrueInfo.lastAccrued = uint64(block.timestamp); Rebase memory _totalBorrow = totalBorrow; if (_totalBorrow.base == 0) { // If there are no borrows, reset the interest rate if (_accrueInfo.interestPerSecond != STARTING_INTEREST_PER_SECOND) { _accrueInfo.interestPerSecond = STARTING_INTEREST_PER_SECOND; emit LogAccrue(0, 0, STARTING_INTEREST_PER_SECOND, 0); } accrueInfo = _accrueInfo; return; } uint256 extraAmount = 0; uint256 feeFraction = 0; Rebase memory _totalAsset = totalAsset; // Accrue interest extraAmount = uint256(_totalBorrow.elastic).mul(_accrueInfo.interestPerSecond).mul(elapsedTime) / 1e18; _totalBorrow.elastic = _totalBorrow.elastic.add(extraAmount.to128()); uint256 fullAssetAmount = bentoBox.toAmount(asset, _totalAsset.elastic, false).add(_totalBorrow.elastic); uint256 feeAmount = extraAmount.mul(PROTOCOL_FEE) / PROTOCOL_FEE_DIVISOR; // % of interest paid goes to fee feeFraction = feeAmount.mul(_totalAsset.base) / fullAssetAmount; _accrueInfo.feesEarnedFraction = _accrueInfo.feesEarnedFraction.add(feeFraction.to128()); totalAsset.base = _totalAsset.base.add(feeFraction.to128()); totalBorrow = _totalBorrow; // Update interest rate uint256 utilization = uint256(_totalBorrow.elastic).mul(UTILIZATION_PRECISION) / fullAssetAmount; if (utilization < MINIMUM_TARGET_UTILIZATION) { uint256 underFactor = MINIMUM_TARGET_UTILIZATION.sub(utilization).mul(FACTOR_PRECISION) / MINIMUM_TARGET_UTILIZATION; uint256 scale = INTEREST_ELASTICITY.add(underFactor.mul(underFactor).mul(elapsedTime)); _accrueInfo.interestPerSecond = uint64(uint256(_accrueInfo.interestPerSecond).mul(INTEREST_ELASTICITY) / scale); if (_accrueInfo.interestPerSecond < MINIMUM_INTEREST_PER_SECOND) { _accrueInfo.interestPerSecond = MINIMUM_INTEREST_PER_SECOND; // 0.25% APR minimum } } else if (utilization > MAXIMUM_TARGET_UTILIZATION) { uint256 overFactor = utilization.sub(MAXIMUM_TARGET_UTILIZATION).mul(FACTOR_PRECISION) / FULL_UTILIZATION_MINUS_MAX; uint256 scale = INTEREST_ELASTICITY.add(overFactor.mul(overFactor).mul(elapsedTime)); uint256 newInterestPerSecond = uint256(_accrueInfo.interestPerSecond).mul(scale) / INTEREST_ELASTICITY; if (newInterestPerSecond > MAXIMUM_INTEREST_PER_SECOND) { newInterestPerSecond = MAXIMUM_INTEREST_PER_SECOND; // 1000% APR maximum } _accrueInfo.interestPerSecond = uint64(newInterestPerSecond); } emit LogAccrue(extraAmount, feeFraction, _accrueInfo.interestPerSecond, utilization); accrueInfo = _accrueInfo; } /// @notice Concrete implementation of `isSolvent`. Includes a third parameter to allow caching `exchangeRate`. /// @param _exchangeRate The exchange rate. Used to cache the `exchangeRate` between calls. function _isSolvent( address user, bool open, uint256 _exchangeRate ) internal view returns (bool) { // accrue must have already been called! uint256 borrowPart = userBorrowPart[user]; if (borrowPart == 0) return true; uint256 collateralShare = userCollateralShare[user]; if (collateralShare == 0) return false; Rebase memory _totalBorrow = totalBorrow; return bentoBox.toAmount( collateral, collateralShare.mul(EXCHANGE_RATE_PRECISION / COLLATERIZATION_RATE_PRECISION).mul( open ? OPEN_COLLATERIZATION_RATE : CLOSED_COLLATERIZATION_RATE ), false ) >= // Moved exchangeRate here instead of dividing the other side to preserve more precision borrowPart.mul(_totalBorrow.elastic).mul(_exchangeRate) / _totalBorrow.base; } /// @dev Checks if the user is solvent in the closed liquidation case at the end of the function body. modifier solvent() { _; require(_isSolvent(msg.sender, false, exchangeRate), "KashiPair: user insolvent"); } /// @notice Gets the exchange rate. I.e how much collateral to buy 1e18 asset. /// This function is supposed to be invoked if needed because Oracle queries can be expensive. /// @return updated True if `exchangeRate` was updated. /// @return rate The new exchange rate. function updateExchangeRate() public returns (bool updated, uint256 rate) { (updated, rate) = oracle.get(oracleData); if (updated) { exchangeRate = rate; emit LogExchangeRate(rate); } else { // Return the old rate if fetching wasn't successful rate = exchangeRate; } } /// @dev Helper function to move tokens. /// @param token The ERC-20 token. /// @param share The amount in shares to add. /// @param total Grand total amount to deduct from this contract's balance. Only applicable if `skim` is True. /// Only used for accounting checks. /// @param skim If True, only does a balance check on this contract. /// False if tokens from msg.sender in `bentoBox` should be transferred. function _addTokens( IERC20 token, uint256 share, uint256 total, bool skim ) internal { if (skim) { require(share <= bentoBox.balanceOf(token, address(this)).sub(total), "KashiPair: Skim too much"); } else { bentoBox.transfer(token, msg.sender, address(this), share); } } /// @notice Adds `collateral` from msg.sender to the account `to`. /// @param to The receiver of the tokens. /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender. /// False if tokens from msg.sender in `bentoBox` should be transferred. /// @param share The amount of shares to add for `to`. function addCollateral( address to, bool skim, uint256 share ) public { userCollateralShare[to] = userCollateralShare[to].add(share); uint256 oldTotalCollateralShare = totalCollateralShare; totalCollateralShare = oldTotalCollateralShare.add(share); _addTokens(collateral, share, oldTotalCollateralShare, skim); emit LogAddCollateral(skim ? address(bentoBox) : msg.sender, to, share); } /// @dev Concrete implementation of `removeCollateral`. function _removeCollateral(address to, uint256 share) internal { userCollateralShare[msg.sender] = userCollateralShare[msg.sender].sub(share); totalCollateralShare = totalCollateralShare.sub(share); emit LogRemoveCollateral(msg.sender, to, share); bentoBox.transfer(collateral, address(this), to, share); } /// @notice Removes `share` amount of collateral and transfers it to `to`. /// @param to The receiver of the shares. /// @param share Amount of shares to remove. function removeCollateral(address to, uint256 share) public solvent { // accrue must be called because we check solvency accrue(); _removeCollateral(to, share); } /// @dev Concrete implementation of `addAsset`. function _addAsset( address to, bool skim, uint256 share ) internal returns (uint256 fraction) { Rebase memory _totalAsset = totalAsset; uint256 totalAssetShare = _totalAsset.elastic; uint256 allShare = _totalAsset.elastic + bentoBox.toShare(asset, totalBorrow.elastic, true); fraction = allShare == 0 ? share : share.mul(_totalAsset.base) / allShare; if (_totalAsset.base.add(fraction.to128()) < 1000) { return 0; } totalAsset = _totalAsset.add(share, fraction); balanceOf[to] = balanceOf[to].add(fraction); _addTokens(asset, share, totalAssetShare, skim); emit LogAddAsset(skim ? address(bentoBox) : msg.sender, to, share, fraction); } /// @notice Adds assets to the lending pair. /// @param to The address of the user to receive the assets. /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender. /// False if tokens from msg.sender in `bentoBox` should be transferred. /// @param share The amount of shares to add. /// @return fraction Total fractions added. function addAsset( address to, bool skim, uint256 share ) public returns (uint256 fraction) { accrue(); fraction = _addAsset(to, skim, share); } /// @dev Concrete implementation of `removeAsset`. function _removeAsset(address to, uint256 fraction) internal returns (uint256 share) { Rebase memory _totalAsset = totalAsset; uint256 allShare = _totalAsset.elastic + bentoBox.toShare(asset, totalBorrow.elastic, true); share = fraction.mul(allShare) / _totalAsset.base; balanceOf[msg.sender] = balanceOf[msg.sender].sub(fraction); _totalAsset.elastic = _totalAsset.elastic.sub(share.to128()); _totalAsset.base = _totalAsset.base.sub(fraction.to128()); require(_totalAsset.base >= 1000, "Kashi: below minimum"); totalAsset = _totalAsset; emit LogRemoveAsset(msg.sender, to, share, fraction); bentoBox.transfer(asset, address(this), to, share); } /// @notice Removes an asset from msg.sender and transfers it to `to`. /// @param to The user that receives the removed assets. /// @param fraction The amount/fraction of assets held to remove. /// @return share The amount of shares transferred to `to`. function removeAsset(address to, uint256 fraction) public returns (uint256 share) { accrue(); share = _removeAsset(to, fraction); } /// @dev Concrete implementation of `borrow`. function _borrow(address to, uint256 amount) internal returns (uint256 part, uint256 share) { uint256 feeAmount = amount.mul(BORROW_OPENING_FEE) / BORROW_OPENING_FEE_PRECISION; // A flat % fee is charged for any borrow (totalBorrow, part) = totalBorrow.add(amount.add(feeAmount), true); userBorrowPart[msg.sender] = userBorrowPart[msg.sender].add(part); emit LogBorrow(msg.sender, to, amount, feeAmount, part); share = bentoBox.toShare(asset, amount, false); Rebase memory _totalAsset = totalAsset; require(_totalAsset.base >= 1000, "Kashi: below minimum"); _totalAsset.elastic = _totalAsset.elastic.sub(share.to128()); totalAsset = _totalAsset; bentoBox.transfer(asset, address(this), to, share); } /// @notice Sender borrows `amount` and transfers it to `to`. /// @return part Total part of the debt held by borrowers. /// @return share Total amount in shares borrowed. function borrow(address to, uint256 amount) public solvent returns (uint256 part, uint256 share) { accrue(); (part, share) = _borrow(to, amount); } /// @dev Concrete implementation of `repay`. function _repay( address to, bool skim, uint256 part ) internal returns (uint256 amount) { (totalBorrow, amount) = totalBorrow.sub(part, true); userBorrowPart[to] = userBorrowPart[to].sub(part); uint256 share = bentoBox.toShare(asset, amount, true); uint128 totalShare = totalAsset.elastic; _addTokens(asset, share, uint256(totalShare), skim); totalAsset.elastic = totalShare.add(share.to128()); emit LogRepay(skim ? address(bentoBox) : msg.sender, to, amount, part); } /// @notice Repays a loan. /// @param to Address of the user this payment should go. /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender. /// False if tokens from msg.sender in `bentoBox` should be transferred. /// @param part The amount to repay. See `userBorrowPart`. /// @return amount The total amount repayed. function repay( address to, bool skim, uint256 part ) public returns (uint256 amount) { accrue(); amount = _repay(to, skim, part); } // Functions that need accrue to be called uint8 internal constant ACTION_ADD_ASSET = 1; uint8 internal constant ACTION_REPAY = 2; uint8 internal constant ACTION_REMOVE_ASSET = 3; uint8 internal constant ACTION_REMOVE_COLLATERAL = 4; uint8 internal constant ACTION_BORROW = 5; uint8 internal constant ACTION_GET_REPAY_SHARE = 6; uint8 internal constant ACTION_GET_REPAY_PART = 7; uint8 internal constant ACTION_ACCRUE = 8; // Functions that don't need accrue to be called uint8 internal constant ACTION_ADD_COLLATERAL = 10; uint8 internal constant ACTION_UPDATE_EXCHANGE_RATE = 11; // Function on BentoBox uint8 internal constant ACTION_BENTO_DEPOSIT = 20; uint8 internal constant ACTION_BENTO_WITHDRAW = 21; uint8 internal constant ACTION_BENTO_TRANSFER = 22; uint8 internal constant ACTION_BENTO_TRANSFER_MULTIPLE = 23; uint8 internal constant ACTION_BENTO_SETAPPROVAL = 24; // Any external call (except to BentoBox) uint8 internal constant ACTION_CALL = 30; int256 internal constant USE_VALUE1 = -1; int256 internal constant USE_VALUE2 = -2; /// @dev Helper function for choosing the correct value (`value1` or `value2`) depending on `inNum`. function _num( int256 inNum, uint256 value1, uint256 value2 ) internal pure returns (uint256 outNum) { outNum = inNum >= 0 ? uint256(inNum) : (inNum == USE_VALUE1 ? value1 : value2); } /// @dev Helper function for depositing into `bentoBox`. function _bentoDeposit( bytes memory data, uint256 value, uint256 value1, uint256 value2 ) internal returns (uint256, uint256) { (IERC20 token, address to, int256 amount, int256 share) = abi.decode(data, (IERC20, address, int256, int256)); amount = int256(_num(amount, value1, value2)); // Done this way to avoid stack too deep errors share = int256(_num(share, value1, value2)); return bentoBox.deposit{value: value}(token, msg.sender, to, uint256(amount), uint256(share)); } /// @dev Helper function to withdraw from the `bentoBox`. function _bentoWithdraw( bytes memory data, uint256 value1, uint256 value2 ) internal returns (uint256, uint256) { (IERC20 token, address to, int256 amount, int256 share) = abi.decode(data, (IERC20, address, int256, int256)); return bentoBox.withdraw(token, msg.sender, to, _num(amount, value1, value2), _num(share, value1, value2)); } /// @dev Helper function to perform a contract call and eventually extracting revert messages on failure. /// Calls to `bentoBox` are not allowed for obvious security reasons. /// This also means that calls made from this contract shall *not* be trusted. function _call( uint256 value, bytes memory data, uint256 value1, uint256 value2 ) internal returns (bytes memory, uint8) { (address callee, bytes memory callData, bool useValue1, bool useValue2, uint8 returnValues) = abi.decode(data, (address, bytes, bool, bool, uint8)); if (useValue1 && !useValue2) { callData = abi.encodePacked(callData, value1); } else if (!useValue1 && useValue2) { callData = abi.encodePacked(callData, value2); } else if (useValue1 && useValue2) { callData = abi.encodePacked(callData, value1, value2); } require(callee != address(bentoBox) && callee != address(this), "KashiPair: can't call"); (bool success, bytes memory returnData) = callee.call{value: value}(callData); require(success, "KashiPair: call failed"); return (returnData, returnValues); } struct CookStatus { bool needsSolvencyCheck; bool hasAccrued; } /// @notice Executes a set of actions and allows composability (contract calls) to other contracts. /// @param actions An array with a sequence of actions to execute (see ACTION_ declarations). /// @param values A one-to-one mapped array to `actions`. ETH amounts to send along with the actions. /// Only applicable to `ACTION_CALL`, `ACTION_BENTO_DEPOSIT`. /// @param datas A one-to-one mapped array to `actions`. Contains abi encoded data of function arguments. /// @return value1 May contain the first positioned return value of the last executed action (if applicable). /// @return value2 May contain the second positioned return value of the last executed action which returns 2 values (if applicable). function cook( uint8[] calldata actions, uint256[] calldata values, bytes[] calldata datas ) external payable returns (uint256 value1, uint256 value2) { CookStatus memory status; for (uint256 i = 0; i < actions.length; i++) { uint8 action = actions[i]; if (!status.hasAccrued && action < 10) { accrue(); status.hasAccrued = true; } if (action == ACTION_ADD_COLLATERAL) { (int256 share, address to, bool skim) = abi.decode(datas[i], (int256, address, bool)); addCollateral(to, skim, _num(share, value1, value2)); } else if (action == ACTION_ADD_ASSET) { (int256 share, address to, bool skim) = abi.decode(datas[i], (int256, address, bool)); value1 = _addAsset(to, skim, _num(share, value1, value2)); } else if (action == ACTION_REPAY) { (int256 part, address to, bool skim) = abi.decode(datas[i], (int256, address, bool)); _repay(to, skim, _num(part, value1, value2)); } else if (action == ACTION_REMOVE_ASSET) { (int256 fraction, address to) = abi.decode(datas[i], (int256, address)); value1 = _removeAsset(to, _num(fraction, value1, value2)); } else if (action == ACTION_REMOVE_COLLATERAL) { (int256 share, address to) = abi.decode(datas[i], (int256, address)); _removeCollateral(to, _num(share, value1, value2)); status.needsSolvencyCheck = true; } else if (action == ACTION_BORROW) { (int256 amount, address to) = abi.decode(datas[i], (int256, address)); (value1, value2) = _borrow(to, _num(amount, value1, value2)); status.needsSolvencyCheck = true; } else if (action == ACTION_UPDATE_EXCHANGE_RATE) { (bool must_update, uint256 minRate, uint256 maxRate) = abi.decode(datas[i], (bool, uint256, uint256)); (bool updated, uint256 rate) = updateExchangeRate(); require((!must_update || updated) && rate > minRate && (maxRate == 0 || rate > maxRate), "KashiPair: rate not ok"); } else if (action == ACTION_BENTO_SETAPPROVAL) { (address user, address _masterContract, bool approved, uint8 v, bytes32 r, bytes32 s) = abi.decode(datas[i], (address, address, bool, uint8, bytes32, bytes32)); bentoBox.setMasterContractApproval(user, _masterContract, approved, v, r, s); } else if (action == ACTION_BENTO_DEPOSIT) { (value1, value2) = _bentoDeposit(datas[i], values[i], value1, value2); } else if (action == ACTION_BENTO_WITHDRAW) { (value1, value2) = _bentoWithdraw(datas[i], value1, value2); } else if (action == ACTION_BENTO_TRANSFER) { (IERC20 token, address to, int256 share) = abi.decode(datas[i], (IERC20, address, int256)); bentoBox.transfer(token, msg.sender, to, _num(share, value1, value2)); } else if (action == ACTION_BENTO_TRANSFER_MULTIPLE) { (IERC20 token, address[] memory tos, uint256[] memory shares) = abi.decode(datas[i], (IERC20, address[], uint256[])); bentoBox.transferMultiple(token, msg.sender, tos, shares); } else if (action == ACTION_CALL) { (bytes memory returnData, uint8 returnValues) = _call(values[i], datas[i], value1, value2); if (returnValues == 1) { (value1) = abi.decode(returnData, (uint256)); } else if (returnValues == 2) { (value1, value2) = abi.decode(returnData, (uint256, uint256)); } } else if (action == ACTION_GET_REPAY_SHARE) { int256 part = abi.decode(datas[i], (int256)); value1 = bentoBox.toShare(asset, totalBorrow.toElastic(_num(part, value1, value2), true), true); } else if (action == ACTION_GET_REPAY_PART) { int256 amount = abi.decode(datas[i], (int256)); value1 = totalBorrow.toBase(_num(amount, value1, value2), false); } } if (status.needsSolvencyCheck) { require(_isSolvent(msg.sender, false, exchangeRate), "KashiPair: user insolvent"); } } /// @notice Handles the liquidation of users' balances, once the users' amount of collateral is too low. /// @param users An array of user addresses. /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user. /// @param to Address of the receiver in open liquidations if `swapper` is zero. /// @param swapper Contract address of the `ISwapper` implementation. Swappers are restricted for closed liquidations. See `setSwapper`. /// @param open True to perform a open liquidation else False. function liquidate( address[] calldata users, uint256[] calldata maxBorrowParts, address to, ISwapper swapper, bool open ) public { // Oracle can fail but we still need to allow liquidations (, uint256 _exchangeRate) = updateExchangeRate(); accrue(); uint256 allCollateralShare; uint256 allBorrowAmount; uint256 allBorrowPart; Rebase memory _totalBorrow = totalBorrow; Rebase memory bentoBoxTotals = bentoBox.totals(collateral); for (uint256 i = 0; i < users.length; i++) { address user = users[i]; if (!_isSolvent(user, open, _exchangeRate)) { uint256 borrowPart; { uint256 availableBorrowPart = userBorrowPart[user]; borrowPart = maxBorrowParts[i] > availableBorrowPart ? availableBorrowPart : maxBorrowParts[i]; userBorrowPart[user] = availableBorrowPart.sub(borrowPart); } uint256 borrowAmount = _totalBorrow.toElastic(borrowPart, false); uint256 collateralShare = bentoBoxTotals.toBase( borrowAmount.mul(LIQUIDATION_MULTIPLIER).mul(_exchangeRate) / (LIQUIDATION_MULTIPLIER_PRECISION * EXCHANGE_RATE_PRECISION), false ); userCollateralShare[user] = userCollateralShare[user].sub(collateralShare); emit LogRemoveCollateral(user, swapper == ISwapper(0) ? to : address(swapper), collateralShare); emit LogRepay(swapper == ISwapper(0) ? msg.sender : address(swapper), user, borrowAmount, borrowPart); // Keep totals allCollateralShare = allCollateralShare.add(collateralShare); allBorrowAmount = allBorrowAmount.add(borrowAmount); allBorrowPart = allBorrowPart.add(borrowPart); } } require(allBorrowAmount != 0, "KashiPair: all are solvent"); _totalBorrow.elastic = _totalBorrow.elastic.sub(allBorrowAmount.to128()); _totalBorrow.base = _totalBorrow.base.sub(allBorrowPart.to128()); totalBorrow = _totalBorrow; totalCollateralShare = totalCollateralShare.sub(allCollateralShare); uint256 allBorrowShare = bentoBox.toShare(asset, allBorrowAmount, true); if (!open) { // Closed liquidation using a pre-approved swapper for the benefit of the LPs require(masterContract.swappers(swapper), "KashiPair: Invalid swapper"); // Swaps the users' collateral for the borrowed asset bentoBox.transfer(collateral, address(this), address(swapper), allCollateralShare); swapper.swap(collateral, asset, address(this), allBorrowShare, allCollateralShare); uint256 returnedShare = bentoBox.balanceOf(asset, address(this)).sub(uint256(totalAsset.elastic)); uint256 extraShare = returnedShare.sub(allBorrowShare); uint256 feeShare = extraShare.mul(PROTOCOL_FEE) / PROTOCOL_FEE_DIVISOR; // % of profit goes to fee // solhint-disable-next-line reentrancy bentoBox.transfer(asset, address(this), masterContract.feeTo(), feeShare); totalAsset.elastic = totalAsset.elastic.add(returnedShare.sub(feeShare).to128()); emit LogAddAsset(address(swapper), address(this), extraShare.sub(feeShare), 0); } else { // Swap using a swapper freely chosen by the caller // Open (flash) liquidation: get proceeds first and provide the borrow after bentoBox.transfer(collateral, address(this), swapper == ISwapper(0) ? to : address(swapper), allCollateralShare); if (swapper != ISwapper(0)) { swapper.swap(collateral, asset, msg.sender, allBorrowShare, allCollateralShare); } bentoBox.transfer(asset, msg.sender, address(this), allBorrowShare); totalAsset.elastic = totalAsset.elastic.add(allBorrowShare.to128()); } } /// @notice Withdraws the fees accumulated. function withdrawFees() public { accrue(); address _feeTo = masterContract.feeTo(); uint256 _feesEarnedFraction = accrueInfo.feesEarnedFraction; balanceOf[_feeTo] = balanceOf[_feeTo].add(_feesEarnedFraction); accrueInfo.feesEarnedFraction = 0; emit LogWithdrawFees(_feeTo, _feesEarnedFraction); } /// @notice Used to register and enable or disable swapper contracts used in closed liquidations. /// MasterContract Only Admin function. /// @param swapper The address of the swapper contract that conforms to `ISwapper`. /// @param enable True to enable the swapper. To disable use False. function setSwapper(ISwapper swapper, bool enable) public onlyOwner { swappers[swapper] = enable; } /// @notice Sets the beneficiary of fees accrued in liquidations. /// MasterContract Only Admin function. /// @param newFeeTo The address of the receiver. function setFeeTo(address newFeeTo) public onlyOwner { feeTo = newFeeTo; emit LogFeeTo(newFeeTo); } }
Contract Security Audit
- Certora - March 17th, 2021 - Security Audit Report
Contract ABI
API[{"inputs":[{"internalType":"contract IBentoBoxV1","name":"bentoBox_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"accruedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeFraction","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"rate","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"utilization","type":"uint256"}],"name":"LogAccrue","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":"share","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fraction","type":"uint256"}],"name":"LogAddAsset","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":"share","type":"uint256"}],"name":"LogAddCollateral","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":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"part","type":"uint256"}],"name":"LogBorrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"}],"name":"LogExchangeRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newFeeTo","type":"address"}],"name":"LogFeeTo","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":"share","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fraction","type":"uint256"}],"name":"LogRemoveAsset","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":"share","type":"uint256"}],"name":"LogRemoveCollateral","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":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"part","type":"uint256"}],"name":"LogRepay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"feeTo","type":"address"},{"indexed":false,"internalType":"uint256","name":"feesEarnedFraction","type":"uint256"}],"name":"LogWithdrawFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accrue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"accrueInfo","outputs":[{"internalType":"uint64","name":"interestPerSecond","type":"uint64"},{"internalType":"uint64","name":"lastAccrued","type":"uint64"},{"internalType":"uint128","name":"feesEarnedFraction","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"skim","type":"bool"},{"internalType":"uint256","name":"share","type":"uint256"}],"name":"addAsset","outputs":[{"internalType":"uint256","name":"fraction","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"skim","type":"bool"},{"internalType":"uint256","name":"share","type":"uint256"}],"name":"addCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","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":"asset","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bentoBox","outputs":[{"internalType":"contract IBentoBoxV1","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"borrow","outputs":[{"internalType":"uint256","name":"part","type":"uint256"},{"internalType":"uint256","name":"share","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"actions","type":"uint8[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"datas","type":"bytes[]"}],"name":"cook","outputs":[{"internalType":"uint256","name":"value1","type":"uint256"},{"internalType":"uint256","name":"value2","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"init","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"uint256[]","name":"maxBorrowParts","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"contract ISwapper","name":"swapper","type":"address"},{"internalType":"bool","name":"open","type":"bool"}],"name":"liquidate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"masterContract","outputs":[{"internalType":"contract KashiPairMediumRiskV1","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"fraction","type":"uint256"}],"name":"removeAsset","outputs":[{"internalType":"uint256","name":"share","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"share","type":"uint256"}],"name":"removeCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"skim","type":"bool"},{"internalType":"uint256","name":"part","type":"uint256"}],"name":"repay","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeTo","type":"address"}],"name":"setFeeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISwapper","name":"swapper","type":"address"},{"internalType":"bool","name":"enable","type":"bool"}],"name":"setSwapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISwapper","name":"","type":"address"}],"name":"swappers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAsset","outputs":[{"internalType":"uint128","name":"elastic","type":"uint128"},{"internalType":"uint128","name":"base","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBorrow","outputs":[{"internalType":"uint128","name":"elastic","type":"uint128"},{"internalType":"uint128","name":"base","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCollateralShare","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":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","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"},{"internalType":"bool","name":"direct","type":"bool"},{"internalType":"bool","name":"renounce","type":"bool"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateExchangeRate","outputs":[{"internalType":"bool","name":"updated","type":"bool"},{"internalType":"uint256","name":"rate","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userBorrowPart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userCollateralShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6101006040523480156200001257600080fd5b506040516200621c3803806200621c833981016040819052620000359162000110565b4660a08190526200004681620000ba565b60805250600380546001600160a01b031916339081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36001600160601b0319606091821b1660c05230901b60e052600580546001600160a01b031916331790556200015f565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692188230604051602001620000f39392919062000140565b604051602081830303815290604052805190602001209050919050565b60006020828403121562000122578081fd5b81516001600160a01b038116811462000139578182fd5b9392505050565b92835260208301919091526001600160a01b0316604082015260600190565b60805160a05160c05160601c60e05160601c615fe66200023660003980610e0c5280611f9f528061228f5280612970525080611496528061165e528061173652806118a95280611a4e5280611b7d5280611ef6528061205a528061218a52806122495280612423528061256c52806126d05280612e0d528061336c5280613474528061353652806136ee52806137ae528061397f5280613c4d5280613d9c5280613ec55280614052528061410852806141e45280614369528061466452806146eb525080610d35525080610d6a5250615fe66000f3fe6080604052600436106102f25760003560e01c8063656f3d641161018f5780638da5cb5b116100e1578063d8dfeb451161008a578063f46901ed11610064578063f46901ed146107bb578063f8ba4cff146107db578063f9557ccb146107f0576102f2565b8063d8dfeb4514610771578063dd62ed3e14610786578063e30c3978146107a6576102f2565b8063b27c0e74116100bb578063b27c0e7414610718578063cd446e221461073c578063d505accf14610751576102f2565b80638da5cb5b146106ce57806395d89b41146106e3578063a9059cbb146106f8576102f2565b80637dc0d1d011610143578063860ffea11161011d578063860ffea11461066e578063876467f81461068e5780638cad7fbe146106ae576102f2565b80637dc0d1d0146106165780637ecebe001461062b5780638285ef401461064b576102f2565b806370a082311161017457806370a08231146105c157806374645ff3146105e157806376ee101b146105f6576102f2565b8063656f3d64146105995780636b2ace87146105ac576102f2565b8063313ce56711610248578063473e3ce7116101fc5780634b8a3529116101d65780634b8a3529146105435780634ddf47d4146105715780634e71e0c814610584576102f2565b8063473e3ce7146104f9578063476343ee1461050e57806348e4163e14610523576102f2565b806338d52e0f1161022d57806338d52e0f146104af5780633ba0b9a9146104c45780633f2617cb146104d9576102f2565b8063313ce567146104785780633644e5151461049a576102f2565b806315294c40116102aa5780631c9e379b116102845780631c9e379b146104185780632317ef671461043857806323b872dd14610458576102f2565b806315294c40146103b657806318160ddd146103e35780631b51e940146103f8576102f2565b806306fdde03116102db57806306fdde0314610345578063078dfbe714610367578063095ea7b314610389576102f2565b8063017e7e58146102f757806302ce728f14610322575b600080fd5b34801561030357600080fd5b5061030c610805565b6040516103199190615613565b60405180910390f35b34801561032e57600080fd5b50610337610814565b60405161031992919061566b565b34801561035157600080fd5b5061035a6108f1565b60405161031991906156f5565b34801561037357600080fd5b50610387610382366004614e87565b6109c9565b005b34801561039557600080fd5b506103a96103a4366004614f00565b610ab9565b6040516103199190615660565b3480156103c257600080fd5b506103d66103d1366004614ed1565b610b24565b604051610319919061567b565b3480156103ef57600080fd5b506103d6610b41565b34801561040457600080fd5b506103d6610413366004614ed1565b610b57565b34801561042457600080fd5b506103d6610433366004614c6f565b610b6c565b34801561044457600080fd5b506103d6610453366004614f00565b610b7e565b34801561046457600080fd5b506103a9610473366004614dd7565b610b99565b34801561048457600080fd5b5061048d610d13565b6040516103199190615e70565b3480156104a657600080fd5b506103d6610d30565b3480156104bb57600080fd5b5061030c610d90565b3480156104d057600080fd5b506103d6610d9f565b3480156104e557600080fd5b506103876104f4366004615316565b610da5565b34801561050557600080fd5b506103d6610dfa565b34801561051a57600080fd5b50610387610e00565b34801561052f57600080fd5b506103d661053e366004614c6f565b610f3d565b34801561054f57600080fd5b5061056361055e366004614f00565b610f4f565b604051610319929190615e1f565b61038761057f3660046150e4565b610f9d565b34801561059057600080fd5b50610387611080565b6105636105a7366004614fd1565b61110e565b3480156105b857600080fd5b5061030c611a4c565b3480156105cd57600080fd5b506103d66105dc366004614c6f565b611a70565b3480156105ed57600080fd5b5061035a611a82565b34801561060257600080fd5b50610387610611366004614f2b565b611b10565b34801561062257600080fd5b5061030c61261a565b34801561063757600080fd5b506103d6610646366004614c6f565b612629565b34801561065757600080fd5b5061066061263b565b604051610319929190615e05565b34801561067a57600080fd5b50610387610689366004614ed1565b612655565b34801561069a57600080fd5b506103876106a9366004614f00565b612736565b3480156106ba57600080fd5b506103a96106c9366004614c6f565b612776565b3480156106da57600080fd5b5061030c61278b565b3480156106ef57600080fd5b5061035a61279a565b34801561070457600080fd5b506103a9610713366004614f00565b61285e565b34801561072457600080fd5b5061072d61293b565b60405161031993929190615e43565b34801561074857600080fd5b5061030c61296e565b34801561075d57600080fd5b5061038761076c366004614e17565b612992565b34801561077d57600080fd5b5061030c612b33565b34801561079257600080fd5b506103d66107a1366004614d9f565b612b42565b3480156107b257600080fd5b5061030c612b5f565b3480156107c757600080fd5b506103876107d6366004614c6f565b612b6e565b3480156107e757600080fd5b50610387612be2565b3480156107fc57600080fd5b506106606131c7565b6005546001600160a01b031681565b60095460405163d6d7d52560e01b815260009182916001600160a01b039091169063d6d7d5259061084a90600a90600401615708565b6040805180830381600087803b15801561086357600080fd5b505af1158015610877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089b9190615083565b909250905081156108e85760108190556040517f9f9192b5edb17356c524e08d9e025c8e2f6307e6ea52fb7968faa3081f51c3c8906108db90839061567b565b60405180910390a16108ed565b506010545b9091565b600754606090610909906001600160a01b03166131e1565b60085461091e906001600160a01b03166131e1565b60095460405163355a219b60e21b81526001600160a01b039091169063d568866c9061094f90600a90600401615708565b60006040518083038186803b15801561096757600080fd5b505afa15801561097b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109a391908101906153a5565b6040516020016109b59392919061551e565b604051602081830303815290604052905090565b6003546001600160a01b031633146109fc5760405162461bcd60e51b81526004016109f390615be3565b60405180910390fd5b8115610a98576001600160a01b038316151580610a165750805b610a325760405162461bcd60e51b81526004016109f3906159f4565b6003546040516001600160a01b038086169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600380546001600160a01b0385166001600160a01b031991821617909155600480549091169055610ab4565b600480546001600160a01b0319166001600160a01b0385161790555b505050565b3360008181526001602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610b1290869061567b565b60405180910390a35060015b92915050565b6000610b2e612be2565b610b398484846132a6565b949350505050565b600c54600160801b90046001600160801b031690565b6000610b61612be2565b610b398484846134df565b600e6020526000908152604090205481565b6000610b88612be2565b610b92838361375a565b9392505050565b60008115610cbe576001600160a01b03841660009081526020819052604090205482811015610bda5760405162461bcd60e51b81526004016109f390615cbb565b836001600160a01b0316856001600160a01b031614610cbc576001600160a01b03851660009081526001602090815260408083203384529091529020546000198114610c695783811015610c405760405162461bcd60e51b81526004016109f390615b07565b6001600160a01b0386166000908152600160209081526040808320338452909152902084820390555b6001600160a01b038516610c8f5760405162461bcd60e51b81526004016109f390615986565b506001600160a01b0380861660009081526020819052604080822086850390559186168152208054840190555b505b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d01919061567b565b60405180910390a35060019392505050565b600854600090610d2b906001600160a01b03166139f8565b905090565b6000467f00000000000000000000000000000000000000000000000000000000000000008114610d6857610d6381613ab1565b610d8a565b7f00000000000000000000000000000000000000000000000000000000000000005b91505090565b6008546001600160a01b031681565b60105481565b6003546001600160a01b03163314610dcf5760405162461bcd60e51b81526004016109f390615be3565b6001600160a01b03919091166000908152600660205260409020805460ff1916911515919091179055565b600b5481565b610e08612be2565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b158015610e6357600080fd5b505afa158015610e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9b9190614c8b565b6011546001600160a01b038216600090815260208190526040902054919250600160801b90046001600160801b031690610ed59082613b05565b6001600160a01b0383166000818152602081905260409081902092909255601180546001600160801b0316905590517fbe641c3ffc44b2d6c184f023fa4ed7bda4b6ffa71e03b3c98ae0c776da1f17e790610f3190849061567b565b60405180910390a25050565b600f6020526000908152604090205481565b600080610f5a612be2565b610f648484613b28565b8092508193505050610f7a336000601054613e16565b610f965760405162461bcd60e51b81526004016109f390615bac565b9250929050565b6007546001600160a01b031615610fc65760405162461bcd60e51b81526004016109f39061594f565b610fd28183018361526b565b805160079060009060089082906009908290610ff590600a9060208a0190614aa1565b5081546001600160a01b0398891661010092830a908102908a021990911617909155825497871691810a918202918702199097161790558154958416940a938402938302199094169290921790925550600754166110655760405162461bcd60e51b81526004016109f390615ad0565b50506011805467ffffffffffffffff19166312e687c0179055565b6004546001600160a01b03163381146110ab5760405162461bcd60e51b81526004016109f390615c18565b6003546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600380546001600160a01b039092166001600160a01b0319928316179055600480549091169055565b600080611119614b1b565b60005b88811015611a0e5760008a8a8381811061113257fe5b90506020020160208101906111479190615455565b9050826020015115801561115e5750600a8160ff16105b156111735761116b612be2565b600160208401525b60ff8116600a14156111cd57600080600089898681811061119057fe5b90506020028101906111a29190615e7e565b8101906111af919061537f565b9250925092506111c58282610689868c8c613f91565b505050611a05565b60ff81166001141561122e5760008060008989868181106111ea57fe5b90506020028101906111fc9190615e7e565b810190611209919061537f565b925092509250611224828261121f868c8c613f91565b6134df565b9750505050611a05565b60ff81166002141561128e57600080600089898681811061124b57fe5b905060200281019061125d9190615e7e565b81019061126a919061537f565b9250925092506112858282611280868c8c613f91565b6132a6565b50505050611a05565b60ff8116600314156112e9576000808888858181106112a957fe5b90506020028101906112bb9190615e7e565b8101906112c8919061535b565b915091506112e0816112db848a8a613f91565b61375a565b96505050611a05565b60ff8116600414156113465760008088888581811061130457fe5b90506020028101906113169190615e7e565b810190611323919061535b565b9150915061133b81611336848a8a613f91565b613fb9565b505060018352611a05565b60ff8116600514156113a95760008088888581811061136157fe5b90506020028101906113739190615e7e565b810190611380919061535b565b9150915061139881611393848a8a613f91565b613b28565b600187529097509550611a05915050565b60ff8116600b14156114485760008060008989868181106113c657fe5b90506020028101906113d89190615e7e565b8101906113e591906150b0565b9250925092506000806113f6610814565b915091508415806114045750815b801561140f57508381115b8015611422575082158061142257508281115b61143e5760405162461bcd60e51b81526004016109f390615d97565b5050505050611a05565b60ff811660181415611527576000806000806000808c8c8981811061146957fe5b905060200281019061147b9190615e7e565b8101906114889190614ca7565b9550955095509550955095507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c0a47c938787878787876040518763ffffffff1660e01b81526004016114ea96959493929190615627565b600060405180830381600087803b15801561150457600080fd5b505af1158015611518573d6000803e3d6000fd5b50505050505050505050611a05565b60ff8116601414156115af576115a587878481811061154257fe5b90506020028101906115549190615e7e565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508c915086905081811061159757fe5b9050602002013587876140c7565b9095509350611a05565b60ff81166015141561161a576115a58787848181106115ca57fe5b90506020028101906115dc9190615e7e565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508992508891506141bd9050565b60ff8116601614156116f257600080600089898681811061163757fe5b90506020028101906116499190615e7e565b8101906116569190614dd7565b9250925092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f18d03cc843385611699868e8e613f91565b6040518563ffffffff1660e01b81526004016116b894939291906157ac565b600060405180830381600087803b1580156116d257600080fd5b505af11580156116e6573d6000803e3d6000fd5b50505050505050611a05565b60ff81166017141561178657600060608089898681811061170f57fe5b90506020028101906117219190615e7e565b81019061172e9190615198565b9250925092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630fca8843843385856040518563ffffffff1660e01b81526004016116b8949392919061580a565b60ff8116601e141561186057606060006118088b8b868181106117a557fe5b905060200201358a8a878181106117b857fe5b90506020028101906117ca9190615e7e565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b91506142ab9050565b915091508060ff1660011415611833578180602001905181019061182c919061541a565b9650611859565b8060ff166002141561185957818060200190518101906118539190615432565b90975095505b5050611a05565b60ff81166006141561198857600087878481811061187a57fe5b905060200281019061188c9190615e7e565b8101906118999190615343565b6008549091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169163da5139ca91166119106118e0858b8b613f91565b60408051808201909152600d546001600160801b038082168352600160801b909104166020820152906001614461565b60016040518463ffffffff1660e01b8152600401611930939291906158d0565b60206040518083038186803b15801561194857600080fd5b505afa15801561195c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611980919061541a565b955050611a05565b60ff811660071415611a055760008787848181106119a257fe5b90506020028101906119b49190615e7e565b8101906119c19190615343565b9050611a016119d1828888613f91565b60408051808201909152600d546001600160801b038082168352600160801b9091041660208201529060006144fa565b9550505b5060010161111c565b50805115611a4057611a24336000601054613e16565b611a405760405162461bcd60e51b81526004016109f390615bac565b50965096945050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006020819052908152604090205481565b600a805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015611b085780601f10611add57610100808354040283529160200191611b08565b820191906000526020600020905b815481529060010190602001808311611aeb57829003601f168201915b505050505081565b6000611b1a610814565b915050611b25612be2565b6000806000611b32614b1b565b5060408051808201909152600d546001600160801b038082168352600160801b909104166020820152611b63614b1b565b600754604051634ffe34db60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692634ffe34db92611bb6929190911690600401615613565b604080518083038186803b158015611bcd57600080fd5b505afa158015611be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0591906153d8565b905060005b8c811015611e2c5760008e8e83818110611c2057fe5b9050602002016020810190611c359190614c6f565b9050611c42818a8a613e16565b611e23576001600160a01b0381166000908152600f6020526040812054808f8f86818110611c6c57fe5b9050602002013511611c90578e8e85818110611c8457fe5b90506020020135611c92565b805b9150611c9e8183614573565b6001600160a01b0384166000908152600f60205260408120919091559050611cc7868383614461565b90506000611d0269152d02c7e14af6800000611cf08d611cea866201b580614596565b90614596565b81611cf757fe5b8891900460006144fa565b6001600160a01b0385166000908152600e6020526040902054909150611d289082614573565b6001600160a01b038086166000908152600e60205260409020919091558d1615611d52578c611d54565b8d5b6001600160a01b0316846001600160a01b03167f8ad4d3ff00da092c7ad9a573ea4f5f6a3dffc6712dc06d3f78f49b862297c40283604051611d96919061567b565b60405180910390a36001600160a01b03808516908e1615611db7578d611db9565b335b6001600160a01b03167fc8e512d8f188ca059984b5853d2bf653da902696b8512785b182b2c813789a6e8486604051611df3929190615e1f565b60405180910390a3611e058a82613b05565b9950611e118983613b05565b9850611e1d8884613b05565b97505050505b50600101611c0a565b5083611e4a5760405162461bcd60e51b81526004016109f3906159bd565b611e67611e56856145cd565b83516001600160801b0316906145fa565b6001600160801b03168252611e92611e7e846145cd565b60208401516001600160801b0316906145fa565b6001600160801b03908116602084018190528351600d80546001600160801b03191691841691909117909216600160801b909102179055600b54611ed69086614573565b600b55600854604051636d289ce560e11b81526000916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263da5139ca92611f3192169089906001906004016158d0565b60206040518083038186803b158015611f4957600080fd5b505afa158015611f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f81919061541a565b90508761241657604051634656bfdf60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638cad7fbe90611fd4908c90600401615613565b60206040518083038186803b158015611fec57600080fd5b505afa158015612000573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120249190615067565b6120405760405162461bcd60e51b81526004016109f390615d29565b600754604051633c6340f360e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263f18d03cc9261209992919091169030908e908c906004016157ac565b600060405180830381600087803b1580156120b357600080fd5b505af11580156120c7573d6000803e3d6000fd5b50506007546008546040516371a1ff0960e11b81526001600160a01b03808f16955063e343fe129450612107938116921690309087908d906004016157d6565b6040805180830381600087803b15801561212057600080fd5b505af1158015612134573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121589190615432565b5050600c54600854604051633de222bb60e21b815260009261221b926001600160801b03909116916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263f7888aec926121c59291909116903090600401615792565b60206040518083038186803b1580156121dd57600080fd5b505afa1580156121f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612215919061541a565b90614573565b905060006122298284614573565b90506000620186a061223d83612710614596565b8161224457fe5b0490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f18d03cc600860009054906101000a90046001600160a01b0316307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b1580156122e657600080fd5b505afa1580156122fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231e9190614c8b565b856040518563ffffffff1660e01b815260040161233e94939291906157ac565b600060405180830381600087803b15801561235857600080fd5b505af115801561236c573d6000803e3d6000fd5b505050506123a061238e612389838661457390919063ffffffff16565b6145cd565b600c546001600160801b031690614629565b600c80546001600160801b0319166001600160801b0392909216919091179055306001600160a01b038d167f30a8c4f9ab5af7e1309ca87c32377d1a83366c5990472dbf9d262450eae14e386123f68585614573565b6000604051612406929190615e1f565b60405180910390a350505061260a565b6007546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169163f18d03cc919081169030908d161561245e578c612460565b8d5b8a6040518563ffffffff1660e01b815260040161248094939291906157ac565b600060405180830381600087803b15801561249a57600080fd5b505af11580156124ae573d6000803e3d6000fd5b505050506001600160a01b03891615612552576007546008546040516371a1ff0960e11b81526001600160a01b03808d169363e343fe12936124fe93918316921690339087908d906004016157d6565b6040805180830381600087803b15801561251757600080fd5b505af115801561252b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254f9190615432565b50505b600854604051633c6340f360e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263f18d03cc926125ab9291909116903390309087906004016157ac565b600060405180830381600087803b1580156125c557600080fd5b505af11580156125d9573d6000803e3d6000fd5b505050506125e961238e826145cd565b600c80546001600160801b0319166001600160801b03929092169190911790555b5050505050505050505050505050565b6009546001600160a01b031681565b60026020526000908152604090205481565b600d546001600160801b0380821691600160801b90041682565b6001600160a01b0383166000908152600e60205260409020546126789082613b05565b6001600160a01b0384166000908152600e6020526040902055600b5461269e8183613b05565b600b556007546126b9906001600160a01b0316838386614658565b836001600160a01b0316836126ce57336126f0565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b03167f9ed03113de523cebfe5e49d5f8e12894b1c0d42ce805990461726444c90eab8784604051612728919061567b565b60405180910390a350505050565b61273e612be2565b6127488282613fb9565b612756336000601054613e16565b6127725760405162461bcd60e51b81526004016109f390615bac565b5050565b60066020526000908152604090205460ff1681565b6003546001600160a01b031681565b6007546060906127b2906001600160a01b031661475f565b6008546127c7906001600160a01b031661475f565b60095460405163634ce26b60e11b81526001600160a01b039091169063c699c4d6906127f890600a90600401615708565b60006040518083038186803b15801561281057600080fd5b505afa158015612824573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261284c91908101906153a5565b6040516020016109b5939291906155a6565b600081156128f85733600090815260208190526040902054828110156128965760405162461bcd60e51b81526004016109f390615cbb565b336001600160a01b038516146128f6576001600160a01b0384166128cc5760405162461bcd60e51b81526004016109f390615986565b3360009081526020819052604080822085840390556001600160a01b038616825290208054840190555b505b826001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610b12919061567b565b60115467ffffffffffffffff8082169168010000000000000000810490911690600160801b90046001600160801b031683565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001600160a01b0387166129b85760405162461bcd60e51b81526004016109f390615c4d565b8342106129d75760405162461bcd60e51b81526004016109f390615b75565b6001600160a01b0387166000818152600260209081526040918290208054600181810190925592519092612a5592612a3a927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e92918e9101615684565b604051602081830303815290604052805190602001206147a6565b85858560405160008152602001604052604051612a7594939291906156d7565b6020604051602081039080840390855afa158015612a97573d6000803e3d6000fd5b505050602060405103516001600160a01b031614612ac75760405162461bcd60e51b81526004016109f390615dce565b6001600160a01b038088166000818152600160209081526040808320948b168084529490915290819020889055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590612b2290899061567b565b60405180910390a350505050505050565b6007546001600160a01b031681565b600160209081526000928352604080842090915290825290205481565b6004546001600160a01b031681565b6003546001600160a01b03163314612b985760405162461bcd60e51b81526004016109f390615be3565b600580546001600160a01b0319166001600160a01b0383169081179091556040517fcf1d3f17e521c635e0d20b8acba94ba170afc041d0546d46dafa09d3c9c19eb390600090a250565b612bea614b32565b506040805160608101825260115467ffffffffffffffff80821683526801000000000000000082041660208301819052600160801b9091046001600160801b03169282019290925290420380612c415750506131c5565b67ffffffffffffffff42166020830152612c59614b1b565b5060408051808201909152600d546001600160801b038082168352600160801b9091041660208201819052612d5757825167ffffffffffffffff166312e687c014612ce4576312e687c08084526040517f33af5ce86e8438eff54589f85332916444457dfa8685493fbd579b809097026b91612cdb91600091829182906158f3565b60405180910390a15b5050805160118054602084015160409094015167ffffffffffffffff1990911667ffffffffffffffff938416176fffffffffffffffff00000000000000001916680100000000000000009390941692909202929092176001600160801b03908116600160801b91909216021790556131c5565b600080612d62614b1b565b5060408051808201909152600c546001600160801b038082168352600160801b9091048116602083015286518551670de0b6b3a764000092612db5928992611cea92169067ffffffffffffffff16614596565b81612dbc57fe5b049250612ddc612dcb846145cd565b85516001600160801b031690614629565b6001600160801b03168085526008548251604051630acc462360e31b8152600093612e9d9390926001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811693635662311893612e47939216919088906004016158a4565b60206040518083038186803b158015612e5f57600080fd5b505afa158015612e73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e97919061541a565b90613b05565b90506000620186a0612eb186612710614596565b81612eb857fe5b04905081612edc84602001516001600160801b03168361459690919063ffffffff16565b81612ee357fe5b049350612f06612ef2856145cd565b60408a01516001600160801b031690614629565b6001600160801b03166040890152612f34612f20856145cd565b60208501516001600160801b031690614629565b600c80546001600160801b03908116600160801b9382168402179091558751600d805460208b01516001600160801b031990911692841692831784169316909302919091179091556000908390612f9390670de0b6b3a7640000614596565b81612f9a57fe5b0490506709b6e64a8ec6000081101561305e5760006709b6e64a8ec60000612fce670de0b6b3a7640000611cea8386614573565b81612fd557fe5b0490506000613003612feb8b611cea8580614596565b7054a2b63d65d79d094abb6688000000000090613b05565b8b51909150819061302f9067ffffffffffffffff167054a2b63d65d79d094abb66880000000000614596565b8161303657fe5b0467ffffffffffffffff16808c526304b9a1f01115613057576304b9a1f08b525b5050613111565b670b1a2bc2ec5000008111156131115760006702c68af0bb140000613097670de0b6b3a7640000611cea85670b1a2bc2ec500000614573565b8161309e57fe5b04905060006130b4612feb8b611cea8580614596565b8b519091506000907054a2b63d65d79d094abb66880000000000906130e39067ffffffffffffffff1684614596565b816130ea57fe5b0490506449d482460081111561310257506449d48246005b67ffffffffffffffff168b5250505b88516040517f33af5ce86e8438eff54589f85332916444457dfa8685493fbd579b809097026b91613147918991899186906158f3565b60405180910390a1505086516011805460208a01516040909a015167ffffffffffffffff1990911667ffffffffffffffff938416176fffffffffffffffff000000000000000019166801000000000000000093909a1692909202989098176001600160801b03908116600160801b9190921602179096555050505050505b565b600c546001600160801b0380821691600160801b90041682565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b179052905160609160009183916001600160a01b0386169161322891906154b9565b600060405180830381855afa9150503d8060008114613263576040519150601f19603f3d011682016040523d82523d6000602084013e613268565b606091505b50915091508161329357604051806040016040528060038152602001623f3f3f60e81b81525061329c565b61329c816147de565b925050505b919050565b60408051808201909152600d546001600160801b038082168352600160801b9091041660208201526000906132dd9083600161498c565b8151600d80546020948501516001600160801b03908116600160801b029381166001600160801b031990921691909117169190911790556001600160a01b0386166000908152600f90925260409091205490915061333b9083614573565b6001600160a01b038086166000908152600f6020526040808220939093556008549251636d289ce560e11b815290927f000000000000000000000000000000000000000000000000000000000000000083169263da5139ca926133a9929091169086906001906004016158d0565b60206040518083038186803b1580156133c157600080fd5b505afa1580156133d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f9919061541a565b600c546008549192506001600160801b031690613421906001600160a01b0316838388614658565b61343d61342d836145cd565b6001600160801b03831690614629565b600c80546001600160801b0319166001600160801b03929092169190911790556001600160a01b038616856134725733613494565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b03167fc8e512d8f188ca059984b5853d2bf653da902696b8512785b182b2c813789a6e85876040516134ce929190615e1f565b60405180910390a350509392505050565b60006134e9614b1b565b50604080518082018252600c546001600160801b03808216808452600160801b90920481166020840152600854600d549451636d289ce560e11b8152939492936000936001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169463da5139ca946135729492169216906001906004016158a4565b60206040518083038186803b15801561358a57600080fd5b505afa15801561359e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c2919061541a565b83516001600160801b0316019050801561360457806135f784602001516001600160801b03168761459690919063ffffffff16565b816135fe57fe5b04613606565b845b93506103e861362b613617866145cd565b60208601516001600160801b031690614629565b6001600160801b031610156136465760009350505050610b92565b613651838686614a01565b8051600c80546020938401516001600160801b03908116600160801b029381166001600160801b031990921691909117169190911790556001600160a01b03881660009081529081905260409020546136aa9085613b05565b6001600160a01b038089166000908152602081905260409020919091556008546136d79116868489614658565b866001600160a01b0316866136ec573361370e565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b03167f30a8c4f9ab5af7e1309ca87c32377d1a83366c5990472dbf9d262450eae14e388787604051613748929190615e1f565b60405180910390a35050509392505050565b6000613764614b1b565b50604080518082018252600c546001600160801b038082168352600160801b90910481166020830152600854600d549351636d289ce560e11b815292936000936001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169463da5139ca946137eb949216929116906001906004016158a4565b60206040518083038186803b15801561380357600080fd5b505afa158015613817573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061383b919061541a565b825160208401516001600160801b039182169290920192501661385e8583614596565b8161386557fe5b3360009081526020819052604090205491900493506138849085614573565b336000908152602081905260409020556138a0611e56846145cd565b6001600160801b031682526138b7611e7e856145cd565b6001600160801b0316602083018190526103e811156138e85760405162461bcd60e51b81526004016109f390615c84565b8151600c805460208501516001600160801b03908116600160801b029381166001600160801b031990921691909117169190911790556040516001600160a01b0386169033907f6e853a5fd6b51d773691f542ebac8513c9992a51380d4c342031056a641142289061395d9087908990615e1f565b60405180910390a3600854604051633c6340f360e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263f18d03cc926139be92919091169030908a9089906004016157ac565b600060405180830381600087803b1580156139d857600080fd5b505af11580156139ec573d6000803e3d6000fd5b50505050505092915050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b179052905160009182916060916001600160a01b03861691613a3f91906154b9565b600060405180830381855afa9150503d8060008114613a7a576040519150601f19603f3d011682016040523d82523d6000602084013e613a7f565b606091505b5091509150818015613a92575080516020145b613a9d57601261329c565b8080602001905181019061329c9190615471565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692188230604051602001613ae8939291906156b8565b604051602081830303815290604052805190602001209050919050565b81810181811015610b1e5760405162461bcd60e51b81526004016109f390615a99565b60008080620186a0613b3b856032614596565b81613b4257fe5b049050613b82613b528583613b05565b60408051808201909152600d546001600160801b038082168352600160801b909104166020820152906001614a42565b8151600d80546020948501516001600160801b03908116600160801b029381166001600160801b03199092169190911716919091179055336000908152600f909252604090912054909350613bd79084613b05565b336000818152600f6020526040908190209290925590516001600160a01b03871691907f3a5151e57d3bc9798e7853034ac52293d1a0e12a2b44725e75b03b21f86477a690613c2b90889086908990615e2d565b60405180910390a3600854604051636d289ce560e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263da5139ca92613c8b92919091169088906000906004016158d0565b60206040518083038186803b158015613ca357600080fd5b505afa158015613cb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cdb919061541a565b9150613ce5614b1b565b5060408051808201909152600c546001600160801b038082168352600160801b90910416602082018190526103e81115613d315760405162461bcd60e51b81526004016109f390615c84565b613d4e613d3d846145cd565b82516001600160801b0316906145fa565b6001600160801b03908116808352600c805460208501518416600160801b026001600160801b0319909116909217909216179055600854604051633c6340f360e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263f18d03cc92613ddb92919091169030908b9089906004016157ac565b600060405180830381600087803b158015613df557600080fd5b505af1158015613e09573d6000803e3d6000fd5b5050505050509250929050565b6001600160a01b0383166000908152600f602052604081205480613e3e576001915050610b92565b6001600160a01b0385166000908152600e602052604090205480613e6757600092505050610b92565b613e6f614b1b565b5060408051808201909152600d546001600160801b03808216808452600160801b909204166020830181905290613ead908790611cea908790614596565b81613eb457fe5b600754919004906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169163566231189116613f148a613eff57620124f8613f04565b62012cc85b611cea886509184e72a000614596565b60006040518463ffffffff1660e01b8152600401613f34939291906158d0565b60206040518083038186803b158015613f4c57600080fd5b505afa158015613f60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f84919061541a565b1015979650505050505050565b600080841215613fb1576000198414613faa5781613fac565b825b610b39565b509192915050565b336000908152600e6020526040902054613fd39082614573565b336000908152600e6020526040902055600b54613ff09082614573565b600b556040516001600160a01b0383169033907f8ad4d3ff00da092c7ad9a573ea4f5f6a3dffc6712dc06d3f78f49b862297c4029061403090859061567b565b60405180910390a3600754604051633c6340f360e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263f18d03cc926140919291909116903090879087906004016157ac565b600060405180830381600087803b1580156140ab57600080fd5b505af11580156140bf573d6000803e3d6000fd5b505050505050565b600080600080600080898060200190518101906140e49190615151565b93509350935093506140f7828989613f91565b9150614104818989613f91565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166302b9446c8a86338787876040518763ffffffff1660e01b815260040161415b9594939291906157d6565b60408051808303818588803b15801561417357600080fd5b505af1158015614187573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906141ac9190615432565b955095505050505094509492505050565b600080600080600080888060200190518101906141da9190615151565b93509350935093507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166397da6d3085338661421f878e8e613f91565b61422a878f8f613f91565b6040518663ffffffff1660e01b815260040161424a9594939291906157d6565b6040805180830381600087803b15801561426357600080fd5b505af1158015614277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061429b9190615432565b9550955050505050935093915050565b606060008060606000806000898060200190518101906142cb9190614d14565b945094509450945094508280156142e0575081155b1561430e5783896040516020016142f89291906154d5565b6040516020818303038152906040529350614367565b821580156143195750815b156143315783886040516020016142f89291906154d5565b82801561433b5750815b1561436757838989604051602001614355939291906154f7565b60405160208183030381529060405293505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316141580156143b257506001600160a01b0385163014155b6143ce5760405162461bcd60e51b81526004016109f390615b3e565b60006060866001600160a01b03168d876040516143eb91906154b9565b60006040518083038185875af1925050503d8060008114614428576040519150601f19603f3d011682016040523d82523d6000602084013e61442d565b606091505b50915091508161444f5760405162461bcd60e51b81526004016109f390615a2b565b9c919b50909950505050505050505050565b600083602001516001600160801b031660001415614480575081610b92565b602084015184516001600160801b039182169161449f91869116614596565b816144a657fe5b0490508180156144ea57508284600001516001600160801b03166144e086602001516001600160801b03168461459690919063ffffffff16565b816144e757fe5b04105b15610b9257610b39816001613b05565b82516000906001600160801b0316614513575081610b92565b835160208501516001600160801b039182169161453291869116614596565b8161453957fe5b0490508180156144ea57508284602001516001600160801b03166144e086600001516001600160801b03168461459690919063ffffffff16565b80820382811115610b1e5760405162461bcd60e51b81526004016109f390615918565b60008115806145b1575050808202828282816145ae57fe5b04145b610b1e5760405162461bcd60e51b81526004016109f390615d60565b60006001600160801b038211156145f65760405162461bcd60e51b81526004016109f390615a62565b5090565b8082036001600160801b038084169082161115610b1e5760405162461bcd60e51b81526004016109f390615918565b8181016001600160801b038083169082161015610b1e5760405162461bcd60e51b81526004016109f390615a99565b80156146d4576146b0827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f7888aec87306040518363ffffffff1660e01b81526004016121c5929190615792565b8311156146cf5760405162461bcd60e51b81526004016109f390615cf2565b614759565b604051633c6340f360e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f18d03cc906147269087903390309089906004016157ac565b600060405180830381600087803b15801561474057600080fd5b505af1158015614754573d6000803e3d6000fd5b505050505b50505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b179052905160609160009183916001600160a01b0386169161322891906154b9565b600060405180604001604052806002815260200161190160f01b8152506147cb610d30565b83604051602001613ae8939291906154f7565b6060604082511061480457818060200190518101906147fd91906153a5565b90506132a1565b81516020141561496c5760005b60208160ff161080156148585750828160ff168151811061482e57fe5b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1561486557600101614811565b60608160ff1667ffffffffffffffff8111801561488157600080fd5b506040519080825280601f01601f1916602001820160405280156148ac576020820181803683370190505b509050600091505b60208260ff161080156148fb5750838260ff16815181106148d157fe5b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1561496357838260ff168151811061490f57fe5b602001015160f81c60f81b818360ff168151811061492957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001909101906148b4565b91506132a19050565b506040805180820190915260038152623f3f3f60e81b60208201526132a1565b614994614b1b565b60006149a1858585614461565b90506149c06149af826145cd565b86516001600160801b0316906145fa565b6001600160801b031685526149eb6149d7856145cd565b60208701516001600160801b0316906145fa565b6001600160801b03166020860152939492505050565b614a09614b1b565b614a15612dcb846145cd565b6001600160801b03168452614a2c613617836145cd565b6001600160801b03166020850152509192915050565b614a4a614b1b565b6000614a578585856144fa565b9050614a76614a65856145cd565b86516001600160801b031690614629565b6001600160801b031685526149eb614a8d826145cd565b60208701516001600160801b031690614629565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614ae257805160ff1916838001178555614b0f565b82800160010185558215614b0f579182015b82811115614b0f578251825591602001919060010190614af4565b506145f6929150614b52565b604080518082019091526000808252602082015290565b604080516060810182526000808252602082018190529181019190915290565b5b808211156145f65760008155600101614b53565b8035610b1e81615f66565b60008083601f840112614b83578182fd5b50813567ffffffffffffffff811115614b9a578182fd5b6020830191508360208083028501011115610f9657600080fd5b600082601f830112614bc4578081fd5b8135614bd7614bd282615eea565b615ec3565b818152915060208083019084810181840286018201871015614bf857600080fd5b60005b84811015614c1757813584529282019290820190600101614bfb565b505050505092915050565b600082601f830112614c32578081fd5b8151614c40614bd282615f0a565b9150808252836020828501011115614c5757600080fd5b614c68816020840160208601615f3a565b5092915050565b600060208284031215614c80578081fd5b8135610b9281615f66565b600060208284031215614c9c578081fd5b8151610b9281615f66565b60008060008060008060c08789031215614cbf578182fd5b8635614cca81615f66565b95506020870135614cda81615f66565b94506040870135614cea81615f7e565b93506060870135614cfa81615fa1565b9598949750929560808101359460a0909101359350915050565b600080600080600060a08688031215614d2b578283fd5b8551614d3681615f66565b602087015190955067ffffffffffffffff811115614d52578384fd5b614d5e88828901614c22565b9450506040860151614d6f81615f7e565b6060870151909350614d8081615f7e565b6080870151909250614d9181615fa1565b809150509295509295909350565b60008060408385031215614db1578182fd5b8235614dbc81615f66565b91506020830135614dcc81615f66565b809150509250929050565b600080600060608486031215614deb578081fd5b8335614df681615f66565b92506020840135614e0681615f66565b929592945050506040919091013590565b600080600080600080600060e0888a031215614e31578485fd5b8735614e3c81615f66565b96506020880135614e4c81615f66565b955060408801359450606088013593506080880135614e6a81615fa1565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215614e9b578081fd5b8335614ea681615f66565b92506020840135614eb681615f7e565b91506040840135614ec681615f7e565b809150509250925092565b600080600060608486031215614ee5578081fd5b8335614ef081615f66565b92506020840135614e0681615f7e565b60008060408385031215614f12578182fd5b8235614f1d81615f66565b946020939093013593505050565b600080600080600080600060a0888a031215614f45578081fd5b873567ffffffffffffffff80821115614f5c578283fd5b614f688b838c01614b72565b909950975060208a0135915080821115614f80578283fd5b50614f8d8a828b01614b72565b9096509450506040880135614fa181615f66565b92506060880135614fb181615f66565b91506080880135614fc181615f7e565b8091505092959891949750929550565b60008060008060008060608789031215614fe9578384fd5b863567ffffffffffffffff80821115615000578586fd5b61500c8a838b01614b72565b90985096506020890135915080821115615024578586fd5b6150308a838b01614b72565b90965094506040890135915080821115615048578384fd5b5061505589828a01614b72565b979a9699509497509295939492505050565b600060208284031215615078578081fd5b8151610b9281615f7e565b60008060408385031215615095578182fd5b82516150a081615f7e565b6020939093015192949293505050565b6000806000606084860312156150c4578081fd5b83356150cf81615f7e565b95602085013595506040909401359392505050565b600080602083850312156150f6578182fd5b823567ffffffffffffffff8082111561510d578384fd5b818501915085601f830112615120578384fd5b81358181111561512e578485fd5b86602082850101111561513f578485fd5b60209290920196919550909350505050565b60008060008060808587031215615166578182fd5b845161517181615f66565b602086015190945061518281615f66565b6040860151606090960151949790965092505050565b6000806000606084860312156151ac578081fd5b83356151b781615f66565b925060208481013567ffffffffffffffff808211156151d4578384fd5b818701915087601f8301126151e7578384fd5b81356151f5614bd282615eea565b81815284810190848601868402860187018c1015615211578788fd5b8795505b8386101561523b576152278c82614b67565b835260019590950194918601918601615215565b50965050506040870135925080831115615253578384fd5b505061526186828701614bb4565b9150509250925092565b60008060008060808587031215615280578182fd5b843561528b81615f66565b9350602085013561529b81615f66565b925060408501356152ab81615f66565b9150606085013567ffffffffffffffff8111156152c6578182fd5b8501601f810187136152d6578182fd5b80356152e4614bd282615f0a565b8181528860208385010111156152f8578384fd5b81602084016020830137908101602001929092525092959194509250565b60008060408385031215615328578182fd5b823561533381615f66565b91506020830135614dcc81615f7e565b600060208284031215615354578081fd5b5035919050565b6000806040838503121561536d578182fd5b823591506020830135614dcc81615f66565b600080600060608486031215615393578081fd5b833592506020840135614eb681615f66565b6000602082840312156153b6578081fd5b815167ffffffffffffffff8111156153cc578182fd5b610b3984828501614c22565b6000604082840312156153e9578081fd5b6153f36040615ec3565b82516153fe81615f8c565b8152602083015161540e81615f8c565b60208201529392505050565b60006020828403121561542b578081fd5b5051919050565b60008060408385031215615444578182fd5b505080516020909101519092909150565b600060208284031215615466578081fd5b8135610b9281615fa1565b600060208284031215615482578081fd5b8151610b9281615fa1565b600081518084526154a5816020860160208601615f3a565b601f01601f19169290920160200192915050565b600082516154cb818460208701615f3a565b9190910192915050565b600083516154e7818460208801615f3a565b9190910191825250602001919050565b60008451615509818460208901615f3a565b91909101928352506020820152604001919050565b60007f4b61736869204d656469756d205269736b20000000000000000000000000000082528451615556816012850160208901615f3a565b602f60f81b6012918401918201528451615577816013840160208901615f3a565b602d60f81b601392909101918201528351615599816014840160208801615f3a565b0160140195945050505050565b6000616b6d60f01b825284516155c3816002850160208901615f3a565b602f60f81b60029184019182015284516155e4816003840160208901615f3a565b602d60f81b600392909101918201528351615606816004840160208801615f3a565b0160040195945050505050565b6001600160a01b0391909116815260200190565b6001600160a01b039687168152949095166020850152911515604084015260ff166060830152608082015260a081019190915260c00190565b901515815260200190565b9115158252602082015260400190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b92835260208301919091526001600160a01b0316604082015260600190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610b92602083018461548d565b6000602080830181845282855460018082166000811461572f576001811461574d57615785565b60028304607f16855260ff1983166040890152606088019350615785565b6002830480865261575d8a615f2e565b885b8281101561577b5781548b82016040015290840190880161575f565b8a01604001955050505b5091979650505050505050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b03958616815293851660208501529190931660408301526060820192909252608081019190915260a00190565b6000608082016001600160a01b0380881684526020818816818601526080604086015282875180855260a0870191508289019450855b8181101561585e578551851683529483019491830191600101615840565b50508581036060870152865180825290820193509150808601845b8381101561589557815185529382019390820190600101615879565b50929998505050505050505050565b6001600160a01b039390931683526001600160801b039190911660208301521515604082015260600190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b938452602084019290925267ffffffffffffffff166040830152606082015260800190565b60208082526015908201527f426f72696e674d6174683a20556e646572666c6f770000000000000000000000604082015260600190565b6020808252601e908201527f4b61736869506169723a20616c726561647920696e697469616c697a65640000604082015260600190565b60208082526016908201527f45524332303a206e6f207a65726f206164647265737300000000000000000000604082015260600190565b6020808252601a908201527f4b61736869506169723a20616c6c2061726520736f6c76656e74000000000000604082015260600190565b60208082526015908201527f4f776e61626c653a207a65726f20616464726573730000000000000000000000604082015260600190565b60208082526016908201527f4b61736869506169723a2063616c6c206661696c656400000000000000000000604082015260600190565b6020808252601c908201527f426f72696e674d6174683a2075696e74313238204f766572666c6f7700000000604082015260600190565b60208082526018908201527f426f72696e674d6174683a20416464204f766572666c6f770000000000000000604082015260600190565b60208082526013908201527f4b61736869506169723a20626164207061697200000000000000000000000000604082015260600190565b60208082526018908201527f45524332303a20616c6c6f77616e636520746f6f206c6f770000000000000000604082015260600190565b60208082526015908201527f4b61736869506169723a2063616e27742063616c6c0000000000000000000000604082015260600190565b6020808252600e908201527f45524332303a2045787069726564000000000000000000000000000000000000604082015260600190565b60208082526019908201527f4b61736869506169723a207573657220696e736f6c76656e7400000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c657220213d2070656e64696e67206f776e6572604082015260600190565b60208082526018908201527f45524332303a204f776e65722063616e6e6f7420626520300000000000000000604082015260600190565b60208082526014908201527f4b617368693a2062656c6f77206d696e696d756d000000000000000000000000604082015260600190565b60208082526016908201527f45524332303a2062616c616e636520746f6f206c6f7700000000000000000000604082015260600190565b60208082526018908201527f4b61736869506169723a20536b696d20746f6f206d7563680000000000000000604082015260600190565b6020808252601a908201527f4b61736869506169723a20496e76616c69642073776170706572000000000000604082015260600190565b60208082526018908201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604082015260600190565b60208082526016908201527f4b61736869506169723a2072617465206e6f74206f6b00000000000000000000604082015260600190565b60208082526018908201527f45524332303a20496e76616c6964205369676e61747572650000000000000000604082015260600190565b6001600160801b0392831681529116602082015260400190565b918252602082015260400190565b9283526020830191909152604082015260600190565b67ffffffffffffffff93841681529190921660208201526001600160801b03909116604082015260600190565b60ff91909116815260200190565b6000808335601e19843603018112615e94578283fd5b83018035915067ffffffffffffffff821115615eae578283fd5b602001915036819003821315610f9657600080fd5b60405181810167ffffffffffffffff81118282101715615ee257600080fd5b604052919050565b600067ffffffffffffffff821115615f00578081fd5b5060209081020190565b600067ffffffffffffffff821115615f20578081fd5b50601f01601f191660200190565b60009081526020902090565b60005b83811015615f55578181015183820152602001615f3d565b838111156147595750506000910152565b6001600160a01b0381168114615f7b57600080fd5b50565b8015158114615f7b57600080fd5b6001600160801b0381168114615f7b57600080fd5b60ff81168114615f7b57600080fdfea264697066735822122043def0759137241cf8df2e558f293223dcafcd6c3de768f29848ee9f923dc5a964736f6c634300060c0033000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd643966
Deployed Bytecode
0x6080604052600436106102f25760003560e01c8063656f3d641161018f5780638da5cb5b116100e1578063d8dfeb451161008a578063f46901ed11610064578063f46901ed146107bb578063f8ba4cff146107db578063f9557ccb146107f0576102f2565b8063d8dfeb4514610771578063dd62ed3e14610786578063e30c3978146107a6576102f2565b8063b27c0e74116100bb578063b27c0e7414610718578063cd446e221461073c578063d505accf14610751576102f2565b80638da5cb5b146106ce57806395d89b41146106e3578063a9059cbb146106f8576102f2565b80637dc0d1d011610143578063860ffea11161011d578063860ffea11461066e578063876467f81461068e5780638cad7fbe146106ae576102f2565b80637dc0d1d0146106165780637ecebe001461062b5780638285ef401461064b576102f2565b806370a082311161017457806370a08231146105c157806374645ff3146105e157806376ee101b146105f6576102f2565b8063656f3d64146105995780636b2ace87146105ac576102f2565b8063313ce56711610248578063473e3ce7116101fc5780634b8a3529116101d65780634b8a3529146105435780634ddf47d4146105715780634e71e0c814610584576102f2565b8063473e3ce7146104f9578063476343ee1461050e57806348e4163e14610523576102f2565b806338d52e0f1161022d57806338d52e0f146104af5780633ba0b9a9146104c45780633f2617cb146104d9576102f2565b8063313ce567146104785780633644e5151461049a576102f2565b806315294c40116102aa5780631c9e379b116102845780631c9e379b146104185780632317ef671461043857806323b872dd14610458576102f2565b806315294c40146103b657806318160ddd146103e35780631b51e940146103f8576102f2565b806306fdde03116102db57806306fdde0314610345578063078dfbe714610367578063095ea7b314610389576102f2565b8063017e7e58146102f757806302ce728f14610322575b600080fd5b34801561030357600080fd5b5061030c610805565b6040516103199190615613565b60405180910390f35b34801561032e57600080fd5b50610337610814565b60405161031992919061566b565b34801561035157600080fd5b5061035a6108f1565b60405161031991906156f5565b34801561037357600080fd5b50610387610382366004614e87565b6109c9565b005b34801561039557600080fd5b506103a96103a4366004614f00565b610ab9565b6040516103199190615660565b3480156103c257600080fd5b506103d66103d1366004614ed1565b610b24565b604051610319919061567b565b3480156103ef57600080fd5b506103d6610b41565b34801561040457600080fd5b506103d6610413366004614ed1565b610b57565b34801561042457600080fd5b506103d6610433366004614c6f565b610b6c565b34801561044457600080fd5b506103d6610453366004614f00565b610b7e565b34801561046457600080fd5b506103a9610473366004614dd7565b610b99565b34801561048457600080fd5b5061048d610d13565b6040516103199190615e70565b3480156104a657600080fd5b506103d6610d30565b3480156104bb57600080fd5b5061030c610d90565b3480156104d057600080fd5b506103d6610d9f565b3480156104e557600080fd5b506103876104f4366004615316565b610da5565b34801561050557600080fd5b506103d6610dfa565b34801561051a57600080fd5b50610387610e00565b34801561052f57600080fd5b506103d661053e366004614c6f565b610f3d565b34801561054f57600080fd5b5061056361055e366004614f00565b610f4f565b604051610319929190615e1f565b61038761057f3660046150e4565b610f9d565b34801561059057600080fd5b50610387611080565b6105636105a7366004614fd1565b61110e565b3480156105b857600080fd5b5061030c611a4c565b3480156105cd57600080fd5b506103d66105dc366004614c6f565b611a70565b3480156105ed57600080fd5b5061035a611a82565b34801561060257600080fd5b50610387610611366004614f2b565b611b10565b34801561062257600080fd5b5061030c61261a565b34801561063757600080fd5b506103d6610646366004614c6f565b612629565b34801561065757600080fd5b5061066061263b565b604051610319929190615e05565b34801561067a57600080fd5b50610387610689366004614ed1565b612655565b34801561069a57600080fd5b506103876106a9366004614f00565b612736565b3480156106ba57600080fd5b506103a96106c9366004614c6f565b612776565b3480156106da57600080fd5b5061030c61278b565b3480156106ef57600080fd5b5061035a61279a565b34801561070457600080fd5b506103a9610713366004614f00565b61285e565b34801561072457600080fd5b5061072d61293b565b60405161031993929190615e43565b34801561074857600080fd5b5061030c61296e565b34801561075d57600080fd5b5061038761076c366004614e17565b612992565b34801561077d57600080fd5b5061030c612b33565b34801561079257600080fd5b506103d66107a1366004614d9f565b612b42565b3480156107b257600080fd5b5061030c612b5f565b3480156107c757600080fd5b506103876107d6366004614c6f565b612b6e565b3480156107e757600080fd5b50610387612be2565b3480156107fc57600080fd5b506106606131c7565b6005546001600160a01b031681565b60095460405163d6d7d52560e01b815260009182916001600160a01b039091169063d6d7d5259061084a90600a90600401615708565b6040805180830381600087803b15801561086357600080fd5b505af1158015610877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089b9190615083565b909250905081156108e85760108190556040517f9f9192b5edb17356c524e08d9e025c8e2f6307e6ea52fb7968faa3081f51c3c8906108db90839061567b565b60405180910390a16108ed565b506010545b9091565b600754606090610909906001600160a01b03166131e1565b60085461091e906001600160a01b03166131e1565b60095460405163355a219b60e21b81526001600160a01b039091169063d568866c9061094f90600a90600401615708565b60006040518083038186803b15801561096757600080fd5b505afa15801561097b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109a391908101906153a5565b6040516020016109b59392919061551e565b604051602081830303815290604052905090565b6003546001600160a01b031633146109fc5760405162461bcd60e51b81526004016109f390615be3565b60405180910390fd5b8115610a98576001600160a01b038316151580610a165750805b610a325760405162461bcd60e51b81526004016109f3906159f4565b6003546040516001600160a01b038086169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600380546001600160a01b0385166001600160a01b031991821617909155600480549091169055610ab4565b600480546001600160a01b0319166001600160a01b0385161790555b505050565b3360008181526001602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610b1290869061567b565b60405180910390a35060015b92915050565b6000610b2e612be2565b610b398484846132a6565b949350505050565b600c54600160801b90046001600160801b031690565b6000610b61612be2565b610b398484846134df565b600e6020526000908152604090205481565b6000610b88612be2565b610b92838361375a565b9392505050565b60008115610cbe576001600160a01b03841660009081526020819052604090205482811015610bda5760405162461bcd60e51b81526004016109f390615cbb565b836001600160a01b0316856001600160a01b031614610cbc576001600160a01b03851660009081526001602090815260408083203384529091529020546000198114610c695783811015610c405760405162461bcd60e51b81526004016109f390615b07565b6001600160a01b0386166000908152600160209081526040808320338452909152902084820390555b6001600160a01b038516610c8f5760405162461bcd60e51b81526004016109f390615986565b506001600160a01b0380861660009081526020819052604080822086850390559186168152208054840190555b505b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d01919061567b565b60405180910390a35060019392505050565b600854600090610d2b906001600160a01b03166139f8565b905090565b6000467f00000000000000000000000000000000000000000000000000000000000000018114610d6857610d6381613ab1565b610d8a565b7f24171f50cde49cb508b31af883d6c3e007ff6a792f967b36bc4ee6898ac7267e5b91505090565b6008546001600160a01b031681565b60105481565b6003546001600160a01b03163314610dcf5760405162461bcd60e51b81526004016109f390615be3565b6001600160a01b03919091166000908152600660205260409020805460ff1916911515919091179055565b600b5481565b610e08612be2565b60007f00000000000000000000000074a81cb5b6996d9347b864b9a1492a6509e51e656001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b158015610e6357600080fd5b505afa158015610e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9b9190614c8b565b6011546001600160a01b038216600090815260208190526040902054919250600160801b90046001600160801b031690610ed59082613b05565b6001600160a01b0383166000818152602081905260409081902092909255601180546001600160801b0316905590517fbe641c3ffc44b2d6c184f023fa4ed7bda4b6ffa71e03b3c98ae0c776da1f17e790610f3190849061567b565b60405180910390a25050565b600f6020526000908152604090205481565b600080610f5a612be2565b610f648484613b28565b8092508193505050610f7a336000601054613e16565b610f965760405162461bcd60e51b81526004016109f390615bac565b9250929050565b6007546001600160a01b031615610fc65760405162461bcd60e51b81526004016109f39061594f565b610fd28183018361526b565b805160079060009060089082906009908290610ff590600a9060208a0190614aa1565b5081546001600160a01b0398891661010092830a908102908a021990911617909155825497871691810a918202918702199097161790558154958416940a938402938302199094169290921790925550600754166110655760405162461bcd60e51b81526004016109f390615ad0565b50506011805467ffffffffffffffff19166312e687c0179055565b6004546001600160a01b03163381146110ab5760405162461bcd60e51b81526004016109f390615c18565b6003546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600380546001600160a01b039092166001600160a01b0319928316179055600480549091169055565b600080611119614b1b565b60005b88811015611a0e5760008a8a8381811061113257fe5b90506020020160208101906111479190615455565b9050826020015115801561115e5750600a8160ff16105b156111735761116b612be2565b600160208401525b60ff8116600a14156111cd57600080600089898681811061119057fe5b90506020028101906111a29190615e7e565b8101906111af919061537f565b9250925092506111c58282610689868c8c613f91565b505050611a05565b60ff81166001141561122e5760008060008989868181106111ea57fe5b90506020028101906111fc9190615e7e565b810190611209919061537f565b925092509250611224828261121f868c8c613f91565b6134df565b9750505050611a05565b60ff81166002141561128e57600080600089898681811061124b57fe5b905060200281019061125d9190615e7e565b81019061126a919061537f565b9250925092506112858282611280868c8c613f91565b6132a6565b50505050611a05565b60ff8116600314156112e9576000808888858181106112a957fe5b90506020028101906112bb9190615e7e565b8101906112c8919061535b565b915091506112e0816112db848a8a613f91565b61375a565b96505050611a05565b60ff8116600414156113465760008088888581811061130457fe5b90506020028101906113169190615e7e565b810190611323919061535b565b9150915061133b81611336848a8a613f91565b613fb9565b505060018352611a05565b60ff8116600514156113a95760008088888581811061136157fe5b90506020028101906113739190615e7e565b810190611380919061535b565b9150915061139881611393848a8a613f91565b613b28565b600187529097509550611a05915050565b60ff8116600b14156114485760008060008989868181106113c657fe5b90506020028101906113d89190615e7e565b8101906113e591906150b0565b9250925092506000806113f6610814565b915091508415806114045750815b801561140f57508381115b8015611422575082158061142257508281115b61143e5760405162461bcd60e51b81526004016109f390615d97565b5050505050611a05565b60ff811660181415611527576000806000806000808c8c8981811061146957fe5b905060200281019061147b9190615e7e565b8101906114889190614ca7565b9550955095509550955095507f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439666001600160a01b031663c0a47c938787878787876040518763ffffffff1660e01b81526004016114ea96959493929190615627565b600060405180830381600087803b15801561150457600080fd5b505af1158015611518573d6000803e3d6000fd5b50505050505050505050611a05565b60ff8116601414156115af576115a587878481811061154257fe5b90506020028101906115549190615e7e565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508c915086905081811061159757fe5b9050602002013587876140c7565b9095509350611a05565b60ff81166015141561161a576115a58787848181106115ca57fe5b90506020028101906115dc9190615e7e565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508992508891506141bd9050565b60ff8116601614156116f257600080600089898681811061163757fe5b90506020028101906116499190615e7e565b8101906116569190614dd7565b9250925092507f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439666001600160a01b031663f18d03cc843385611699868e8e613f91565b6040518563ffffffff1660e01b81526004016116b894939291906157ac565b600060405180830381600087803b1580156116d257600080fd5b505af11580156116e6573d6000803e3d6000fd5b50505050505050611a05565b60ff81166017141561178657600060608089898681811061170f57fe5b90506020028101906117219190615e7e565b81019061172e9190615198565b9250925092507f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439666001600160a01b0316630fca8843843385856040518563ffffffff1660e01b81526004016116b8949392919061580a565b60ff8116601e141561186057606060006118088b8b868181106117a557fe5b905060200201358a8a878181106117b857fe5b90506020028101906117ca9190615e7e565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b91506142ab9050565b915091508060ff1660011415611833578180602001905181019061182c919061541a565b9650611859565b8060ff166002141561185957818060200190518101906118539190615432565b90975095505b5050611a05565b60ff81166006141561198857600087878481811061187a57fe5b905060200281019061188c9190615e7e565b8101906118999190615343565b6008549091506001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169163da5139ca91166119106118e0858b8b613f91565b60408051808201909152600d546001600160801b038082168352600160801b909104166020820152906001614461565b60016040518463ffffffff1660e01b8152600401611930939291906158d0565b60206040518083038186803b15801561194857600080fd5b505afa15801561195c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611980919061541a565b955050611a05565b60ff811660071415611a055760008787848181106119a257fe5b90506020028101906119b49190615e7e565b8101906119c19190615343565b9050611a016119d1828888613f91565b60408051808201909152600d546001600160801b038082168352600160801b9091041660208201529060006144fa565b9550505b5060010161111c565b50805115611a4057611a24336000601054613e16565b611a405760405162461bcd60e51b81526004016109f390615bac565b50965096945050505050565b7f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681565b60006020819052908152604090205481565b600a805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015611b085780601f10611add57610100808354040283529160200191611b08565b820191906000526020600020905b815481529060010190602001808311611aeb57829003601f168201915b505050505081565b6000611b1a610814565b915050611b25612be2565b6000806000611b32614b1b565b5060408051808201909152600d546001600160801b038082168352600160801b909104166020820152611b63614b1b565b600754604051634ffe34db60e01b81526001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd643966811692634ffe34db92611bb6929190911690600401615613565b604080518083038186803b158015611bcd57600080fd5b505afa158015611be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0591906153d8565b905060005b8c811015611e2c5760008e8e83818110611c2057fe5b9050602002016020810190611c359190614c6f565b9050611c42818a8a613e16565b611e23576001600160a01b0381166000908152600f6020526040812054808f8f86818110611c6c57fe5b9050602002013511611c90578e8e85818110611c8457fe5b90506020020135611c92565b805b9150611c9e8183614573565b6001600160a01b0384166000908152600f60205260408120919091559050611cc7868383614461565b90506000611d0269152d02c7e14af6800000611cf08d611cea866201b580614596565b90614596565b81611cf757fe5b8891900460006144fa565b6001600160a01b0385166000908152600e6020526040902054909150611d289082614573565b6001600160a01b038086166000908152600e60205260409020919091558d1615611d52578c611d54565b8d5b6001600160a01b0316846001600160a01b03167f8ad4d3ff00da092c7ad9a573ea4f5f6a3dffc6712dc06d3f78f49b862297c40283604051611d96919061567b565b60405180910390a36001600160a01b03808516908e1615611db7578d611db9565b335b6001600160a01b03167fc8e512d8f188ca059984b5853d2bf653da902696b8512785b182b2c813789a6e8486604051611df3929190615e1f565b60405180910390a3611e058a82613b05565b9950611e118983613b05565b9850611e1d8884613b05565b97505050505b50600101611c0a565b5083611e4a5760405162461bcd60e51b81526004016109f3906159bd565b611e67611e56856145cd565b83516001600160801b0316906145fa565b6001600160801b03168252611e92611e7e846145cd565b60208401516001600160801b0316906145fa565b6001600160801b03908116602084018190528351600d80546001600160801b03191691841691909117909216600160801b909102179055600b54611ed69086614573565b600b55600854604051636d289ce560e11b81526000916001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169263da5139ca92611f3192169089906001906004016158d0565b60206040518083038186803b158015611f4957600080fd5b505afa158015611f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f81919061541a565b90508761241657604051634656bfdf60e11b81526001600160a01b037f00000000000000000000000074a81cb5b6996d9347b864b9a1492a6509e51e651690638cad7fbe90611fd4908c90600401615613565b60206040518083038186803b158015611fec57600080fd5b505afa158015612000573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120249190615067565b6120405760405162461bcd60e51b81526004016109f390615d29565b600754604051633c6340f360e21b81526001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169263f18d03cc9261209992919091169030908e908c906004016157ac565b600060405180830381600087803b1580156120b357600080fd5b505af11580156120c7573d6000803e3d6000fd5b50506007546008546040516371a1ff0960e11b81526001600160a01b03808f16955063e343fe129450612107938116921690309087908d906004016157d6565b6040805180830381600087803b15801561212057600080fd5b505af1158015612134573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121589190615432565b5050600c54600854604051633de222bb60e21b815260009261221b926001600160801b03909116916001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169263f7888aec926121c59291909116903090600401615792565b60206040518083038186803b1580156121dd57600080fd5b505afa1580156121f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612215919061541a565b90614573565b905060006122298284614573565b90506000620186a061223d83612710614596565b8161224457fe5b0490507f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439666001600160a01b031663f18d03cc600860009054906101000a90046001600160a01b0316307f00000000000000000000000074a81cb5b6996d9347b864b9a1492a6509e51e656001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b1580156122e657600080fd5b505afa1580156122fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231e9190614c8b565b856040518563ffffffff1660e01b815260040161233e94939291906157ac565b600060405180830381600087803b15801561235857600080fd5b505af115801561236c573d6000803e3d6000fd5b505050506123a061238e612389838661457390919063ffffffff16565b6145cd565b600c546001600160801b031690614629565b600c80546001600160801b0319166001600160801b0392909216919091179055306001600160a01b038d167f30a8c4f9ab5af7e1309ca87c32377d1a83366c5990472dbf9d262450eae14e386123f68585614573565b6000604051612406929190615e1f565b60405180910390a350505061260a565b6007546001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169163f18d03cc919081169030908d161561245e578c612460565b8d5b8a6040518563ffffffff1660e01b815260040161248094939291906157ac565b600060405180830381600087803b15801561249a57600080fd5b505af11580156124ae573d6000803e3d6000fd5b505050506001600160a01b03891615612552576007546008546040516371a1ff0960e11b81526001600160a01b03808d169363e343fe12936124fe93918316921690339087908d906004016157d6565b6040805180830381600087803b15801561251757600080fd5b505af115801561252b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254f9190615432565b50505b600854604051633c6340f360e21b81526001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169263f18d03cc926125ab9291909116903390309087906004016157ac565b600060405180830381600087803b1580156125c557600080fd5b505af11580156125d9573d6000803e3d6000fd5b505050506125e961238e826145cd565b600c80546001600160801b0319166001600160801b03929092169190911790555b5050505050505050505050505050565b6009546001600160a01b031681565b60026020526000908152604090205481565b600d546001600160801b0380821691600160801b90041682565b6001600160a01b0383166000908152600e60205260409020546126789082613b05565b6001600160a01b0384166000908152600e6020526040902055600b5461269e8183613b05565b600b556007546126b9906001600160a01b0316838386614658565b836001600160a01b0316836126ce57336126f0565b7f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439665b6001600160a01b03167f9ed03113de523cebfe5e49d5f8e12894b1c0d42ce805990461726444c90eab8784604051612728919061567b565b60405180910390a350505050565b61273e612be2565b6127488282613fb9565b612756336000601054613e16565b6127725760405162461bcd60e51b81526004016109f390615bac565b5050565b60066020526000908152604090205460ff1681565b6003546001600160a01b031681565b6007546060906127b2906001600160a01b031661475f565b6008546127c7906001600160a01b031661475f565b60095460405163634ce26b60e11b81526001600160a01b039091169063c699c4d6906127f890600a90600401615708565b60006040518083038186803b15801561281057600080fd5b505afa158015612824573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261284c91908101906153a5565b6040516020016109b5939291906155a6565b600081156128f85733600090815260208190526040902054828110156128965760405162461bcd60e51b81526004016109f390615cbb565b336001600160a01b038516146128f6576001600160a01b0384166128cc5760405162461bcd60e51b81526004016109f390615986565b3360009081526020819052604080822085840390556001600160a01b038616825290208054840190555b505b826001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610b12919061567b565b60115467ffffffffffffffff8082169168010000000000000000810490911690600160801b90046001600160801b031683565b7f00000000000000000000000074a81cb5b6996d9347b864b9a1492a6509e51e6581565b6001600160a01b0387166129b85760405162461bcd60e51b81526004016109f390615c4d565b8342106129d75760405162461bcd60e51b81526004016109f390615b75565b6001600160a01b0387166000818152600260209081526040918290208054600181810190925592519092612a5592612a3a927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928e928e928e92918e9101615684565b604051602081830303815290604052805190602001206147a6565b85858560405160008152602001604052604051612a7594939291906156d7565b6020604051602081039080840390855afa158015612a97573d6000803e3d6000fd5b505050602060405103516001600160a01b031614612ac75760405162461bcd60e51b81526004016109f390615dce565b6001600160a01b038088166000818152600160209081526040808320948b168084529490915290819020889055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590612b2290899061567b565b60405180910390a350505050505050565b6007546001600160a01b031681565b600160209081526000928352604080842090915290825290205481565b6004546001600160a01b031681565b6003546001600160a01b03163314612b985760405162461bcd60e51b81526004016109f390615be3565b600580546001600160a01b0319166001600160a01b0383169081179091556040517fcf1d3f17e521c635e0d20b8acba94ba170afc041d0546d46dafa09d3c9c19eb390600090a250565b612bea614b32565b506040805160608101825260115467ffffffffffffffff80821683526801000000000000000082041660208301819052600160801b9091046001600160801b03169282019290925290420380612c415750506131c5565b67ffffffffffffffff42166020830152612c59614b1b565b5060408051808201909152600d546001600160801b038082168352600160801b9091041660208201819052612d5757825167ffffffffffffffff166312e687c014612ce4576312e687c08084526040517f33af5ce86e8438eff54589f85332916444457dfa8685493fbd579b809097026b91612cdb91600091829182906158f3565b60405180910390a15b5050805160118054602084015160409094015167ffffffffffffffff1990911667ffffffffffffffff938416176fffffffffffffffff00000000000000001916680100000000000000009390941692909202929092176001600160801b03908116600160801b91909216021790556131c5565b600080612d62614b1b565b5060408051808201909152600c546001600160801b038082168352600160801b9091048116602083015286518551670de0b6b3a764000092612db5928992611cea92169067ffffffffffffffff16614596565b81612dbc57fe5b049250612ddc612dcb846145cd565b85516001600160801b031690614629565b6001600160801b03168085526008548251604051630acc462360e31b8152600093612e9d9390926001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd643966811693635662311893612e47939216919088906004016158a4565b60206040518083038186803b158015612e5f57600080fd5b505afa158015612e73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e97919061541a565b90613b05565b90506000620186a0612eb186612710614596565b81612eb857fe5b04905081612edc84602001516001600160801b03168361459690919063ffffffff16565b81612ee357fe5b049350612f06612ef2856145cd565b60408a01516001600160801b031690614629565b6001600160801b03166040890152612f34612f20856145cd565b60208501516001600160801b031690614629565b600c80546001600160801b03908116600160801b9382168402179091558751600d805460208b01516001600160801b031990911692841692831784169316909302919091179091556000908390612f9390670de0b6b3a7640000614596565b81612f9a57fe5b0490506709b6e64a8ec6000081101561305e5760006709b6e64a8ec60000612fce670de0b6b3a7640000611cea8386614573565b81612fd557fe5b0490506000613003612feb8b611cea8580614596565b7054a2b63d65d79d094abb6688000000000090613b05565b8b51909150819061302f9067ffffffffffffffff167054a2b63d65d79d094abb66880000000000614596565b8161303657fe5b0467ffffffffffffffff16808c526304b9a1f01115613057576304b9a1f08b525b5050613111565b670b1a2bc2ec5000008111156131115760006702c68af0bb140000613097670de0b6b3a7640000611cea85670b1a2bc2ec500000614573565b8161309e57fe5b04905060006130b4612feb8b611cea8580614596565b8b519091506000907054a2b63d65d79d094abb66880000000000906130e39067ffffffffffffffff1684614596565b816130ea57fe5b0490506449d482460081111561310257506449d48246005b67ffffffffffffffff168b5250505b88516040517f33af5ce86e8438eff54589f85332916444457dfa8685493fbd579b809097026b91613147918991899186906158f3565b60405180910390a1505086516011805460208a01516040909a015167ffffffffffffffff1990911667ffffffffffffffff938416176fffffffffffffffff000000000000000019166801000000000000000093909a1692909202989098176001600160801b03908116600160801b9190921602179096555050505050505b565b600c546001600160801b0380821691600160801b90041682565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b179052905160609160009183916001600160a01b0386169161322891906154b9565b600060405180830381855afa9150503d8060008114613263576040519150601f19603f3d011682016040523d82523d6000602084013e613268565b606091505b50915091508161329357604051806040016040528060038152602001623f3f3f60e81b81525061329c565b61329c816147de565b925050505b919050565b60408051808201909152600d546001600160801b038082168352600160801b9091041660208201526000906132dd9083600161498c565b8151600d80546020948501516001600160801b03908116600160801b029381166001600160801b031990921691909117169190911790556001600160a01b0386166000908152600f90925260409091205490915061333b9083614573565b6001600160a01b038086166000908152600f6020526040808220939093556008549251636d289ce560e11b815290927f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396683169263da5139ca926133a9929091169086906001906004016158d0565b60206040518083038186803b1580156133c157600080fd5b505afa1580156133d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f9919061541a565b600c546008549192506001600160801b031690613421906001600160a01b0316838388614658565b61343d61342d836145cd565b6001600160801b03831690614629565b600c80546001600160801b0319166001600160801b03929092169190911790556001600160a01b038616856134725733613494565b7f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439665b6001600160a01b03167fc8e512d8f188ca059984b5853d2bf653da902696b8512785b182b2c813789a6e85876040516134ce929190615e1f565b60405180910390a350509392505050565b60006134e9614b1b565b50604080518082018252600c546001600160801b03808216808452600160801b90920481166020840152600854600d549451636d289ce560e11b8152939492936000936001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169463da5139ca946135729492169216906001906004016158a4565b60206040518083038186803b15801561358a57600080fd5b505afa15801561359e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c2919061541a565b83516001600160801b0316019050801561360457806135f784602001516001600160801b03168761459690919063ffffffff16565b816135fe57fe5b04613606565b845b93506103e861362b613617866145cd565b60208601516001600160801b031690614629565b6001600160801b031610156136465760009350505050610b92565b613651838686614a01565b8051600c80546020938401516001600160801b03908116600160801b029381166001600160801b031990921691909117169190911790556001600160a01b03881660009081529081905260409020546136aa9085613b05565b6001600160a01b038089166000908152602081905260409020919091556008546136d79116868489614658565b866001600160a01b0316866136ec573361370e565b7f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439665b6001600160a01b03167f30a8c4f9ab5af7e1309ca87c32377d1a83366c5990472dbf9d262450eae14e388787604051613748929190615e1f565b60405180910390a35050509392505050565b6000613764614b1b565b50604080518082018252600c546001600160801b038082168352600160801b90910481166020830152600854600d549351636d289ce560e11b815292936000936001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169463da5139ca946137eb949216929116906001906004016158a4565b60206040518083038186803b15801561380357600080fd5b505afa158015613817573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061383b919061541a565b825160208401516001600160801b039182169290920192501661385e8583614596565b8161386557fe5b3360009081526020819052604090205491900493506138849085614573565b336000908152602081905260409020556138a0611e56846145cd565b6001600160801b031682526138b7611e7e856145cd565b6001600160801b0316602083018190526103e811156138e85760405162461bcd60e51b81526004016109f390615c84565b8151600c805460208501516001600160801b03908116600160801b029381166001600160801b031990921691909117169190911790556040516001600160a01b0386169033907f6e853a5fd6b51d773691f542ebac8513c9992a51380d4c342031056a641142289061395d9087908990615e1f565b60405180910390a3600854604051633c6340f360e21b81526001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169263f18d03cc926139be92919091169030908a9089906004016157ac565b600060405180830381600087803b1580156139d857600080fd5b505af11580156139ec573d6000803e3d6000fd5b50505050505092915050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b179052905160009182916060916001600160a01b03861691613a3f91906154b9565b600060405180830381855afa9150503d8060008114613a7a576040519150601f19603f3d011682016040523d82523d6000602084013e613a7f565b606091505b5091509150818015613a92575080516020145b613a9d57601261329c565b8080602001905181019061329c9190615471565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692188230604051602001613ae8939291906156b8565b604051602081830303815290604052805190602001209050919050565b81810181811015610b1e5760405162461bcd60e51b81526004016109f390615a99565b60008080620186a0613b3b856032614596565b81613b4257fe5b049050613b82613b528583613b05565b60408051808201909152600d546001600160801b038082168352600160801b909104166020820152906001614a42565b8151600d80546020948501516001600160801b03908116600160801b029381166001600160801b03199092169190911716919091179055336000908152600f909252604090912054909350613bd79084613b05565b336000818152600f6020526040908190209290925590516001600160a01b03871691907f3a5151e57d3bc9798e7853034ac52293d1a0e12a2b44725e75b03b21f86477a690613c2b90889086908990615e2d565b60405180910390a3600854604051636d289ce560e11b81526001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169263da5139ca92613c8b92919091169088906000906004016158d0565b60206040518083038186803b158015613ca357600080fd5b505afa158015613cb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cdb919061541a565b9150613ce5614b1b565b5060408051808201909152600c546001600160801b038082168352600160801b90910416602082018190526103e81115613d315760405162461bcd60e51b81526004016109f390615c84565b613d4e613d3d846145cd565b82516001600160801b0316906145fa565b6001600160801b03908116808352600c805460208501518416600160801b026001600160801b0319909116909217909216179055600854604051633c6340f360e21b81526001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169263f18d03cc92613ddb92919091169030908b9089906004016157ac565b600060405180830381600087803b158015613df557600080fd5b505af1158015613e09573d6000803e3d6000fd5b5050505050509250929050565b6001600160a01b0383166000908152600f602052604081205480613e3e576001915050610b92565b6001600160a01b0385166000908152600e602052604090205480613e6757600092505050610b92565b613e6f614b1b565b5060408051808201909152600d546001600160801b03808216808452600160801b909204166020830181905290613ead908790611cea908790614596565b81613eb457fe5b600754919004906001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169163566231189116613f148a613eff57620124f8613f04565b62012cc85b611cea886509184e72a000614596565b60006040518463ffffffff1660e01b8152600401613f34939291906158d0565b60206040518083038186803b158015613f4c57600080fd5b505afa158015613f60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f84919061541a565b1015979650505050505050565b600080841215613fb1576000198414613faa5781613fac565b825b610b39565b509192915050565b336000908152600e6020526040902054613fd39082614573565b336000908152600e6020526040902055600b54613ff09082614573565b600b556040516001600160a01b0383169033907f8ad4d3ff00da092c7ad9a573ea4f5f6a3dffc6712dc06d3f78f49b862297c4029061403090859061567b565b60405180910390a3600754604051633c6340f360e21b81526001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd64396681169263f18d03cc926140919291909116903090879087906004016157ac565b600060405180830381600087803b1580156140ab57600080fd5b505af11580156140bf573d6000803e3d6000fd5b505050505050565b600080600080600080898060200190518101906140e49190615151565b93509350935093506140f7828989613f91565b9150614104818989613f91565b90507f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439666001600160a01b03166302b9446c8a86338787876040518763ffffffff1660e01b815260040161415b9594939291906157d6565b60408051808303818588803b15801561417357600080fd5b505af1158015614187573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906141ac9190615432565b955095505050505094509492505050565b600080600080600080888060200190518101906141da9190615151565b93509350935093507f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439666001600160a01b03166397da6d3085338661421f878e8e613f91565b61422a878f8f613f91565b6040518663ffffffff1660e01b815260040161424a9594939291906157d6565b6040805180830381600087803b15801561426357600080fd5b505af1158015614277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061429b9190615432565b9550955050505050935093915050565b606060008060606000806000898060200190518101906142cb9190614d14565b945094509450945094508280156142e0575081155b1561430e5783896040516020016142f89291906154d5565b6040516020818303038152906040529350614367565b821580156143195750815b156143315783886040516020016142f89291906154d5565b82801561433b5750815b1561436757838989604051602001614355939291906154f7565b60405160208183030381529060405293505b7f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439666001600160a01b0316856001600160a01b0316141580156143b257506001600160a01b0385163014155b6143ce5760405162461bcd60e51b81526004016109f390615b3e565b60006060866001600160a01b03168d876040516143eb91906154b9565b60006040518083038185875af1925050503d8060008114614428576040519150601f19603f3d011682016040523d82523d6000602084013e61442d565b606091505b50915091508161444f5760405162461bcd60e51b81526004016109f390615a2b565b9c919b50909950505050505050505050565b600083602001516001600160801b031660001415614480575081610b92565b602084015184516001600160801b039182169161449f91869116614596565b816144a657fe5b0490508180156144ea57508284600001516001600160801b03166144e086602001516001600160801b03168461459690919063ffffffff16565b816144e757fe5b04105b15610b9257610b39816001613b05565b82516000906001600160801b0316614513575081610b92565b835160208501516001600160801b039182169161453291869116614596565b8161453957fe5b0490508180156144ea57508284602001516001600160801b03166144e086600001516001600160801b03168461459690919063ffffffff16565b80820382811115610b1e5760405162461bcd60e51b81526004016109f390615918565b60008115806145b1575050808202828282816145ae57fe5b04145b610b1e5760405162461bcd60e51b81526004016109f390615d60565b60006001600160801b038211156145f65760405162461bcd60e51b81526004016109f390615a62565b5090565b8082036001600160801b038084169082161115610b1e5760405162461bcd60e51b81526004016109f390615918565b8181016001600160801b038083169082161015610b1e5760405162461bcd60e51b81526004016109f390615a99565b80156146d4576146b0827f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd6439666001600160a01b031663f7888aec87306040518363ffffffff1660e01b81526004016121c5929190615792565b8311156146cf5760405162461bcd60e51b81526004016109f390615cf2565b614759565b604051633c6340f360e21b81526001600160a01b037f000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd643966169063f18d03cc906147269087903390309089906004016157ac565b600060405180830381600087803b15801561474057600080fd5b505af1158015614754573d6000803e3d6000fd5b505050505b50505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b179052905160609160009183916001600160a01b0386169161322891906154b9565b600060405180604001604052806002815260200161190160f01b8152506147cb610d30565b83604051602001613ae8939291906154f7565b6060604082511061480457818060200190518101906147fd91906153a5565b90506132a1565b81516020141561496c5760005b60208160ff161080156148585750828160ff168151811061482e57fe5b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1561486557600101614811565b60608160ff1667ffffffffffffffff8111801561488157600080fd5b506040519080825280601f01601f1916602001820160405280156148ac576020820181803683370190505b509050600091505b60208260ff161080156148fb5750838260ff16815181106148d157fe5b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1561496357838260ff168151811061490f57fe5b602001015160f81c60f81b818360ff168151811061492957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001909101906148b4565b91506132a19050565b506040805180820190915260038152623f3f3f60e81b60208201526132a1565b614994614b1b565b60006149a1858585614461565b90506149c06149af826145cd565b86516001600160801b0316906145fa565b6001600160801b031685526149eb6149d7856145cd565b60208701516001600160801b0316906145fa565b6001600160801b03166020860152939492505050565b614a09614b1b565b614a15612dcb846145cd565b6001600160801b03168452614a2c613617836145cd565b6001600160801b03166020850152509192915050565b614a4a614b1b565b6000614a578585856144fa565b9050614a76614a65856145cd565b86516001600160801b031690614629565b6001600160801b031685526149eb614a8d826145cd565b60208701516001600160801b031690614629565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614ae257805160ff1916838001178555614b0f565b82800160010185558215614b0f579182015b82811115614b0f578251825591602001919060010190614af4565b506145f6929150614b52565b604080518082019091526000808252602082015290565b604080516060810182526000808252602082018190529181019190915290565b5b808211156145f65760008155600101614b53565b8035610b1e81615f66565b60008083601f840112614b83578182fd5b50813567ffffffffffffffff811115614b9a578182fd5b6020830191508360208083028501011115610f9657600080fd5b600082601f830112614bc4578081fd5b8135614bd7614bd282615eea565b615ec3565b818152915060208083019084810181840286018201871015614bf857600080fd5b60005b84811015614c1757813584529282019290820190600101614bfb565b505050505092915050565b600082601f830112614c32578081fd5b8151614c40614bd282615f0a565b9150808252836020828501011115614c5757600080fd5b614c68816020840160208601615f3a565b5092915050565b600060208284031215614c80578081fd5b8135610b9281615f66565b600060208284031215614c9c578081fd5b8151610b9281615f66565b60008060008060008060c08789031215614cbf578182fd5b8635614cca81615f66565b95506020870135614cda81615f66565b94506040870135614cea81615f7e565b93506060870135614cfa81615fa1565b9598949750929560808101359460a0909101359350915050565b600080600080600060a08688031215614d2b578283fd5b8551614d3681615f66565b602087015190955067ffffffffffffffff811115614d52578384fd5b614d5e88828901614c22565b9450506040860151614d6f81615f7e565b6060870151909350614d8081615f7e565b6080870151909250614d9181615fa1565b809150509295509295909350565b60008060408385031215614db1578182fd5b8235614dbc81615f66565b91506020830135614dcc81615f66565b809150509250929050565b600080600060608486031215614deb578081fd5b8335614df681615f66565b92506020840135614e0681615f66565b929592945050506040919091013590565b600080600080600080600060e0888a031215614e31578485fd5b8735614e3c81615f66565b96506020880135614e4c81615f66565b955060408801359450606088013593506080880135614e6a81615fa1565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215614e9b578081fd5b8335614ea681615f66565b92506020840135614eb681615f7e565b91506040840135614ec681615f7e565b809150509250925092565b600080600060608486031215614ee5578081fd5b8335614ef081615f66565b92506020840135614e0681615f7e565b60008060408385031215614f12578182fd5b8235614f1d81615f66565b946020939093013593505050565b600080600080600080600060a0888a031215614f45578081fd5b873567ffffffffffffffff80821115614f5c578283fd5b614f688b838c01614b72565b909950975060208a0135915080821115614f80578283fd5b50614f8d8a828b01614b72565b9096509450506040880135614fa181615f66565b92506060880135614fb181615f66565b91506080880135614fc181615f7e565b8091505092959891949750929550565b60008060008060008060608789031215614fe9578384fd5b863567ffffffffffffffff80821115615000578586fd5b61500c8a838b01614b72565b90985096506020890135915080821115615024578586fd5b6150308a838b01614b72565b90965094506040890135915080821115615048578384fd5b5061505589828a01614b72565b979a9699509497509295939492505050565b600060208284031215615078578081fd5b8151610b9281615f7e565b60008060408385031215615095578182fd5b82516150a081615f7e565b6020939093015192949293505050565b6000806000606084860312156150c4578081fd5b83356150cf81615f7e565b95602085013595506040909401359392505050565b600080602083850312156150f6578182fd5b823567ffffffffffffffff8082111561510d578384fd5b818501915085601f830112615120578384fd5b81358181111561512e578485fd5b86602082850101111561513f578485fd5b60209290920196919550909350505050565b60008060008060808587031215615166578182fd5b845161517181615f66565b602086015190945061518281615f66565b6040860151606090960151949790965092505050565b6000806000606084860312156151ac578081fd5b83356151b781615f66565b925060208481013567ffffffffffffffff808211156151d4578384fd5b818701915087601f8301126151e7578384fd5b81356151f5614bd282615eea565b81815284810190848601868402860187018c1015615211578788fd5b8795505b8386101561523b576152278c82614b67565b835260019590950194918601918601615215565b50965050506040870135925080831115615253578384fd5b505061526186828701614bb4565b9150509250925092565b60008060008060808587031215615280578182fd5b843561528b81615f66565b9350602085013561529b81615f66565b925060408501356152ab81615f66565b9150606085013567ffffffffffffffff8111156152c6578182fd5b8501601f810187136152d6578182fd5b80356152e4614bd282615f0a565b8181528860208385010111156152f8578384fd5b81602084016020830137908101602001929092525092959194509250565b60008060408385031215615328578182fd5b823561533381615f66565b91506020830135614dcc81615f7e565b600060208284031215615354578081fd5b5035919050565b6000806040838503121561536d578182fd5b823591506020830135614dcc81615f66565b600080600060608486031215615393578081fd5b833592506020840135614eb681615f66565b6000602082840312156153b6578081fd5b815167ffffffffffffffff8111156153cc578182fd5b610b3984828501614c22565b6000604082840312156153e9578081fd5b6153f36040615ec3565b82516153fe81615f8c565b8152602083015161540e81615f8c565b60208201529392505050565b60006020828403121561542b578081fd5b5051919050565b60008060408385031215615444578182fd5b505080516020909101519092909150565b600060208284031215615466578081fd5b8135610b9281615fa1565b600060208284031215615482578081fd5b8151610b9281615fa1565b600081518084526154a5816020860160208601615f3a565b601f01601f19169290920160200192915050565b600082516154cb818460208701615f3a565b9190910192915050565b600083516154e7818460208801615f3a565b9190910191825250602001919050565b60008451615509818460208901615f3a565b91909101928352506020820152604001919050565b60007f4b61736869204d656469756d205269736b20000000000000000000000000000082528451615556816012850160208901615f3a565b602f60f81b6012918401918201528451615577816013840160208901615f3a565b602d60f81b601392909101918201528351615599816014840160208801615f3a565b0160140195945050505050565b6000616b6d60f01b825284516155c3816002850160208901615f3a565b602f60f81b60029184019182015284516155e4816003840160208901615f3a565b602d60f81b600392909101918201528351615606816004840160208801615f3a565b0160040195945050505050565b6001600160a01b0391909116815260200190565b6001600160a01b039687168152949095166020850152911515604084015260ff166060830152608082015260a081019190915260c00190565b901515815260200190565b9115158252602082015260400190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b92835260208301919091526001600160a01b0316604082015260600190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252610b92602083018461548d565b6000602080830181845282855460018082166000811461572f576001811461574d57615785565b60028304607f16855260ff1983166040890152606088019350615785565b6002830480865261575d8a615f2e565b885b8281101561577b5781548b82016040015290840190880161575f565b8a01604001955050505b5091979650505050505050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b03958616815293851660208501529190931660408301526060820192909252608081019190915260a00190565b6000608082016001600160a01b0380881684526020818816818601526080604086015282875180855260a0870191508289019450855b8181101561585e578551851683529483019491830191600101615840565b50508581036060870152865180825290820193509150808601845b8381101561589557815185529382019390820190600101615879565b50929998505050505050505050565b6001600160a01b039390931683526001600160801b039190911660208301521515604082015260600190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b938452602084019290925267ffffffffffffffff166040830152606082015260800190565b60208082526015908201527f426f72696e674d6174683a20556e646572666c6f770000000000000000000000604082015260600190565b6020808252601e908201527f4b61736869506169723a20616c726561647920696e697469616c697a65640000604082015260600190565b60208082526016908201527f45524332303a206e6f207a65726f206164647265737300000000000000000000604082015260600190565b6020808252601a908201527f4b61736869506169723a20616c6c2061726520736f6c76656e74000000000000604082015260600190565b60208082526015908201527f4f776e61626c653a207a65726f20616464726573730000000000000000000000604082015260600190565b60208082526016908201527f4b61736869506169723a2063616c6c206661696c656400000000000000000000604082015260600190565b6020808252601c908201527f426f72696e674d6174683a2075696e74313238204f766572666c6f7700000000604082015260600190565b60208082526018908201527f426f72696e674d6174683a20416464204f766572666c6f770000000000000000604082015260600190565b60208082526013908201527f4b61736869506169723a20626164207061697200000000000000000000000000604082015260600190565b60208082526018908201527f45524332303a20616c6c6f77616e636520746f6f206c6f770000000000000000604082015260600190565b60208082526015908201527f4b61736869506169723a2063616e27742063616c6c0000000000000000000000604082015260600190565b6020808252600e908201527f45524332303a2045787069726564000000000000000000000000000000000000604082015260600190565b60208082526019908201527f4b61736869506169723a207573657220696e736f6c76656e7400000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c657220213d2070656e64696e67206f776e6572604082015260600190565b60208082526018908201527f45524332303a204f776e65722063616e6e6f7420626520300000000000000000604082015260600190565b60208082526014908201527f4b617368693a2062656c6f77206d696e696d756d000000000000000000000000604082015260600190565b60208082526016908201527f45524332303a2062616c616e636520746f6f206c6f7700000000000000000000604082015260600190565b60208082526018908201527f4b61736869506169723a20536b696d20746f6f206d7563680000000000000000604082015260600190565b6020808252601a908201527f4b61736869506169723a20496e76616c69642073776170706572000000000000604082015260600190565b60208082526018908201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604082015260600190565b60208082526016908201527f4b61736869506169723a2072617465206e6f74206f6b00000000000000000000604082015260600190565b60208082526018908201527f45524332303a20496e76616c6964205369676e61747572650000000000000000604082015260600190565b6001600160801b0392831681529116602082015260400190565b918252602082015260400190565b9283526020830191909152604082015260600190565b67ffffffffffffffff93841681529190921660208201526001600160801b03909116604082015260600190565b60ff91909116815260200190565b6000808335601e19843603018112615e94578283fd5b83018035915067ffffffffffffffff821115615eae578283fd5b602001915036819003821315610f9657600080fd5b60405181810167ffffffffffffffff81118282101715615ee257600080fd5b604052919050565b600067ffffffffffffffff821115615f00578081fd5b5060209081020190565b600067ffffffffffffffff821115615f20578081fd5b50601f01601f191660200190565b60009081526020902090565b60005b83811015615f55578181015183820152602001615f3d565b838111156147595750506000910152565b6001600160a01b0381168114615f7b57600080fd5b50565b8015158114615f7b57600080fd5b6001600160801b0381168114615f7b57600080fd5b60ff81168114615f7b57600080fdfea264697066735822122043def0759137241cf8df2e558f293223dcafcd6c3de768f29848ee9f923dc5a964736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd643966
-----Decoded View---------------
Arg [0] : bentoBox_ (address): 0xF5BCE5077908a1b7370B9ae04AdC565EBd643966
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000f5bce5077908a1b7370b9ae04adc565ebd643966
Deployed Bytecode Sourcemap
30594:33844:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31866:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41363:363;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;33282:202::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3778:506::-;;;;;;;;;;-1:-1:-1;3778:506:0;;;;;:::i;:::-;;:::i;:::-;;10514:205;;;;;;;;;;-1:-1:-1;10514:205:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;49097:187::-;;;;;;;;;;-1:-1:-1;49097:187:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;33640:94::-;;;;;;;;;;;;;:::i;45414:199::-;;;;;;;;;;-1:-1:-1;45414:199:0;;;;;:::i;:::-;;:::i;32504:54::-;;;;;;;;;;-1:-1:-1;32504:54:0;;;;;:::i;:::-;;:::i;46699:154::-;;;;;;;;;;-1:-1:-1;46699:154:0;;;;;:::i;:::-;;:::i;9000:1219::-;;;;;;;;;;-1:-1:-1;9000:1219:0;;;;;:::i;:::-;;:::i;33492:96::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;6421:268::-;;;;;;;;;;;;;:::i;32030:19::-;;;;;;;;;;;;;:::i;32846:27::-;;;;;;;;;;;;;:::i;64022:113::-;;;;;;;;;;-1:-1:-1;64022:113:0;;;;;:::i;:::-;;:::i;32138:35::-;;;;;;;;;;;;;:::i;63347:357::-;;;;;;;;;;;;;:::i;32655:49::-;;;;;;;;;;-1:-1:-1;32655:49:0;;;;;:::i;:::-;;:::i;47905:170::-;;;;;;;;;;-1:-1:-1;47905:170:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;35853:445::-;;;;;;:::i;:::-;;:::i;4366:340::-;;;;;;;;;;;;;:::i;53969:4503::-;;;;;;:::i;:::-;;:::i;31727:37::-;;;;;;;;;;;;;:::i;7228:44::-;;;;;;;;;;-1:-1:-1;7228:44:0;;;;;:::i;:::-;;:::i;32084:23::-;;;;;;;;;;;;;:::i;59081:4209::-;;;;;;;;;;-1:-1:-1;59081:4209:0;;;;;:::i;:::-;;:::i;32056:21::-;;;;;;;;;;;;;:::i;7462:41::-;;;;;;;;;;-1:-1:-1;7462:41:0;;;;;:::i;:::-;;:::i;32339:25::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;42914:467::-;;;;;;;;;;-1:-1:-1;42914:467:0;;;;;:::i;:::-;;:::i;43982:194::-;;;;;;;;;;-1:-1:-1;43982:194:0;;;;;:::i;:::-;;:::i;31893:41::-;;;;;;;;;;-1:-1:-1;31893:41:0;;;;;:::i;:::-;;:::i;2924:20::-;;;;;;;;;;;;;:::i;33080:194::-;;;;;;;;;;;;;:::i;7942:751::-;;;;;;;;;;-1:-1:-1;7942:751:0;;;;;:::i;:::-;;:::i;33017:28::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;31771:53::-;;;;;;;;;;;;;:::i;11348:665::-;;;;;;;;;;-1:-1:-1;11348:665:0;;;;;:::i;:::-;;:::i;31999:24::-;;;;;;;;;;;;;:::i;7333:64::-;;;;;;;;;;-1:-1:-1;7333:64:0;;;;;:::i;:::-;;:::i;2951:27::-;;;;;;;;;;;;;:::i;64313:122::-;;;;;;;;;;-1:-1:-1;64313:122:0;;;;;:::i;:::-;;:::i;36405:3227::-;;;;;;;;;;;;;:::i;32209:24::-;;;;;;;;;;;;;:::i;31866:20::-;;;-1:-1:-1;;;;;31866:20:0;;:::o;41363:363::-;41466:6;;:22;;-1:-1:-1;;;41466:22:0;;41409:12;;;;-1:-1:-1;;;;;41466:6:0;;;;:10;;:22;;41477:10;;41466:22;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41448:40;;-1:-1:-1;41448:40:0;-1:-1:-1;41501:218:0;;;;41529:12;:19;;;41568:21;;;;;;41544:4;;41568:21;:::i;:::-;;;;;;;;41501:218;;;-1:-1:-1;41695:12:0;;41501:218;41363:363;;:::o;33282:202::-;33400:10;;33321:13;;33400:21;;-1:-1:-1;;;;;33400:10:0;:19;:21::i;:::-;33428:5;;:16;;-1:-1:-1;;;;;33428:5:0;:14;:16::i;:::-;33451:6;;:23;;-1:-1:-1;;;33451:23:0;;-1:-1:-1;;;;;33451:6:0;;;;:11;;:23;;33463:10;;33451:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;33451:23:0;;;;;;;;;;;;:::i;:::-;33361:114;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;33347:129;;33282:202;:::o;3778:506::-;4834:5;;-1:-1:-1;;;;;4834:5:0;4820:10;:19;4812:64;;;;-1:-1:-1;;;4812:64:0;;;;;;;:::i;:::-;;;;;;;;;3917:6:::1;3913:364;;;-1:-1:-1::0;;;;;3971:22:0;::::1;::::0;::::1;::::0;:34:::1;;;3997:8;3971:34;3963:68;;;;-1:-1:-1::0;;;3963:68:0::1;;;;;;;:::i;:::-;4098:5;::::0;4077:37:::1;::::0;-1:-1:-1;;;;;4077:37:0;;::::1;::::0;4098:5:::1;::::0;4077:37:::1;::::0;4098:5:::1;::::0;4077:37:::1;4129:5;:16:::0;;-1:-1:-1;;;;;4129:16:0;::::1;-1:-1:-1::0;;;;;;4129:16:0;;::::1;;::::0;;;4160:12:::1;:25:::0;;;;::::1;::::0;;3913:364:::1;;;4242:12;:23:::0;;-1:-1:-1;;;;;;4242:23:0::1;-1:-1:-1::0;;;;;4242:23:0;::::1;;::::0;;3913:364:::1;3778:506:::0;;;:::o;10514:205::-;10607:10;10580:4;10597:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;10597:30:0;;;;;;;;;;:39;;;10652:37;10580:4;;10597:30;;10652:37;;;;10630:6;;10652:37;:::i;:::-;;;;;;;;-1:-1:-1;10707:4:0;10514:205;;;;;:::o;49097:187::-;49199:14;49226:8;:6;:8::i;:::-;49254:22;49261:2;49265:4;49271;49254:6;:22::i;:::-;49245:31;49097:187;-1:-1:-1;;;;49097:187:0:o;33640:94::-;33711:10;:15;-1:-1:-1;;;33711:15:0;;-1:-1:-1;;;;;33711:15:0;;33640:94::o;45414:199::-;45520:16;45549:8;:6;:8::i;:::-;45579:26;45589:2;45593:4;45599:5;45579:9;:26::i;32504:54::-;;;;;;;;;;;;;:::o;46699:154::-;46766:13;46792:8;:6;:8::i;:::-;46819:26;46832:2;46836:8;46819:12;:26::i;:::-;46811:34;46699:154;-1:-1:-1;;;46699:154:0:o;9000:1219::-;9114:4;9199:11;;9195:953;;-1:-1:-1;;;;;9248:15:0;;9227:18;9248:15;;;;;;;;;;;9286:20;;;;9278:55;;;;-1:-1:-1;;;9278:55:0;;;;;;;:::i;:::-;9362:2;-1:-1:-1;;;;;9354:10:0;:4;-1:-1:-1;;;;;9354:10:0;;9350:787;;-1:-1:-1;;;;;9412:15:0;;9385:24;9412:15;;;:9;:15;;;;;;;;9428:10;9412:27;;;;;;;;-1:-1:-1;;9563:37:0;;9559:251;;9653:6;9633:16;:26;;9625:63;;;;-1:-1:-1;;;9625:63:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;9711:15:0;;;;;;:9;:15;;;;;;;;9727:10;9711:27;;;;;;;9741:25;;;9711:55;;9559:251;-1:-1:-1;;;;;9836:16:0;;9828:51;;;;-1:-1:-1;;;9828:51:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;9950:15:0;;;:9;:15;;;;;;;;;;;9968:19;;;9950:37;;10030:13;;;;;;:23;;;;;;9350:787;9195:953;;10178:2;-1:-1:-1;;;;;10163:26:0;10172:4;-1:-1:-1;;;;;10163:26:0;;10182:6;10163:26;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;10207:4:0;9000:1219;;;;;:::o;33492:96::-;33560:5;;33535;;33560:20;;-1:-1:-1;;;;;33560:5:0;:18;:20::i;:::-;33553:27;;33492:96;:::o;6421:268::-;6470:7;6551:9;6599:25;6588:36;;:93;;6647:34;6673:7;6647:25;:34::i;:::-;6588:93;;;6627:17;6588:93;6581:100;;;6421:268;:::o;32030:19::-;;;-1:-1:-1;;;;;32030:19:0;;:::o;32846:27::-;;;;:::o;64022:113::-;4834:5;;-1:-1:-1;;;;;4834:5:0;4820:10;:19;4812:64;;;;-1:-1:-1;;;4812:64:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64101:17:0;;;::::1;;::::0;;;:8:::1;:17;::::0;;;;:26;;-1:-1:-1;;64101:26:0::1;::::0;::::1;;::::0;;;::::1;::::0;;64022:113::o;32138:35::-;;;;:::o;63347:357::-;63389:8;:6;:8::i;:::-;63408:14;63425;-1:-1:-1;;;;;63425:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63488:10;:29;-1:-1:-1;;;;;63548:17:0;;63458:27;63548:17;;;;;;;;;;;;;-1:-1:-1;;;;63488:29:0;;-1:-1:-1;;;;;63488:29:0;;63548:42;;63488:29;63548:21;:42::i;:::-;-1:-1:-1;;;;;63528:17:0;;:9;:17;;;;;;;;;;;;:62;;;;63601:10;:33;;-1:-1:-1;;;;;63601:33:0;;;63652:44;;;;;;63676:19;;63652:44;:::i;:::-;;;;;;;;63347:357;;:::o;32655:49::-;;;;;;;;;;;;;:::o;47905:170::-;47973:12;47987:13;48013:8:::1;:6;:8::i;:::-;48048:19;48056:2;48060:6;48048:7;:19::i;:::-;48032:35;;;;;;;;40984:43:::0;40995:10;41007:5;41014:12;;40984:10;:43::i;:::-;40976:81;;;;-1:-1:-1;;;40976:81:0;;;;;;;:::i;:::-;47905:170;;;;;:::o;35853:445::-;35939:10;;-1:-1:-1;;;;;35939:10:0;35931:33;35923:76;;;;-1:-1:-1;;;35923:76:0;;;;;;;:::i;:::-;36052:50;;;;36063:4;36052:50;:::i;:::-;36010:92;;36011:10;;;;36023:5;;36011:10;;36030:6;;36011:10;;36010:92;;36038:10;;36010:92;;;;;:::i;:::-;-1:-1:-1;36010:92:0;;-1:-1:-1;;;;;36010:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36129:10:0;;;36113:65;;;;-1:-1:-1;;;36113:65:0;;;;;;;:::i;:::-;-1:-1:-1;;36191:10:0;:67;;-1:-1:-1;;36191:67:0;34555:9;36191:67;;;35853:445::o;4366:340::-;4434:12;;-1:-1:-1;;;;;4434:12:0;4486:10;:27;;4478:72;;;;-1:-1:-1;;;4478:72:0;;;;;;;:::i;:::-;4609:5;;4588:42;;-1:-1:-1;;;;;4588:42:0;;;;4609:5;;4588:42;;4609:5;;4588:42;4641:5;:21;;-1:-1:-1;;;;;4641:21:0;;;-1:-1:-1;;;;;;4641:21:0;;;;;;4673:12;:25;;;;;;;4366:340::o;53969:4503::-;54120:14;54136;54163:24;;:::i;:::-;54203:9;54198:4116;54218:18;;;54198:4116;;;54258:12;54273:7;;54281:1;54273:10;;;;;;;;;;;;;;;;;;;;:::i;:::-;54258:25;;54303:6;:17;;;54302:18;:33;;;;;54333:2;54324:6;:11;;;54302:33;54298:125;;;54356:8;:6;:8::i;:::-;54403:4;54383:17;;;:24;54298:125;54441:31;;;49864:2;54441:31;54437:3866;;;54494:12;54508:10;54520:9;54544:5;;54550:1;54544:8;;;;;;;;;;;;;;;;;;:::i;:::-;54533:45;;;;;;;:::i;:::-;54493:85;;;;;;54597:52;54611:2;54615:4;54621:27;54626:5;54633:6;54641;54621:4;:27::i;54597:52::-;54437:3866;;;;;;54675:26;;;49383:1;54675:26;54671:3632;;;54723:12;54737:10;54749:9;54773:5;;54779:1;54773:8;;;;;;;;;;;;;;;;;;:::i;:::-;54762:45;;;;;;;:::i;:::-;54722:85;;;;;;54835:48;54845:2;54849:4;54855:27;54860:5;54867:6;54875;54855:4;:27::i;:::-;54835:9;:48::i;:::-;54826:57;;54671:3632;;;;;;54909:22;;;49430:1;54909:22;54905:3398;;;54953:11;54966:10;54978:9;55002:5;;55008:1;55002:8;;;;;;;;;;;;;;;;;;:::i;:::-;54991:45;;;;;;;:::i;:::-;54952:84;;;;;;55055:44;55062:2;55066:4;55072:26;55077:4;55083:6;55091;55072:4;:26::i;:::-;55055:6;:44::i;:::-;;54905:3398;;;;;;55125:29;;;49484:1;55125:29;55121:3182;;;55176:15;55193:10;55218:5;;55224:1;55218:8;;;;;;;;;;;;;;;;;;:::i;:::-;55207:39;;;;;;;:::i;:::-;55175:71;;;;55274:48;55287:2;55291:30;55296:8;55306:6;55314;55291:4;:30::i;:::-;55274:12;:48::i;:::-;55265:57;;55121:3182;;;;;55348:34;;;49543:1;55348:34;55344:2959;;;55404:12;55418:10;55443:5;;55449:1;55443:8;;;;;;;;;;;;;;;;;;:::i;:::-;55432:39;;;;;;;:::i;:::-;55403:68;;;;55490:50;55508:2;55512:27;55517:5;55524:6;55532;55512:4;:27::i;:::-;55490:17;:50::i;:::-;-1:-1:-1;;55587:4:0;55559:32;;55344:2959;;;55617:23;;;49591:1;55617:23;55613:2690;;;55662:13;55677:10;55702:5;;55708:1;55702:8;;;;;;;;;;;;;;;;;;:::i;:::-;55691:39;;;;;;;:::i;:::-;55661:69;;;;55768:41;55776:2;55780:28;55785:6;55793;55801;55780:4;:28::i;:::-;55768:7;:41::i;:::-;55856:4;55828:32;;55749:60;;-1:-1:-1;55749:60:0;-1:-1:-1;55613:2690:0;;-1:-1:-1;;55613:2690:0;;55886:37;;;49927:2;55886:37;55882:2421;;;55945:16;55963:15;55980;56010:5;;56016:1;56010:8;;;;;;;;;;;;;;;;;;:::i;:::-;55999:46;;;;;;;:::i;:::-;55944:101;;;;;;56065:12;56079;56095:20;:18;:20::i;:::-;56064:51;;;;56144:11;56143:12;:23;;;;56159:7;56143:23;56142:43;;;;;56178:7;56171:4;:14;56142:43;:79;;;;-1:-1:-1;56190:12:0;;;:30;;;56213:7;56206:4;:14;56190:30;56134:114;;;;-1:-1:-1;;;56134:114:0;;;;;;;:::i;:::-;55882:2421;;;;;;;;56274:34;;;50254:2;56274:34;56270:2033;;;56330:12;56344:23;56369:13;56384:7;56393:9;56404;56449:5;;56455:1;56449:8;;;;;;;;;;;;;;;;;;:::i;:::-;56438:71;;;;;;;:::i;:::-;56329:180;;;;;;;;;;;;56528:8;-1:-1:-1;;;;;56528:34:0;;56563:4;56569:15;56586:8;56596:1;56599;56602;56528:76;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56270:2033;;;;;;;;;56630:30;;;50014:2;56630:30;56626:1677;;;56700:50;56714:5;;56720:1;56714:8;;;;;;;;;;;;;;;;;;:::i;:::-;56700:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56724:6:0;;-1:-1:-1;56724:6:0;;-1:-1:-1;56731:1:0;;-1:-1:-1;56724:9:0;;;;;;;;;;;;;56735:6;56743;56700:13;:50::i;:::-;56681:69;;-1:-1:-1;56681:69:0;-1:-1:-1;56626:1677:0;;;56776:31;;;50071:2;56776:31;56772:1531;;;56847:40;56862:5;;56868:1;56862:8;;;;;;;;;;;;;;;;;;:::i;:::-;56847:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56872:6:0;;-1:-1:-1;56880:6:0;;-1:-1:-1;56847:14:0;;-1:-1:-1;56847:40:0:i;56772:1531::-;56913:31;;;50128:2;56913:31;56909:1394;;;56966:12;56980:10;56992:12;57019:5;;57025:1;57019:8;;;;;;;;;;;;;;;;;;:::i;:::-;57008:47;;;;;;;:::i;:::-;56965:90;;;;;;57074:8;-1:-1:-1;;;;;57074:17:0;;57092:5;57099:10;57111:2;57115:27;57120:5;57127:6;57135;57115:4;:27::i;:::-;57074:69;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56909:1394;;;;;;57169:40;;;50194:2;57169:40;57165:1138;;;57231:12;57245:20;57267:23;57305:5;;57311:1;57305:8;;;;;;;;;;;;;;;;;;:::i;:::-;57294:52;;;;;;;:::i;:::-;57230:116;;;;;;57365:8;-1:-1:-1;;;;;57365:25:0;;57391:5;57398:10;57410:3;57415:6;57365:57;;;;;;;;;;;;;;;;;;:::i;57165:1138::-;57448:21;;;50350:2;57448:21;57444:859;;;57491:23;57516:18;57538:42;57544:6;;57551:1;57544:9;;;;;;;;;;;;;57555:5;;57561:1;57555:8;;;;;;;;;;;;;;;;;;:::i;:::-;57538:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57565:6:0;;-1:-1:-1;57573:6:0;;-1:-1:-1;57538:5:0;;-1:-1:-1;57538:42:0:i;:::-;57490:90;;;;57605:12;:17;;57621:1;57605:17;57601:243;;;57669:10;57658:33;;;;;;;;;;;;:::i;:::-;57647:44;;57601:243;;;57721:12;:17;;57737:1;57721:17;57717:127;;;57793:10;57782:42;;;;;;;;;;;;:::i;:::-;57763:61;;-1:-1:-1;57763:61:0;-1:-1:-1;57717:127:0;57444:859;;;;;57869:32;;;49648:1;57869:32;57865:438;;;57922:11;57947:5;;57953:1;57947:8;;;;;;;;;;;;;;;;;;:::i;:::-;57936:30;;;;;;;:::i;:::-;58011:5;;57922:44;;-1:-1:-1;;;;;;57994:8:0;:16;;;;;58011:5;58018:55;58040:26;57922:44;58051:6;58059;58040:4;:26::i;:::-;58018:21;;;;;;;;;:11;:21;-1:-1:-1;;;;;58018:21:0;;;;;-1:-1:-1;;;58018:21:0;;;;;;;;;58068:4;58018:21;:55::i;:::-;58075:4;57994:86;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57985:95;;57865:438;;;;58106:31;;;49704:1;58106:31;58102:201;;;58158:13;58185:5;;58191:1;58185:8;;;;;;;;;;;;;;;;;;:::i;:::-;58174:30;;;;;;;:::i;:::-;58158:46;;58232:55;58251:28;58256:6;58264;58272;58251:4;:28::i;:::-;58232:18;;;;;;;;;:11;:18;-1:-1:-1;;;;;58232:18:0;;;;;-1:-1:-1;;;58232:18:0;;;;;;;;;58281:5;58232:18;:55::i;:::-;58223:64;;58102:201;;-1:-1:-1;54238:3:0;;54198:4116;;;-1:-1:-1;58330:25:0;;58326:139;;;58380:43;58391:10;58403:5;58410:12;;58380:10;:43::i;:::-;58372:81;;;;-1:-1:-1;;;58372:81:0;;;;;;;:::i;:::-;53969:4503;;;;;;;;;;:::o;31727:37::-;;;:::o;7228:44::-;;;;;;;;;;;;;;:::o;32084:23::-;;;;;;;;;;;;;;;-1:-1:-1;;32084:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;59081:4209::-;59343:21;59368:20;:18;:20::i;:::-;59340:48;;;59399:8;:6;:8::i;:::-;59420:26;59457:23;59491:21;59523:26;;:::i;:::-;-1:-1:-1;59523:40:0;;;;;;;;;59552:11;59523:40;-1:-1:-1;;;;;59523:40:0;;;;;-1:-1:-1;;;59523:40:0;;;;;;;;59574:28;;:::i;:::-;59621:10;;59605:27;;-1:-1:-1;;;59605:27:0;;-1:-1:-1;;;;;59605:8:0;:15;;;;;:27;;59621:10;;;;;59605:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59574:58;;59648:9;59643:1492;59663:16;;;59643:1492;;;59701:12;59716:5;;59722:1;59716:8;;;;;;;;;;;;;;;;;;;;:::i;:::-;59701:23;;59744:37;59755:4;59761;59767:13;59744:10;:37::i;:::-;59739:1385;;-1:-1:-1;;;;;59892:20:0;;59802:18;59892:20;;;:14;:20;;;;;;;59948:14;;59963:1;59948:17;;;;;;;;;;;;;:39;:81;;60012:14;;60027:1;60012:17;;;;;;;;;;;;;59948:81;;;59990:19;59948:81;59935:94;-1:-1:-1;60075:35:0;:19;59935:94;60075:23;:35::i;:::-;-1:-1:-1;;;;;60052:20:0;;;;;;:14;:20;;;;;:58;;;;:20;-1:-1:-1;60171:41:0;:12;60194:10;60052:20;60171:22;:41::i;:::-;60148:64;-1:-1:-1;60231:23:0;60278:254;60418:58;60326:59;60371:13;60326:40;60148:64;35003:6;60326:16;:40::i;:::-;:44;;:59::i;:::-;:151;;;;;60278:14;;60326:151;;60504:5;60278:21;:254::i;:::-;-1:-1:-1;;;;;60581:25:0;;;;;;:19;:25;;;;;;60231:301;;-1:-1:-1;60581:46:0;;60231:301;60581:29;:46::i;:::-;-1:-1:-1;;;;;60553:25:0;;;;;;;:19;:25;;;;;:74;;;;60677:22;;;:46;;60715:7;60677:46;;;60702:2;60677:46;-1:-1:-1;;;;;60651:90:0;60671:4;-1:-1:-1;;;;;60651:90:0;;60725:15;60651:90;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;60765:96:0;;;;60774:22;;;:54;;60820:7;60774:54;;;60799:10;60774:54;-1:-1:-1;;;;;60765:96:0;;60836:12;60850:10;60765:96;;;;;;;:::i;:::-;;;;;;;;60935:39;:18;60958:15;60935:22;:39::i;:::-;60914:60;-1:-1:-1;61011:33:0;:15;61031:12;61011:19;:33::i;:::-;60993:51;-1:-1:-1;61079:29:0;:13;61097:10;61079:17;:29::i;:::-;61063:45;;59739:1385;;;;-1:-1:-1;59681:3:0;;59643:1492;;;-1:-1:-1;61153:20:0;61145:59;;;;-1:-1:-1;;;61145:59:0;;;;;;;:::i;:::-;61238:49;61263:23;:15;:21;:23::i;:::-;61238:20;;-1:-1:-1;;;;;61238:24:0;;;:49::i;:::-;-1:-1:-1;;;;;61215:72:0;;;61318:44;61340:21;:13;:19;:21::i;:::-;61318:17;;;;-1:-1:-1;;;;;61318:21:0;;;:44::i;:::-;-1:-1:-1;;;;;61298:64:0;;;:17;;;:64;;;61373:26;;:11;:26;;-1:-1:-1;;;;;;61373:26:0;;;;;;;;;;;-1:-1:-1;;;61373:26:0;;;;;;61433:20;;:44;;61458:18;61433:24;:44::i;:::-;61410:20;:67;61532:5;;61515:46;;-1:-1:-1;;;61515:46:0;;61490:22;;-1:-1:-1;;;;;61515:8:0;:16;;;;;:46;;61532:5;;61539:15;;61532:5;;61515:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61490:71;;61579:4;61574:1709;;61699:32;;-1:-1:-1;;;61699:32:0;;-1:-1:-1;;;;;61699:14:0;:23;;;;:32;;61723:7;;61699:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61691:71;;;;-1:-1:-1;;;61691:71:0;;;;;;;:::i;:::-;61864:10;;61846:82;;-1:-1:-1;;;61846:82:0;;-1:-1:-1;;;;;61846:8:0;:17;;;;;:82;;61864:10;;;;;61884:4;;61899:7;;61909:18;;61846:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;61956:10:0;;61968:5;;61943:82;;-1:-1:-1;;;61943:82:0;;-1:-1:-1;;;;;61943:12:0;;;;-1:-1:-1;61943:12:0;;-1:-1:-1;61943:82:0;;61956:10;;;61968:5;;61983:4;;61990:14;;62006:18;;61943:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;62119:10:0;:18;62085:5;;62066:40;;-1:-1:-1;;;62066:40:0;;62042:21;;62066:73;;-1:-1:-1;;;;;62119:18:0;;;;-1:-1:-1;;;;;62066:8:0;:18;;;;;:40;;62085:5;;;;;62100:4;;62066:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;:73::i;:::-;62042:97;-1:-1:-1;62154:18:0;62175:33;62042:97;62193:14;62175:17;:33::i;:::-;62154:54;-1:-1:-1;62223:16:0;35219:3;62242:28;62154:54;35152:5;62242:14;:28::i;:::-;:51;;;;;;62223:70;;62388:8;-1:-1:-1;;;;;62388:17:0;;62406:5;;;;;;;;;-1:-1:-1;;;;;62406:5:0;62421:4;62428:14;-1:-1:-1;;;;;62428:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62452:8;62388:73;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62497:59;62520:35;:27;62538:8;62520:13;:17;;:27;;;;:::i;:::-;:33;:35::i;:::-;62497:10;:18;-1:-1:-1;;;;;62497:18:0;;:22;:59::i;:::-;62476:10;:80;;-1:-1:-1;;;;;;62476:80:0;-1:-1:-1;;;;;62476:80:0;;;;;;;;;;62614:4;-1:-1:-1;;;;;62576:73:0;;;62621:24;:10;62636:8;62621:14;:24::i;:::-;62647:1;62576:73;;;;;;;:::i;:::-;;;;;;;;61574:1709;;;;;;62855:10;;-1:-1:-1;;;;;62837:8:0;:17;;;;;62855:10;;;;62875:4;;62882:22;;;:46;;62920:7;62882:46;;;62907:2;62882:46;62930:18;62837:112;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;62968:22:0;;;62964:142;;63024:10;;63036:5;;63011:79;;-1:-1:-1;;;63011:79:0;;-1:-1:-1;;;;;63011:12:0;;;;;;:79;;63024:10;;;;63036:5;;63043:10;;63055:14;;63071:18;;63011:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;62964:142;63140:5;;63122:67;;-1:-1:-1;;;63122:67:0;;-1:-1:-1;;;;;63122:8:0;:17;;;;;:67;;63140:5;;;;;63147:10;;63167:4;;63174:14;;63122:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63225:46;63248:22;:14;:20;:22::i;63225:46::-;63204:10;:67;;-1:-1:-1;;;;;;63204:67:0;-1:-1:-1;;;;;63204:67:0;;;;;;;;;;61574:1709;59081:4209;;;;;;;;;;;;;;:::o;32056:21::-;;;-1:-1:-1;;;;;32056:21:0;;:::o;7462:41::-;;;;;;;;;;;;;:::o;32339:25::-;;;-1:-1:-1;;;;;32339:25:0;;;;-1:-1:-1;;;32339:25:0;;;;:::o;42914:467::-;-1:-1:-1;;;;;43053:23:0;;;;;;:19;:23;;;;;;:34;;43081:5;43053:27;:34::i;:::-;-1:-1:-1;;;;;43027:23:0;;;;;;:19;:23;;;;;:60;43132:20;;43186:34;43132:20;43214:5;43186:27;:34::i;:::-;43163:20;:57;43242:10;;43231:60;;-1:-1:-1;;;;;43242:10:0;43254:5;43261:23;43286:4;43231:10;:60::i;:::-;43363:2;-1:-1:-1;;;;;43307:66:0;43324:4;:37;;43351:10;43324:37;;;43339:8;43324:37;-1:-1:-1;;;;;43307:66:0;;43367:5;43307:66;;;;;;:::i;:::-;;;;;;;;42914:467;;;;:::o;43982:194::-;44121:8:::1;:6;:8::i;:::-;44140:28;44158:2;44162:5;44140:17;:28::i;:::-;40984:43:::0;40995:10;41007:5;41014:12;;40984:10;:43::i;:::-;40976:81;;;;-1:-1:-1;;;40976:81:0;;;;;;;:::i;:::-;43982:194;;:::o;31893:41::-;;;;;;;;;;;;;;;:::o;2924:20::-;;;-1:-1:-1;;;;;2924:20:0;;:::o;33080:194::-;33184:10;;33121:13;;33184:23;;-1:-1:-1;;;;;33184:10:0;:21;:23::i;:::-;33214:5;;:18;;-1:-1:-1;;;;;33214:5:0;:16;:18::i;:::-;33239:6;;:25;;-1:-1:-1;;;33239:25:0;;-1:-1:-1;;;;;33239:6:0;;;;:13;;:25;;33253:10;;33239:25;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;33239:25:0;;;;;;;;;;;;:::i;:::-;33161:104;;;;;;;;;;:::i;7942:751::-;8004:4;8095:11;;8091:525;;8154:10;8123:18;8144:21;;;;;;;;;;;8188:20;;;;8180:55;;;;-1:-1:-1;;;8180:55:0;;;;;;;:::i;:::-;8254:10;-1:-1:-1;;;;;8254:16:0;;;8250:355;;-1:-1:-1;;;;;8299:16:0;;8291:51;;;;-1:-1:-1;;;8291:51:0;;;;;;;:::i;:::-;8422:10;8412:9;:21;;;;;;;;;;;8436:19;;;8412:43;;-1:-1:-1;;;;;8498:13:0;;;;;;:23;;;;;;8250:355;8091:525;;8652:2;-1:-1:-1;;;;;8631:32:0;8640:10;-1:-1:-1;;;;;8631:32:0;;8656:6;8631:32;;;;;;:::i;33017:28::-;;;;;;;;;;;;;;;-1:-1:-1;;;33017:28:0;;-1:-1:-1;;;;;33017:28:0;;:::o;31771:53::-;;;:::o;11348:665::-;-1:-1:-1;;;;;11559:20:0;;11551:57;;;;-1:-1:-1;;;11551:57:0;;;;;;;:::i;:::-;11645:8;11627:15;:26;11619:53;;;;-1:-1:-1;;;11619:53:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;11705:155:0;;11747:21;11794:14;;;:6;:14;;;;;;;;;:16;;11705:128;11794:16;;;;;;11736:85;;11705:128;;11715:108;;11736:85;;10881:66;;11854:6;;11778:7;;11787:5;;11794:16;11812:8;;11736:85;;:::i;:::-;;;;;;;;;;;;;11726:96;;;;;;11715:10;:108::i;:::-;11825:1;11828;11831;11705:128;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11705:155:0;;11683:229;;;;-1:-1:-1;;;11683:229:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;11923:17:0;;;;;;;:9;:17;;;;;;;;:26;;;;;;;;;;;;;;:34;;;11973:32;;;;;11952:5;;11973:32;:::i;:::-;;;;;;;;11348:665;;;;;;;:::o;31999:24::-;;;-1:-1:-1;;;;;31999:24:0;;:::o;7333:64::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;2951:27::-;;;-1:-1:-1;;;;;2951:27:0;;:::o;64313:122::-;4834:5;;-1:-1:-1;;;;;4834:5:0;4820:10;:19;4812:64;;;;-1:-1:-1;;;4812:64:0;;;;;;;:::i;:::-;64377:5:::1;:16:::0;;-1:-1:-1;;;;;;64377:16:0::1;-1:-1:-1::0;;;;;64377:16:0;::::1;::::0;;::::1;::::0;;;64409:18:::1;::::0;::::1;::::0;-1:-1:-1;;64409:18:0::1;64313:122:::0;:::o;36405:3227::-;36441:29;;:::i;:::-;-1:-1:-1;36441:42:0;;;;;;;;36473:10;36441:42;;;;;;;;;;;;;;;;;-1:-1:-1;;;36441:42:0;;;-1:-1:-1;;;;;36441:42:0;;;;;;;;;36570:15;:41;;36622:55;;36659:7;;;;36622:55;36687:49;36720:15;36687:49;:23;;;:49;36749:26;;:::i;:::-;-1:-1:-1;36749:40:0;;;;;;;;;36778:11;36749:40;-1:-1:-1;;;;;36749:40:0;;;;;-1:-1:-1;;;36749:40:0;;;;;;;;;;36800:413;;36912:29;;:61;;34555:9;36912:61;36908:234;;34555:9;36994:60;;;37078:48;;;;;;36994:29;;;;;;37078:48;:::i;:::-;;;;;;;;36908:234;-1:-1:-1;;37156:24:0;;:10;:24;;;;;;;;;;;-1:-1:-1;;37156:24:0;;;;;;;;-1:-1:-1;;37156:24:0;;;;;;;;;;;;;;-1:-1:-1;;;;;37156:24:0;;;-1:-1:-1;;;37156:24:0;;;;;;;;37195:7;;36800:413;37225:19;37259;37293:25;;:::i;:::-;-1:-1:-1;37293:38:0;;;;;;;;;37321:10;37293:38;-1:-1:-1;;;;;37293:38:0;;;;;-1:-1:-1;;;37293:38:0;;;;;;;;;37420:29;;37394:20;;37470:4;;37386:81;;37455:11;;37386:64;;:29;;:64;;:33;:64::i;:81::-;:88;;;;;;37372:102;;37508:45;37533:19;:11;:17;:19::i;:::-;37508:20;;-1:-1:-1;;;;;37508:24:0;;;:45::i;:::-;-1:-1:-1;;;;;37485:68:0;;;;37608:5;;37615:19;;37590:52;;-1:-1:-1;;;37590:52:0;;37485:20;;37590:78;;37485:68;;-1:-1:-1;;;;;37590:8:0;:17;;;;;:52;;37608:5;;;37615:19;37485:20;;37590:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:56;;:78::i;:::-;37564:104;-1:-1:-1;37681:17:0;35219:3;37701:29;:11;35152:5;37701:15;:29::i;:::-;:52;;;;;;37681:72;;37846:15;37812:31;37826:11;:16;;;-1:-1:-1;;;;;37812:31:0;:9;:13;;:31;;;;:::i;:::-;:49;;;;;;37798:63;;37905:55;37940:19;:11;:17;:19::i;:::-;37905:30;;;;-1:-1:-1;;;;;37905:34:0;;;:55::i;:::-;-1:-1:-1;;;;;37872:88:0;:30;;;:88;37989:41;38010:19;:11;:17;:19::i;:::-;37989:16;;;;-1:-1:-1;;;;;37989:20:0;;;:41::i;:::-;37971:10;:59;;-1:-1:-1;;;;;37971:59:0;;;-1:-1:-1;;;37971:59:0;;;;;;;;;38041:26;;:11;:26;;;;;;-1:-1:-1;;;;;;38041:26:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;38194:15:0;;38135:56;;34271:4;38135:33;:56::i;:::-;:74;;;;;;38113:96;;34132:4;38224:11;:40;38220:1273;;;38281:19;34132:4;38303:65;34487:4;38303:43;34132:4;38334:11;38303:30;:43::i;:65::-;:94;;;;;;;-1:-1:-1;38412:13:0;38428:70;38452:45;38485:11;38452:28;38303:94;;38452:15;:28::i;:45::-;34817:8;;38428:23;:70::i;:::-;38560:29;;38412:86;;-1:-1:-1;38412:86:0;;38552:63;;:38;;34817:8;38552:42;:63::i;:::-;:71;;;;;;38513:111;;;;;34642:8;-1:-1:-1;38641:180:0;;;34642:8;38725:59;;38641:180;38220:1273;;;;;34204:4;38842:11;:40;38838:655;;;38899:18;34391:45;38920:65;34326:4;38920:43;:11;34204:4;38920:15;:43::i;:65::-;:94;;;;;;;-1:-1:-1;39029:13:0;39045:68;39069:43;39100:11;39069:26;38920:94;;39069:14;:26::i;39045:68::-;39167:29;;39029:84;;-1:-1:-1;39128:28:0;;34817:8;;39159:49;;:38;;39029:84;39159:42;:49::i;:::-;:71;;;;;;;-1:-1:-1;34731:12:0;39249:50;;39245:162;;;-1:-1:-1;34731:12:0;39245:162;39421:60;;;;-1:-1:-1;;38838:655:0;39546:29;;39510:79;;;;;;39520:11;;39533;;39577;;39510:79;:::i;:::-;;;;;;;;-1:-1:-1;;39600:24:0;;:10;:24;;;;;;;;;;;-1:-1:-1;;39600:24:0;;;;;;;;-1:-1:-1;;39600:24:0;;;;;;;;;;;;;;-1:-1:-1;;;;;39600:24:0;;;-1:-1:-1;;;39600:24:0;;;;;;;;;-1:-1:-1;;;;;;36405:3227:0;:::o;32209:24::-;;;-1:-1:-1;;;;;32209:24:0;;;;-1:-1:-1;;;32209:24:0;;;;:::o;18239:244::-;18382:32;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18382:32:0;-1:-1:-1;;;18382:32:0;;;18356:59;;18294:13;;18321:12;;18294:13;;-1:-1:-1;;;;;18356:25:0;;;:59;;18382:32;18356:59;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18320:95;;;;18433:7;:42;;;;;;;;;;;;;;;-1:-1:-1;;;18433:42:0;;;;;;18443:24;18462:4;18443:18;:24::i;:::-;18426:49;;;;18239:244;;;;:::o;48133:571::-;48289:15;;;;;;;;;:11;:15;-1:-1:-1;;;;;48289:15:0;;;;;-1:-1:-1;;;48289:15:0;;;;;;;;48238:14;;48289:27;;48305:4;48311;48289:15;:27::i;:::-;48265:51;;48266:11;48265:51;;;;;;;-1:-1:-1;;;;;48265:51:0;;;-1:-1:-1;;;48265:51:0;;;;-1:-1:-1;;;;;;48265:51:0;;;;;;;;;;;;;;-1:-1:-1;;;;;48348:18:0;;48266:11;48348:18;;;:14;:18;;;;;;;;48265:51;;-1:-1:-1;48348:28:0;;48371:4;48348:22;:28::i;:::-;-1:-1:-1;;;;;48327:18:0;;;;;;;:14;:18;;;;;;:49;;;;48422:5;;48405:37;;-1:-1:-1;;;48405:37:0;;48327:18;;48405:8;:16;;;;;:37;;48422:5;;;;48429:6;;48422:5;;48405:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48474:10;:18;48514:5;;48389:53;;-1:-1:-1;;;;;;48474:18:0;;48503:51;;-1:-1:-1;;;;;48514:5:0;48389:53;48474:18;48549:4;48503:10;:51::i;:::-;48586:29;48601:13;:5;:11;:13::i;:::-;-1:-1:-1;;;;;48586:14:0;;;;:29::i;:::-;48565:10;:50;;-1:-1:-1;;;;;;48565:50:0;-1:-1:-1;;;;;48565:50:0;;;;;;;;;;-1:-1:-1;;;;;48631:65:0;;48640:4;:37;;48667:10;48640:37;;;48655:8;48640:37;-1:-1:-1;;;;;48631:65:0;;48683:6;48691:4;48631:65;;;;;;;:::i;:::-;;;;;;;;48133:571;;;;;;;:::o;44237:777::-;44346:16;44375:25;;:::i;:::-;-1:-1:-1;44375:38:0;;;;;;;;44403:10;44375:38;-1:-1:-1;;;;;44375:38:0;;;;;;-1:-1:-1;;;44375:38:0;;;;;;;;;44538:5;;44545:11;:19;44521:50;;-1:-1:-1;;;44521:50:0;;44375:38;;;;-1:-1:-1;;;;;;;44521:8:0;:16;;;;;:50;;44538:5;;;44545:19;;44375:38;;44521:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44499:19;;-1:-1:-1;;;;;44499:72:0;;;-1:-1:-1;44593:13:0;;:62;;44647:8;44617:27;44627:11;:16;;;-1:-1:-1;;;;;44617:27:0;:5;:9;;:27;;;;:::i;:::-;:38;;;;;;44593:62;;;44609:5;44593:62;44582:73;;44711:4;44670:38;44691:16;:8;:14;:16::i;:::-;44670;;;;-1:-1:-1;;;;;44670:20:0;;;:38::i;:::-;-1:-1:-1;;;;;44670:45:0;;44666:86;;;44739:1;44732:8;;;;;;;44666:86;44775:32;:11;44791:5;44798:8;44775:15;:32::i;:::-;44762:45;;:10;:45;;;;;;;-1:-1:-1;;;;;44762:45:0;;;-1:-1:-1;;;44762:45:0;;;;-1:-1:-1;;;;;;44762:45:0;;;;;;;;;;;;;;-1:-1:-1;;;;;44834:13:0;;44762:45;44834:13;;;;;;;;;;;:27;;44852:8;44834:17;:27::i;:::-;-1:-1:-1;;;;;44818:13:0;;;:9;:13;;;;;;;;;;:43;;;;44883:5;;44872:47;;44883:5;44890;44897:15;44914:4;44872:10;:47::i;:::-;44986:2;-1:-1:-1;;;;;44935:71:0;44947:4;:37;;44974:10;44947:37;;;44962:8;44947:37;-1:-1:-1;;;;;44935:71:0;;44990:5;44997:8;44935:71;;;;;;;:::i;:::-;;;;;;;;44237:777;;;;;;;;:::o;45677:740::-;45747:13;45773:25;;:::i;:::-;-1:-1:-1;45773:38:0;;;;;;;;45801:10;45773:38;-1:-1:-1;;;;;45773:38:0;;;;;-1:-1:-1;;;45773:38:0;;;;;;;;;45880:5;;45887:11;:19;45863:50;;-1:-1:-1;;;45863:50:0;;45773:38;;-1:-1:-1;;;;;;;45863:8:0;:16;;;;;:50;;45880:5;;;45887:19;;;45773:38;;45863:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45841:19;;45957:16;;;;-1:-1:-1;;;;;45841:72:0;;;;;;;;-1:-1:-1;45932:41:0;:22;:8;45841:72;45932:12;:22::i;:::-;:41;;;;;46018:10;46008:9;:21;;;;;;;;;;;45932:41;;;;-1:-1:-1;46008:35:0;;46034:8;46008:25;:35::i;:::-;45994:10;45984:9;:21;;;;;;;;;;:59;46076:38;46100:13;:5;:11;:13::i;46076:38::-;-1:-1:-1;;;;;46054:60:0;;;46144:38;46165:16;:8;:14;:16::i;46144:38::-;-1:-1:-1;;;;;46125:57:0;:16;;;:57;;;46221:4;-1:-1:-1;46201:24:0;46193:57;;;;-1:-1:-1;;;46193:57:0;;;;;;;:::i;:::-;46261:24;;:10;:24;;;;;;-1:-1:-1;;;;;46261:24:0;;;-1:-1:-1;;;46261:24:0;;;;-1:-1:-1;;;;;;46261:24:0;;;;;;;;;;;;;;46301:47;;-1:-1:-1;;;;;46301:47:0;;;46316:10;;46301:47;;;;46332:5;;46339:8;;46301:47;:::i;:::-;;;;;;;;46377:5;;46359:50;;-1:-1:-1;;;46359:50:0;;-1:-1:-1;;;;;46359:8:0;:17;;;;;:50;;46377:5;;;;;46392:4;;46399:2;;46403:5;;46359:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45677:740;;;;;;:::o;18690:263::-;18829:36;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18829:36:0;-1:-1:-1;;;18829:36:0;;;18803:63;;18749:5;;;;18782:17;;-1:-1:-1;;;;;18803:25:0;;;:63;;18829:36;18803:63;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18767:99;;;;18884:7;:28;;;;;18895:4;:11;18910:2;18895:17;18884:28;:61;;18943:2;18884:61;;;18926:4;18915:25;;;;;;;;;;;;:::i;5706:187::-;5780:7;5296:68;5861:7;5878:4;5817:67;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5807:78;;;;;;5800:85;;5706:187;;;:::o;1207:141::-;1300:5;;;1295:16;;;;1287:53;;;;-1:-1:-1;;;1287:53:0;;;;;;;:::i;46912:798::-;46975:12;;;35349:3;47035:30;:6;35275:2;47035:10;:30::i;:::-;:61;;;;;;;-1:-1:-1;47173:44:0;47189:21;:6;47035:61;47189:10;:21::i;:::-;47173:15;;;;;;;;;:11;:15;-1:-1:-1;;;;;47173:15:0;;;;;-1:-1:-1;;;47173:15:0;;;;;;;;;47212:4;47173:15;:44::i;:::-;47151:66;;47152:11;47151:66;;;;;;;-1:-1:-1;;;;;47151:66:0;;;-1:-1:-1;;;47151:66:0;;;;-1:-1:-1;;;;;;47151:66:0;;;;;;;;;;;;;;47272:10;47152:11;47257:26;;;:14;:26;;;;;;;;47151:66;;-1:-1:-1;47257:36:0;;47151:66;47257:30;:36::i;:::-;47243:10;47228:26;;;;:14;:26;;;;;;;:65;;;;47309:50;;-1:-1:-1;;;;;47309:50:0;;;47243:10;47309:50;;;;47335:6;;47343:9;;47354:4;;47309:50;:::i;:::-;;;;;;;;47397:5;;47380:38;;-1:-1:-1;;;47380:38:0;;-1:-1:-1;;;;;47380:8:0;:16;;;;;:38;;47397:5;;;;;47404:6;;47397:5;;47380:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47372:46;;47429:25;;:::i;:::-;-1:-1:-1;47429:38:0;;;;;;;;;47457:10;47429:38;-1:-1:-1;;;;;47429:38:0;;;;;-1:-1:-1;;;47429:38:0;;;;;;;;;;47506:4;-1:-1:-1;47486:24:0;47478:57;;;;-1:-1:-1;;;47478:57:0;;;;;;;:::i;:::-;47568:38;47592:13;:5;:11;:13::i;:::-;47568:19;;-1:-1:-1;;;;;47568:23:0;;;:38::i;:::-;-1:-1:-1;;;;;47546:60:0;;;;;;47617:10;:24;;;;;;;;-1:-1:-1;;;47617:24:0;-1:-1:-1;;;;;;47617:24:0;;;;;;;;;;;;47670:5;;47652:50;;-1:-1:-1;;;47652:50:0;;-1:-1:-1;;;;;47652:8:0;:17;;;;;:50;;47670:5;;;;;47685:4;;47692:2;;47696:5;;47652:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46912:798;;;;;;;:::o;39854:964::-;-1:-1:-1;;;;;40067:20:0;;39979:4;40067:20;;;:14;:20;;;;;;40102:15;40098:32;;40126:4;40119:11;;;;;40098:32;-1:-1:-1;;;;;40167:25:0;;40141:23;40167:25;;;:19;:25;;;;;;40207:20;40203:38;;40236:5;40229:12;;;;;;40203:38;40254:26;;:::i;:::-;-1:-1:-1;40254:40:0;;;;;;;;;40283:11;40254:40;-1:-1:-1;;;;;40254:40:0;;;;;;-1:-1:-1;;;40254:40:0;;;;;;;;;;;40735:55;;40776:13;;40735:36;;:10;;:14;:36::i;:55::-;:75;;;;;40363:10;;40735:75;;;;-1:-1:-1;;;;;40327:8:0;:17;;;;;40363:10;40392:185;40496:4;:62;;33844:5;40496:62;;;33916:5;40496:62;40392:77;:15;40412:56;40392:19;:77::i;:185::-;40596:5;40327:289;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:483;;;39854:964;-1:-1:-1;;;;;;;39854:964:0:o;50563:230::-;50680:14;50725:1;50716:5;:10;;:69;;-1:-1:-1;;50747:5:0;:19;:37;;50778:6;50747:37;;;50769:6;50747:37;50716:69;;;-1:-1:-1;50737:5:0;;50707:78;-1:-1:-1;;50563:230:0:o;43450:347::-;43578:10;43558:31;;;;:19;:31;;;;;;:42;;43594:5;43558:35;:42::i;:::-;43544:10;43524:31;;;;:19;:31;;;;;:76;43634:20;;:31;;43659:5;43634:24;:31::i;:::-;43611:20;:54;43681:42;;-1:-1:-1;;;;;43681:42:0;;;43701:10;;43681:42;;;;43717:5;;43681:42;:::i;:::-;;;;;;;;43752:10;;43734:55;;-1:-1:-1;;;43734:55:0;;-1:-1:-1;;;;;43734:8:0;:17;;;;;:55;;43752:10;;;;;43772:4;;43779:2;;43783:5;;43734:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43450:347;;:::o;50863:558::-;51013:7;51022;51043:12;51057:10;51069:13;51084:12;51111:4;51100:51;;;;;;;;;;;;:::i;:::-;51042:109;;;;;;;;51178:28;51183:6;51191;51199;51178:4;:28::i;:::-;51162:45;;51281:27;51286:5;51293:6;51301;51281:4;:27::i;:::-;51266:43;;51327:8;-1:-1:-1;;;;;51327:16:0;;51351:5;51358;51365:10;51377:2;51389:6;51406:5;51327:86;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51320:93;;;;;;;;50863:558;;;;;;;:::o;51492:390::-;51619:7;51628;51649:12;51663:10;51675:13;51690:12;51717:4;51706:51;;;;;;;;;;;;:::i;:::-;51648:109;;;;;;;;51775:8;-1:-1:-1;;;;;51775:17:0;;51793:5;51800:10;51812:2;51816:28;51821:6;51829;51837;51816:4;:28::i;:::-;51846:27;51851:5;51858:6;51866;51846:4;:27::i;:::-;51775:99;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51768:106;;;;;;;;51492:390;;;;;;:::o;52160:964::-;52302:12;52316:5;52335:14;52351:21;52374:14;52390;52406:18;52452:4;52441:53;;;;;;;;;;;;:::i;:::-;52334:160;;;;;;;;;;52511:9;:23;;;;;52525:9;52524:10;52511:23;52507:322;;;52579:8;52589:6;52562:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52551:45;;52507:322;;;52619:9;52618:10;:23;;;;;52632:9;52618:23;52614:215;;;52686:8;52696:6;52669:34;;;;;;;;;:::i;52614:215::-;52725:9;:22;;;;;52738:9;52725:22;52721:108;;;52792:8;52802:6;52810;52775:42;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52764:53;;52721:108;52867:8;-1:-1:-1;;;;;52849:27:0;:6;-1:-1:-1;;;;;52849:27:0;;;:54;;;;-1:-1:-1;;;;;;52880:23:0;;52898:4;52880:23;;52849:54;52841:88;;;;-1:-1:-1;;;52841:88:0;;;;;;;:::i;:::-;52943:12;52957:23;52984:6;-1:-1:-1;;;;;52984:11:0;53003:5;53010:8;52984:35;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52942:77;;;;53038:7;53030:42;;;;-1:-1:-1;;;53030:42:0;;;;;;;:::i;:::-;53091:10;53103:12;;-1:-1:-1;52160:964:0;;-1:-1:-1;;;;;;;;;;52160:964:0:o;13454:437::-;13579:15;13611:5;:10;;;-1:-1:-1;;;;;13611:15:0;13625:1;13611:15;13607:277;;;-1:-1:-1;13653:4:0;13607:277;;;13726:10;;;;13709:13;;-1:-1:-1;;;;;13700:36:0;;;;:23;;:4;;:23;:8;:23::i;:::-;:36;;;;;;13690:46;;13755:7;:57;;;;;13808:4;13792:5;:13;;;-1:-1:-1;;;;;13766:39:0;:23;13778:5;:10;;;-1:-1:-1;;;;;13766:23:0;:7;:11;;:23;;;;:::i;:::-;:39;;;;;;:46;13755:57;13751:122;;;13843:14;:7;13855:1;13843:11;:14::i;12930:431::-;13084:13;;13055:12;;-1:-1:-1;;;;;13084:18:0;13080:274;;-1:-1:-1;13126:7:0;13080:274;;;13199:13;;13185:10;;;;-1:-1:-1;;;;;13173:39:0;;;;:23;;:7;;:23;:11;:23::i;:::-;:39;;;;;;13166:46;;13231:7;:57;;;;;13281:7;13268:5;:10;;;-1:-1:-1;;;;;13242:36:0;:23;13251:5;:13;;;-1:-1:-1;;;;;13242:23:0;:4;:8;;:23;;;;:::i;1356:138::-;1449:5;;;1444:16;;;;1436:50;;;;-1:-1:-1;;;1436:50:0;;;;;;;:::i;1502:155::-;1560:9;1590:6;;;:30;;-1:-1:-1;;1605:5:0;;;1619:1;1614;1605:5;1614:1;1600:15;;;;;:20;1590:30;1582:67;;;;-1:-1:-1;;;1582:67:0;;;;;;;:::i;1665:161::-;1714:9;-1:-1:-1;;;;;1744:16:0;;;1736:57;;;;-1:-1:-1;;;1736:57:0;;;;;;;:::i;:::-;-1:-1:-1;1816:1:0;1665:161::o;2439:138::-;2532:5;;;-1:-1:-1;;;;;2527:16:0;;;;;;;;2519:50;;;;-1:-1:-1;;;2519:50:0;;;;;;;:::i;2290:141::-;2383:5;;;-1:-1:-1;;;;;2378:16:0;;;;;;;;2370:53;;;;-1:-1:-1;;;2370:53:0;;;;;;;:::i;42181:370::-;42323:4;42319:225;;;42361:51;42406:5;42361:8;-1:-1:-1;;;;;42361:18:0;;42380:5;42395:4;42361:40;;;;;;;;;;;;;;;;:::i;:51::-;42352:5;:60;;42344:97;;;;-1:-1:-1;;;42344:97:0;;;;;;;:::i;:::-;42319:225;;;42474:58;;-1:-1:-1;;;42474:58:0;;-1:-1:-1;;;;;42474:8:0;:17;;;;:58;;42492:5;;42499:10;;42519:4;;42526:5;;42474:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42319:225;42181:370;;;;:::o;17789:248::-;17934:34;;;;;;;;;;;;;;;;-1:-1:-1;;;;;17934:34:0;-1:-1:-1;;;17934:34:0;;;17908:61;;17846:13;;17873:12;;17846:13;;-1:-1:-1;;;;;17908:25:0;;;:61;;17934:34;17908:61;:::i;6697:204::-;6758:14;6821:40;;;;;;;;;;;;;-1:-1:-1;;;6821:40:0;;;6863:18;:16;:18::i;:::-;6883:8;6804:88;;;;;;;;;;:::i;16996:587::-;17066:13;17111:2;17096:4;:11;:17;17092:484;;17148:4;17137:26;;;;;;;;;;;;:::i;:::-;17130:33;;;;17092:484;17185:4;:11;17200:2;17185:17;17181:395;;;17219:7;17245:69;17256:2;17252:1;:6;;;:22;;;;;17262:4;17267:1;17262:7;;;;;;;;;;;;;;;;:12;;17252:22;17245:69;;;17295:3;;17245:69;;;17328:23;17364:1;17354:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17354:12:0;;17328:38;;17390:1;17386:5;;17381:99;17397:2;17393:1;:6;;;:22;;;;;17403:4;17408:1;17403:7;;;;;;;;;;;;;;;;:12;;17393:22;17381:99;;;17457:4;17462:1;17457:7;;;;;;;;;;;;;;;;;;17441:10;17452:1;17441:13;;;;;;;;;;;;;:23;;;;;;;;;;-1:-1:-1;17417:3:0;;;;;17381:99;;;17508:10;-1:-1:-1;17494:25:0;;-1:-1:-1;17494:25:0;17181:395;-1:-1:-1;17552:12:0;;;;;;;;;;;;-1:-1:-1;;;17552:12:0;;;;;;14582:358;14701:13;;:::i;:::-;14716:15;14754:31;14764:5;14771:4;14777:7;14754:9;:31::i;:::-;14744:41;;14812:34;14830:15;:7;:13;:15::i;:::-;14812:13;;-1:-1:-1;;;;;14812:17:0;;;:34::i;:::-;-1:-1:-1;;;;;14796:50:0;;;14870:28;14885:12;:4;:10;:12::i;:::-;14870:10;;;;-1:-1:-1;;;;;14870:14:0;;;:28::i;:::-;-1:-1:-1;;;;;14857:41:0;:10;;;:41;:10;;14582:358;-1:-1:-1;;;14582:358:0:o;15002:281::-;15124:13;;:::i;:::-;15166:34;15184:15;:7;:13;:15::i;15166:34::-;-1:-1:-1;;;;;15150:50:0;;;15224:28;15239:12;:4;:10;:12::i;15224:28::-;-1:-1:-1;;;;;15211:41:0;:10;;;:41;-1:-1:-1;15211:10:0;;15002:281;-1:-1:-1;;15002:281:0:o;14060:352::-;14182:13;;:::i;:::-;14197:12;14229:31;14236:5;14243:7;14252;14229:6;:31::i;:::-;14222:38;;14287:34;14305:15;:7;:13;:15::i;:::-;14287:13;;-1:-1:-1;;;;;14287:17:0;;;:34::i;:::-;-1:-1:-1;;;;;14271:50:0;;;14345:28;14360:12;:4;:10;:12::i;:::-;14345:10;;;;-1:-1:-1;;;;;14345:14:0;;;:28::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;5:130;72:20;;97:33;72:20;97:33;:::i;611:352::-;;;741:3;734:4;726:6;722:17;718:27;708:2;;-1:-1;;749:12;708:2;-1:-1;779:20;;819:18;808:30;;805:2;;;-1:-1;;841:12;805:2;885:4;877:6;873:17;861:29;;936:3;885:4;;920:6;916:17;877:6;902:32;;899:41;896:2;;;953:1;;943:12;2487:707;;2604:3;2597:4;2589:6;2585:17;2581:27;2571:2;;-1:-1;;2612:12;2571:2;2659:6;2646:20;2681:80;2696:64;2753:6;2696:64;:::i;:::-;2681:80;:::i;:::-;2789:21;;;2672:89;-1:-1;2833:4;2846:14;;;;2821:17;;;2935;;;2926:27;;;;2923:36;-1:-1;2920:2;;;2972:1;;2962:12;2920:2;2997:1;2982:206;3007:6;3004:1;3001:13;2982:206;;;7378:20;;3075:50;;3139:14;;;;3167;;;;3029:1;3022:9;2982:206;;;2986:14;;;;;2564:630;;;;:::o;4787:442::-;;4899:3;4892:4;4884:6;4880:17;4876:27;4866:2;;-1:-1;;4907:12;4866:2;4947:6;4941:13;4969:64;4984:48;5025:6;4984:48;:::i;4969:64::-;4960:73;;5053:6;5046:5;5039:21;5157:3;5089:4;5148:6;5081;5139:16;;5136:25;5133:2;;;5174:1;;5164:12;5133:2;5184:39;5216:6;5089:4;5115:5;5111:16;5089:4;5081:6;5077:17;5184:39;:::i;:::-;;4859:370;;;;:::o;7859:241::-;;7963:2;7951:9;7942:7;7938:23;7934:32;7931:2;;;-1:-1;;7969:12;7931:2;85:6;72:20;97:33;124:5;97:33;:::i;8107:263::-;;8222:2;8210:9;8201:7;8197:23;8193:32;8190:2;;;-1:-1;;8228:12;8190:2;226:6;220:13;238:33;265:5;238:33;:::i;8377:891::-;;;;;;;8577:3;8565:9;8556:7;8552:23;8548:33;8545:2;;;-1:-1;;8584:12;8545:2;371:6;358:20;383:41;418:5;383:41;:::i;:::-;8636:71;-1:-1;8744:2;8791:22;;358:20;383:41;358:20;383:41;:::i;:::-;8752:71;-1:-1;8860:2;8896:22;;3640:20;3665:30;3640:20;3665:30;:::i;:::-;8868:60;-1:-1;8965:2;9002:22;;7654:20;7679:31;7654:20;7679:31;:::i;:::-;8539:729;;;;-1:-1;8539:729;;9071:3;9111:22;;3909:20;;9180:3;9220:22;;;3909:20;;-1:-1;8539:729;-1:-1;;8539:729::o;9275:906::-;;;;;;9467:3;9455:9;9446:7;9442:23;9438:33;9435:2;;;-1:-1;;9474:12;9435:2;528:6;522:13;540:41;575:5;540:41;:::i;:::-;9666:2;9651:18;;9645:25;9526:82;;-1:-1;9690:18;9679:30;;9676:2;;;-1:-1;;9712:12;9676:2;9742:73;9807:7;9798:6;9787:9;9783:22;9742:73;:::i;:::-;9732:83;;;9852:2;9903:9;9899:22;3782:13;3800:30;3824:5;3800:30;:::i;:::-;9968:2;10015:22;;3782:13;9860:71;;-1:-1;3800:30;3782:13;3800:30;:::i;:::-;10084:3;10133:22;;7798:13;9976:71;;-1:-1;7816:31;7798:13;7816:31;:::i;:::-;10093:72;;;;9429:752;;;;;;;;:::o;10188:366::-;;;10309:2;10297:9;10288:7;10284:23;10280:32;10277:2;;;-1:-1;;10315:12;10277:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;10367:63;-1:-1;10467:2;10506:22;;72:20;97:33;72:20;97:33;:::i;:::-;10475:63;;;;10271:283;;;;;:::o;10561:491::-;;;;10699:2;10687:9;10678:7;10674:23;10670:32;10667:2;;;-1:-1;;10705:12;10667:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;10757:63;-1:-1;10857:2;10896:22;;72:20;97:33;72:20;97:33;:::i;:::-;10661:391;;10865:63;;-1:-1;;;10965:2;11004:22;;;;7378:20;;10661:391::o;11059:991::-;;;;;;;;11263:3;11251:9;11242:7;11238:23;11234:33;11231:2;;;-1:-1;;11270:12;11231:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;11322:63;-1:-1;11422:2;11461:22;;72:20;97:33;72:20;97:33;:::i;:::-;11430:63;-1:-1;11530:2;11569:22;;7378:20;;-1:-1;11638:2;11677:22;;7378:20;;-1:-1;11746:3;11784:22;;7654:20;7679:31;7654:20;7679:31;:::i;:::-;11225:825;;;;-1:-1;11225:825;;;;11755:61;11853:3;11893:22;;3909:20;;-1:-1;11962:3;12002:22;;;3909:20;;11225:825;-1:-1;;11225:825::o;12057:479::-;;;;12189:2;12177:9;12168:7;12164:23;12160:32;12157:2;;;-1:-1;;12195:12;12157:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;12247:63;-1:-1;12347:2;12383:22;;3640:20;3665:30;3640:20;3665:30;:::i;:::-;12355:60;-1:-1;12452:2;12488:22;;3640:20;3665:30;3640:20;3665:30;:::i;:::-;12460:60;;;;12151:385;;;;;:::o;12543:485::-;;;;12678:2;12666:9;12657:7;12653:23;12649:32;12646:2;;;-1:-1;;12684:12;12646:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;12736:63;-1:-1;12836:2;12872:22;;3640:20;3665:30;3640:20;3665:30;:::i;13035:366::-;;;13156:2;13144:9;13135:7;13131:23;13127:32;13124:2;;;-1:-1;;13162:12;13124:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;13214:63;13314:2;13353:22;;;;7378:20;;-1:-1;;;13118:283::o;13408:1083::-;;;;;;;;13664:3;13652:9;13643:7;13639:23;13635:33;13632:2;;;-1:-1;;13671:12;13632:2;13729:17;13716:31;13767:18;;13759:6;13756:30;13753:2;;;-1:-1;;13789:12;13753:2;13827:80;13899:7;13890:6;13879:9;13875:22;13827:80;:::i;:::-;13809:98;;-1:-1;13809:98;-1:-1;13972:2;13957:18;;13944:32;;-1:-1;13985:30;;;13982:2;;;-1:-1;;14018:12;13982:2;;14056:80;14128:7;14119:6;14108:9;14104:22;14056:80;:::i;:::-;14038:98;;-1:-1;14038:98;-1:-1;;14173:2;14212:22;;72:20;97:33;72:20;97:33;:::i;:::-;14181:63;-1:-1;14281:2;14337:22;;5828:20;5853:50;5828:20;5853:50;:::i;:::-;14289:80;-1:-1;14406:3;14443:22;;3640:20;3665:30;3640:20;3665:30;:::i;:::-;14415:60;;;;13626:865;;;;;;;;;;:::o;14498:977::-;;;;;;;14750:2;14738:9;14729:7;14725:23;14721:32;14718:2;;;-1:-1;;14756:12;14718:2;14814:17;14801:31;14852:18;;14844:6;14841:30;14838:2;;;-1:-1;;14874:12;14838:2;14912:78;14982:7;14973:6;14962:9;14958:22;14912:78;:::i;:::-;14894:96;;-1:-1;14894:96;-1:-1;15055:2;15040:18;;15027:32;;-1:-1;15068:30;;;15065:2;;;-1:-1;;15101:12;15065:2;15139:80;15211:7;15202:6;15191:9;15187:22;15139:80;:::i;:::-;15121:98;;-1:-1;15121:98;-1:-1;15284:2;15269:18;;15256:32;;-1:-1;15297:30;;;15294:2;;;-1:-1;;15330:12;15294:2;;15368:91;15451:7;15442:6;15431:9;15427:22;15368:91;:::i;:::-;14712:763;;;;-1:-1;14712:763;;-1:-1;14712:763;;15350:109;;14712:763;-1:-1;;;14712:763::o;15482:257::-;;15594:2;15582:9;15573:7;15569:23;15565:32;15562:2;;;-1:-1;;15600:12;15562:2;3788:6;3782:13;3800:30;3824:5;3800:30;:::i;15746:393::-;;;15875:2;15863:9;15854:7;15850:23;15846:32;15843:2;;;-1:-1;;15881:12;15843:2;3788:6;3782:13;3800:30;3824:5;3800:30;:::i;:::-;16041:2;16091:22;;;;7526:13;15933:71;;7526:13;;-1:-1;;;15837:302::o;16146:485::-;;;;16281:2;16269:9;16260:7;16256:23;16252:32;16249:2;;;-1:-1;;16287:12;16249:2;3653:6;3640:20;3665:30;3689:5;3665:30;:::i;:::-;16339:60;16436:2;16475:22;;7378:20;;-1:-1;16544:2;16583:22;;;7378:20;;16243:388;-1:-1;;;16243:388::o;16638:365::-;;;16761:2;16749:9;16740:7;16736:23;16732:32;16729:2;;;-1:-1;;16767:12;16729:2;16825:17;16812:31;16863:18;;16855:6;16852:30;16849:2;;;-1:-1;;16885:12;16849:2;16970:6;16959:9;16955:22;;;4107:3;4100:4;4092:6;4088:17;4084:27;4074:2;;-1:-1;;4115:12;4074:2;4158:6;4145:20;16863:18;4177:6;4174:30;4171:2;;;-1:-1;;4207:12;4171:2;4302:3;16761:2;4282:17;4243:6;4268:32;;4265:41;4262:2;;;-1:-1;;4309:12;4262:2;16761;4239:17;;;;;16905:82;;-1:-1;16723:280;;-1:-1;;;;16723:280::o;17552:714::-;;;;;17739:3;17727:9;17718:7;17714:23;17710:33;17707:2;;;-1:-1;;17746:12;17707:2;5503:6;5497:13;5515:48;5557:5;5515:48;:::i;:::-;17924:2;17982:22;;522:13;17798:89;;-1:-1;540:41;522:13;540:41;:::i;:::-;18051:2;18100:22;;6127:13;18169:2;18218:22;;;6127:13;17701:565;;17932:82;;-1:-1;17701:565;-1:-1;;;17701:565::o;18273:793::-;;;;18476:2;18464:9;18455:7;18451:23;18447:32;18444:2;;;-1:-1;;18482:12;18444:2;5332:6;5319:20;5344:48;5386:5;5344:48;:::i;:::-;18534:78;-1:-1;18677:2;18662:18;;;18649:32;18701:18;18690:30;;;18687:2;;;-1:-1;;18723:12;18687:2;18814:6;18803:9;18799:22;;;1106:3;1099:4;1091:6;1087:17;1083:27;1073:2;;-1:-1;;1114:12;1073:2;1161:6;1148:20;1183:80;1198:64;1255:6;1198:64;:::i;1183:80::-;1291:21;;;1348:14;;;;1323:17;;;1437;;;1428:27;;;;1425:36;-1:-1;1422:2;;;-1:-1;;1464:12;1422:2;-1:-1;1490:10;;1484:206;1509:6;1506:1;1503:13;1484:206;;;1589:37;1622:3;1610:10;1589:37;:::i;:::-;1577:50;;1531:1;1524:9;;;;;1641:14;;;;1669;;1484:206;;;-1:-1;18743:88;-1:-1;;;18896:2;18881:18;;18868:32;;-1:-1;18909:30;;;18906:2;;;-1:-1;;18942:12;18906:2;;;18972:78;19042:7;19033:6;19022:9;19018:22;18972:78;:::i;:::-;18962:88;;;18438:628;;;;;:::o;19073:813::-;;;;;19283:3;19271:9;19262:7;19258:23;19254:33;19251:2;;;-1:-1;;19290:12;19251:2;5332:6;5319:20;5344:48;5386:5;5344:48;:::i;:::-;19342:78;-1:-1;19457:2;19511:22;;5319:20;5344:48;5319:20;5344:48;:::i;:::-;19465:78;-1:-1;19580:2;19635:22;;5658:20;5683:49;5658:20;5683:49;:::i;:::-;19588:79;-1:-1;19732:2;19717:18;;19704:32;19756:18;19745:30;;19742:2;;;-1:-1;;19778:12;19742:2;19838:22;;4432:4;4420:17;;4416:27;-1:-1;4406:2;;-1:-1;;4447:12;4406:2;4494:6;4481:20;4516:64;4531:48;4572:6;4531:48;:::i;4516:64::-;4600:6;4593:5;4586:21;4704:3;19457:2;4695:6;4628;4686:16;;4683:25;4680:2;;;-1:-1;;4711:12;4680:2;76607:6;19457:2;4628:6;4624:17;19457:2;4662:5;4658:16;76584:30;76645:16;;;19457:2;76645:16;76638:27;;;;-1:-1;19245:641;;;;-1:-1;19245:641;-1:-1;19245:641::o;20175:394::-;;;20310:2;20298:9;20289:7;20285:23;20281:32;20278:2;;;-1:-1;;20316:12;20278:2;5841:6;5828:20;5853:50;5897:5;5853:50;:::i;:::-;20368:80;-1:-1;20485:2;20521:22;;3640:20;3665:30;3640:20;3665:30;:::i;20576:239::-;;20679:2;20667:9;20658:7;20654:23;20650:32;20647:2;;;-1:-1;;20685:12;20647:2;-1:-1;5981:20;;20641:174;-1:-1;20641:174::o;20822:380::-;;;20950:2;20938:9;20929:7;20925:23;20921:32;20918:2;;;-1:-1;;20956:12;20918:2;5994:6;5981:20;21008:62;;21107:2;21158:9;21154:22;358:20;383:41;418:5;383:41;:::i;21209:499::-;;;;21351:2;21339:9;21330:7;21326:23;21322:32;21319:2;;;-1:-1;;21357:12;21319:2;5994:6;5981:20;21409:62;;21508:2;21559:9;21555:22;358:20;383:41;418:5;383:41;:::i;21715:362::-;;21840:2;21828:9;21819:7;21815:23;21811:32;21808:2;;;-1:-1;;21846:12;21808:2;21897:17;21891:24;21935:18;21927:6;21924:30;21921:2;;;-1:-1;;21957:12;21921:2;21987:74;22053:7;22044:6;22033:9;22029:22;21987:74;:::i;22084:309::-;;22222:2;22210:9;22201:7;22197:23;22193:32;22190:2;;;-1:-1;;22228:12;22190:2;6821:20;22222:2;6821:20;:::i;:::-;7254:6;7248:13;7266:33;7293:5;7266:33;:::i;:::-;6901:86;;7048:2;7113:22;;7248:13;7266:33;7248:13;7266:33;:::i;:::-;7048:2;7063:16;;7056:86;7067:5;22184:209;-1:-1;;;22184:209::o;22400:263::-;;22515:2;22503:9;22494:7;22490:23;22486:32;22483:2;;;-1:-1;;22521:12;22483:2;-1:-1;7526:13;;22477:186;-1:-1;22477:186::o;22670:399::-;;;22802:2;22790:9;22781:7;22777:23;22773:32;22770:2;;;-1:-1;;22808:12;22770:2;-1:-1;;7526:13;;22971:2;23021:22;;;7526:13;;;;;-1:-1;22764:305::o;23076:237::-;;23178:2;23166:9;23157:7;23153:23;23149:32;23146:2;;;-1:-1;;23184:12;23146:2;7667:6;7654:20;7679:31;7704:5;7679:31;:::i;23320:259::-;;23433:2;23421:9;23412:7;23408:23;23404:32;23401:2;;;-1:-1;;23439:12;23401:2;7804:6;7798:13;7816:31;7841:5;7816:31;:::i;26177:343::-;;26319:5;71390:12;72193:6;72188:3;72181:19;26412:52;26457:6;72230:4;72225:3;72221:14;72230:4;26438:5;26434:16;26412:52;:::i;:::-;77202:7;77186:14;-1:-1;;77182:28;26476:39;;;;72230:4;26476:39;;26267:253;-1:-1;;26267:253::o;39393:271::-;;26687:5;71390:12;26798:52;26843:6;26838:3;26831:4;26824:5;26820:16;26798:52;:::i;:::-;26862:16;;;;;39527:137;-1:-1;;39527:137::o;39671:410::-;;26687:5;71390:12;26798:52;26843:6;26838:3;26831:4;26824:5;26820:16;26798:52;:::i;:::-;26862:16;;;;25969:37;;;-1:-1;26831:4;40044:12;;39833:248;-1:-1;39833:248::o;40088:549::-;;26687:5;71390:12;26798:52;26843:6;26838:3;26831:4;26824:5;26820:16;26798:52;:::i;:::-;26862:16;;;;25969:37;;;-1:-1;26831:4;40489:12;;25969:37;40600:12;;;40278:359;-1:-1;40278:359::o;41204:1398::-;;30436:20;30423:11;30416:41;26687:5;71390:12;26798:52;26843:6;30400:2;30480:3;30476:12;26831:4;26824:5;26820:16;26798:52;:::i;:::-;-1:-1;;;30400:2;26862:16;;;;;;38119:24;71390:12;;26798:52;71390:12;38162:11;;;26831:4;26820:16;;26798:52;:::i;:::-;-1:-1;;;38162:11;26862:16;;;;;;;35438:24;71390:12;;26798:52;71390:12;35481:11;;;26831:4;26820:16;;26798:52;:::i;:::-;26862:16;35481:11;26862:16;;41739:863;-1:-1;;;;;41739:863::o;42609:1398::-;;-1:-1;;;35789:11;35782:25;26687:5;71390:12;26798:52;26843:6;35767:1;35830:3;35826:11;26831:4;26824:5;26820:16;26798:52;:::i;:::-;-1:-1;;;35767:1;26862:16;;;;;;38119:24;71390:12;;26798:52;71390:12;38162:11;;;26831:4;26820:16;;26798:52;:::i;:::-;-1:-1;;;38162:11;26862:16;;;;;;;35438:24;71390:12;;26798:52;71390:12;35481:11;;;26831:4;26820:16;;26798:52;:::i;:::-;26862:16;35481:11;26862:16;;43144:863;-1:-1;;;;;43144:863::o;44014:222::-;-1:-1;;;;;74063:54;;;;24160:37;;44141:2;44126:18;;44112:124::o;44243:760::-;-1:-1;;;;;74063:54;;;24160:37;;74063:54;;;;44665:2;44650:18;;24160:37;73356:13;;73349:21;44742:2;44727:18;;25852:34;74382:4;74371:16;44821:2;44806:18;;39346:35;44904:3;44889:19;;25969:37;44988:3;44973:19;;25969:37;;;;44500:3;44485:19;;44471:532::o;45010:210::-;73356:13;;73349:21;25852:34;;45131:2;45116:18;;45102:118::o;45227:321::-;73356:13;;73349:21;25852:34;;45534:2;45519:18;;25969:37;45376:2;45361:18;;45347:201::o;45555:222::-;25969:37;;;45682:2;45667:18;;45653:124::o;45784:780::-;25969:37;;;-1:-1;;;;;74063:54;;;46216:2;46201:18;;24160:37;74063:54;;;;46299:2;46284:18;;24160:37;46382:2;46367:18;;25969:37;46465:3;46450:19;;25969:37;;;;46549:3;46534:19;;25969:37;46051:3;46036:19;;46022:542::o;46571:444::-;25969:37;;;46918:2;46903:18;;25969:37;;;;-1:-1;;;;;74063:54;47001:2;46986:18;;24160:37;46754:2;46739:18;;46725:290::o;47022:548::-;25969:37;;;74382:4;74371:16;;;;47390:2;47375:18;;39346:35;47473:2;47458:18;;25969:37;47556:2;47541:18;;25969:37;47229:3;47214:19;;47200:370::o;47577:306::-;;47722:2;47743:17;47736:47;47797:76;47722:2;47711:9;47707:18;47859:6;47797:76;:::i;47890:300::-;;48032:2;;48021:9;48017:18;48032:2;48053:17;48046:47;-1:-1;27030:5;27024:12;27064:1;;27053:9;27049:17;27077:1;27072:247;;;;27330:1;27325:400;;;;27042:683;;27072:247;27146:1;27131:17;;27150:4;27127:28;72181:19;;-1:-1;;27258:25;;72221:14;;;27246:38;27298:14;;;;-1:-1;27072:247;;27325:400;27394:1;27383:9;27379:17;72193:6;72188:3;72181:19;27502:37;27533:5;27502:37;:::i;:::-;-1:-1;27563:130;27577:6;27574:1;27571:13;27563:130;;;27636:14;;27623:11;;;72221:14;27623:11;27616:35;27670:15;;;;27592:12;;27563:130;;;27707:11;;72221:14;27707:11;;-1:-1;;;27042:683;-1:-1;48099:81;;48003:187;-1:-1;;;;;;;48003:187::o;48725:363::-;-1:-1;;;;;74063:54;;;27830:70;;74063:54;;49074:2;49059:18;;24160:37;48895:2;48880:18;;48866:222::o;49095:602::-;-1:-1;;;;;74063:54;;;27830:70;;74063:54;;;49517:2;49502:18;;24029:58;74063:54;;49600:2;49585:18;;24160:37;49683:2;49668:18;;25969:37;;;;49329:3;49314:19;;49300:397::o;49704:714::-;-1:-1;;;;;74063:54;;;27830:70;;74063:54;;;50154:2;50139:18;;24029:58;74063:54;;;;50237:2;50222:18;;24160:37;50320:2;50305:18;;25969:37;;;;50403:3;50388:19;;25969:37;;;;49966:3;49951:19;;49937:481::o;50425:898::-;;50759:3;50748:9;50744:19;-1:-1;;;;;74074:42;73166:5;74063:54;27837:3;27830:70;50947:2;74074:42;73166:5;74063:54;50947:2;50936:9;50932:18;24029:58;50759:3;50984:2;50973:9;50969:18;50962:48;51024:108;24553:5;71390:12;72193:6;72188:3;72181:19;72221:14;50748:9;72221:14;24565:93;;50947:2;24729:5;70922:14;24741:21;;-1:-1;24768:260;24793:6;24790:1;24787:13;24768:260;;;24854:13;;74063:54;;24160:37;;71921:14;;;;23740;;;;24815:1;24808:9;24768:260;;;-1:-1;;51170:20;;;51165:2;51150:18;;51143:48;71390:12;;72181:19;;;72221:14;;;;-1:-1;71390:12;-1:-1;70922:14;;;-1:-1;25497:260;25522:6;25519:1;25516:13;25497:260;;;25583:13;;25969:37;;23922:14;;;;71921;;;;24815:1;25537:9;25497:260;;;-1:-1;51197:116;;50730:593;-1:-1;;;;;;;;;50730:593::o;53409:462::-;-1:-1;;;;;74063:54;;;;27830:70;;-1:-1;;;;;73943:46;;;;53780:2;53765:18;;38711:50;73356:13;73349:21;53857:2;53842:18;;25852:34;53601:2;53586:18;;53572:299::o;53878:462::-;-1:-1;;;;;74063:54;;;;27830:70;;54249:2;54234:18;;25969:37;;;;73356:13;73349:21;54326:2;54311:18;;25852:34;54070:2;54055:18;;54041:299::o;55160:600::-;28679:58;;;55574:2;55559:18;;28679:58;;;;74280:18;74269:30;55655:2;55640:18;;39231:36;55746:2;55731:18;;28679:58;55393:3;55378:19;;55364:396::o;56084:416::-;56284:2;56298:47;;;29695:2;56269:18;;;72181:19;29731:23;72221:14;;;29711:44;29774:12;;;56255:245::o;56507:416::-;56707:2;56721:47;;;30025:2;56692:18;;;72181:19;30061:32;72221:14;;;30041:53;30113:12;;;56678:245::o;56930:416::-;57130:2;57144:47;;;30727:2;57115:18;;;72181:19;30763:24;72221:14;;;30743:45;30807:12;;;57101:245::o;57353:416::-;57553:2;57567:47;;;31058:2;57538:18;;;72181:19;31094:28;72221:14;;;31074:49;31142:12;;;57524:245::o;57776:416::-;57976:2;57990:47;;;31393:2;57961:18;;;72181:19;31429:23;72221:14;;;31409:44;31472:12;;;57947:245::o;58199:416::-;58399:2;58413:47;;;31723:2;58384:18;;;72181:19;31759:24;72221:14;;;31739:45;31803:12;;;58370:245::o;58622:416::-;58822:2;58836:47;;;32054:2;58807:18;;;72181:19;32090:30;72221:14;;;32070:51;32140:12;;;58793:245::o;59045:416::-;59245:2;59259:47;;;32391:2;59230:18;;;72181:19;32427:26;72221:14;;;32407:47;32473:12;;;59216:245::o;59468:416::-;59668:2;59682:47;;;32724:2;59653:18;;;72181:19;32760:21;72221:14;;;32740:42;32801:12;;;59639:245::o;59891:416::-;60091:2;60105:47;;;33052:2;60076:18;;;72181:19;33088:26;72221:14;;;33068:47;33134:12;;;60062:245::o;60314:416::-;60514:2;60528:47;;;33385:2;60499:18;;;72181:19;33421:23;72221:14;;;33401:44;33464:12;;;60485:245::o;60737:416::-;60937:2;60951:47;;;33715:2;60922:18;;;72181:19;33751:16;72221:14;;;33731:37;33787:12;;;60908:245::o;61160:416::-;61360:2;61374:47;;;34038:2;61345:18;;;72181:19;34074:27;72221:14;;;34054:48;34121:12;;;61331:245::o;61583:416::-;61783:2;61797:47;;;61768:18;;;72181:19;34408:34;72221:14;;;34388:55;34462:12;;;61754:245::o;62006:416::-;62206:2;62220:47;;;62191:18;;;72181:19;34749:34;72221:14;;;34729:55;34803:12;;;62177:245::o;62429:416::-;62629:2;62643:47;;;35054:2;62614:18;;;72181:19;35090:26;72221:14;;;35070:47;35136:12;;;62600:245::o;62852:416::-;63052:2;63066:47;;;36076:2;63037:18;;;72181:19;36112:22;72221:14;;;36092:43;36154:12;;;63023:245::o;63275:416::-;63475:2;63489:47;;;36405:2;63460:18;;;72181:19;36441:24;72221:14;;;36421:45;36485:12;;;63446:245::o;63698:416::-;63898:2;63912:47;;;36736:2;63883:18;;;72181:19;36772:26;72221:14;;;36752:47;36818:12;;;63869:245::o;64121:416::-;64321:2;64335:47;;;37069:2;64306:18;;;72181:19;37105:28;72221:14;;;37085:49;37153:12;;;64292:245::o;64544:416::-;64744:2;64758:47;;;37404:2;64729:18;;;72181:19;37440:26;72221:14;;;37420:47;37486:12;;;64715:245::o;64967:416::-;65167:2;65181:47;;;37737:2;65152:18;;;72181:19;37773:24;72221:14;;;37753:45;37817:12;;;65138:245::o;65390:416::-;65590:2;65604:47;;;38412:2;65575:18;;;72181:19;38448:26;72221:14;;;38428:47;38494:12;;;65561:245::o;65813:333::-;-1:-1;;;;;73943:46;;;38591:37;;73943:46;;66132:2;66117:18;;38591:37;65968:2;65953:18;;65939:207::o;66382:349::-;25969:37;;;66717:2;66702:18;;28679:58;66545:2;66530:18;;66516:215::o;67078:444::-;25969:37;;;67425:2;67410:18;;25969:37;;;;67508:2;67493:18;;25969:37;67261:2;67246:18;;67232:290::o;68088:436::-;74280:18;74269:30;;;39231:36;;74269:30;;;;68427:2;68412:18;;39231:36;-1:-1;;;;;73943:46;;;68510:2;68495:18;;38591:37;68267:2;68252:18;;68238:286::o;68531:214::-;74382:4;74371:16;;;;39346:35;;68654:2;68639:18;;68625:120::o;68752:506::-;;;68887:11;68874:25;68938:48;;68962:8;68946:14;68942:29;68938:48;68918:18;68914:73;68904:2;;-1:-1;;68991:12;68904:2;69018:33;;69072:18;;;-1:-1;69110:18;69099:30;;69096:2;;;-1:-1;;69132:12;69096:2;68977:4;69160:13;;-1:-1;68946:14;69192:38;;;69182:49;;69179:2;;;69244:1;;69234:12;69265:256;69327:2;69321:9;69353:17;;;69428:18;69413:34;;69449:22;;;69410:62;69407:2;;;69485:1;;69475:12;69407:2;69327;69494:22;69305:216;;-1:-1;69305:216::o;69528:304::-;;69687:18;69679:6;69676:30;69673:2;;;-1:-1;;69709:12;69673:2;-1:-1;69754:4;69742:17;;;69807:15;;69610:222::o;70150:321::-;;70293:18;70285:6;70282:30;70279:2;;;-1:-1;;70315:12;70279:2;-1:-1;77202:7;70369:17;-1:-1;;70365:33;70456:4;70446:15;;70216:255::o;71123:157::-;;71217:14;;;71259:4;71246:18;;;71176:104::o;76680:268::-;76745:1;76752:101;76766:6;76763:1;76760:13;76752:101;;;76833:11;;;76827:18;76814:11;;;76807:39;76788:2;76781:10;76752:101;;;76868:6;76865:1;76862:13;76859:2;;;-1:-1;;76745:1;76915:16;;76908:27;76729:219::o;77223:117::-;-1:-1;;;;;77310:5;74063:54;77285:5;77282:35;77272:2;;77331:1;;77321:12;77272:2;77266:74;:::o;77487:111::-;77568:5;73356:13;73349:21;77546:5;77543:32;77533:2;;77589:1;;77579:12;78319:117;-1:-1;;;;;78406:5;73943:46;78381:5;78378:35;78368:2;;78427:1;;78417:12;78567:113;74382:4;78650:5;74371:16;78627:5;78624:33;78614:2;;78671:1;;78661:12
Swarm Source
ipfs://43def0759137241cf8df2e558f293223dcafcd6c3de768f29848ee9f923dc5a9
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.