Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 13024441 | 1091 days ago | IN | 0 ETH | 0.23307378 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
StakingV1_1
Compiler Version
v0.5.17+commit.d19bba13
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-08-14 */ /** * Copyright 2017-2020, bZeroX, LLC <https://bzx.network/>. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.5.17; pragma experimental ABIEncoderV2; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. * * _Available since v2.4.0._ */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call.value(amount)(""); require(success, "Address: unable to send value, recipient may have reverted"); } } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } library MathUtil { /** * @dev Integer division of two numbers, rounding up and truncating the quotient */ function divCeil(uint256 a, uint256 b) internal pure returns (uint256) { return divCeil(a, b, "SafeMath: division by zero"); } /** * @dev Integer division of two numbers, rounding up and truncating the quotient */ function divCeil(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b != 0, errorMessage); if (a == 0) { return 0; } uint256 c = ((a - 1) / b) + 1; return c; } function min256(uint256 _a, uint256 _b) internal pure returns (uint256) { return _a < _b ? _a : _b; } } interface IPriceFeeds { function queryRate( address sourceToken, address destToken) external view returns (uint256 rate, uint256 precision); function queryPrecision( address sourceToken, address destToken) external view returns (uint256 precision); function queryReturn( address sourceToken, address destToken, uint256 sourceAmount) external view returns (uint256 destAmount); function checkPriceDisagreement( address sourceToken, address destToken, uint256 sourceAmount, uint256 destAmount, uint256 maxSlippage) external view returns (uint256 sourceToDestSwapRate); function amountInEth( address Token, uint256 amount) external view returns (uint256 ethAmount); function getMaxDrawdown( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount, uint256 maintenanceMargin) external view returns (uint256); function getCurrentMarginAndCollateralSize( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount) external view returns (uint256 currentMargin, uint256 collateralInEthAmount); function getCurrentMargin( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount) external view returns (uint256 currentMargin, uint256 collateralToLoanRate); function shouldLiquidate( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount, uint256 maintenanceMargin) external view returns (bool); function getFastGasPrice( address payToken) external view returns (uint256); } contract IVestingToken is IERC20 { function claim() external; function vestedBalanceOf( address _owner) external view returns (uint256); function claimedBalanceOf( address _owner) external view returns (uint256); } /** * @dev Library for managing loan sets * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * Include with `using EnumerableBytes32Set for EnumerableBytes32Set.Bytes32Set;`. * */ library EnumerableBytes32Set { struct Bytes32Set { // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) index; bytes32[] values; } /** * @dev Add an address value to a set. O(1). * Returns false if the value was already in the set. */ function addAddress(Bytes32Set storage set, address addrvalue) internal returns (bool) { bytes32 value; assembly { value := addrvalue } return addBytes32(set, value); } /** * @dev Add a value to a set. O(1). * Returns false if the value was already in the set. */ function addBytes32(Bytes32Set storage set, bytes32 value) internal returns (bool) { if (!contains(set, value)){ set.index[value] = set.values.push(value); return true; } else { return false; } } /** * @dev Removes an address value from a set. O(1). * Returns false if the value was not present in the set. */ function removeAddress(Bytes32Set storage set, address addrvalue) internal returns (bool) { bytes32 value; assembly { value := addrvalue } return removeBytes32(set, value); } /** * @dev Removes a value from a set. O(1). * Returns false if the value was not present in the set. */ function removeBytes32(Bytes32Set storage set, bytes32 value) internal returns (bool) { if (contains(set, value)){ uint256 toDeleteIndex = set.index[value] - 1; uint256 lastIndex = set.values.length - 1; // If the element we're deleting is the last one, we can just remove it without doing a swap if (lastIndex != toDeleteIndex) { bytes32 lastValue = set.values[lastIndex]; // Move the last value to the index where the deleted value is set.values[toDeleteIndex] = lastValue; // Update the index for the moved value set.index[lastValue] = toDeleteIndex + 1; // All indexes are 1-based } // Delete the index entry for the deleted value delete set.index[value]; // Delete the old entry for the moved value set.values.pop(); return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return set.index[value] != 0; } /** * @dev Returns true if the value is in the set. O(1). */ function containsAddress(Bytes32Set storage set, address addrvalue) internal view returns (bool) { bytes32 value; assembly { value := addrvalue } return set.index[value] != 0; } /** * @dev Returns an array with all values in the set. O(N). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * WARNING: This function may run out of gas on large sets: use {length} and * {get} instead in these cases. */ function enumerate(Bytes32Set storage set, uint256 start, uint256 count) internal view returns (bytes32[] memory output) { uint256 end = start + count; require(end >= start, "addition overflow"); end = set.values.length < end ? set.values.length : end; if (end == 0 || start >= end) { return output; } output = new bytes32[](end-start); for (uint256 i = start; i < end; i++) { output[i-start] = set.values[i]; } return output; } /** * @dev Returns the number of elements on the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return set.values.length; } /** @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function get(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return set.values[index]; } /** @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function getAddress(Bytes32Set storage set, uint256 index) internal view returns (address) { bytes32 value = set.values[index]; address addrvalue; assembly { addrvalue := value } return addrvalue; } } interface IUniswapV2Router { // 0x38ed1739 function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external returns (uint256[] memory amounts); // 0x8803dbee function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline) external returns (uint256[] memory amounts); // 0x1f00ca74 function getAmountsIn( uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); // 0xd06ca61f function getAmountsOut( uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); } interface ICurve3Pool { function add_liquidity( uint256[3] calldata amounts, uint256 min_mint_amount) external; function get_virtual_price() external view returns (uint256); } /// @title A proxy interface for The Protocol /// @author bZeroX /// @notice This is just an interface, not to be deployed itself. /// @dev This interface is to be used for the protocol interactions. interface IBZx { ////// Protocol ////// /// @dev adds or replaces existing proxy module /// @param target target proxy module address function replaceContract(address target) external; /// @dev updates all proxy modules addreses and function signatures. /// sigsArr and targetsArr should be of equal length /// @param sigsArr array of function signatures /// @param targetsArr array of target proxy module addresses function setTargets( string[] calldata sigsArr, address[] calldata targetsArr ) external; /// @dev returns protocol module address given a function signature /// @return module address function getTarget(string calldata sig) external view returns (address); ////// Protocol Settings ////// /// @dev sets price feed contract address. The contract on the addres should implement IPriceFeeds interface /// @param newContract module address for the IPriceFeeds implementation function setPriceFeedContract(address newContract) external; /// @dev sets swaps contract address. The contract on the addres should implement ISwapsImpl interface /// @param newContract module address for the ISwapsImpl implementation function setSwapsImplContract(address newContract) external; /// @dev sets loan pool with assets. Accepts two arrays of equal length /// @param pools array of address of pools /// @param assets array of addresses of assets function setLoanPool(address[] calldata pools, address[] calldata assets) external; /// @dev updates list of supported tokens, it can be use also to disable or enable particualr token /// @param addrs array of address of pools /// @param toggles array of addresses of assets /// @param withApprovals resets tokens to unlimited approval with the swaps integration (kyber, etc.) function setSupportedTokens( address[] calldata addrs, bool[] calldata toggles, bool withApprovals ) external; /// @dev sets lending fee with WEI_PERCENT_PRECISION /// @param newValue lending fee percent function setLendingFeePercent(uint256 newValue) external; /// @dev sets trading fee with WEI_PERCENT_PRECISION /// @param newValue trading fee percent function setTradingFeePercent(uint256 newValue) external; /// @dev sets borrowing fee with WEI_PERCENT_PRECISION /// @param newValue borrowing fee percent function setBorrowingFeePercent(uint256 newValue) external; /// @dev sets affiliate fee with WEI_PERCENT_PRECISION /// @param newValue affiliate fee percent function setAffiliateFeePercent(uint256 newValue) external; /// @dev sets liquidation inncetive percent per loan per token. This is the profit percent /// that liquidator gets in the process of liquidating. /// @param loanTokens array list of loan tokens /// @param collateralTokens array list of collateral tokens /// @param amounts array list of liquidation inncetive amount function setLiquidationIncentivePercent( address[] calldata loanTokens, address[] calldata collateralTokens, uint256[] calldata amounts ) external; /// @dev sets max swap rate slippage percent. /// @param newAmount max swap rate slippage percent. function setMaxDisagreement(uint256 newAmount) external; /// TODO function setSourceBufferPercent(uint256 newAmount) external; /// @dev sets maximum supported swap size in ETH /// @param newAmount max swap size in ETH. function setMaxSwapSize(uint256 newAmount) external; /// @dev sets fee controller address /// @param newController address of the new fees controller function setFeesController(address newController) external; /// @dev withdraws lending fees to receiver. Only can be called by feesController address /// @param tokens array of token addresses. /// @param receiver fees receiver address /// @return amounts array of amounts withdrawn function withdrawFees( address[] calldata tokens, address receiver, FeeClaimType feeType ) external returns (uint256[] memory amounts); /// @dev withdraw protocol token (BZRX) from vesting contract vBZRX /// @param receiver address of BZRX tokens claimed /// @param amount of BZRX token to be claimed. max is claimed if amount is greater than balance. /// @return rewardToken reward token address /// @return withdrawAmount amount function withdrawProtocolToken(address receiver, uint256 amount) external returns (address rewardToken, uint256 withdrawAmount); /// @dev depozit protocol token (BZRX) /// @param amount address of BZRX tokens to deposit function depositProtocolToken(uint256 amount) external; function grantRewards(address[] calldata users, uint256[] calldata amounts) external returns (uint256 totalAmount); // NOTE: this doesn't sanitize inputs -> inaccurate values may be returned if there are duplicates tokens input function queryFees(address[] calldata tokens, FeeClaimType feeType) external view returns (uint256[] memory amountsHeld, uint256[] memory amountsPaid); function priceFeeds() external view returns (address); function swapsImpl() external view returns (address); function logicTargets(bytes4) external view returns (address); function loans(bytes32) external view returns (Loan memory); function loanParams(bytes32) external view returns (LoanParams memory); // we don't use this yet // function lenderOrders(address, bytes32) external returns (Order memory); // function borrowerOrders(address, bytes32) external returns (Order memory); function delegatedManagers(bytes32, address) external view returns (bool); function lenderInterest(address, address) external view returns (LenderInterest memory); function loanInterest(bytes32) external view returns (LoanInterest memory); function feesController() external view returns (address); function lendingFeePercent() external view returns (uint256); function lendingFeeTokensHeld(address) external view returns (uint256); function lendingFeeTokensPaid(address) external view returns (uint256); function borrowingFeePercent() external view returns (uint256); function borrowingFeeTokensHeld(address) external view returns (uint256); function borrowingFeeTokensPaid(address) external view returns (uint256); function protocolTokenHeld() external view returns (uint256); function protocolTokenPaid() external view returns (uint256); function affiliateFeePercent() external view returns (uint256); function liquidationIncentivePercent(address, address) external view returns (uint256); function loanPoolToUnderlying(address) external view returns (address); function underlyingToLoanPool(address) external view returns (address); function supportedTokens(address) external view returns (bool); function maxDisagreement() external view returns (uint256); function sourceBufferPercent() external view returns (uint256); function maxSwapSize() external view returns (uint256); /// @dev get list of loan pools in the system. Ordering is not guaranteed /// @param start start index /// @param count number of pools to return /// @return loanPoolsList array of loan pools function getLoanPoolsList(uint256 start, uint256 count) external view returns (address[] memory loanPoolsList); /// @dev checks whether addreess is a loan pool address /// @return boolean function isLoanPool(address loanPool) external view returns (bool); ////// Loan Settings ////// /// @dev creates new loan param settings /// @param loanParamsList array of LoanParams /// @return loanParamsIdList array of loan ids created function setupLoanParams(LoanParams[] calldata loanParamsList) external returns (bytes32[] memory loanParamsIdList); /// @dev Deactivates LoanParams for future loans. Active loans using it are unaffected. /// @param loanParamsIdList array of loan ids function disableLoanParams(bytes32[] calldata loanParamsIdList) external; /// @dev gets array of LoanParams by given ids /// @param loanParamsIdList array of loan ids /// @return loanParamsList array of LoanParams function getLoanParams(bytes32[] calldata loanParamsIdList) external view returns (LoanParams[] memory loanParamsList); /// @dev Enumerates LoanParams in the system by owner /// @param owner of the loan params /// @param start number of loans to return /// @param count total number of the items /// @return loanParamsList array of LoanParams function getLoanParamsList( address owner, uint256 start, uint256 count ) external view returns (bytes32[] memory loanParamsList); /// @dev returns total loan principal for token address /// @param lender address /// @param loanToken address /// @return total principal of the loan function getTotalPrincipal(address lender, address loanToken) external view returns (uint256); ////// Loan Openings ////// /// @dev This is THE function that borrows or trades on the protocol /// @param loanParamsId id of the LoanParam created beforehand by setupLoanParams function /// @param loanId id of existing loan, if 0, start a new loan /// @param isTorqueLoan boolean whether it is toreque or non torque loan /// @param initialMargin in WEI_PERCENT_PRECISION /// @param sentAddresses array of size 4: /// lender: must match loan if loanId provided /// borrower: must match loan if loanId provided /// receiver: receiver of funds (address(0) assumes borrower address) /// manager: delegated manager of loan unless address(0) /// @param sentValues array of size 5: /// newRate: new loan interest rate /// newPrincipal: new loan size (borrowAmount + any borrowed interest) /// torqueInterest: new amount of interest to escrow for Torque loan (determines initial loan length) /// loanTokenReceived: total loanToken deposit (amount not sent to borrower in the case of Torque loans) /// collateralTokenReceived: total collateralToken deposit /// @param loanDataBytes required when sending ether /// @return principal of the loan and collateral amount function borrowOrTradeFromPool( bytes32 loanParamsId, bytes32 loanId, bool isTorqueLoan, uint256 initialMargin, address[4] calldata sentAddresses, uint256[5] calldata sentValues, bytes calldata loanDataBytes ) external payable returns (LoanOpenData memory); /// @dev sets/disables/enables the delegated manager for the loan /// @param loanId id of the loan /// @param delegated delegated manager address /// @param toggle boolean set enabled or disabled function setDelegatedManager( bytes32 loanId, address delegated, bool toggle ) external; /// @dev estimates margin exposure for simulated position /// @param loanToken address of the loan token /// @param collateralToken address of collateral token /// @param loanTokenSent amout of loan token sent /// @param collateralTokenSent amount of collateral token sent /// @param interestRate yearly interest rate /// @param newPrincipal principal amount of the loan /// @return estimated margin exposure amount function getEstimatedMarginExposure( address loanToken, address collateralToken, uint256 loanTokenSent, uint256 collateralTokenSent, uint256 interestRate, uint256 newPrincipal ) external view returns (uint256); /// @dev calculates required collateral for simulated position /// @param loanToken address of loan token /// @param collateralToken address of collateral token /// @param newPrincipal principal amount of the loan /// @param marginAmount margin amount of the loan /// @param isTorqueLoan boolean torque or non torque loan /// @return collateralAmountRequired amount required function getRequiredCollateral( address loanToken, address collateralToken, uint256 newPrincipal, uint256 marginAmount, bool isTorqueLoan ) external view returns (uint256 collateralAmountRequired); function getRequiredCollateralByParams( bytes32 loanParamsId, uint256 newPrincipal ) external view returns (uint256 collateralAmountRequired); /// @dev calculates borrow amount for simulated position /// @param loanToken address of loan token /// @param collateralToken address of collateral token /// @param collateralTokenAmount amount of collateral token sent /// @param marginAmount margin amount /// @param isTorqueLoan boolean torque or non torque loan /// @return borrowAmount possible borrow amount function getBorrowAmount( address loanToken, address collateralToken, uint256 collateralTokenAmount, uint256 marginAmount, bool isTorqueLoan ) external view returns (uint256 borrowAmount); function getBorrowAmountByParams( bytes32 loanParamsId, uint256 collateralTokenAmount ) external view returns (uint256 borrowAmount); ////// Loan Closings ////// /// @dev liquidates unhealty loans /// @param loanId id of the loan /// @param receiver address receiving liquidated loan collateral /// @param closeAmount amount to close denominated in loanToken /// @return loanCloseAmount amount of the collateral token of the loan /// @return seizedAmount sezied amount in the collateral token /// @return seizedToken loan token address function liquidate( bytes32 loanId, address receiver, uint256 closeAmount ) external payable returns ( uint256 loanCloseAmount, uint256 seizedAmount, address seizedToken ); /// @dev rollover loan /// @param loanId id of the loan /// @param loanDataBytes reserved for future use. function rollover(bytes32 loanId, bytes calldata loanDataBytes) external returns (address rebateToken, uint256 gasRebate); /// @dev close position with loan token deposit /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param depositAmount amount of loan token to deposit /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithDeposit( bytes32 loanId, address receiver, uint256 depositAmount // denominated in loanToken ) external payable returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); /// @dev close position with swap /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param swapAmount amount of loan token to swap /// @param returnTokenIsCollateral boolean whether to return tokens is collateral /// @param loanDataBytes reserved for future use /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithSwap( bytes32 loanId, address receiver, uint256 swapAmount, // denominated in collateralToken bool returnTokenIsCollateral, // true: withdraws collateralToken, false: withdraws loanToken bytes calldata loanDataBytes ) external returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); ////// Loan Closings With Gas Token ////// /// @dev liquidates unhealty loans by using Gas token /// @param loanId id of the loan /// @param receiver address receiving liquidated loan collateral /// @param gasTokenUser user address of the GAS token /// @param closeAmount amount to close denominated in loanToken /// @return loanCloseAmount loan close amount /// @return seizedAmount loan token withdraw amount /// @return seizedToken loan token address function liquidateWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 closeAmount // denominated in loanToken ) external payable returns ( uint256 loanCloseAmount, uint256 seizedAmount, address seizedToken ); /// @dev rollover loan /// @param loanId id of the loan /// @param gasTokenUser user address of the GAS token function rolloverWithGasToken( bytes32 loanId, address gasTokenUser, bytes calldata /*loanDataBytes*/ ) external returns (address rebateToken, uint256 gasRebate); /// @dev close position with loan token deposit /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param gasTokenUser user address of the GAS token /// @param depositAmount amount of loan token to deposit denominated in loanToken /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithDepositWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 depositAmount ) external payable returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); /// @dev close position with swap /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param gasTokenUser user address of the GAS token /// @param swapAmount amount of loan token to swap denominated in collateralToken /// @param returnTokenIsCollateral true: withdraws collateralToken, false: withdraws loanToken /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithSwapWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 swapAmount, bool returnTokenIsCollateral, bytes calldata loanDataBytes ) external returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); ////// Loan Maintenance ////// /// @dev deposit collateral to existing loan /// @param loanId existing loan id /// @param depositAmount amount to deposit which must match msg.value if ether is sent function depositCollateral(bytes32 loanId, uint256 depositAmount) external payable; /// @dev withdraw collateral from existing loan /// @param loanId existing lona id /// @param receiver address of withdrawn tokens /// @param withdrawAmount amount to withdraw /// @return actualWithdrawAmount actual amount withdrawn function withdrawCollateral( bytes32 loanId, address receiver, uint256 withdrawAmount ) external returns (uint256 actualWithdrawAmount); /// @dev withdraw accrued interest rate for a loan given token address /// @param loanToken loan token address function withdrawAccruedInterest(address loanToken) external; /// @dev extends loan duration by depositing more collateral /// @param loanId id of the existing loan /// @param depositAmount amount to deposit /// @param useCollateral boolean whether to extend using collateral or deposit amount /// @return secondsExtended by that number of seconds loan duration was extended function extendLoanDuration( bytes32 loanId, uint256 depositAmount, bool useCollateral, bytes calldata // for future use /*loanDataBytes*/ ) external payable returns (uint256 secondsExtended); /// @dev reduces loan duration by withdrawing collateral /// @param loanId id of the existing loan /// @param receiver address to receive tokens /// @param withdrawAmount amount to withdraw /// @return secondsReduced by that number of seconds loan duration was extended function reduceLoanDuration( bytes32 loanId, address receiver, uint256 withdrawAmount ) external returns (uint256 secondsReduced); function setDepositAmount( bytes32 loanId, uint256 depositValueAsLoanToken, uint256 depositValueAsCollateralToken ) external; function claimRewards(address receiver) external returns (uint256 claimAmount); function transferLoan(bytes32 loanId, address newOwner) external; function rewardsBalanceOf(address user) external view returns (uint256 rewardsBalance); /// @dev Gets current lender interest data totals for all loans with a specific oracle and interest token /// @param lender The lender address /// @param loanToken The loan token address /// @return interestPaid The total amount of interest that has been paid to a lender so far /// @return interestPaidDate The date of the last interest pay out, or 0 if no interest has been withdrawn yet /// @return interestOwedPerDay The amount of interest the lender is earning per day /// @return interestUnPaid The total amount of interest the lender is owned and not yet withdrawn /// @return interestFeePercent The fee retained by the protocol before interest is paid to the lender /// @return principalTotal The total amount of outstading principal the lender has loaned function getLenderInterestData(address lender, address loanToken) external view returns ( uint256 interestPaid, uint256 interestPaidDate, uint256 interestOwedPerDay, uint256 interestUnPaid, uint256 interestFeePercent, uint256 principalTotal ); /// @dev Gets current interest data for a loan /// @param loanId A unique id representing the loan /// @return loanToken The loan token that interest is paid in /// @return interestOwedPerDay The amount of interest the borrower is paying per day /// @return interestDepositTotal The total amount of interest the borrower has deposited /// @return interestDepositRemaining The amount of deposited interest that is not yet owed to a lender function getLoanInterestData(bytes32 loanId) external view returns ( address loanToken, uint256 interestOwedPerDay, uint256 interestDepositTotal, uint256 interestDepositRemaining ); /// @dev gets list of loans of particular user address /// @param user address of the loans /// @param start of the index /// @param count number of loans to return /// @param loanType type of the loan: All(0), Margin(1), NonMargin(2) /// @param isLender whether to list lender loans or borrower loans /// @param unsafeOnly booleat if true return only unsafe loans that are open for liquidation /// @return loansData LoanReturnData array of loans function getUserLoans( address user, uint256 start, uint256 count, LoanType loanType, bool isLender, bool unsafeOnly ) external view returns (LoanReturnData[] memory loansData); function getUserLoansCount(address user, bool isLender) external view returns (uint256); /// @dev gets existing loan /// @param loanId id of existing loan /// @return loanData array of loans function getLoan(bytes32 loanId) external view returns (LoanReturnData memory loanData); /// @dev get current active loans in the system /// @param start of the index /// @param count number of loans to return /// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation) function getActiveLoans( uint256 start, uint256 count, bool unsafeOnly ) external view returns (LoanReturnData[] memory loansData); /// @dev get current active loans in the system /// @param start of the index /// @param count number of loans to return /// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation) /// @param isLiquidatable boolean if true return liquidatable loans only function getActiveLoansAdvanced( uint256 start, uint256 count, bool unsafeOnly, bool isLiquidatable ) external view returns (LoanReturnData[] memory loansData); function getActiveLoansCount() external view returns (uint256); ////// Swap External ////// /// @dev swap thru external integration /// @param sourceToken source token address /// @param destToken destintaion token address /// @param receiver address to receive tokens /// @param returnToSender TODO /// @param sourceTokenAmount source token amount /// @param requiredDestTokenAmount destination token amount /// @param swapData TODO /// @return destTokenAmountReceived destination token received /// @return sourceTokenAmountUsed source token amount used function swapExternal( address sourceToken, address destToken, address receiver, address returnToSender, uint256 sourceTokenAmount, uint256 requiredDestTokenAmount, bytes calldata swapData ) external payable returns ( uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed ); /// @dev swap thru external integration using GAS /// @param sourceToken source token address /// @param destToken destintaion token address /// @param receiver address to receive tokens /// @param returnToSender TODO /// @param gasTokenUser user address of the GAS token /// @param sourceTokenAmount source token amount /// @param requiredDestTokenAmount destination token amount /// @param swapData TODO /// @return destTokenAmountReceived destination token received /// @return sourceTokenAmountUsed source token amount used function swapExternalWithGasToken( address sourceToken, address destToken, address receiver, address returnToSender, address gasTokenUser, uint256 sourceTokenAmount, uint256 requiredDestTokenAmount, bytes calldata swapData ) external payable returns ( uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed ); /// @dev calculate simulated return of swap /// @param sourceToken source token address /// @param destToken destination token address /// @param sourceTokenAmount source token amount /// @return amoun denominated in destination token function getSwapExpectedReturn( address sourceToken, address destToken, uint256 sourceTokenAmount ) external view returns (uint256); function owner() external view returns (address); function transferOwnership(address newOwner) external; struct LoanParams { bytes32 id; bool active; address owner; address loanToken; address collateralToken; uint256 minInitialMargin; uint256 maintenanceMargin; uint256 maxLoanTerm; } struct LoanOpenData { bytes32 loanId; uint256 principal; uint256 collateral; } enum LoanType { All, Margin, NonMargin } struct LoanReturnData { bytes32 loanId; uint96 endTimestamp; address loanToken; address collateralToken; uint256 principal; uint256 collateral; uint256 interestOwedPerDay; uint256 interestDepositRemaining; uint256 startRate; uint256 startMargin; uint256 maintenanceMargin; uint256 currentMargin; uint256 maxLoanTerm; uint256 maxLiquidatable; uint256 maxSeizable; uint256 depositValueAsLoanToken; uint256 depositValueAsCollateralToken; } enum FeeClaimType { All, Lending, Trading, Borrowing } struct Loan { bytes32 id; // id of the loan bytes32 loanParamsId; // the linked loan params id bytes32 pendingTradesId; // the linked pending trades id uint256 principal; // total borrowed amount outstanding uint256 collateral; // total collateral escrowed for the loan uint256 startTimestamp; // loan start time uint256 endTimestamp; // for active loans, this is the expected loan end time, for in-active loans, is the actual (past) end time uint256 startMargin; // initial margin when the loan opened uint256 startRate; // reference rate when the loan opened for converting collateralToken to loanToken address borrower; // borrower of this loan address lender; // lender of this loan bool active; // if false, the loan has been fully closed } struct LenderInterest { uint256 principalTotal; // total borrowed amount outstanding of asset uint256 owedPerDay; // interest owed per day for all loans of asset uint256 owedTotal; // total interest owed for all loans of asset (assuming they go to full term) uint256 paidTotal; // total interest paid so far for asset uint256 updatedTimestamp; // last update } struct LoanInterest { uint256 owedPerDay; // interest owed per day for loan uint256 depositTotal; // total escrowed interest for loan uint256 updatedTimestamp; // last update } } /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return _msgSender() == _owner; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } interface IMasterChefSushi { struct UserInfo { uint256 amount; uint256 rewardDebt; } function deposit(uint256 _pid, uint256 _amount) external; function withdraw(uint256 _pid, uint256 _amount) external; // Info of each user that stakes LP tokens. function userInfo(uint256, address) external view returns (UserInfo memory); function pendingSushi(uint256 _pid, address _user) external view returns (uint256); } contract StakingConstants { address public constant BZRX = 0x56d811088235F11C8920698a204A5010a788f4b3; address public constant vBZRX = 0xB72B31907C1C95F3650b64b2469e08EdACeE5e8F; address public constant iBZRX = 0x18240BD9C07fA6156Ce3F3f61921cC82b2619157; address public constant LPToken = 0xa30911e072A0C88D55B5D0A0984B66b0D04569d0; // sushiswap address public constant LPTokenOld = 0xe26A220a341EAca116bDa64cF9D5638A935ae629; // balancer IERC20 public constant curve3Crv = IERC20(0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490); address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address public constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; address public constant SUSHI = 0x6B3595068778DD592e39A122f4f5a5cF09C90fE2; IUniswapV2Router public constant uniswapRouter = IUniswapV2Router(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F); // sushiswap ICurve3Pool public constant curve3pool = ICurve3Pool(0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7); IBZx public constant bZx = IBZx(0xD8Ee69652E4e4838f2531732a46d1f7F584F0b7f); uint256 public constant cliffDuration = 15768000; // 86400 * 365 * 0.5 uint256 public constant vestingDuration = 126144000; // 86400 * 365 * 4 uint256 internal constant vestingDurationAfterCliff = 110376000; // 86400 * 365 * 3.5 uint256 internal constant vestingStartTimestamp = 1594648800; // start_time uint256 internal constant vestingCliffTimestamp = vestingStartTimestamp + cliffDuration; uint256 internal constant vestingEndTimestamp = vestingStartTimestamp + vestingDuration; uint256 internal constant _startingVBZRXBalance = 889389933e18; // 889,389,933 BZRX address internal constant SUSHI_MASTERCHEF = 0xc2EdaD668740f1aA35E4D8f227fB8E17dcA888Cd; uint256 internal constant BZRX_ETH_SUSHI_MASTERCHEF_PID = 188; uint256 public constant BZRXWeightStored = 1e18; struct DelegatedTokens { address user; uint256 BZRX; uint256 vBZRX; uint256 iBZRX; uint256 LPToken; uint256 totalVotes; } event Stake( address indexed user, address indexed token, address indexed delegate, uint256 amount ); event Unstake( address indexed user, address indexed token, address indexed delegate, uint256 amount ); event AddRewards( address indexed sender, uint256 bzrxAmount, uint256 stableCoinAmount ); event Claim( address indexed user, uint256 bzrxAmount, uint256 stableCoinAmount ); event ChangeDelegate( address indexed user, address indexed oldDelegate, address indexed newDelegate ); event WithdrawFees( address indexed sender ); event ConvertFees( address indexed sender, uint256 bzrxOutput, uint256 stableCoinOutput ); event DistributeFees( address indexed sender, uint256 bzrxRewards, uint256 stableCoinRewards ); event AddAltRewards( address indexed sender, address indexed token, uint256 amount ); event ClaimAltRewards( address indexed user, address indexed token, uint256 amount ); } contract StakingUpgradeable is Ownable { address public implementation; } contract StakingState is StakingUpgradeable { using SafeMath for uint256; using SafeERC20 for IERC20; using EnumerableBytes32Set for EnumerableBytes32Set.Bytes32Set; uint256 public constant initialCirculatingSupply = 1030000000e18 - 889389933e18; address internal constant ZERO_ADDRESS = address(0); bool public isPaused; address public fundsWallet; mapping(address => uint256) internal _totalSupplyPerToken; // token => value mapping(address => mapping(address => uint256)) internal _balancesPerToken; // token => account => value mapping(address => address) public delegate; // user => delegate mapping(address => mapping(address => uint256)) public delegatedPerToken; // token => user => value uint256 public bzrxPerTokenStored; mapping(address => uint256) public bzrxRewardsPerTokenPaid; // user => value mapping(address => uint256) public bzrxRewards; // user => value mapping(address => uint256) public bzrxVesting; // user => value uint256 public stableCoinPerTokenStored; mapping(address => uint256) public stableCoinRewardsPerTokenPaid; // user => value mapping(address => uint256) public stableCoinRewards; // user => value mapping(address => uint256) public stableCoinVesting; // user => value uint256 public vBZRXWeightStored; uint256 public iBZRXWeightStored; uint256 public LPTokenWeightStored; EnumerableBytes32Set.Bytes32Set internal _delegatedSet; uint256 public lastRewardsAddTime; mapping(address => uint256) public vestingLastSync; mapping(address => address[]) public swapPaths; mapping(address => uint256) public stakingRewards; uint256 public rewardPercent = 50e18; uint256 public maxUniswapDisagreement = 3e18; uint256 public maxCurveDisagreement = 3e18; uint256 public callerRewardDivisor = 100; address[] public currentFeeTokens; struct ProposalState { uint256 proposalTime; uint256 iBZRXWeight; uint256 lpBZRXBalance; uint256 lpTotalSupply; } address public governor; mapping(uint256 => ProposalState) internal _proposalState; mapping(address => uint256[]) public altRewardsRounds; // token => value (accumulated rewardsPerToken) mapping(address => uint256) public userAltRewardsRounds; // user => lastClaimedRound } contract StakingV1_1 is StakingState, StakingConstants { using MathUtil for uint256; modifier onlyEOA() { require(msg.sender == tx.origin, "unauthorized"); _; } modifier checkPause() { require(!isPaused, "paused"); _; } function getCurrentFeeTokens() external view returns (address[] memory) { return currentFeeTokens; } // View function to see pending sushi rewards on frontend. function pendingSushiRewards(address _user) external view returns (uint256) { uint256 pendingSushi = IMasterChefSushi(SUSHI_MASTERCHEF) .pendingSushi(BZRX_ETH_SUSHI_MASTERCHEF_PID, address(this) ); return _pendingAltRewards( SUSHI, _user, balanceOfByAsset(LPToken, _user), pendingSushi.mul(1e12).div(_totalSupplyPerToken[LPToken]) ); } function pendingAltRewards(address token, address _user) external view returns (uint256) { uint256 userSupply = balanceOfByAsset(token, _user); return _pendingAltRewards(token, _user, userSupply, 0); } function _pendingAltRewards(address token, address _user, uint256 userSupply, uint256 addRewardsPerShare) internal view returns (uint256) { uint256[] memory _altRewardsRounds = altRewardsRounds[token]; uint256 _currentRound = _altRewardsRounds.length; if (_currentRound == 0) return 0; if (userSupply == 0) return 0; uint256 _lastClaimedRound = userAltRewardsRounds[_user]; uint256 currentAccumulatedAltRewards = _altRewardsRounds[_currentRound-1].add(addRewardsPerShare); // Never claimed yet if (_lastClaimedRound == 0) { return userSupply .mul(currentAccumulatedAltRewards) .div(1e12); } _lastClaimedRound--; //correct index to start from 0 _currentRound--; //correct index to start from 0 // Already claimed everything if (_lastClaimedRound == _currentRound) { return 0; } uint256 _lastAccumulatedAltRewards = _altRewardsRounds[_lastClaimedRound]; uint256 _currentRewards = userSupply.mul(currentAccumulatedAltRewards); uint256 _clamedRewards = userSupply.mul(_lastAccumulatedAltRewards); return (_currentRewards.sub(_clamedRewards)).div(1e12); } function _paySushiRewards(address _user, uint256 pendingSushi) internal { //Update userAltRewardsRounds even if user got nothing in the current round uint256[] memory _altRewardsPerShare = altRewardsRounds[SUSHI]; if (_altRewardsPerShare.length > 0) { userAltRewardsRounds[_user] = _altRewardsPerShare.length; } if (pendingSushi != 0) { IERC20(SUSHI).safeTransfer(_user, pendingSushi); emit ClaimAltRewards(_user, SUSHI, pendingSushi); } } // Withdraw all from sushi masterchef function exitSushi() external onlyOwner { IMasterChefSushi chef = IMasterChefSushi(SUSHI_MASTERCHEF); uint256 balance = chef.userInfo(BZRX_ETH_SUSHI_MASTERCHEF_PID, address(this)).amount; chef.withdraw( BZRX_ETH_SUSHI_MASTERCHEF_PID, balance ); } function stake( address[] memory tokens, uint256[] memory values ) public { stake(tokens, values, false); } function stake( address[] memory tokens, uint256[] memory values, bool claimSushi ) public checkPause updateRewards(msg.sender) { require(tokens.length == values.length, "count mismatch"); address token; uint256 stakeAmount; uint256 lptUserSupply = claimSushi ? balanceOfByAsset(LPToken, msg.sender) : 0; for (uint256 i = 0; i < tokens.length; i++) { token = tokens[i]; require(token == BZRX || token == vBZRX || token == iBZRX || token == LPToken, "invalid token"); stakeAmount = values[i]; if (stakeAmount == 0) { continue; } _balancesPerToken[token][msg.sender] = _balancesPerToken[token][msg.sender].add(stakeAmount); _totalSupplyPerToken[token] = _totalSupplyPerToken[token].add(stakeAmount); IERC20(token).safeTransferFrom(msg.sender, address(this), stakeAmount); // Deposit to sushi masterchef if (token == LPToken) { uint256 sushiBalanceBefore = IERC20(SUSHI).balanceOf(address(this)); IMasterChefSushi(SUSHI_MASTERCHEF).deposit( BZRX_ETH_SUSHI_MASTERCHEF_PID, IERC20(LPToken).balanceOf(address(this)) ); uint256 sushiRewards = IERC20(SUSHI).balanceOf(address(this)) - sushiBalanceBefore; if (sushiRewards != 0) { _addAltRewards(SUSHI, sushiRewards); } } emit Stake( msg.sender, token, msg.sender, //currentDelegate, stakeAmount ); } if (claimSushi) { _paySushiRewards( msg.sender, _pendingAltRewards(SUSHI, msg.sender, lptUserSupply, 0) ); } } function unstake( address[] memory tokens, uint256[] memory values ) public { unstake(tokens, values, false); } function unstake( address[] memory tokens, uint256[] memory values, bool claimSushi ) public checkPause updateRewards(msg.sender) { require(tokens.length == values.length, "count mismatch"); address token; uint256 unstakeAmount; uint256 stakedAmount; uint256 lptUserSupply = claimSushi ? balanceOfByAsset(LPToken, msg.sender) : 0; for (uint256 i = 0; i < tokens.length; i++) { token = tokens[i]; require(token == BZRX || token == vBZRX || token == iBZRX || token == LPToken || token == LPTokenOld, "invalid token"); unstakeAmount = values[i]; stakedAmount = _balancesPerToken[token][msg.sender]; if (unstakeAmount == 0 || stakedAmount == 0) { continue; } if (unstakeAmount > stakedAmount) { unstakeAmount = stakedAmount; } _balancesPerToken[token][msg.sender] = stakedAmount - unstakeAmount; // will not overflow _totalSupplyPerToken[token] = _totalSupplyPerToken[token] - unstakeAmount; // will not overflow if (token == BZRX && IERC20(BZRX).balanceOf(address(this)) < unstakeAmount) { // settle vested BZRX only if needed IVestingToken(vBZRX).claim(); } // Withdraw to sushi masterchef if (token == LPToken) { uint256 sushiBalanceBefore = IERC20(SUSHI).balanceOf(address(this)); IMasterChefSushi(SUSHI_MASTERCHEF).withdraw(BZRX_ETH_SUSHI_MASTERCHEF_PID, unstakeAmount); uint256 sushiRewards = IERC20(SUSHI).balanceOf(address(this)) - sushiBalanceBefore; if (sushiRewards != 0) { _addAltRewards(SUSHI, sushiRewards); } } IERC20(token).safeTransfer(msg.sender, unstakeAmount); emit Unstake( msg.sender, token, msg.sender, //currentDelegate, unstakeAmount ); } if (claimSushi) { _paySushiRewards( msg.sender, _pendingAltRewards(SUSHI, msg.sender, lptUserSupply, 0) ); } } function claim( bool restake) external checkPause updateRewards(msg.sender) returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned) { return _claim(restake); } function claimBzrx() external checkPause updateRewards(msg.sender) returns (uint256 bzrxRewardsEarned) { bzrxRewardsEarned = _claimBzrx(false); emit Claim( msg.sender, bzrxRewardsEarned, 0 ); } function claim3Crv() external checkPause updateRewards(msg.sender) returns (uint256 stableCoinRewardsEarned) { stableCoinRewardsEarned = _claim3Crv(); emit Claim( msg.sender, 0, stableCoinRewardsEarned ); } function _claim( bool restake) internal returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned) { bzrxRewardsEarned = _claimBzrx(restake); stableCoinRewardsEarned = _claim3Crv(); emit Claim( msg.sender, bzrxRewardsEarned, stableCoinRewardsEarned ); } function _claimBzrx( bool restake) internal returns (uint256 bzrxRewardsEarned) { bzrxRewardsEarned = bzrxRewards[msg.sender]; if (bzrxRewardsEarned != 0) { bzrxRewards[msg.sender] = 0; if (restake) { _restakeBZRX( msg.sender, bzrxRewardsEarned ); } else { if (IERC20(BZRX).balanceOf(address(this)) < bzrxRewardsEarned) { // settle vested BZRX only if needed IVestingToken(vBZRX).claim(); } IERC20(BZRX).transfer(msg.sender, bzrxRewardsEarned); } } } function _claim3Crv() internal returns (uint256 stableCoinRewardsEarned) { stableCoinRewardsEarned = stableCoinRewards[msg.sender]; if (stableCoinRewardsEarned != 0) { stableCoinRewards[msg.sender] = 0; curve3Crv.transfer(msg.sender, stableCoinRewardsEarned); } } function _restakeBZRX( address account, uint256 amount) internal { _balancesPerToken[BZRX][account] = _balancesPerToken[BZRX][account] .add(amount); _totalSupplyPerToken[BZRX] = _totalSupplyPerToken[BZRX] .add(amount); emit Stake( account, BZRX, account, //currentDelegate, amount ); } function exit() public // unstake() does a checkPause { address[] memory tokens = new address[](4); uint256[] memory values = new uint256[](4); tokens[0] = iBZRX; tokens[1] = LPToken; tokens[2] = vBZRX; tokens[3] = BZRX; values[0] = uint256(-1); values[1] = uint256(-1); values[2] = uint256(-1); values[3] = uint256(-1); unstake(tokens, values, true); // calls updateRewards _claim(false); } modifier updateRewards(address account) { uint256 _bzrxPerTokenStored = bzrxPerTokenStored; uint256 _stableCoinPerTokenStored = stableCoinPerTokenStored; (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting) = _earned( account, _bzrxPerTokenStored, _stableCoinPerTokenStored ); bzrxRewardsPerTokenPaid[account] = _bzrxPerTokenStored; stableCoinRewardsPerTokenPaid[account] = _stableCoinPerTokenStored; // vesting amounts get updated before sync bzrxVesting[account] = bzrxRewardsVesting; stableCoinVesting[account] = stableCoinRewardsVesting; (bzrxRewards[account], stableCoinRewards[account]) = _syncVesting( account, bzrxRewardsEarned, stableCoinRewardsEarned, bzrxRewardsVesting, stableCoinRewardsVesting ); vestingLastSync[account] = block.timestamp; _; } function earned( address account) external view returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting) { (bzrxRewardsEarned, stableCoinRewardsEarned, bzrxRewardsVesting, stableCoinRewardsVesting) = _earned( account, bzrxPerTokenStored, stableCoinPerTokenStored ); (bzrxRewardsEarned, stableCoinRewardsEarned) = _syncVesting( account, bzrxRewardsEarned, stableCoinRewardsEarned, bzrxRewardsVesting, stableCoinRewardsVesting ); // discount vesting amounts for vesting time uint256 multiplier = vestedBalanceForAmount( 1e36, 0, block.timestamp ); bzrxRewardsVesting = bzrxRewardsVesting .sub(bzrxRewardsVesting .mul(multiplier) .div(1e36) ); stableCoinRewardsVesting = stableCoinRewardsVesting .sub(stableCoinRewardsVesting .mul(multiplier) .div(1e36) ); } function _earned( address account, uint256 _bzrxPerToken, uint256 _stableCoinPerToken) internal view returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting) { uint256 bzrxPerTokenUnpaid = _bzrxPerToken.sub(bzrxRewardsPerTokenPaid[account]); uint256 stableCoinPerTokenUnpaid = _stableCoinPerToken.sub(stableCoinRewardsPerTokenPaid[account]); bzrxRewardsEarned = bzrxRewards[account]; stableCoinRewardsEarned = stableCoinRewards[account]; bzrxRewardsVesting = bzrxVesting[account]; stableCoinRewardsVesting = stableCoinVesting[account]; if (bzrxPerTokenUnpaid != 0 || stableCoinPerTokenUnpaid != 0) { uint256 value; uint256 multiplier; uint256 lastSync; (uint256 vestedBalance, uint256 vestingBalance) = balanceOfStored(account); value = vestedBalance .mul(bzrxPerTokenUnpaid); value /= 1e36; bzrxRewardsEarned = value .add(bzrxRewardsEarned); value = vestedBalance .mul(stableCoinPerTokenUnpaid); value /= 1e36; stableCoinRewardsEarned = value .add(stableCoinRewardsEarned); if (vestingBalance != 0 && bzrxPerTokenUnpaid != 0) { // add new vesting amount for BZRX value = vestingBalance .mul(bzrxPerTokenUnpaid); value /= 1e36; bzrxRewardsVesting = bzrxRewardsVesting .add(value); // true up earned amount to vBZRX vesting schedule lastSync = vestingLastSync[account]; multiplier = vestedBalanceForAmount( 1e36, 0, lastSync ); value = value .mul(multiplier); value /= 1e36; bzrxRewardsEarned = bzrxRewardsEarned .add(value); } if (vestingBalance != 0 && stableCoinPerTokenUnpaid != 0) { // add new vesting amount for 3crv value = vestingBalance .mul(stableCoinPerTokenUnpaid); value /= 1e36; stableCoinRewardsVesting = stableCoinRewardsVesting .add(value); // true up earned amount to vBZRX vesting schedule if (lastSync == 0) { lastSync = vestingLastSync[account]; multiplier = vestedBalanceForAmount( 1e36, 0, lastSync ); } value = value .mul(multiplier); value /= 1e36; stableCoinRewardsEarned = stableCoinRewardsEarned .add(value); } } } function _syncVesting( address account, uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting) internal view returns (uint256, uint256) { uint256 lastVestingSync = vestingLastSync[account]; if (lastVestingSync != block.timestamp) { uint256 rewardsVested; uint256 multiplier = vestedBalanceForAmount( 1e36, lastVestingSync, block.timestamp ); if (bzrxRewardsVesting != 0) { rewardsVested = bzrxRewardsVesting .mul(multiplier) .div(1e36); bzrxRewardsEarned += rewardsVested; } if (stableCoinRewardsVesting != 0) { rewardsVested = stableCoinRewardsVesting .mul(multiplier) .div(1e36); stableCoinRewardsEarned += rewardsVested; } uint256 vBZRXBalance = _balancesPerToken[vBZRX][account]; if (vBZRXBalance != 0) { // add vested BZRX to rewards balance rewardsVested = vBZRXBalance .mul(multiplier) .div(1e36); bzrxRewardsEarned += rewardsVested; } } return (bzrxRewardsEarned, stableCoinRewardsEarned); } // note: anyone can contribute rewards to the contract function addDirectRewards( address[] calldata accounts, uint256[] calldata bzrxAmounts, uint256[] calldata stableCoinAmounts) external checkPause returns (uint256 bzrxTotal, uint256 stableCoinTotal) { require(accounts.length == bzrxAmounts.length && accounts.length == stableCoinAmounts.length, "count mismatch"); for (uint256 i = 0; i < accounts.length; i++) { bzrxRewards[accounts[i]] = bzrxRewards[accounts[i]].add(bzrxAmounts[i]); bzrxTotal = bzrxTotal.add(bzrxAmounts[i]); stableCoinRewards[accounts[i]] = stableCoinRewards[accounts[i]].add(stableCoinAmounts[i]); stableCoinTotal = stableCoinTotal.add(stableCoinAmounts[i]); } if (bzrxTotal != 0) { IERC20(BZRX).transferFrom(msg.sender, address(this), bzrxTotal); } if (stableCoinTotal != 0) { curve3Crv.transferFrom(msg.sender, address(this), stableCoinTotal); } } // note: anyone can contribute rewards to the contract function addRewards( uint256 newBZRX, uint256 newStableCoin) external checkPause { if (newBZRX != 0 || newStableCoin != 0) { _addRewards(newBZRX, newStableCoin); if (newBZRX != 0) { IERC20(BZRX).transferFrom(msg.sender, address(this), newBZRX); } if (newStableCoin != 0) { curve3Crv.transferFrom(msg.sender, address(this), newStableCoin); } } } function _addRewards( uint256 newBZRX, uint256 newStableCoin) internal { (vBZRXWeightStored, iBZRXWeightStored, LPTokenWeightStored) = getVariableWeights(); uint256 totalTokens = totalSupplyStored(); require(totalTokens != 0, "nothing staked"); bzrxPerTokenStored = newBZRX .mul(1e36) .div(totalTokens) .add(bzrxPerTokenStored); stableCoinPerTokenStored = newStableCoin .mul(1e36) .div(totalTokens) .add(stableCoinPerTokenStored); lastRewardsAddTime = block.timestamp; emit AddRewards( msg.sender, newBZRX, newStableCoin ); } function addAltRewards(address token, uint256 amount) public { if (amount != 0) { _addAltRewards(token, amount); IERC20(token).transferFrom(msg.sender, address(this), amount); } } function _addAltRewards(address token, uint256 amount) internal { address poolAddress = token == SUSHI ? LPToken : token; uint256 totalSupply = _totalSupplyPerToken[poolAddress]; require(totalSupply != 0, "no deposits"); uint256 _prevAltRewardsPerShare = 0; uint256[] memory _altRewardsRounds = altRewardsRounds[token]; if (_altRewardsRounds.length > 0) { _prevAltRewardsPerShare = _altRewardsRounds[_altRewardsRounds.length - 1]; } uint256 _currentAltRewardsPerShare = amount.mul(1e12).div(totalSupply); uint256 _rewardsPerShare = _currentAltRewardsPerShare.add(_prevAltRewardsPerShare); altRewardsRounds[token].push(_rewardsPerShare); emit AddAltRewards(msg.sender, token, amount); } function getVariableWeights() public view returns (uint256 vBZRXWeight, uint256 iBZRXWeight, uint256 LPTokenWeight) { uint256 totalVested = vestedBalanceForAmount( _startingVBZRXBalance, 0, block.timestamp ); vBZRXWeight = SafeMath.mul(_startingVBZRXBalance - totalVested, 1e18) // overflow not possible .div(_startingVBZRXBalance); iBZRXWeight = _calcIBZRXWeight(); uint256 lpTokenSupply = _totalSupplyPerToken[LPToken]; if (lpTokenSupply != 0) { // staked LP tokens are assumed to represent the total unstaked supply (circulated supply - staked BZRX) uint256 normalizedLPTokenSupply = initialCirculatingSupply + totalVested - _totalSupplyPerToken[BZRX]; LPTokenWeight = normalizedLPTokenSupply .mul(1e18) .div(lpTokenSupply); } } function _calcIBZRXWeight() internal view returns (uint256) { return IERC20(BZRX).balanceOf(iBZRX) .mul(1e50) .div(IERC20(iBZRX).totalSupply()); } function balanceOfByAsset( address token, address account) public view returns (uint256 balance) { balance = _balancesPerToken[token][account]; } function balanceOfByAssets( address account) external view returns ( uint256 bzrxBalance, uint256 iBZRXBalance, uint256 vBZRXBalance, uint256 LPTokenBalance, uint256 LPTokenBalanceOld ) { return ( balanceOfByAsset(BZRX, account), balanceOfByAsset(iBZRX, account), balanceOfByAsset(vBZRX, account), balanceOfByAsset(LPToken, account), balanceOfByAsset(LPTokenOld, account) ); } function balanceOfStored( address account) public view returns (uint256 vestedBalance, uint256 vestingBalance) { uint256 balance = _balancesPerToken[vBZRX][account]; if (balance != 0) { vestingBalance = _balancesPerToken[vBZRX][account] .mul(vBZRXWeightStored) .div(1e18); } vestedBalance = _balancesPerToken[BZRX][account]; balance = _balancesPerToken[iBZRX][account]; if (balance != 0) { vestedBalance = balance .mul(iBZRXWeightStored) .div(1e50) .add(vestedBalance); } balance = _balancesPerToken[LPToken][account]; if (balance != 0) { vestedBalance = balance .mul(LPTokenWeightStored) .div(1e18) .add(vestedBalance); } } function totalSupplyByAsset( address token) external view returns (uint256) { return _totalSupplyPerToken[token]; } function totalSupplyStored() public view returns (uint256 supply) { supply = _totalSupplyPerToken[vBZRX] .mul(vBZRXWeightStored) .div(1e18); supply = _totalSupplyPerToken[BZRX] .add(supply); supply = _totalSupplyPerToken[iBZRX] .mul(iBZRXWeightStored) .div(1e50) .add(supply); supply = _totalSupplyPerToken[LPToken] .mul(LPTokenWeightStored) .div(1e18) .add(supply); } function vestedBalanceForAmount( uint256 tokenBalance, uint256 lastUpdate, uint256 vestingEndTime) public view returns (uint256 vested) { vestingEndTime = vestingEndTime.min256(block.timestamp); if (vestingEndTime > lastUpdate) { if (vestingEndTime <= vestingCliffTimestamp || lastUpdate >= vestingEndTimestamp) { // time cannot be before vesting starts // OR all vested token has already been claimed return 0; } if (lastUpdate < vestingCliffTimestamp) { // vesting starts at the cliff timestamp lastUpdate = vestingCliffTimestamp; } if (vestingEndTime > vestingEndTimestamp) { // vesting ends at the end timestamp vestingEndTime = vestingEndTimestamp; } uint256 timeSinceClaim = vestingEndTime.sub(lastUpdate); vested = tokenBalance.mul(timeSinceClaim) / vestingDurationAfterCliff; // will never divide by 0 } } // Governance Logic // function votingBalanceOf( address account, uint256 proposalId) public view returns (uint256 totalVotes) { return _votingBalanceOf(account, _proposalState[proposalId]); } function votingBalanceOfNow( address account) public view returns (uint256 totalVotes) { return _votingBalanceOf(account, _getProposalState()); } function _setProposalVals( address account, uint256 proposalId) public returns (uint256) { require(msg.sender == governor, "unauthorized"); require(_proposalState[proposalId].proposalTime == 0, "proposal exists"); ProposalState memory newProposal = _getProposalState(); _proposalState[proposalId] = newProposal; return _votingBalanceOf(account, newProposal); } function _getProposalState() internal view returns (ProposalState memory) { return ProposalState({ proposalTime: block.timestamp - 1, iBZRXWeight: _calcIBZRXWeight(), lpBZRXBalance: IERC20(BZRX).balanceOf(LPToken), lpTotalSupply: IERC20(LPToken).totalSupply() }); } function _votingBalanceOf( address account, ProposalState memory proposal) internal view returns (uint256 totalVotes) { uint256 _vestingLastSync = vestingLastSync[account]; if (proposal.proposalTime == 0 || _vestingLastSync > proposal.proposalTime - 1) { return 0; } uint256 _vBZRXBalance = _balancesPerToken[vBZRX][account]; if (_vBZRXBalance != 0) { // staked vBZRX is prorated based on total vested totalVotes = _vBZRXBalance .mul(_startingVBZRXBalance - vestedBalanceForAmount( // overflow not possible _startingVBZRXBalance, 0, proposal.proposalTime ) ).div(_startingVBZRXBalance); // user is attributed a staked balance of vested BZRX, from their last update to the present totalVotes = vestedBalanceForAmount( _vBZRXBalance, _vestingLastSync, proposal.proposalTime ).add(totalVotes); } totalVotes = _balancesPerToken[BZRX][account] .add(bzrxRewards[account]) // unclaimed BZRX rewards count as votes .add(totalVotes); totalVotes = _balancesPerToken[iBZRX][account] .mul(proposal.iBZRXWeight) .div(1e50) .add(totalVotes); // LPToken votes are measured based on amount of underlying BZRX staked totalVotes = proposal.lpBZRXBalance .mul(_balancesPerToken[LPToken][account]) .div(proposal.lpTotalSupply) .add(totalVotes); } // OnlyOwner functions function togglePause( bool _isPaused) external onlyOwner { isPaused = _isPaused; } function setFundsWallet( address _fundsWallet) external onlyOwner { fundsWallet = _fundsWallet; } function setGovernor( address _governor) external onlyOwner { governor = _governor; } function setFeeTokens( address[] calldata tokens) external onlyOwner { currentFeeTokens = tokens; } function setRewardPercent( uint256 _rewardPercent) external onlyOwner { require(_rewardPercent <= 1e20, "value too high"); rewardPercent = _rewardPercent; } function setMaxUniswapDisagreement( uint256 _maxUniswapDisagreement) external onlyOwner { require(_maxUniswapDisagreement != 0, "invalid param"); maxUniswapDisagreement = _maxUniswapDisagreement; } function setMaxCurveDisagreement( uint256 _maxCurveDisagreement) external onlyOwner { require(_maxCurveDisagreement != 0, "invalid param"); maxCurveDisagreement = _maxCurveDisagreement; } function setCallerRewardDivisor( uint256 _callerRewardDivisor) external onlyOwner { require(_callerRewardDivisor != 0, "invalid param"); callerRewardDivisor = _callerRewardDivisor; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AddAltRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinAmount","type":"uint256"}],"name":"AddRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"oldDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"newDelegate","type":"address"}],"name":"ChangeDelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinAmount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimAltRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxOutput","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinOutput","type":"uint256"}],"name":"ConvertFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxRewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinRewards","type":"uint256"}],"name":"DistributeFees","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":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"WithdrawFees","type":"event"},{"constant":true,"inputs":[],"name":"BZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DAI","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LPToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LPTokenOld","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LPTokenWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SUSHI","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"USDT","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"_setProposalVals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addAltRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"bzrxAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"stableCoinAmounts","type":"uint256[]"}],"name":"addDirectRewards","outputs":[{"internalType":"uint256","name":"bzrxTotal","type":"uint256"},{"internalType":"uint256","name":"stableCoinTotal","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newBZRX","type":"uint256"},{"internalType":"uint256","name":"newStableCoin","type":"uint256"}],"name":"addRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"altRewardsRounds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bZx","outputs":[{"internalType":"contract IBZx","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfByAsset","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfByAssets","outputs":[{"internalType":"uint256","name":"bzrxBalance","type":"uint256"},{"internalType":"uint256","name":"iBZRXBalance","type":"uint256"},{"internalType":"uint256","name":"vBZRXBalance","type":"uint256"},{"internalType":"uint256","name":"LPTokenBalance","type":"uint256"},{"internalType":"uint256","name":"LPTokenBalanceOld","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfStored","outputs":[{"internalType":"uint256","name":"vestedBalance","type":"uint256"},{"internalType":"uint256","name":"vestingBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bzrxPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxRewardsPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxVesting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"callerRewardDivisor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"restake","type":"bool"}],"name":"claim","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claim3Crv","outputs":[{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimBzrx","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cliffDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"currentFeeTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curve3Crv","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curve3pool","outputs":[{"internalType":"contract ICurve3Pool","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegate","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"delegatedPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"bzrxRewardsVesting","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsVesting","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"exit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"exitSushi","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fundsWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentFeeTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getVariableWeights","outputs":[{"internalType":"uint256","name":"vBZRXWeight","type":"uint256"},{"internalType":"uint256","name":"iBZRXWeight","type":"uint256"},{"internalType":"uint256","name":"LPTokenWeight","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"iBZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"iBZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"initialCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastRewardsAddTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxCurveDisagreement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxUniswapDisagreement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingAltRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingSushiRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_callerRewardDivisor","type":"uint256"}],"name":"setCallerRewardDivisor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"setFeeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_fundsWallet","type":"address"}],"name":"setFundsWallet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_governor","type":"address"}],"name":"setGovernor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxCurveDisagreement","type":"uint256"}],"name":"setMaxCurveDisagreement","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxUniswapDisagreement","type":"uint256"}],"name":"setMaxUniswapDisagreement","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_rewardPercent","type":"uint256"}],"name":"setRewardPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stableCoinPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinRewardsPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinVesting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bool","name":"claimSushi","type":"bool"}],"name":"stake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"stake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapPaths","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"_isPaused","type":"bool"}],"name":"togglePause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"totalSupplyByAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupplyStored","outputs":[{"internalType":"uint256","name":"supply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract IUniswapV2Router","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bool","name":"claimSushi","type":"bool"}],"name":"unstake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"unstake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userAltRewardsRounds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vBZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vBZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenBalance","type":"uint256"},{"internalType":"uint256","name":"lastUpdate","type":"uint256"},{"internalType":"uint256","name":"vestingEndTime","type":"uint256"}],"name":"vestedBalanceForAmount","outputs":[{"internalType":"uint256","name":"vested","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vestingDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vestingLastSync","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"votingBalanceOf","outputs":[{"internalType":"uint256","name":"totalVotes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"votingBalanceOfNow","outputs":[{"internalType":"uint256","name":"totalVotes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040526802b5e3af16b18800006018556729a2241af62c00006019819055601a556064601b5560006200003c6001600160e01b036200008c16565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35062000090565b3390565b61522580620000a06000396000f3fe608060405234801561001057600080fd5b50600436106104ab5760003560e01c80637f3fd8ba1161026d578063b6d6d88d11610151578063d85349f7116100ce578063e9fad8ee11610092578063e9fad8ee14610962578063eb0e8d1a1461096a578063ef1c243a14610972578063f2fde38b1461097a578063f30127a51461098d578063fc41aa0914610995576104ab565b8063d85349f71461092f578063dae607db14610937578063db8bb3a11461093f578063e0bab4c414610952578063e53b958d1461095a576104ab565b8063c54e44eb11610115578063c54e44eb146108e4578063cf86add5146108ec578063cff361e5146108ff578063d030205114610912578063d3d204311461091a576104ab565b8063b6d6d88d14610885578063bcca1e0414610898578063c1159297146108ab578063c1c5dd27146108be578063c42cf535146108d1576104ab565b80638da5cb5b116101ea578063ab560e10116101ae578063ab560e1014610834578063abbd3ab11461083c578063ad5c46481461084f578063b02eba0514610857578063b187bd261461086a578063b293fdc514610872576104ab565b80638da5cb5b146107de5780638f32d59b146107e65780638fc9c962146107fb5780639674a9311461080e578063a5795eba14610821576104ab565b806386be87a61161023157806386be87a61461079557806387359ebe146107a857806389a30271146107bb57806389ffc781146107c35780638caaf9e6146107cb576104ab565b80637f3fd8ba14610748578063802971a61461075b57806382a8af151461076357806383e02cd814610776578063863f2e181461078d576104ab565b80633d0b00241161039457806357d159c611610311578063633e9470116102d5578063633e94701461070257806364e39b871461070a57806366067a951461071d57806369636ff614610725578063715018a614610738578063735de9f714610740576104ab565b806357d159c6146106b957806359d99805146106cc57806359dcf522146106d45780635c19a95c146106e75780635c60da1b146106fa576104ab565b8063499d7f9611610358578063499d7f961461067b5780635224eaf41461068e57806352fb1c9d146106a157806353a8f1ec146106a9578063547d0738146106b1576104ab565b80633d0b0024146106325780633e1755c71461063a57806341adca421461064d5780634330c263146106605780634811538514610673576104ab565b806319e772c21161042d5780632a5522af116103f15780632a5522af146105b75780632d06e5bf146105ca5780632d81a78e146105d25780632ee1a86e146105f3578063307e85a4146106175780633bb20ece1461062a576104ab565b806319e772c2146105775780631c9c44081461057f5780631ca97a2d146105875780631d3e39551461059a5780632194f3a2146105af576104ab565b80630a4d2924116104745780630a4d29241461052c5780630c340a241461053f5780630da47e0a146105475780631514617e1461055a57806317a1d01214610562576104ab565b80628cc262146104b05780630114a05e146104dc578063011cee36146104fc57806302baf1b01461051157806302dd19d914610524575b600080fd5b6104c36104be36600461460a565b6109a8565b6040516104d39493929190614fb1565b60405180910390f35b6104ef6104ea36600461460a565b610a72565b6040516104d39190614f44565b610504610a84565b6040516104d39190614d8b565b6104ef61051f36600461460a565b610a96565b6104ef610ab5565b6104ef61053a366004614662565b610abb565b610504610ae9565b6104ef61055536600461460a565b610af8565b6104ef610b0a565b61056a610b12565b6040516104d39190614e17565b6104ef610b2a565b6104ef610b30565b6104ef61059536600461460a565b610b36565b6105ad6105a83660046148aa565b610b48565b005b610504610b97565b6104ef6105c5366004614662565b610ba6565b6104ef610c58565b6105e56105e0366004614850565b610c67565b6040516104d3929190614f88565b61060661060136600461460a565b610d4e565b6040516104d3959493929190614fe6565b6105ad6106253660046148aa565b610df2565b6104ef610e38565b610504610e3e565b6105ad610648366004614662565b610e56565b6104ef61065b36600461460a565b610eee565b6104ef61066e36600461460a565b610f00565b6104ef610f12565b6104ef61068936600461460a565b611039565b6105ad61069c3660046147d4565b61104b565b6104ef61166a565b6104ef611670565b610504611676565b6105ad6106c7366004614850565b61168e565b6104ef6116d0565b6105e56106e236600461460a565b6116d6565b6105046106f536600461460a565b611853565b61050461186e565b61056a61187d565b6105ad61071836600461460a565b611895565b6104ef6118db565b6104ef61073336600461460a565b6118e1565b6105ad6118f2565b61056a611960565b6104ef610756366004614905565b611978565b610504611a1c565b6105046107713660046148aa565b611a34565b61077e611a5b565b6040516104d393929190614f96565b6105ad611b54565b6104ef6107a3366004614628565b611c6f565b6104ef6107b6366004614628565b611c8b565b610504611cb6565b61056a611cce565b6105ad6107d93660046148aa565b611ce6565b610504611d2c565b6107ee611d3c565b6040516104d39190614e09565b6105ad6108093660046147d4565b611d60565b6104ef61081c36600461460a565b6122de565b6105e561082f3660046146d4565b6122f0565b6105046125df565b6104ef61084a36600461460a565b6125f1565b610504612604565b6104ef61086536600461460a565b61261c565b6107ee61262e565b6105ad610880366004614692565b61263e565b6104ef610893366004614628565b61266e565b6105ad6108a6366004614775565b61268b565b6104ef6108b9366004614662565b612697565b6105ad6108cc3660046148aa565b6126e0565b6105ad6108df36600461460a565b612732565b610504612778565b6105ad6108fa366004614775565b612790565b6104ef61090d36600461460a565b61279c565b6104ef6128af565b6109226128b5565b6040516104d39190614df8565b6104ef612917565b6104ef61291e565b61050461094d366004614662565b61292a565b61050461295f565b6104ef612977565b6105ad612a89565b6104ef612c58565b6104ef612c5e565b6105ad61098836600461460a565b612dd7565b610504612e07565b6105ad6109a33660046148e6565b612e19565b6000806000806109bd85600754600b54612f2f565b929650909450925090506109d485858585856131c1565b909450925060006109f46a0c097ce7bc90715b34b9f160241b8242611978565b9050610a34610a276a0c097ce7bc90715b34b9f160241b610a1b868563ffffffff6132c616565b9063ffffffff61330016565b849063ffffffff61334216565b9250610a68610a5b6a0c097ce7bc90715b34b9f160241b610a1b858563ffffffff6132c616565b839063ffffffff61334216565b9150509193509193565b60086020526000908152604090205481565b60008051602061516383398151915281565b6001600160a01b0381166000908152600360205260409020545b919050565b601b5481565b601f6020528160005260406000208181548110610ad457fe5b90600052602060002001600091509150505481565b601d546001600160a01b031681565b600d6020526000908152604090205481565b630784ce0081565b73bebc44782c7db0a1a60cb6fe97d0b483032ff1c781565b600f5481565b60105481565b60096020526000908152604090205481565b610b50611d3c565b610b755760405162461bcd60e51b8152600401610b6c90614ee4565b60405180910390fd5b80610b925760405162461bcd60e51b8152600401610b6c90614ef4565b601a55565b6002546001600160a01b031681565b601d546000906001600160a01b03163314610bd35760405162461bcd60e51b8152600401610b6c90614ed4565b6000828152601e602052604090205415610bff5760405162461bcd60e51b8152600401610b6c90614e94565b610c076143af565b610c0f613384565b6000848152601e60209081526040918290208351815590830151600182015590820151600282015560608201516003909101559050610c4e84826134ca565b9150505b92915050565b6a744f570177f475546c000081565b6001546000908190600160a01b900460ff1615610c965760405162461bcd60e51b8152600401610b6c90614f14565b600754600b543391906000808080610caf878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050610d0287858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055610d3e8a6136ad565b9850985050505050505050915091565b6000806000806000610d6e60008051602061512383398151915287611c8b565b610d8c7318240bd9c07fa6156ce3f3f61921cc82b261915788611c8b565b610daa73b72b31907c1c95f3650b64b2469e08edacee5e8f89611c8b565b610dc26000805160206151638339815191528a611c8b565b610de073e26a220a341eaca116bda64cf9d5638a935ae6298b611c8b565b939a9299509097509550909350915050565b610dfa611d3c565b610e165760405162461bcd60e51b8152600401610b6c90614ee4565b80610e335760405162461bcd60e51b8152600401610b6c90614ef4565b601b55565b600b5481565b73e26a220a341eaca116bda64cf9d5638a935ae62981565b8015610eea57610e66828261370d565b6040516323b872dd60e01b81526001600160a01b038316906323b872dd90610e9690339030908690600401614d99565b602060405180830381600087803b158015610eb057600080fd5b505af1158015610ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ee8919081019061486e565b505b5050565b600e6020526000908152604090205481565b600a6020526000908152604090205481565b600154600090600160a01b900460ff1615610f3f5760405162461bcd60e51b8152600401610b6c90614f14565b600754600b543391906000808080610f58878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050610fab87858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d835281842094909455939092556015909152908120429055610fe9906138a9565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf7896000604051611027929190614f6d565b60405180910390a25050505050505090565b60176020526000908152604090205481565b600154600160a01b900460ff16156110755760405162461bcd60e51b8152600401610b6c90614f14565b600754600b54339190600080808061108e878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e9091529020819055929650909450925090506110e187858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d8352818420949094559390925560159091522042905588518a51146111355760405162461bcd60e51b8152600401610b6c90614e84565b6000806000808b61114757600061115f565b61115f60008051602061516383398151915233611c8b565b905060005b8e5181101561162f578e818151811061117957fe5b602002602001015194506000805160206151238339815191526001600160a01b0316856001600160a01b031614806111cd57506001600160a01b03851673b72b31907c1c95f3650b64b2469e08edacee5e8f145b806111f457506001600160a01b0385167318240bd9c07fa6156ce3f3f61921cc82b2619157145b8061121557506001600160a01b038516600080516020615163833981519152145b8061123c57506001600160a01b03851673e26a220a341eaca116bda64cf9d5638a935ae629145b6112585760405162461bcd60e51b8152600401610b6c90614ec4565b8d818151811061126457fe5b6020908102919091018101516001600160a01b0387166000908152600483526040808220338352909352919091205490945092508315806112a3575082155b156112ad57611627565b828411156112b9578293505b6001600160a01b038516600081815260046020908152604080832033845282528083208888039055838352600390915290208054869003905560008051602061512383398151915214801561138e57506040516370a0823160e01b81528490600080516020615123833981519152906370a082319061133c903090600401614d8b565b60206040518083038186803b15801561135457600080fd5b505afa158015611368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061138c91908101906148c8565b105b156113fb5773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156113e257600080fd5b505af11580156113f6573d6000803e3d6000fd5b505050505b6001600160a01b03851660008051602061516383398151915214156115b7576040516370a0823160e01b81526000906000805160206151c3833981519152906370a082319061144e903090600401614d8b565b60206040518083038186803b15801561146657600080fd5b505afa15801561147a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061149e91908101906148c8565b604051630441a3e760e41b815290915073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063441a3e70906114db9060bc908990600401614f88565b600060405180830381600087803b1580156114f557600080fd5b505af1158015611509573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092508391506000805160206151c3833981519152906370a0823190611543903090600401614d8b565b60206040518083038186803b15801561155b57600080fd5b505afa15801561156f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061159391908101906148c8565b03905080156115b4576115b46000805160206151c38339815191528261370d565b50505b6115d16001600160a01b038616338663ffffffff613a6016565b336001600160a01b0316856001600160a01b0316336001600160a01b03167f2cbcd809a4c90d11f8d12c4b6d09986b255ae1e68f54f076c145fbb2185904e18760405161161e9190614f44565b60405180910390a45b600101611164565b508b1561165a5761165a336116556000805160206151c383398151915233856000613ab9565b613c46565b5050505050505050505050505050565b60115481565b601a5481565b73b72b31907c1c95f3650b64b2469e08edacee5e8f81565b611696611d3c565b6116b25760405162461bcd60e51b8152600401610b6c90614ee4565b60018054911515600160a01b0260ff60a01b19909216919091179055565b60195481565b6001600160a01b038116600090815260008051602061518383398151915260205260408120548190801561174d57600f546001600160a01b0385166000908152600080516020615183833981519152602052604090205461174a91670de0b6b3a764000091610a1b9163ffffffff6132c616565b91505b506001600160a01b038316600090815260008051602061514383398151915260209081526040808320547fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c79092529091205490925080156117e6576117e3836117d76e111b0ec57e6499a1f4b1014d3f6d5960321b610a1b601054866132c690919063ffffffff16565b9063ffffffff613d7816565b92505b506001600160a01b03831660009081527f064d7c8613d225af78bbf2a77ee533cb03ae723d97d3a14f96452520f45833f26020526040902054801561184d5761184a836117d7670de0b6b3a7640000610a1b601154866132c690919063ffffffff16565b92505b50915091565b6005602052600090815260409020546001600160a01b031681565b6001546001600160a01b031681565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b61189d611d3c565b6118b95760405162461bcd60e51b8152600401610b6c90614ee4565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60145481565b602080526000908152604090205481565b6118fa611d3c565b6119165760405162461bcd60e51b8152600401610b6c90614ee4565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f81565b600061198a824263ffffffff613d9d16565b915082821115611a1557635ffd02a0821115806119ab575063669136e08310155b156119b857506000611a15565b635ffd02a08310156119cc57635ffd02a092505b63669136e08211156119e05763669136e091505b60006119f2838563ffffffff61334216565b90506306943440611a09868363ffffffff6132c616565b81611a1057fe5b049150505b9392505050565b7318240bd9c07fa6156ce3f3f61921cc82b261915781565b601c8181548110611a4157fe5b6000918252602090912001546001600160a01b0316905081565b600080600080611a796b02dfafa4e0948fa071940000600042611978565b9050611aab6b02dfafa4e0948fa071940000610a1b836b02dfafa4e0948fa07194000003670de0b6b3a76400006132c6565b9350611ab5613db3565b60008051602061516383398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b6549093508015611b4d5760008051602061512383398151915260005260036020526000805160206151a38339815191525482036a744f570177f475546c000001611b4982610a1b83670de0b6b3a764000063ffffffff6132c616565b9350505b5050909192565b611b5c611d3c565b611b785760405162461bcd60e51b8152600401610b6c90614ee4565b6040516393f1a40b60e01b815273c2edad668740f1aa35e4d8f227fb8e17dca888cd9060009082906393f1a40b90611bb79060bc903090600401614f52565b604080518083038186803b158015611bce57600080fd5b505afa158015611be2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c06919081019061488c565b51604051630441a3e760e41b81529091506001600160a01b0383169063441a3e7090611c399060bc908590600401614f88565b600060405180830381600087803b158015611c5357600080fd5b505af1158015611c67573d6000803e3d6000fd5b505050505050565b600080611c7c8484611c8b565b9050610c4e8484836000613ab9565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b736c3f90f043a72fa612cbac8115ee7e52bde6e49081565b611cee611d3c565b611d0a5760405162461bcd60e51b8152600401610b6c90614ee4565b80611d275760405162461bcd60e51b8152600401610b6c90614ef4565b601955565b6000546001600160a01b03165b90565b600080546001600160a01b0316611d51613ef6565b6001600160a01b031614905090565b600154600160a01b900460ff1615611d8a5760405162461bcd60e51b8152600401610b6c90614f14565b600754600b543391906000808080611da3878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050611df687858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d8352818420949094559390925560159091522042905588518a5114611e4a5760405162461bcd60e51b8152600401610b6c90614e84565b60008060008a611e5b576000611e73565b611e7360008051602061516383398151915233611c8b565b905060005b8d518110156122a9578d8181518110611e8d57fe5b602002602001015193506000805160206151238339815191526001600160a01b0316846001600160a01b03161480611ee157506001600160a01b03841673b72b31907c1c95f3650b64b2469e08edacee5e8f145b80611f0857506001600160a01b0384167318240bd9c07fa6156ce3f3f61921cc82b2619157145b80611f2957506001600160a01b038416600080516020615163833981519152145b611f455760405162461bcd60e51b8152600401610b6c90614ec4565b8c8181518110611f5157fe5b602002602001015192508260001415611f69576122a1565b6001600160a01b0384166000908152600460209081526040808320338452909152902054611f9d908463ffffffff613d7816565b6001600160a01b038516600081815260046020908152604080832033845282528083209490945591815260039091522054611fde908463ffffffff613d7816565b6001600160a01b03851660008181526003602052604090209190915561200c9033308663ffffffff613efa16565b6001600160a01b038416600080516020615163833981519152141561224b576040516370a0823160e01b81526000906000805160206151c3833981519152906370a082319061205f903090600401614d8b565b60206040518083038186803b15801561207757600080fd5b505afa15801561208b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120af91908101906148c8565b6040516370a0823160e01b815290915073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063e2bbb1589060bc90600080516020615163833981519152906370a0823190612102903090600401614d8b565b60206040518083038186803b15801561211a57600080fd5b505afa15801561212e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061215291908101906148c8565b6040518363ffffffff1660e01b815260040161216f929190614f88565b600060405180830381600087803b15801561218957600080fd5b505af115801561219d573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092508391506000805160206151c3833981519152906370a08231906121d7903090600401614d8b565b60206040518083038186803b1580156121ef57600080fd5b505afa158015612203573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061222791908101906148c8565b0390508015612248576122486000805160206151c38339815191528261370d565b50505b336001600160a01b0316846001600160a01b0316336001600160a01b03167fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd7866040516122989190614f44565b60405180910390a45b600101611e78565b508a156122cf576122cf336116556000805160206151c383398151915233856000613ab9565b50505050505050505050505050565b60156020526000908152604090205481565b6001546000908190600160a01b900460ff161561231f5760405162461bcd60e51b8152600401610b6c90614f14565b868514801561232d57508683145b6123495760405162461bcd60e51b8152600401610b6c90614e84565b60005b878110156124af576123b587878381811061236357fe5b90506020020135600960008c8c8681811061237a57fe5b905060200201602061238f919081019061460a565b6001600160a01b031681526020810191909152604001600020549063ffffffff613d7816565b600960008b8b858181106123c557fe5b90506020020160206123da919081019061460a565b6001600160a01b0316815260208101919091526040016000205561241987878381811061240357fe5b9050602002013584613d7890919063ffffffff16565b925061244185858381811061242a57fe5b90506020020135600d60008c8c8681811061237a57fe5b600d60008b8b8581811061245157fe5b9050602002016020612466919081019061460a565b6001600160a01b031681526020810191909152604001600020556124a585858381811061248f57fe5b9050602002013583613d7890919063ffffffff16565b915060010161234c565b50811561253f576040516323b872dd60e01b8152600080516020615123833981519152906323b872dd906124eb90339030908790600401614d99565b602060405180830381600087803b15801561250557600080fd5b505af1158015612519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061253d919081019061486e565b505b80156125d4576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd9061258090339030908690600401614d99565b602060405180830381600087803b15801561259a57600080fd5b505af11580156125ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125d2919081019061486e565b505b965096945050505050565b6000805160206151c383398151915281565b6000610c52826125ff613384565b6134ca565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600c6020526000908152604090205481565b600154600160a01b900460ff1681565b612646611d3c565b6126625760405162461bcd60e51b8152600401610b6c90614ee4565b610ee8601c83836143d7565b600660209081526000928352604080842090915290825290205481565b610eea8282600061104b565b6000818152601e60209081526040808320815160808101835281548152600182015493810193909352600281015491830191909152600301546060820152611a159084906134ca565b6126e8611d3c565b6127045760405162461bcd60e51b8152600401610b6c90614ee4565b68056bc75e2d6310000081111561272d5760405162461bcd60e51b8152600401610b6c90614ea4565b601855565b61273a611d3c565b6127565760405162461bcd60e51b8152600401610b6c90614ee4565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b73dac17f958d2ee523a2206206994597c13d831ec781565b610eea82826000611d60565b60405163065509bb60e21b8152600090819073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063195426ec906127db9060bc903090600401614f52565b60206040518083038186803b1580156127f357600080fd5b505afa158015612807573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061282b91908101906148c8565b9050611a156000805160206151c38339815191528461285860008051602061516383398151915287611c8b565b60008051602061516383398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b6546128aa90610a1b8764e8d4a5100063ffffffff6132c616565b613ab9565b60185481565b6060601c80548060200260200160405190810160405280929190818152602001828054801561290d57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116128ef575b5050505050905090565b62f099c081565b670de0b6b3a764000081565b6016602052816000526040600020818154811061294357fe5b6000918252602090912001546001600160a01b03169150829050565b736b175474e89094c44da98b954eedeac495271d0f81565b600154600090600160a01b900460ff16156129a45760405162461bcd60e51b8152600401610b6c90614f14565b600754600b5433919060008080806129bd878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050612a1087858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055612a4b613f1e565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf760008a604051611027929190614e25565b60408051600480825260a0820190925260609160208201608080388339505060408051600480825260a082019092529293506060929150602082016080803883390190505090507318240bd9c07fa6156ce3f3f61921cc82b261915782600081518110612af257fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060008051602061516383398151915282600181518110612b2e57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073b72b31907c1c95f3650b64b2469e08edacee5e8f82600281518110612b7057fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060008051602061512383398151915282600381518110612bac57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060001981600081518110612bdc57fe5b60200260200101818152505060001981600181518110612bf857fe5b60200260200101818152505060001981600281518110612c1457fe5b60200260200101818152505060001981600381518110612c3057fe5b602002602001018181525050612c488282600161104b565b612c5260006136ad565b50505050565b60075481565b600f5473b72b31907c1c95f3650b64b2469e08edacee5e8f600090815260036020527ffcfc5d57a009157202436965eb7c01b14f1b51f705a3b4f08296120160c5e109549091612cc291670de0b6b3a764000091610a1b919063ffffffff6132c616565b60008051602061512383398151915260005260036020526000805160206151a383398151915254909150612cfc908263ffffffff613d7816565b6010547318240bd9c07fa6156ce3f3f61921cc82b261915760005260036020527f91de0462b01273d0819ee89d2f822b745d4b4dcc3d05d8e0d13f841abd34e4a254919250612d6f9183916117d7916e111b0ec57e6499a1f4b1014d3f6d5960321b91610a1b919063ffffffff6132c616565b60115460008051602061516383398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b654919250612dd29183916117d791670de0b6b3a764000091610a1b919063ffffffff6132c616565b905090565b612ddf611d3c565b612dfb5760405162461bcd60e51b8152600401610b6c90614ee4565b612e0481613fd4565b50565b60008051602061512383398151915281565b600154600160a01b900460ff1615612e435760405162461bcd60e51b8152600401610b6c90614f14565b81151580612e5057508015155b15610eea57612e5f8282614055565b8115612eee576040516323b872dd60e01b8152600080516020615123833981519152906323b872dd90612e9a90339030908790600401614d99565b602060405180830381600087803b158015612eb457600080fd5b505af1158015612ec8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612eec919081019061486e565b505b8015610eea576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90610e9690339030908690600401614d99565b6001600160a01b0383166000908152600860205260408120548190819081908190612f6190889063ffffffff61334216565b6001600160a01b0389166000908152600c602052604081205491925090612f8f90889063ffffffff61334216565b6001600160a01b038a16600090815260096020908152604080832054600d835281842054600a845282852054600e9094529190932054929950975095509350905081151580612fdd57508015155b156131b6576000806000806000612ff38e6116d6565b9092509050613008828863ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b90049450613025858c613d78565b9a50613037828763ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b90049450613054858b613d78565b9950801580159061306457508615155b1561310157613079818863ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b900494506130968986613d78565b6001600160a01b038f16600090815260156020526040812054919a509093506130cf906a0c097ce7bc90715b34b9f160241b9085611978565b93506130e1858563ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b900494506130fe8b86613d78565b9a505b801580159061310f57508515155b156131b057613124818763ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b900494506131418886613d78565b975082613180576001600160a01b038e16600090815260156020526040812054935061317d906a0c097ce7bc90715b34b9f160241b9085611978565b93505b613190858563ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b900494506131ad8a86613d78565b99505b50505050505b505093509350935093565b6001600160a01b03851660009081526015602052604081205481904281146132b8576000806131ff6a0c097ce7bc90715b34b9f160241b8442611978565b90508615613230576132296a0c097ce7bc90715b34b9f160241b610a1b898463ffffffff6132c616565b9889019891505b851561325f576132586a0c097ce7bc90715b34b9f160241b610a1b888463ffffffff6132c616565b9788019791505b6001600160a01b038a166000908152600080516020615183833981519152602052604090205480156132b4576132ad6a0c097ce7bc90715b34b9f160241b610a1b838563ffffffff6132c616565b998a019992505b5050505b509496939550929350505050565b6000826132d557506000610c52565b828202828482816132e257fe5b0414611a155760405162461bcd60e51b8152600401610b6c90614eb4565b6000611a1583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061412c565b6000611a1583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614159565b61338c6143af565b60405180608001604052806001420381526020016133a8613db3565b81526040516370a0823160e01b8152602090910190600080516020615123833981519152906370a08231906133ef9060008051602061516383398151915290600401614d8b565b60206040518083038186803b15801561340757600080fd5b505afa15801561341b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061343f91908101906148c8565b81526020016000805160206151638339815191526001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561348b57600080fd5b505afa15801561349f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506134c391908101906148c8565b9052905090565b6001600160a01b038216600090815260156020526040812054825115806134f5575082516000190181115b15613504576000915050610c52565b6001600160a01b0384166000908152600080516020615183833981519152602052604090205480156135925761357a6b02dfafa4e0948fa071940000610a1b61355f6b02dfafa4e0948fa07194000060008960000151611978565b84906b02dfafa4e0948fa0719400000363ffffffff6132c616565b925061358f836117d783858860000151611978565b92505b6001600160a01b038516600090815260096020908152604080832054600080516020615143833981519152909252909120546135d39185916117d791613d78565b6020808601516001600160a01b03881660009081527fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c79092526040909120549194506136439185916117d7916e111b0ec57e6499a1f4b1014d3f6d5960321b91610a1b919063ffffffff6132c616565b60608501516001600160a01b03871660009081527f064d7c8613d225af78bbf2a77ee533cb03ae723d97d3a14f96452520f45833f260205260409081902054908701519295506136a49286926117d7929091610a1b9163ffffffff6132c616565b95945050505050565b6000806136b9836138a9565b91506136c3613f1e565b9050336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf78383604051613700929190614f88565b60405180910390a2915091565b60006001600160a01b0383166000805160206151c3833981519152146137335782613743565b6000805160206151638339815191525b6001600160a01b0381166000908152600360205260409020549091508061377c5760405162461bcd60e51b8152600401610b6c90614e64565b6001600160a01b0384166000908152601f6020908152604080832080548251818502810185019093528083526060938301828280156137da57602002820191906000526020600020905b8154815260200190600101908083116137c6575b5050505050905060008151111561380657806001825103815181106137fb57fe5b602002602001015191505b600061382184610a1b8864e8d4a5100063ffffffff6132c616565b90506000613835828563ffffffff613d7816565b6001600160a01b0389166000818152601f6020908152604080832080546001810182559084529190922001839055519192509033907f0ec162440d54eb15069478f467bd7294f3d5cead39c9724ff287893483d7c60c90613897908b90614f44565b60405180910390a35050505050505050565b336000908152600960205260409020548015610ab0573360009081526009602052604081205581156138e4576138df3382614185565b610ab0565b6040516370a0823160e01b81528190600080516020615123833981519152906370a0823190613917903090600401614d8b565b60206040518083038186803b15801561392f57600080fd5b505afa158015613943573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061396791908101906148c8565b10156139d55773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156139bc57600080fd5b505af11580156139d0573d6000803e3d6000fd5b505050505b60405163a9059cbb60e01b81526000805160206151238339815191529063a9059cbb90613a089033908590600401614dc1565b602060405180830381600087803b158015613a2257600080fd5b505af1158015613a36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613a5a919081019061486e565b50919050565b604051610ee890849063a9059cbb60e01b90613a829086908690602401614dea565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614291565b6001600160a01b0384166000908152601f602090815260408083208054825181850281018501909352808352606093830182828015613b1757602002820191906000526020600020905b815481526020019060010190808311613b03575b5050835193945050508115159050613b3457600092505050613c3e565b84613b4457600092505050613c3e565b6001600160a01b03861660009081526020805260408120548351909190613b8d90879086906000198701908110613b7757fe5b6020026020010151613d7890919063ffffffff16565b905081613bb857613bad64e8d4a51000610a1b898463ffffffff6132c616565b945050505050613c3e565b600019928301929091019082821415613bd8576000945050505050613c3e565b6000848381518110613be657fe5b602002602001015190506000613c05838a6132c690919063ffffffff16565b90506000613c198a8463ffffffff6132c616565b9050613c3464e8d4a51000610a1b848463ffffffff61334216565b9750505050505050505b949350505050565b6000805160206151c3833981519152600052601f60209081527ff671d343b5ca683fae72ab8c7c043b684239026f02f343b9b49b7056b624a8388054604080518285028101850190915281815260609390929190830182828015613cc957602002820191906000526020600020905b815481526020019060010190808311613cb5575b50505050509050600081511115613cf55780516001600160a01b03841660009081526020805260409020555b8115610ee857613d1a6000805160206151c3833981519152848463ffffffff613a6016565b6000805160206151c38339815191526001600160a01b0316836001600160a01b03167f24bce930431f78244a70aacbe370a3d06e5fd605a0bb737db20457a7f593e5d084604051613d6b9190614f44565b60405180910390a3505050565b600082820183811015611a155760405162461bcd60e51b8152600401610b6c90614e54565b6000818310613dac5781611a15565b5090919050565b6000612dd27318240bd9c07fa6156ce3f3f61921cc82b26191576001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e0557600080fd5b505afa158015613e19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613e3d91908101906148c8565b6040516370a0823160e01b8152610a1b906e111b0ec57e6499a1f4b1014d3f6d5960321b90600080516020615123833981519152906370a0823190613e9a907318240bd9c07fa6156ce3f3f61921cc82b261915790600401614d8b565b60206040518083038186803b158015613eb257600080fd5b505afa158015613ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613eea91908101906148c8565b9063ffffffff6132c616565b3390565b604051612c529085906323b872dd60e01b90613a8290879087908790602401614ddc565b336000908152600d60205260409020548015611d3957336000818152600d6020526040808220919091555163a9059cbb60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e4909163a9059cbb91613f7e91908590600401614dc1565b602060405180830381600087803b158015613f9857600080fd5b505af1158015613fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613fd0919081019061486e565b5090565b6001600160a01b038116613ffa5760405162461bcd60e51b8152600401610b6c90614e44565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b61405d611a5b565b601155601055600f556000614070612c5e565b90508061408f5760405162461bcd60e51b8152600401610b6c90614f34565b6007546140b8906117d783610a1b876a0c097ce7bc90715b34b9f160241b63ffffffff6132c616565b600755600b546140e4906117d783610a1b866a0c097ce7bc90715b34b9f160241b63ffffffff6132c616565b600b554260145560405133907fc88fd69bfa06d2cb1591f4ddd5ebede37737856a00d499e4f51e60984dc13d369061411f9086908690614f88565b60405180910390a2505050565b6000818361414d5760405162461bcd60e51b8152600401610b6c9190614e33565b506000838581611a1057fe5b6000818484111561417d5760405162461bcd60e51b8152600401610b6c9190614e33565b505050900390565b6001600160a01b038216600090815260008051602061514383398151915260205260409020546141bb908263ffffffff613d7816565b6001600160a01b0383166000908152600080516020615143833981519152602090815260408220929092556000805160206151238339815191529052600390526000805160206151a38339815191525461421b908263ffffffff613d7816565b600080516020615123833981519152600081905260036020526000805160206151a3833981519152919091556040516001600160a01b038416919082907fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd790614285908690614f44565b60405180910390a45050565b6142a3826001600160a01b0316614376565b6142bf5760405162461bcd60e51b8152600401610b6c90614f24565b60006060836001600160a01b0316836040516142db9190614d7f565b6000604051808303816000865af19150503d8060008114614318576040519150601f19603f3d011682016040523d82523d6000602084013e61431d565b606091505b50915091508161433f5760405162461bcd60e51b8152600401610b6c90614e74565b805115612c52578080602001905161435a919081019061486e565b612c525760405162461bcd60e51b8152600401610b6c90614f04565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613c3e575050151592915050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b82805482825590600052602060002090810192821561442a579160200282015b8281111561442a5781546001600160a01b0319166001600160a01b038435161782556020909201916001909101906143f7565b50613fd092611d399250905b80821115613fd05780546001600160a01b0319168155600101614436565b8035610c52816150fc565b60008083601f84011261447157600080fd5b50813567ffffffffffffffff81111561448957600080fd5b6020830191508360208202830111156144a157600080fd5b9250929050565b600082601f8301126144b957600080fd5b81356144cc6144c782615059565b615032565b915081818352602084019350602081019050838560208402820111156144f157600080fd5b60005b8381101561451d57816145078882614454565b84525060209283019291909101906001016144f4565b5050505092915050565b600082601f83011261453857600080fd5b81356145466144c782615059565b9150818183526020840193506020810190508385602084028201111561456b57600080fd5b60005b8381101561451d578161458188826145f4565b845250602092830192919091019060010161456e565b8035610c5281615110565b8051610c5281615110565b6000604082840312156145bf57600080fd5b6145c96040615032565b905060006145d784846145ff565b82525060206145e8848483016145ff565b60208301525092915050565b8035610c5281615119565b8051610c5281615119565b60006020828403121561461c57600080fd5b6000610c4e8484614454565b6000806040838503121561463b57600080fd5b60006146478585614454565b925050602061465885828601614454565b9150509250929050565b6000806040838503121561467557600080fd5b60006146818585614454565b9250506020614658858286016145f4565b600080602083850312156146a557600080fd5b823567ffffffffffffffff8111156146bc57600080fd5b6146c88582860161445f565b92509250509250929050565b600080600080600080606087890312156146ed57600080fd5b863567ffffffffffffffff81111561470457600080fd5b61471089828a0161445f565b9650965050602087013567ffffffffffffffff81111561472f57600080fd5b61473b89828a0161445f565b9450945050604087013567ffffffffffffffff81111561475a57600080fd5b61476689828a0161445f565b92509250509295509295509295565b6000806040838503121561478857600080fd5b823567ffffffffffffffff81111561479f57600080fd5b6147ab858286016144a8565b925050602083013567ffffffffffffffff8111156147c857600080fd5b61465885828601614527565b6000806000606084860312156147e957600080fd5b833567ffffffffffffffff81111561480057600080fd5b61480c868287016144a8565b935050602084013567ffffffffffffffff81111561482957600080fd5b61483586828701614527565b925050604061484686828701614597565b9150509250925092565b60006020828403121561486257600080fd5b6000610c4e8484614597565b60006020828403121561488057600080fd5b6000610c4e84846145a2565b60006040828403121561489e57600080fd5b6000610c4e84846145ad565b6000602082840312156148bc57600080fd5b6000610c4e84846145f4565b6000602082840312156148da57600080fd5b6000610c4e84846145ff565b600080604083850312156148f957600080fd5b600061468185856145f4565b60008060006060848603121561491a57600080fd5b600061492686866145f4565b9350506020614937868287016145f4565b9250506040614846868287016145f4565b6000614954838361496b565b505060200190565b614965816150a9565b82525050565b6149658161508d565b600061497f82615080565b6149898185615084565b93506149948361507a565b8060005b838110156149c25781516149ac8882614948565b97506149b78361507a565b925050600101614998565b509495945050505050565b61496581615098565b60006149e182615080565b6149eb8185610ab0565b93506149fb8185602086016150c6565b9290920192915050565b614965816150b0565b614965816150bb565b6000614a2282615080565b614a2c8185615084565b9350614a3c8185602086016150c6565b614a45816150f2565b9093019392505050565b6000614a5c602683615084565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000614aa4601b83615084565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000614add600b83615084565b6a6e6f206465706f7369747360a81b815260200192915050565b6000614b04602083615084565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b6000614b3d600e83615084565b6d0c6deeadce840dad2e6dac2e8c6d60931b815260200192915050565b6000614b67600f83615084565b6e70726f706f73616c2065786973747360881b815260200192915050565b6000614b92600e83615084565b6d0ecc2d8eaca40e8dede40d0d2ced60931b815260200192915050565b6000614bbc602183615084565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000614bff600d83615084565b6c34b73b30b634b2103a37b5b2b760991b815260200192915050565b6000614c28600c83615084565b6b1d5b985d5d1a1bdc9a5e995960a21b815260200192915050565b6000614c50602083615084565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000614c89600d83615084565b6c696e76616c696420706172616d60981b815260200192915050565b6000614cb2602a83615084565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b6000614cfe600683615084565b651c185d5cd95960d21b815260200192915050565b6000614d20601f83615084565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b6000614d59600e83615084565b6d1b9bdd1a1a5b99c81cdd185ad95960921b815260200192915050565b61496581611d39565b6000611a1582846149d6565b60208101610c52828461496b565b60608101614da7828661495c565b614db4602083018561496b565b613c3e6040830184614d76565b60408101614dcf828561495c565b611a156020830184614d76565b60608101614da7828661496b565b60408101614dcf828561496b565b60208082528101611a158184614974565b60208101610c5282846149cd565b60208101610c528284614a05565b60408101614dcf8285614a0e565b60208082528101611a158184614a17565b60208082528101610c5281614a4f565b60208082528101610c5281614a97565b60208082528101610c5281614ad0565b60208082528101610c5281614af7565b60208082528101610c5281614b30565b60208082528101610c5281614b5a565b60208082528101610c5281614b85565b60208082528101610c5281614baf565b60208082528101610c5281614bf2565b60208082528101610c5281614c1b565b60208082528101610c5281614c43565b60208082528101610c5281614c7c565b60208082528101610c5281614ca5565b60208082528101610c5281614cf1565b60208082528101610c5281614d13565b60208082528101610c5281614d4c565b60208101610c528284614d76565b60408101614f608285614d76565b611a15602083018461496b565b60408101614f7b8285614d76565b611a156020830184614a0e565b60408101614dcf8285614d76565b60608101614fa48286614d76565b614db46020830185614d76565b60808101614fbf8287614d76565b614fcc6020830186614d76565b614fd96040830185614d76565b6136a46060830184614d76565b60a08101614ff48288614d76565b6150016020830187614d76565b61500e6040830186614d76565b61501b6060830185614d76565b6150286080830184614d76565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561505157600080fd5b604052919050565b600067ffffffffffffffff82111561507057600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000610c528261509d565b151590565b6001600160a01b031690565b6000610c52825b6000610c528261508d565b6000610c5282611d39565b60005b838110156150e15781810151838201526020016150c9565b83811115612c525750506000910152565b601f01601f191690565b6151058161508d565b8114612e0457600080fd5b61510581615098565b61510581611d3956fe00000000000000000000000056d811088235f11c8920698a204a5010a788f4b31e38d77566003d7f728cfa677ad07e8283e5607bd89a929ee98c93eba1204873000000000000000000000000a30911e072a0c88d55b5d0a0984b66b0d04569d02ce56405c0c0b7d532a6d76ebaf14a8d190d60f3be61dae6890d68141a9cc6f826822d1429e81ba812c5218f96710c8923c00dbf3bebc27a2dcc3894116216710000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2a365627a7a72315820150eb5351e649782ad6b672327c0a6a52b450ffefab6188e5b408367acfdfc846c6578706572696d656e74616cf564736f6c63430005110040
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104ab5760003560e01c80637f3fd8ba1161026d578063b6d6d88d11610151578063d85349f7116100ce578063e9fad8ee11610092578063e9fad8ee14610962578063eb0e8d1a1461096a578063ef1c243a14610972578063f2fde38b1461097a578063f30127a51461098d578063fc41aa0914610995576104ab565b8063d85349f71461092f578063dae607db14610937578063db8bb3a11461093f578063e0bab4c414610952578063e53b958d1461095a576104ab565b8063c54e44eb11610115578063c54e44eb146108e4578063cf86add5146108ec578063cff361e5146108ff578063d030205114610912578063d3d204311461091a576104ab565b8063b6d6d88d14610885578063bcca1e0414610898578063c1159297146108ab578063c1c5dd27146108be578063c42cf535146108d1576104ab565b80638da5cb5b116101ea578063ab560e10116101ae578063ab560e1014610834578063abbd3ab11461083c578063ad5c46481461084f578063b02eba0514610857578063b187bd261461086a578063b293fdc514610872576104ab565b80638da5cb5b146107de5780638f32d59b146107e65780638fc9c962146107fb5780639674a9311461080e578063a5795eba14610821576104ab565b806386be87a61161023157806386be87a61461079557806387359ebe146107a857806389a30271146107bb57806389ffc781146107c35780638caaf9e6146107cb576104ab565b80637f3fd8ba14610748578063802971a61461075b57806382a8af151461076357806383e02cd814610776578063863f2e181461078d576104ab565b80633d0b00241161039457806357d159c611610311578063633e9470116102d5578063633e94701461070257806364e39b871461070a57806366067a951461071d57806369636ff614610725578063715018a614610738578063735de9f714610740576104ab565b806357d159c6146106b957806359d99805146106cc57806359dcf522146106d45780635c19a95c146106e75780635c60da1b146106fa576104ab565b8063499d7f9611610358578063499d7f961461067b5780635224eaf41461068e57806352fb1c9d146106a157806353a8f1ec146106a9578063547d0738146106b1576104ab565b80633d0b0024146106325780633e1755c71461063a57806341adca421461064d5780634330c263146106605780634811538514610673576104ab565b806319e772c21161042d5780632a5522af116103f15780632a5522af146105b75780632d06e5bf146105ca5780632d81a78e146105d25780632ee1a86e146105f3578063307e85a4146106175780633bb20ece1461062a576104ab565b806319e772c2146105775780631c9c44081461057f5780631ca97a2d146105875780631d3e39551461059a5780632194f3a2146105af576104ab565b80630a4d2924116104745780630a4d29241461052c5780630c340a241461053f5780630da47e0a146105475780631514617e1461055a57806317a1d01214610562576104ab565b80628cc262146104b05780630114a05e146104dc578063011cee36146104fc57806302baf1b01461051157806302dd19d914610524575b600080fd5b6104c36104be36600461460a565b6109a8565b6040516104d39493929190614fb1565b60405180910390f35b6104ef6104ea36600461460a565b610a72565b6040516104d39190614f44565b610504610a84565b6040516104d39190614d8b565b6104ef61051f36600461460a565b610a96565b6104ef610ab5565b6104ef61053a366004614662565b610abb565b610504610ae9565b6104ef61055536600461460a565b610af8565b6104ef610b0a565b61056a610b12565b6040516104d39190614e17565b6104ef610b2a565b6104ef610b30565b6104ef61059536600461460a565b610b36565b6105ad6105a83660046148aa565b610b48565b005b610504610b97565b6104ef6105c5366004614662565b610ba6565b6104ef610c58565b6105e56105e0366004614850565b610c67565b6040516104d3929190614f88565b61060661060136600461460a565b610d4e565b6040516104d3959493929190614fe6565b6105ad6106253660046148aa565b610df2565b6104ef610e38565b610504610e3e565b6105ad610648366004614662565b610e56565b6104ef61065b36600461460a565b610eee565b6104ef61066e36600461460a565b610f00565b6104ef610f12565b6104ef61068936600461460a565b611039565b6105ad61069c3660046147d4565b61104b565b6104ef61166a565b6104ef611670565b610504611676565b6105ad6106c7366004614850565b61168e565b6104ef6116d0565b6105e56106e236600461460a565b6116d6565b6105046106f536600461460a565b611853565b61050461186e565b61056a61187d565b6105ad61071836600461460a565b611895565b6104ef6118db565b6104ef61073336600461460a565b6118e1565b6105ad6118f2565b61056a611960565b6104ef610756366004614905565b611978565b610504611a1c565b6105046107713660046148aa565b611a34565b61077e611a5b565b6040516104d393929190614f96565b6105ad611b54565b6104ef6107a3366004614628565b611c6f565b6104ef6107b6366004614628565b611c8b565b610504611cb6565b61056a611cce565b6105ad6107d93660046148aa565b611ce6565b610504611d2c565b6107ee611d3c565b6040516104d39190614e09565b6105ad6108093660046147d4565b611d60565b6104ef61081c36600461460a565b6122de565b6105e561082f3660046146d4565b6122f0565b6105046125df565b6104ef61084a36600461460a565b6125f1565b610504612604565b6104ef61086536600461460a565b61261c565b6107ee61262e565b6105ad610880366004614692565b61263e565b6104ef610893366004614628565b61266e565b6105ad6108a6366004614775565b61268b565b6104ef6108b9366004614662565b612697565b6105ad6108cc3660046148aa565b6126e0565b6105ad6108df36600461460a565b612732565b610504612778565b6105ad6108fa366004614775565b612790565b6104ef61090d36600461460a565b61279c565b6104ef6128af565b6109226128b5565b6040516104d39190614df8565b6104ef612917565b6104ef61291e565b61050461094d366004614662565b61292a565b61050461295f565b6104ef612977565b6105ad612a89565b6104ef612c58565b6104ef612c5e565b6105ad61098836600461460a565b612dd7565b610504612e07565b6105ad6109a33660046148e6565b612e19565b6000806000806109bd85600754600b54612f2f565b929650909450925090506109d485858585856131c1565b909450925060006109f46a0c097ce7bc90715b34b9f160241b8242611978565b9050610a34610a276a0c097ce7bc90715b34b9f160241b610a1b868563ffffffff6132c616565b9063ffffffff61330016565b849063ffffffff61334216565b9250610a68610a5b6a0c097ce7bc90715b34b9f160241b610a1b858563ffffffff6132c616565b839063ffffffff61334216565b9150509193509193565b60086020526000908152604090205481565b60008051602061516383398151915281565b6001600160a01b0381166000908152600360205260409020545b919050565b601b5481565b601f6020528160005260406000208181548110610ad457fe5b90600052602060002001600091509150505481565b601d546001600160a01b031681565b600d6020526000908152604090205481565b630784ce0081565b73bebc44782c7db0a1a60cb6fe97d0b483032ff1c781565b600f5481565b60105481565b60096020526000908152604090205481565b610b50611d3c565b610b755760405162461bcd60e51b8152600401610b6c90614ee4565b60405180910390fd5b80610b925760405162461bcd60e51b8152600401610b6c90614ef4565b601a55565b6002546001600160a01b031681565b601d546000906001600160a01b03163314610bd35760405162461bcd60e51b8152600401610b6c90614ed4565b6000828152601e602052604090205415610bff5760405162461bcd60e51b8152600401610b6c90614e94565b610c076143af565b610c0f613384565b6000848152601e60209081526040918290208351815590830151600182015590820151600282015560608201516003909101559050610c4e84826134ca565b9150505b92915050565b6a744f570177f475546c000081565b6001546000908190600160a01b900460ff1615610c965760405162461bcd60e51b8152600401610b6c90614f14565b600754600b543391906000808080610caf878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050610d0287858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055610d3e8a6136ad565b9850985050505050505050915091565b6000806000806000610d6e60008051602061512383398151915287611c8b565b610d8c7318240bd9c07fa6156ce3f3f61921cc82b261915788611c8b565b610daa73b72b31907c1c95f3650b64b2469e08edacee5e8f89611c8b565b610dc26000805160206151638339815191528a611c8b565b610de073e26a220a341eaca116bda64cf9d5638a935ae6298b611c8b565b939a9299509097509550909350915050565b610dfa611d3c565b610e165760405162461bcd60e51b8152600401610b6c90614ee4565b80610e335760405162461bcd60e51b8152600401610b6c90614ef4565b601b55565b600b5481565b73e26a220a341eaca116bda64cf9d5638a935ae62981565b8015610eea57610e66828261370d565b6040516323b872dd60e01b81526001600160a01b038316906323b872dd90610e9690339030908690600401614d99565b602060405180830381600087803b158015610eb057600080fd5b505af1158015610ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ee8919081019061486e565b505b5050565b600e6020526000908152604090205481565b600a6020526000908152604090205481565b600154600090600160a01b900460ff1615610f3f5760405162461bcd60e51b8152600401610b6c90614f14565b600754600b543391906000808080610f58878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050610fab87858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d835281842094909455939092556015909152908120429055610fe9906138a9565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf7896000604051611027929190614f6d565b60405180910390a25050505050505090565b60176020526000908152604090205481565b600154600160a01b900460ff16156110755760405162461bcd60e51b8152600401610b6c90614f14565b600754600b54339190600080808061108e878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e9091529020819055929650909450925090506110e187858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d8352818420949094559390925560159091522042905588518a51146111355760405162461bcd60e51b8152600401610b6c90614e84565b6000806000808b61114757600061115f565b61115f60008051602061516383398151915233611c8b565b905060005b8e5181101561162f578e818151811061117957fe5b602002602001015194506000805160206151238339815191526001600160a01b0316856001600160a01b031614806111cd57506001600160a01b03851673b72b31907c1c95f3650b64b2469e08edacee5e8f145b806111f457506001600160a01b0385167318240bd9c07fa6156ce3f3f61921cc82b2619157145b8061121557506001600160a01b038516600080516020615163833981519152145b8061123c57506001600160a01b03851673e26a220a341eaca116bda64cf9d5638a935ae629145b6112585760405162461bcd60e51b8152600401610b6c90614ec4565b8d818151811061126457fe5b6020908102919091018101516001600160a01b0387166000908152600483526040808220338352909352919091205490945092508315806112a3575082155b156112ad57611627565b828411156112b9578293505b6001600160a01b038516600081815260046020908152604080832033845282528083208888039055838352600390915290208054869003905560008051602061512383398151915214801561138e57506040516370a0823160e01b81528490600080516020615123833981519152906370a082319061133c903090600401614d8b565b60206040518083038186803b15801561135457600080fd5b505afa158015611368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061138c91908101906148c8565b105b156113fb5773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156113e257600080fd5b505af11580156113f6573d6000803e3d6000fd5b505050505b6001600160a01b03851660008051602061516383398151915214156115b7576040516370a0823160e01b81526000906000805160206151c3833981519152906370a082319061144e903090600401614d8b565b60206040518083038186803b15801561146657600080fd5b505afa15801561147a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061149e91908101906148c8565b604051630441a3e760e41b815290915073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063441a3e70906114db9060bc908990600401614f88565b600060405180830381600087803b1580156114f557600080fd5b505af1158015611509573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092508391506000805160206151c3833981519152906370a0823190611543903090600401614d8b565b60206040518083038186803b15801561155b57600080fd5b505afa15801561156f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061159391908101906148c8565b03905080156115b4576115b46000805160206151c38339815191528261370d565b50505b6115d16001600160a01b038616338663ffffffff613a6016565b336001600160a01b0316856001600160a01b0316336001600160a01b03167f2cbcd809a4c90d11f8d12c4b6d09986b255ae1e68f54f076c145fbb2185904e18760405161161e9190614f44565b60405180910390a45b600101611164565b508b1561165a5761165a336116556000805160206151c383398151915233856000613ab9565b613c46565b5050505050505050505050505050565b60115481565b601a5481565b73b72b31907c1c95f3650b64b2469e08edacee5e8f81565b611696611d3c565b6116b25760405162461bcd60e51b8152600401610b6c90614ee4565b60018054911515600160a01b0260ff60a01b19909216919091179055565b60195481565b6001600160a01b038116600090815260008051602061518383398151915260205260408120548190801561174d57600f546001600160a01b0385166000908152600080516020615183833981519152602052604090205461174a91670de0b6b3a764000091610a1b9163ffffffff6132c616565b91505b506001600160a01b038316600090815260008051602061514383398151915260209081526040808320547fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c79092529091205490925080156117e6576117e3836117d76e111b0ec57e6499a1f4b1014d3f6d5960321b610a1b601054866132c690919063ffffffff16565b9063ffffffff613d7816565b92505b506001600160a01b03831660009081527f064d7c8613d225af78bbf2a77ee533cb03ae723d97d3a14f96452520f45833f26020526040902054801561184d5761184a836117d7670de0b6b3a7640000610a1b601154866132c690919063ffffffff16565b92505b50915091565b6005602052600090815260409020546001600160a01b031681565b6001546001600160a01b031681565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b61189d611d3c565b6118b95760405162461bcd60e51b8152600401610b6c90614ee4565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60145481565b602080526000908152604090205481565b6118fa611d3c565b6119165760405162461bcd60e51b8152600401610b6c90614ee4565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f81565b600061198a824263ffffffff613d9d16565b915082821115611a1557635ffd02a0821115806119ab575063669136e08310155b156119b857506000611a15565b635ffd02a08310156119cc57635ffd02a092505b63669136e08211156119e05763669136e091505b60006119f2838563ffffffff61334216565b90506306943440611a09868363ffffffff6132c616565b81611a1057fe5b049150505b9392505050565b7318240bd9c07fa6156ce3f3f61921cc82b261915781565b601c8181548110611a4157fe5b6000918252602090912001546001600160a01b0316905081565b600080600080611a796b02dfafa4e0948fa071940000600042611978565b9050611aab6b02dfafa4e0948fa071940000610a1b836b02dfafa4e0948fa07194000003670de0b6b3a76400006132c6565b9350611ab5613db3565b60008051602061516383398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b6549093508015611b4d5760008051602061512383398151915260005260036020526000805160206151a38339815191525482036a744f570177f475546c000001611b4982610a1b83670de0b6b3a764000063ffffffff6132c616565b9350505b5050909192565b611b5c611d3c565b611b785760405162461bcd60e51b8152600401610b6c90614ee4565b6040516393f1a40b60e01b815273c2edad668740f1aa35e4d8f227fb8e17dca888cd9060009082906393f1a40b90611bb79060bc903090600401614f52565b604080518083038186803b158015611bce57600080fd5b505afa158015611be2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c06919081019061488c565b51604051630441a3e760e41b81529091506001600160a01b0383169063441a3e7090611c399060bc908590600401614f88565b600060405180830381600087803b158015611c5357600080fd5b505af1158015611c67573d6000803e3d6000fd5b505050505050565b600080611c7c8484611c8b565b9050610c4e8484836000613ab9565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b736c3f90f043a72fa612cbac8115ee7e52bde6e49081565b611cee611d3c565b611d0a5760405162461bcd60e51b8152600401610b6c90614ee4565b80611d275760405162461bcd60e51b8152600401610b6c90614ef4565b601955565b6000546001600160a01b03165b90565b600080546001600160a01b0316611d51613ef6565b6001600160a01b031614905090565b600154600160a01b900460ff1615611d8a5760405162461bcd60e51b8152600401610b6c90614f14565b600754600b543391906000808080611da3878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050611df687858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d8352818420949094559390925560159091522042905588518a5114611e4a5760405162461bcd60e51b8152600401610b6c90614e84565b60008060008a611e5b576000611e73565b611e7360008051602061516383398151915233611c8b565b905060005b8d518110156122a9578d8181518110611e8d57fe5b602002602001015193506000805160206151238339815191526001600160a01b0316846001600160a01b03161480611ee157506001600160a01b03841673b72b31907c1c95f3650b64b2469e08edacee5e8f145b80611f0857506001600160a01b0384167318240bd9c07fa6156ce3f3f61921cc82b2619157145b80611f2957506001600160a01b038416600080516020615163833981519152145b611f455760405162461bcd60e51b8152600401610b6c90614ec4565b8c8181518110611f5157fe5b602002602001015192508260001415611f69576122a1565b6001600160a01b0384166000908152600460209081526040808320338452909152902054611f9d908463ffffffff613d7816565b6001600160a01b038516600081815260046020908152604080832033845282528083209490945591815260039091522054611fde908463ffffffff613d7816565b6001600160a01b03851660008181526003602052604090209190915561200c9033308663ffffffff613efa16565b6001600160a01b038416600080516020615163833981519152141561224b576040516370a0823160e01b81526000906000805160206151c3833981519152906370a082319061205f903090600401614d8b565b60206040518083038186803b15801561207757600080fd5b505afa15801561208b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120af91908101906148c8565b6040516370a0823160e01b815290915073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063e2bbb1589060bc90600080516020615163833981519152906370a0823190612102903090600401614d8b565b60206040518083038186803b15801561211a57600080fd5b505afa15801561212e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061215291908101906148c8565b6040518363ffffffff1660e01b815260040161216f929190614f88565b600060405180830381600087803b15801561218957600080fd5b505af115801561219d573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092508391506000805160206151c3833981519152906370a08231906121d7903090600401614d8b565b60206040518083038186803b1580156121ef57600080fd5b505afa158015612203573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061222791908101906148c8565b0390508015612248576122486000805160206151c38339815191528261370d565b50505b336001600160a01b0316846001600160a01b0316336001600160a01b03167fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd7866040516122989190614f44565b60405180910390a45b600101611e78565b508a156122cf576122cf336116556000805160206151c383398151915233856000613ab9565b50505050505050505050505050565b60156020526000908152604090205481565b6001546000908190600160a01b900460ff161561231f5760405162461bcd60e51b8152600401610b6c90614f14565b868514801561232d57508683145b6123495760405162461bcd60e51b8152600401610b6c90614e84565b60005b878110156124af576123b587878381811061236357fe5b90506020020135600960008c8c8681811061237a57fe5b905060200201602061238f919081019061460a565b6001600160a01b031681526020810191909152604001600020549063ffffffff613d7816565b600960008b8b858181106123c557fe5b90506020020160206123da919081019061460a565b6001600160a01b0316815260208101919091526040016000205561241987878381811061240357fe5b9050602002013584613d7890919063ffffffff16565b925061244185858381811061242a57fe5b90506020020135600d60008c8c8681811061237a57fe5b600d60008b8b8581811061245157fe5b9050602002016020612466919081019061460a565b6001600160a01b031681526020810191909152604001600020556124a585858381811061248f57fe5b9050602002013583613d7890919063ffffffff16565b915060010161234c565b50811561253f576040516323b872dd60e01b8152600080516020615123833981519152906323b872dd906124eb90339030908790600401614d99565b602060405180830381600087803b15801561250557600080fd5b505af1158015612519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061253d919081019061486e565b505b80156125d4576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd9061258090339030908690600401614d99565b602060405180830381600087803b15801561259a57600080fd5b505af11580156125ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125d2919081019061486e565b505b965096945050505050565b6000805160206151c383398151915281565b6000610c52826125ff613384565b6134ca565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600c6020526000908152604090205481565b600154600160a01b900460ff1681565b612646611d3c565b6126625760405162461bcd60e51b8152600401610b6c90614ee4565b610ee8601c83836143d7565b600660209081526000928352604080842090915290825290205481565b610eea8282600061104b565b6000818152601e60209081526040808320815160808101835281548152600182015493810193909352600281015491830191909152600301546060820152611a159084906134ca565b6126e8611d3c565b6127045760405162461bcd60e51b8152600401610b6c90614ee4565b68056bc75e2d6310000081111561272d5760405162461bcd60e51b8152600401610b6c90614ea4565b601855565b61273a611d3c565b6127565760405162461bcd60e51b8152600401610b6c90614ee4565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b73dac17f958d2ee523a2206206994597c13d831ec781565b610eea82826000611d60565b60405163065509bb60e21b8152600090819073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063195426ec906127db9060bc903090600401614f52565b60206040518083038186803b1580156127f357600080fd5b505afa158015612807573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061282b91908101906148c8565b9050611a156000805160206151c38339815191528461285860008051602061516383398151915287611c8b565b60008051602061516383398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b6546128aa90610a1b8764e8d4a5100063ffffffff6132c616565b613ab9565b60185481565b6060601c80548060200260200160405190810160405280929190818152602001828054801561290d57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116128ef575b5050505050905090565b62f099c081565b670de0b6b3a764000081565b6016602052816000526040600020818154811061294357fe5b6000918252602090912001546001600160a01b03169150829050565b736b175474e89094c44da98b954eedeac495271d0f81565b600154600090600160a01b900460ff16156129a45760405162461bcd60e51b8152600401610b6c90614f14565b600754600b5433919060008080806129bd878787612f2f565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050612a1087858585856131c1565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055612a4b613f1e565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf760008a604051611027929190614e25565b60408051600480825260a0820190925260609160208201608080388339505060408051600480825260a082019092529293506060929150602082016080803883390190505090507318240bd9c07fa6156ce3f3f61921cc82b261915782600081518110612af257fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060008051602061516383398151915282600181518110612b2e57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073b72b31907c1c95f3650b64b2469e08edacee5e8f82600281518110612b7057fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060008051602061512383398151915282600381518110612bac57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060001981600081518110612bdc57fe5b60200260200101818152505060001981600181518110612bf857fe5b60200260200101818152505060001981600281518110612c1457fe5b60200260200101818152505060001981600381518110612c3057fe5b602002602001018181525050612c488282600161104b565b612c5260006136ad565b50505050565b60075481565b600f5473b72b31907c1c95f3650b64b2469e08edacee5e8f600090815260036020527ffcfc5d57a009157202436965eb7c01b14f1b51f705a3b4f08296120160c5e109549091612cc291670de0b6b3a764000091610a1b919063ffffffff6132c616565b60008051602061512383398151915260005260036020526000805160206151a383398151915254909150612cfc908263ffffffff613d7816565b6010547318240bd9c07fa6156ce3f3f61921cc82b261915760005260036020527f91de0462b01273d0819ee89d2f822b745d4b4dcc3d05d8e0d13f841abd34e4a254919250612d6f9183916117d7916e111b0ec57e6499a1f4b1014d3f6d5960321b91610a1b919063ffffffff6132c616565b60115460008051602061516383398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b654919250612dd29183916117d791670de0b6b3a764000091610a1b919063ffffffff6132c616565b905090565b612ddf611d3c565b612dfb5760405162461bcd60e51b8152600401610b6c90614ee4565b612e0481613fd4565b50565b60008051602061512383398151915281565b600154600160a01b900460ff1615612e435760405162461bcd60e51b8152600401610b6c90614f14565b81151580612e5057508015155b15610eea57612e5f8282614055565b8115612eee576040516323b872dd60e01b8152600080516020615123833981519152906323b872dd90612e9a90339030908790600401614d99565b602060405180830381600087803b158015612eb457600080fd5b505af1158015612ec8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612eec919081019061486e565b505b8015610eea576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90610e9690339030908690600401614d99565b6001600160a01b0383166000908152600860205260408120548190819081908190612f6190889063ffffffff61334216565b6001600160a01b0389166000908152600c602052604081205491925090612f8f90889063ffffffff61334216565b6001600160a01b038a16600090815260096020908152604080832054600d835281842054600a845282852054600e9094529190932054929950975095509350905081151580612fdd57508015155b156131b6576000806000806000612ff38e6116d6565b9092509050613008828863ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b90049450613025858c613d78565b9a50613037828763ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b90049450613054858b613d78565b9950801580159061306457508615155b1561310157613079818863ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b900494506130968986613d78565b6001600160a01b038f16600090815260156020526040812054919a509093506130cf906a0c097ce7bc90715b34b9f160241b9085611978565b93506130e1858563ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b900494506130fe8b86613d78565b9a505b801580159061310f57508515155b156131b057613124818763ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b900494506131418886613d78565b975082613180576001600160a01b038e16600090815260156020526040812054935061317d906a0c097ce7bc90715b34b9f160241b9085611978565b93505b613190858563ffffffff6132c616565b6a0c097ce7bc90715b34b9f160241b900494506131ad8a86613d78565b99505b50505050505b505093509350935093565b6001600160a01b03851660009081526015602052604081205481904281146132b8576000806131ff6a0c097ce7bc90715b34b9f160241b8442611978565b90508615613230576132296a0c097ce7bc90715b34b9f160241b610a1b898463ffffffff6132c616565b9889019891505b851561325f576132586a0c097ce7bc90715b34b9f160241b610a1b888463ffffffff6132c616565b9788019791505b6001600160a01b038a166000908152600080516020615183833981519152602052604090205480156132b4576132ad6a0c097ce7bc90715b34b9f160241b610a1b838563ffffffff6132c616565b998a019992505b5050505b509496939550929350505050565b6000826132d557506000610c52565b828202828482816132e257fe5b0414611a155760405162461bcd60e51b8152600401610b6c90614eb4565b6000611a1583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061412c565b6000611a1583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614159565b61338c6143af565b60405180608001604052806001420381526020016133a8613db3565b81526040516370a0823160e01b8152602090910190600080516020615123833981519152906370a08231906133ef9060008051602061516383398151915290600401614d8b565b60206040518083038186803b15801561340757600080fd5b505afa15801561341b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061343f91908101906148c8565b81526020016000805160206151638339815191526001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561348b57600080fd5b505afa15801561349f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506134c391908101906148c8565b9052905090565b6001600160a01b038216600090815260156020526040812054825115806134f5575082516000190181115b15613504576000915050610c52565b6001600160a01b0384166000908152600080516020615183833981519152602052604090205480156135925761357a6b02dfafa4e0948fa071940000610a1b61355f6b02dfafa4e0948fa07194000060008960000151611978565b84906b02dfafa4e0948fa0719400000363ffffffff6132c616565b925061358f836117d783858860000151611978565b92505b6001600160a01b038516600090815260096020908152604080832054600080516020615143833981519152909252909120546135d39185916117d791613d78565b6020808601516001600160a01b03881660009081527fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c79092526040909120549194506136439185916117d7916e111b0ec57e6499a1f4b1014d3f6d5960321b91610a1b919063ffffffff6132c616565b60608501516001600160a01b03871660009081527f064d7c8613d225af78bbf2a77ee533cb03ae723d97d3a14f96452520f45833f260205260409081902054908701519295506136a49286926117d7929091610a1b9163ffffffff6132c616565b95945050505050565b6000806136b9836138a9565b91506136c3613f1e565b9050336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf78383604051613700929190614f88565b60405180910390a2915091565b60006001600160a01b0383166000805160206151c3833981519152146137335782613743565b6000805160206151638339815191525b6001600160a01b0381166000908152600360205260409020549091508061377c5760405162461bcd60e51b8152600401610b6c90614e64565b6001600160a01b0384166000908152601f6020908152604080832080548251818502810185019093528083526060938301828280156137da57602002820191906000526020600020905b8154815260200190600101908083116137c6575b5050505050905060008151111561380657806001825103815181106137fb57fe5b602002602001015191505b600061382184610a1b8864e8d4a5100063ffffffff6132c616565b90506000613835828563ffffffff613d7816565b6001600160a01b0389166000818152601f6020908152604080832080546001810182559084529190922001839055519192509033907f0ec162440d54eb15069478f467bd7294f3d5cead39c9724ff287893483d7c60c90613897908b90614f44565b60405180910390a35050505050505050565b336000908152600960205260409020548015610ab0573360009081526009602052604081205581156138e4576138df3382614185565b610ab0565b6040516370a0823160e01b81528190600080516020615123833981519152906370a0823190613917903090600401614d8b565b60206040518083038186803b15801561392f57600080fd5b505afa158015613943573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061396791908101906148c8565b10156139d55773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156139bc57600080fd5b505af11580156139d0573d6000803e3d6000fd5b505050505b60405163a9059cbb60e01b81526000805160206151238339815191529063a9059cbb90613a089033908590600401614dc1565b602060405180830381600087803b158015613a2257600080fd5b505af1158015613a36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613a5a919081019061486e565b50919050565b604051610ee890849063a9059cbb60e01b90613a829086908690602401614dea565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614291565b6001600160a01b0384166000908152601f602090815260408083208054825181850281018501909352808352606093830182828015613b1757602002820191906000526020600020905b815481526020019060010190808311613b03575b5050835193945050508115159050613b3457600092505050613c3e565b84613b4457600092505050613c3e565b6001600160a01b03861660009081526020805260408120548351909190613b8d90879086906000198701908110613b7757fe5b6020026020010151613d7890919063ffffffff16565b905081613bb857613bad64e8d4a51000610a1b898463ffffffff6132c616565b945050505050613c3e565b600019928301929091019082821415613bd8576000945050505050613c3e565b6000848381518110613be657fe5b602002602001015190506000613c05838a6132c690919063ffffffff16565b90506000613c198a8463ffffffff6132c616565b9050613c3464e8d4a51000610a1b848463ffffffff61334216565b9750505050505050505b949350505050565b6000805160206151c3833981519152600052601f60209081527ff671d343b5ca683fae72ab8c7c043b684239026f02f343b9b49b7056b624a8388054604080518285028101850190915281815260609390929190830182828015613cc957602002820191906000526020600020905b815481526020019060010190808311613cb5575b50505050509050600081511115613cf55780516001600160a01b03841660009081526020805260409020555b8115610ee857613d1a6000805160206151c3833981519152848463ffffffff613a6016565b6000805160206151c38339815191526001600160a01b0316836001600160a01b03167f24bce930431f78244a70aacbe370a3d06e5fd605a0bb737db20457a7f593e5d084604051613d6b9190614f44565b60405180910390a3505050565b600082820183811015611a155760405162461bcd60e51b8152600401610b6c90614e54565b6000818310613dac5781611a15565b5090919050565b6000612dd27318240bd9c07fa6156ce3f3f61921cc82b26191576001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e0557600080fd5b505afa158015613e19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613e3d91908101906148c8565b6040516370a0823160e01b8152610a1b906e111b0ec57e6499a1f4b1014d3f6d5960321b90600080516020615123833981519152906370a0823190613e9a907318240bd9c07fa6156ce3f3f61921cc82b261915790600401614d8b565b60206040518083038186803b158015613eb257600080fd5b505afa158015613ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613eea91908101906148c8565b9063ffffffff6132c616565b3390565b604051612c529085906323b872dd60e01b90613a8290879087908790602401614ddc565b336000908152600d60205260409020548015611d3957336000818152600d6020526040808220919091555163a9059cbb60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e4909163a9059cbb91613f7e91908590600401614dc1565b602060405180830381600087803b158015613f9857600080fd5b505af1158015613fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613fd0919081019061486e565b5090565b6001600160a01b038116613ffa5760405162461bcd60e51b8152600401610b6c90614e44565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b61405d611a5b565b601155601055600f556000614070612c5e565b90508061408f5760405162461bcd60e51b8152600401610b6c90614f34565b6007546140b8906117d783610a1b876a0c097ce7bc90715b34b9f160241b63ffffffff6132c616565b600755600b546140e4906117d783610a1b866a0c097ce7bc90715b34b9f160241b63ffffffff6132c616565b600b554260145560405133907fc88fd69bfa06d2cb1591f4ddd5ebede37737856a00d499e4f51e60984dc13d369061411f9086908690614f88565b60405180910390a2505050565b6000818361414d5760405162461bcd60e51b8152600401610b6c9190614e33565b506000838581611a1057fe5b6000818484111561417d5760405162461bcd60e51b8152600401610b6c9190614e33565b505050900390565b6001600160a01b038216600090815260008051602061514383398151915260205260409020546141bb908263ffffffff613d7816565b6001600160a01b0383166000908152600080516020615143833981519152602090815260408220929092556000805160206151238339815191529052600390526000805160206151a38339815191525461421b908263ffffffff613d7816565b600080516020615123833981519152600081905260036020526000805160206151a3833981519152919091556040516001600160a01b038416919082907fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd790614285908690614f44565b60405180910390a45050565b6142a3826001600160a01b0316614376565b6142bf5760405162461bcd60e51b8152600401610b6c90614f24565b60006060836001600160a01b0316836040516142db9190614d7f565b6000604051808303816000865af19150503d8060008114614318576040519150601f19603f3d011682016040523d82523d6000602084013e61431d565b606091505b50915091508161433f5760405162461bcd60e51b8152600401610b6c90614e74565b805115612c52578080602001905161435a919081019061486e565b612c525760405162461bcd60e51b8152600401610b6c90614f04565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613c3e575050151592915050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b82805482825590600052602060002090810192821561442a579160200282015b8281111561442a5781546001600160a01b0319166001600160a01b038435161782556020909201916001909101906143f7565b50613fd092611d399250905b80821115613fd05780546001600160a01b0319168155600101614436565b8035610c52816150fc565b60008083601f84011261447157600080fd5b50813567ffffffffffffffff81111561448957600080fd5b6020830191508360208202830111156144a157600080fd5b9250929050565b600082601f8301126144b957600080fd5b81356144cc6144c782615059565b615032565b915081818352602084019350602081019050838560208402820111156144f157600080fd5b60005b8381101561451d57816145078882614454565b84525060209283019291909101906001016144f4565b5050505092915050565b600082601f83011261453857600080fd5b81356145466144c782615059565b9150818183526020840193506020810190508385602084028201111561456b57600080fd5b60005b8381101561451d578161458188826145f4565b845250602092830192919091019060010161456e565b8035610c5281615110565b8051610c5281615110565b6000604082840312156145bf57600080fd5b6145c96040615032565b905060006145d784846145ff565b82525060206145e8848483016145ff565b60208301525092915050565b8035610c5281615119565b8051610c5281615119565b60006020828403121561461c57600080fd5b6000610c4e8484614454565b6000806040838503121561463b57600080fd5b60006146478585614454565b925050602061465885828601614454565b9150509250929050565b6000806040838503121561467557600080fd5b60006146818585614454565b9250506020614658858286016145f4565b600080602083850312156146a557600080fd5b823567ffffffffffffffff8111156146bc57600080fd5b6146c88582860161445f565b92509250509250929050565b600080600080600080606087890312156146ed57600080fd5b863567ffffffffffffffff81111561470457600080fd5b61471089828a0161445f565b9650965050602087013567ffffffffffffffff81111561472f57600080fd5b61473b89828a0161445f565b9450945050604087013567ffffffffffffffff81111561475a57600080fd5b61476689828a0161445f565b92509250509295509295509295565b6000806040838503121561478857600080fd5b823567ffffffffffffffff81111561479f57600080fd5b6147ab858286016144a8565b925050602083013567ffffffffffffffff8111156147c857600080fd5b61465885828601614527565b6000806000606084860312156147e957600080fd5b833567ffffffffffffffff81111561480057600080fd5b61480c868287016144a8565b935050602084013567ffffffffffffffff81111561482957600080fd5b61483586828701614527565b925050604061484686828701614597565b9150509250925092565b60006020828403121561486257600080fd5b6000610c4e8484614597565b60006020828403121561488057600080fd5b6000610c4e84846145a2565b60006040828403121561489e57600080fd5b6000610c4e84846145ad565b6000602082840312156148bc57600080fd5b6000610c4e84846145f4565b6000602082840312156148da57600080fd5b6000610c4e84846145ff565b600080604083850312156148f957600080fd5b600061468185856145f4565b60008060006060848603121561491a57600080fd5b600061492686866145f4565b9350506020614937868287016145f4565b9250506040614846868287016145f4565b6000614954838361496b565b505060200190565b614965816150a9565b82525050565b6149658161508d565b600061497f82615080565b6149898185615084565b93506149948361507a565b8060005b838110156149c25781516149ac8882614948565b97506149b78361507a565b925050600101614998565b509495945050505050565b61496581615098565b60006149e182615080565b6149eb8185610ab0565b93506149fb8185602086016150c6565b9290920192915050565b614965816150b0565b614965816150bb565b6000614a2282615080565b614a2c8185615084565b9350614a3c8185602086016150c6565b614a45816150f2565b9093019392505050565b6000614a5c602683615084565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000614aa4601b83615084565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000614add600b83615084565b6a6e6f206465706f7369747360a81b815260200192915050565b6000614b04602083615084565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b6000614b3d600e83615084565b6d0c6deeadce840dad2e6dac2e8c6d60931b815260200192915050565b6000614b67600f83615084565b6e70726f706f73616c2065786973747360881b815260200192915050565b6000614b92600e83615084565b6d0ecc2d8eaca40e8dede40d0d2ced60931b815260200192915050565b6000614bbc602183615084565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000614bff600d83615084565b6c34b73b30b634b2103a37b5b2b760991b815260200192915050565b6000614c28600c83615084565b6b1d5b985d5d1a1bdc9a5e995960a21b815260200192915050565b6000614c50602083615084565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000614c89600d83615084565b6c696e76616c696420706172616d60981b815260200192915050565b6000614cb2602a83615084565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b6000614cfe600683615084565b651c185d5cd95960d21b815260200192915050565b6000614d20601f83615084565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b6000614d59600e83615084565b6d1b9bdd1a1a5b99c81cdd185ad95960921b815260200192915050565b61496581611d39565b6000611a1582846149d6565b60208101610c52828461496b565b60608101614da7828661495c565b614db4602083018561496b565b613c3e6040830184614d76565b60408101614dcf828561495c565b611a156020830184614d76565b60608101614da7828661496b565b60408101614dcf828561496b565b60208082528101611a158184614974565b60208101610c5282846149cd565b60208101610c528284614a05565b60408101614dcf8285614a0e565b60208082528101611a158184614a17565b60208082528101610c5281614a4f565b60208082528101610c5281614a97565b60208082528101610c5281614ad0565b60208082528101610c5281614af7565b60208082528101610c5281614b30565b60208082528101610c5281614b5a565b60208082528101610c5281614b85565b60208082528101610c5281614baf565b60208082528101610c5281614bf2565b60208082528101610c5281614c1b565b60208082528101610c5281614c43565b60208082528101610c5281614c7c565b60208082528101610c5281614ca5565b60208082528101610c5281614cf1565b60208082528101610c5281614d13565b60208082528101610c5281614d4c565b60208101610c528284614d76565b60408101614f608285614d76565b611a15602083018461496b565b60408101614f7b8285614d76565b611a156020830184614a0e565b60408101614dcf8285614d76565b60608101614fa48286614d76565b614db46020830185614d76565b60808101614fbf8287614d76565b614fcc6020830186614d76565b614fd96040830185614d76565b6136a46060830184614d76565b60a08101614ff48288614d76565b6150016020830187614d76565b61500e6040830186614d76565b61501b6060830185614d76565b6150286080830184614d76565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561505157600080fd5b604052919050565b600067ffffffffffffffff82111561507057600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000610c528261509d565b151590565b6001600160a01b031690565b6000610c52825b6000610c528261508d565b6000610c5282611d39565b60005b838110156150e15781810151838201526020016150c9565b83811115612c525750506000910152565b601f01601f191690565b6151058161508d565b8114612e0457600080fd5b61510581615098565b61510581611d3956fe00000000000000000000000056d811088235f11c8920698a204a5010a788f4b31e38d77566003d7f728cfa677ad07e8283e5607bd89a929ee98c93eba1204873000000000000000000000000a30911e072a0c88d55b5d0a0984b66b0d04569d02ce56405c0c0b7d532a6d76ebaf14a8d190d60f3be61dae6890d68141a9cc6f826822d1429e81ba812c5218f96710c8923c00dbf3bebc27a2dcc3894116216710000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2a365627a7a72315820150eb5351e649782ad6b672327c0a6a52b450ffefab6188e5b408367acfdfc846c6578706572696d656e74616cf564736f6c63430005110040
Deployed Bytecode Sourcemap
67432:31658:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67432:31658:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80123:1223;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;65639:58;;;;;;;;;:::i;:::-;;;;;;;;61332:76;;;:::i;:::-;;;;;;;;92513:170;;;;;;;;;:::i;66838:40::-;;;:::i;67185:53::-;;;;;;;;;:::i;67089:23::-;;;:::i;66095:52::-;;;;;;;;;:::i;62429:64::-;;;:::i;62151:96::-;;;:::i;:::-;;;;;;;;66301:32;;;:::i;66340:::-;;;:::i;65741:46::-;;;;;;;;;:::i;98600:242::-;;;;;;;;;:::i;:::-;;65127:26;;;:::i;94898:453::-;;;;;;;;;:::i;64952:79::-;;;:::i;75690:236::-;;;;;;;;;:::i;:::-;;;;;;;;;90977:579;;;;;;;;;:::i;:::-;;;;;;;;;;;;98850:237;;;;;;;;;:::i;65947:39::-;;;:::i;61428:79::-;;;:::i;88472:228::-;;;;;;;;;:::i;66197:52::-;;;;;;;;;:::i;65843:46::-;;;;;;;;;:::i;75934:307::-;;;:::i;66639:49::-;;;;;;;;;:::i;73310:2372::-;;;;;;;;;:::i;66379:34::-;;;:::i;66789:42::-;;;:::i;61170:74::-;;;:::i;97542:128::-;;;;;;;;;:::i;66738:44::-;;;:::i;91564:941::-;;;;;;;;;:::i;65381:43::-;;;;;;;;;:::i;64727:29::-;;;:::i;62254:75::-;;;:::i;97678:143::-;;;;;;;;;:::i;66485:33::-;;;:::i;67318:55::-;;;;;;;;;:::i;59757:140::-;;;:::i;62022:109::-;;;:::i;93263:1146::-;;;;;;;;;:::i;61251:74::-;;;:::i;66887:33::-;;;;;;;;;:::i;89528:998::-;;;:::i;:::-;;;;;;;;;;70636:336;;;:::i;68425:256::-;;;;;;;;;:::i;90760:209::-;;;;;;;;;:::i;61779:73::-;;;:::i;61526:85::-;;;:::i;98340:252::-;;;;;;;;;:::i;58946:79::-;;;:::i;59312:94::-;;;:::i;:::-;;;;;;;;71146:1986;;;;;;;;;:::i;66527:50::-;;;;;;;;;:::i;86093:1027::-;;;;;;;;;:::i;61939:74::-;;;:::i;94690:200::-;;;;;;;;;:::i;61620:73::-;;;:::i;65993:64::-;;;;;;;;;:::i;65098:20::-;;;:::i;97968:145::-;;;;;;;;;:::i;65486:72::-;;;;;;;;;:::i;73140:162::-;;;;;;;;;:::i;94449:233::-;;;;;;;;;:::i;98121:211::-;;;;;;;;;:::i;97829:131::-;;;;;;;;;:::i;61859:73::-;;;:::i;70980:158::-;;;;;;;;;:::i;67942:475::-;;;;;;;;;:::i;66695:36::-;;;:::i;67724:146::-;;;:::i;:::-;;;;;;;;62338:63;;;:::i;63158:47::-;;;:::i;66586:46::-;;;;;;;;;:::i;61700:72::-;;;:::i;76249:320::-;;;:::i;78508:537::-;;;:::i;65599:33::-;;;:::i;92691:564::-;;;:::i;60052:109::-;;;;;;;;;:::i;61090:73::-;;;:::i;87188:507::-;;;;;;;;;:::i;80123:1223::-;80216:25;80243:31;80276:26;80304:32;80447:112;80469:7;80491:18;;80524:24;;80447:7;:112::i;:::-;80354:205;;-1:-1:-1;80354:205:0;;-1:-1:-1;80354:205:0;-1:-1:-1;80354:205:0;-1:-1:-1;80619:187:0;80646:7;80354:205;;;;80619:12;:187::i;:::-;80572:234;;-1:-1:-1;80572:234:0;-1:-1:-1;80873:18:0;80894:98;-1:-1:-1;;;80873:18:0;80966:15;80894:22;:98::i;:::-;80873:119;-1:-1:-1;81024:132:0;81061:80;-1:-1:-1;;;81061:52:0;:18;80873:119;81061:52;:40;:52;:::i;:::-;:74;:80;:74;:80;:::i;:::-;81024:18;;:132;:36;:132;:::i;:::-;81003:153;-1:-1:-1;81194:144:0;81237:86;-1:-1:-1;;;81237:58:0;:24;81284:10;81237:58;:46;:58;:::i;:86::-;81194:24;;:144;:42;:144;:::i;:::-;81167:171;;80123:1223;;;;;;:::o;65639:58::-;;;;;;;;;;;;;:::o;61332:76::-;-1:-1:-1;;;;;;;;;;;61332:76:0;:::o;92513:170::-;-1:-1:-1;;;;;92648:27:0;;92616:7;92648:27;;;:20;:27;;;;;;92513:170;;;;:::o;66838:40::-;;;;:::o;67185:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;67089:23::-;;;-1:-1:-1;;;;;67089:23:0;;:::o;66095:52::-;;;;;;;;;;;;;:::o;62429:64::-;62484:9;62429:64;:::o;62151:96::-;62204:42;62151:96;:::o;66301:32::-;;;;:::o;66340:::-;;;;:::o;65741:46::-;;;;;;;;;;;;;:::o;98600:242::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;;;;;;;;;98735:26;98727:52;;;;-1:-1:-1;;;98727:52:0;;;;;;;;;98790:20;:44;98600:242::o;65127:26::-;;;-1:-1:-1;;;;;65127:26:0;;:::o;94898:453::-;95061:8;;95014:7;;-1:-1:-1;;;;;95061:8:0;95047:10;:22;95039:47;;;;-1:-1:-1;;;95039:47:0;;;;;;;;;95105:26;;;;:14;:26;;;;;:39;:44;95097:72;;;;-1:-1:-1;;;95097:72:0;;;;;;;;;95180:32;;:::i;:::-;95215:19;:17;:19::i;:::-;95245:26;;;;:14;:26;;;;;;;;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95180:54;-1:-1:-1;95305:38:0;95322:7;95180:54;95305:16;:38::i;:::-;95298:45;;;94898:453;;;;;:::o;64952:79::-;65003:28;64952:79;:::o;75690:236::-;67677:8;;75820:25;;;;-1:-1:-1;;;67677:8:0;;;;67676:9;67668:28;;;;-1:-1:-1;;;67668:28:0;;;;;;;;;79134:18;;79199:24;;75790:10;;79134:18;79104:27;;;;79361:114;75790:10;79134:18;79199:24;79361:7;:114::i;:::-;-1:-1:-1;;;;;79486:32:0;;;;;;:23;:32;;;;;;;;:54;;;79551:29;:38;;;;;:66;;;79682:11;:20;;;;;:41;;;79734:17;:26;;;;;:53;;;79236:239;;-1:-1:-1;79236:239:0;;-1:-1:-1;79236:239:0;-1:-1:-1;79236:239:0;-1:-1:-1;79853:187:0;79510:7;79236:239;;;;79853:12;:187::i;:::-;-1:-1:-1;;;;;79801:20:0;;;;;;:11;:20;;;;;;;;79823:17;:26;;;;;79800:240;;;;;;;;80051:15;:24;;;;80078:15;80051:42;;75903:15;75910:7;75903:6;:15::i;:::-;75896:22;;;;67707:1;;;;;;;75690:236;;;:::o;90977:579::-;91095:19;91129:20;91164;91199:22;91236:25;91311:31;-1:-1:-1;;;;;;;;;;;91334:7:0;91311:16;:31::i;:::-;91357:32;61283:42;91381:7;91357:16;:32::i;:::-;91404;61202:42;91428:7;91404:16;:32::i;:::-;91451:34;-1:-1:-1;;;;;;;;;;;91477:7:0;91451:16;:34::i;:::-;91500:37;61465:42;91529:7;91500:16;:37::i;:::-;91289:259;;;;-1:-1:-1;91289:259:0;;-1:-1:-1;91289:259:0;-1:-1:-1;91289:259:0;;-1:-1:-1;90977:579:0;-1:-1:-1;;90977:579:0:o;98850:237::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;98983:25;98975:51;;;;-1:-1:-1;;;98975:51:0;;;;;;;;;99037:19;:42;98850:237::o;65947:39::-;;;;:::o;61428:79::-;61465:42;61428:79;:::o;88472:228::-;88548:11;;88544:149;;88576:29;88591:5;88598:6;88576:14;:29::i;:::-;88620:61;;-1:-1:-1;;;88620:61:0;;-1:-1:-1;;;;;88620:26:0;;;;;:61;;88647:10;;88667:4;;88674:6;;88620:61;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;88620:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88620:61:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;88620:61:0;;;;;;;;;;88544:149;88472:228;;:::o;66197:52::-;;;;;;;;;;;;;:::o;65843:46::-;;;;;;;;;;;;;:::o;75934:307::-;67677:8;;76046:25;;-1:-1:-1;;;67677:8:0;;;;67676:9;67668:28;;;;-1:-1:-1;;;67668:28:0;;;;;;;;;79134:18;;79199:24;;76016:10;;79134:18;79104:27;;;;79361:114;76016:10;79134:18;79199:24;79361:7;:114::i;:::-;-1:-1:-1;;;;;79486:32:0;;;;;;:23;:32;;;;;;;;:54;;;79551:29;:38;;;;;:66;;;79682:11;:20;;;;;:41;;;79734:17;:26;;;;;:53;;;79236:239;;-1:-1:-1;79236:239:0;;-1:-1:-1;79236:239:0;-1:-1:-1;79236:239:0;-1:-1:-1;79853:187:0;79510:7;79236:239;;;;79853:12;:187::i;:::-;-1:-1:-1;;;;;79801:20:0;;;;;;:11;:20;;;;;;;;79823:17;:26;;;;;79800:240;;;;;;;;80051:15;:24;;;;;;80078:15;80051:42;;76109:17;;:10;:17::i;:::-;76089:37;;76164:10;-1:-1:-1;;;;;76144:89:0;;76189:17;76221:1;76144:89;;;;;;;;;;;;;;;;67707:1;;;;;;;75934:307;:::o;66639:49::-;;;;;;;;;;;;;:::o;73310:2372::-;67677:8;;-1:-1:-1;;;67677:8:0;;;;67676:9;67668:28;;;;-1:-1:-1;;;67668:28:0;;;;;;;;;79134:18;;79199:24;;73487:10;;79134:18;79104:27;;;;79361:114;73487:10;79134:18;79199:24;79361:7;:114::i;:::-;-1:-1:-1;;;;;79486:32:0;;;;;;:23;:32;;;;;;;;:54;;;79551:29;:38;;;;;:66;;;79682:11;:20;;;;;:41;;;79734:17;:26;;;;;:53;;;79236:239;;-1:-1:-1;79236:239:0;;-1:-1:-1;79236:239:0;-1:-1:-1;79236:239:0;-1:-1:-1;79853:187:0;79510:7;79236:239;;;;79853:12;:187::i;:::-;-1:-1:-1;;;;;79801:20:0;;;;;;:11;:20;;;;;;;;79823:17;:26;;;;;79800:240;;;;;;;;80051:15;:24;;;;80078:15;80051:42;;73540:13;;73523;;:30;73515:57;;;;-1:-1:-1;;;73515:57:0;;;;;;;;;73585:13;73609:21;73641:20;73672:21;73696:10;:54;;73749:1;73696:54;;;73709:37;-1:-1:-1;;;;;;;;;;;73735:10:0;73709:16;:37::i;:::-;73672:78;-1:-1:-1;73768:9:0;73763:1725;73787:6;:13;73783:1;:17;73763:1725;;;73830:6;73837:1;73830:9;;;;;;;;;;;;;;73822:17;;-1:-1:-1;;;;;;;;;;;;;;;;73862:13:0;:5;-1:-1:-1;;;;;73862:13:0;;:31;;;-1:-1:-1;;;;;;73879:14:0;;61202:42;73879:14;73862:31;:49;;;-1:-1:-1;;;;;;73897:14:0;;61283:42;73897:14;73862:49;:69;;;-1:-1:-1;;;;;;73915:16:0;;-1:-1:-1;;;;;;;;;;;73915:16:0;73862:69;:92;;;-1:-1:-1;;;;;;73935:19:0;;61465:42;73935:19;73862:92;73854:118;;;;-1:-1:-1;;;73854:118:0;;;;;;;;;74005:6;74012:1;74005:9;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;74044:24:0;;;;;;:17;:24;;;;;;74069:10;74044:36;;;;;;;;;;74005:9;;-1:-1:-1;74044:36:0;-1:-1:-1;74099:18:0;;;:39;;-1:-1:-1;74121:17:0;;74099:39;74095:88;;;74159:8;;74095:88;74217:12;74201:13;:28;74197:97;;;74266:12;74250:28;;74197:97;-1:-1:-1;;;;;74310:24:0;;;;;;:17;:24;;;;;;;;74335:10;74310:36;;;;;;;74349:28;;;74310:67;;74443:27;;;:20;:27;;;;;;;:43;;;74413:73;;-1:-1:-1;;;;;;;;;;;74528:13:0;:70;;;;-1:-1:-1;74545:37:0;;-1:-1:-1;;;74545:37:0;;74585:13;;-1:-1:-1;;;;;;;;;;;61121:42:0;74545:22;;:37;;74576:4;;74545:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74545:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74545:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;74545:37:0;;;;;;;;;:53;74528:70;74524:193;;;61202:42;-1:-1:-1;;;;;74673:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74673:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74673:28:0;;;;74524:193;-1:-1:-1;;;;;74782:16:0;;-1:-1:-1;;;;;;;;;;;74782:16:0;74778:452;;;74848:38;;-1:-1:-1;;;74848:38:0;;74819:26;;-1:-1:-1;;;;;;;;;;;61971:42:0;74848:23;;:38;;74880:4;;74848:38;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74848:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74848:38:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;74848:38:0;;;;;;;;;74905:89;;-1:-1:-1;;;74905:89:0;;74819:67;;-1:-1:-1;63038:42:0;;74905:43;;:89;;63146:3;;74980:13;;74905:89;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74905:89:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;75036:38:0;;-1:-1:-1;;;75036:38:0;;75013:20;;-1:-1:-1;75077:18:0;;-1:-1:-1;;;;;;;;;;;;61971:42:0;75036:23;;:38;;75068:4;;75036:38;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;75036:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75036:38:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;75036:38:0;;;;;;;;;:59;;-1:-1:-1;75118:17:0;;75114:101;;75160:35;-1:-1:-1;;;;;;;;;;;75182:12:0;75160:14;:35::i;:::-;74778:452;;;75246:53;-1:-1:-1;;;;;75246:26:0;;75273:10;75285:13;75246:53;:26;:53;:::i;:::-;75400:10;-1:-1:-1;;;;;75321:155:0;75376:5;-1:-1:-1;;;;;75321:155:0;75347:10;-1:-1:-1;;;;;75321:155:0;;75448:13;75321:155;;;;;;;;;;;;;;;73763:1725;73802:3;;73763:1725;;;;75502:10;75498:177;;;75529:134;75564:10;75593:55;-1:-1:-1;;;;;;;;;;;75619:10:0;75631:13;75646:1;75593:18;:55::i;:::-;75529:16;:134::i;:::-;80106:1;;;;67707;;;;;;;73310:2372;;;:::o;66379:34::-;;;;:::o;66789:42::-;;;;:::o;61170:74::-;61202:42;61170:74;:::o;97542:128::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;97642:8;:20;;;;;-1:-1:-1;;;97642:20:0;-1:-1:-1;;;;97642:20:0;;;;;;;;;97542:128::o;66738:44::-;;;;:::o;91564:941::-;-1:-1:-1;;;;;91745:33:0;;91664:21;91745:33;;;-1:-1:-1;;;;;;;;;;;91745:24:0;:33;:24;:33;;;91664:21;;91793:12;;91789:164;;91895:17;;-1:-1:-1;;;;;91839:33:0;;:24;:33;;;-1:-1:-1;;;;;;;;;;;91839:24:0;:33;:24;:33;;;:102;;91936:4;;91839:74;;;:55;:74;:::i;:102::-;91822:119;;91789:164;-1:-1:-1;;;;;;91981:32:0;;:23;:32;;;-1:-1:-1;;;;;;;;;;;91981:23:0;:32;;;:23;:32;;;;92036:24;:33;;;;;;;91981:32;;-1:-1:-1;92084:12:0;;92080:174;;92129:113;92228:13;92129:76;-1:-1:-1;;;92129:48:0;92159:17;;92129:7;:29;;:48;;;;:::i;:76::-;:98;:113;:98;:113;:::i;:::-;92113:129;;92080:174;-1:-1:-1;;;;;;92276:35:0;;:26;:35;;;:26;;:35;:26;:35;;;92326:12;;92322:176;;92371:115;92472:13;92371:78;92444:4;92371:50;92401:19;;92371:7;:29;;:50;;;;:::i;:115::-;92355:131;;92322:176;91564:941;;;;:::o;65381:43::-;;;;;;;;;;;;-1:-1:-1;;;;;65381:43:0;;:::o;64727:29::-;;;-1:-1:-1;;;;;64727:29:0;;:::o;62254:75::-;62286:42;62254:75;:::o;97678:143::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;97787:11;:26;;-1:-1:-1;;;;;;97787:26:0;-1:-1:-1;;;;;97787:26:0;;;;;;;;;;97678:143::o;66485:33::-;;;;:::o;67318:55::-;;;;;;;;;;;;;:::o;59757:140::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;59856:1;59840:6;;59819:40;;-1:-1:-1;;;;;59840:6:0;;;;59819:40;;59856:1;;59819:40;59887:1;59870:19;;-1:-1:-1;;;;;;59870:19:0;;;59757:140::o;62022:109::-;62088:42;62022:109;:::o;93263:1146::-;93437:14;93486:38;:14;93508:15;93486:38;:21;:38;:::i;:::-;93469:55;;93556:10;93539:14;:27;93535:867;;;62752:37;93587:39;;;;:93;;-1:-1:-1;62851:39:0;93647:33;;;93587:93;93583:264;;;-1:-1:-1;93830:1:0;93823:8;;93583:264;62752:37;93865:34;;93861:167;;;62752:37;;-1:-1:-1;93861:167:0;62851:39;94046:36;;94042:167;;;62851:39;;-1:-1:-1;94042:167:0;94225:22;94250:30;:14;94269:10;94250:30;:18;:30;:::i;:::-;94225:55;-1:-1:-1;62574:9:0;94304:32;:12;94225:55;94304:32;:16;:32;:::i;:::-;:60;;;;;;94295:69;;93535:867;;93263:1146;;;;;:::o;61251:74::-;61283:42;61251:74;:::o;66887:33::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66887:33:0;;-1:-1:-1;66887:33:0;:::o;89528:998::-;89606:19;89627;89648:21;89687:19;89709:115;62952:12;89782:1;89798:15;89709:22;:115::i;:::-;89687:137;;89851:121;62952:12;89851:55;89888:11;62952:12;89864:35;89901:4;89851:12;:55::i;:121::-;89837:135;;89999:18;:16;:18::i;:::-;-1:-1:-1;;;;;;;;;;;90030:21:0;90054:29;:20;:29;;;;89985:32;;-1:-1:-1;90098:18:0;;90094:425;;-1:-1:-1;;;;;;;;;;;90251:31:0;90360:26;:20;:26;;-1:-1:-1;;;;;;;;;;;90360:26:0;90285:101;;65003:28;90285:101;90419:88;90493:13;90419:51;90285:101;90465:4;90419:51;:45;:51;:::i;:88::-;90403:104;;90094:425;;89528:998;;;;;:::o;70636:336::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;70797:59;;-1:-1:-1;;;70797:59:0;;63038:42;;70710:21;;63038:42;;70797:13;;:59;;63146:3;;70850:4;;70797:59;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70797:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70797:59:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;70797:59:0;;;;;;;;;:66;70874:90;;-1:-1:-1;;;70874:90:0;;70797:66;;-1:-1:-1;;;;;;70874:13:0;;;;;:90;;63146:3;;70797:66;;70874:90;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70874:90:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70874:90:0;;;;59215:1;;70636:336::o;68425:256::-;68532:7;68557:18;68578:30;68595:5;68602;68578:16;:30::i;:::-;68557:51;;68626:47;68645:5;68652;68659:10;68671:1;68626:18;:47::i;90760:209::-;-1:-1:-1;;;;;90928:24:0;;;90885:15;90928:24;;;:17;:24;;;;;;;;:33;;;;;;;;;;;;;90760:209::o;61779:73::-;61810:42;61779:73;:::o;61526:85::-;61568:42;61526:85;:::o;98340:252::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;98479:28;98471:54;;;;-1:-1:-1;;;98471:54:0;;;;;;;;;98536:22;:48;98340:252::o;58946:79::-;58984:7;59011:6;-1:-1:-1;;;;;59011:6:0;58946:79;;:::o;59312:94::-;59352:4;59392:6;;-1:-1:-1;;;;;59392:6:0;59376:12;:10;:12::i;:::-;-1:-1:-1;;;;;59376:22:0;;59369:29;;59312:94;:::o;71146:1986::-;67677:8;;-1:-1:-1;;;67677:8:0;;;;67676:9;67668:28;;;;-1:-1:-1;;;67668:28:0;;;;;;;;;79134:18;;79199:24;;71321:10;;79134:18;79104:27;;;;79361:114;71321:10;79134:18;79199:24;79361:7;:114::i;:::-;-1:-1:-1;;;;;79486:32:0;;;;;;:23;:32;;;;;;;;:54;;;79551:29;:38;;;;;:66;;;79682:11;:20;;;;;:41;;;79734:17;:26;;;;;:53;;;79236:239;;-1:-1:-1;79236:239:0;;-1:-1:-1;79236:239:0;-1:-1:-1;79236:239:0;-1:-1:-1;79853:187:0;79510:7;79236:239;;;;79853:12;:187::i;:::-;-1:-1:-1;;;;;79801:20:0;;;;;;:11;:20;;;;;;;;79823:17;:26;;;;;79800:240;;;;;;;;80051:15;:24;;;;80078:15;80051:42;;71374:13;;71357;;:30;71349:57;;;;-1:-1:-1;;;71349:57:0;;;;;;;;;71419:13;71443:19;71473:21;71497:10;:54;;71550:1;71497:54;;;71510:37;-1:-1:-1;;;;;;;;;;;71536:10:0;71510:16;:37::i;:::-;71473:78;-1:-1:-1;71569:9:0;71564:1372;71588:6;:13;71584:1;:17;71564:1372;;;71631:6;71638:1;71631:9;;;;;;;;;;;;;;71623:17;;-1:-1:-1;;;;;;;;;;;;;;;;71663:13:0;:5;-1:-1:-1;;;;;71663:13:0;;:31;;;-1:-1:-1;;;;;;71680:14:0;;61202:42;71680:14;71663:31;:49;;;-1:-1:-1;;;;;;71698:14:0;;61283:42;71698:14;71663:49;:69;;;-1:-1:-1;;;;;;71716:16:0;;-1:-1:-1;;;;;;;;;;;71716:16:0;71663:69;71655:95;;;;-1:-1:-1;;;71655:95:0;;;;;;;;;71781:6;71788:1;71781:9;;;;;;;;;;;;;;71767:23;;71809:11;71824:1;71809:16;71805:65;;;71846:8;;71805:65;-1:-1:-1;;;;;71925:24:0;;;;;;:17;:24;;;;;;;;71950:10;71925:36;;;;;;;;:53;;71966:11;71925:53;:40;:53;:::i;:::-;-1:-1:-1;;;;;71886:24:0;;;;;;:17;:24;;;;;;;;71911:10;71886:36;;;;;;;:92;;;;72023:27;;;:20;:27;;;;;:44;;72055:11;72023:44;:31;:44;:::i;:::-;-1:-1:-1;;;;;71993:27:0;;;;;;:20;:27;;;;;:74;;;;72084:70;;72115:10;72135:4;72142:11;72084:70;:30;:70;:::i;:::-;-1:-1:-1;;;;;72219:16:0;;-1:-1:-1;;;;;;;;;;;72219:16:0;72215:539;;;72285:38;;-1:-1:-1;;;72285:38:0;;72256:26;;-1:-1:-1;;;;;;;;;;;61971:42:0;72285:23;;:38;;72317:4;;72285:38;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72285:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72285:38:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;72285:38:0;;;;;;;;;72459:40;;-1:-1:-1;;;72459:40:0;;72256:67;;-1:-1:-1;63038:42:0;;72342;;63146:3;;-1:-1:-1;;;;;;;;;;;61366:42:0;72459:25;;:40;;72493:4;;72459:40;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72459:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72459:40:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;72459:40:0;;;;;;;;;72342:176;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72342:176:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;72560:38:0;;-1:-1:-1;;;72560:38:0;;72537:20;;-1:-1:-1;72601:18:0;;-1:-1:-1;;;;;;;;;;;;61971:42:0;72560:23;;:38;;72592:4;;72560:38;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72560:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72560:38:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;72560:38:0;;;;;;;;;:59;;-1:-1:-1;72642:17:0;;72638:101;;72684:35;-1:-1:-1;;;;;;;;;;;72706:12:0;72684:14;:35::i;:::-;72215:539;;;72850:10;-1:-1:-1;;;;;72773:151:0;72826:5;-1:-1:-1;;;;;72773:151:0;72797:10;-1:-1:-1;;;;;72773:151:0;;72898:11;72773:151;;;;;;;;;;;;;;;71564:1372;71603:3;;71564:1372;;;;72952:10;72948:177;;;72979:134;73014:10;73043:55;-1:-1:-1;;;;;;;;;;;73069:10:0;73081:13;73096:1;73043:18;:55::i;72979:134::-;80106:1;;;67707;;;;;;;71146:1986;;;:::o;66527:50::-;;;;;;;;;;;;;:::o;86093:1027::-;67677:8;;86302:17;;;;-1:-1:-1;;;67677:8:0;;;;67676:9;67668:28;;;;-1:-1:-1;;;67668:28:0;;;;;;;;;86370:37;;;:84;;;;-1:-1:-1;86411:43:0;;;86370:84;86362:111;;;;-1:-1:-1;;;86362:111:0;;;;;;;;;86491:9;86486:378;86506:19;;;86486:378;;;86574:44;86603:11;;86615:1;86603:14;;;;;;;;;;;;;86574:11;:24;86586:8;;86595:1;86586:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;86574:24:0;;;;;;;;;;;;-1:-1:-1;86574:24:0;;;:44;:28;:44;:::i;:::-;86547:11;:24;86559:8;;86568:1;86559:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;86547:24:0;;;;;;;;;;;;-1:-1:-1;86547:24:0;:71;86645:29;86659:11;;86671:1;86659:14;;;;;;;;;;;;;86645:9;:13;;:29;;;;:::i;:::-;86633:41;;86722:56;86757:17;;86775:1;86757:20;;;;;;;;;;;;;86722:17;:30;86740:8;;86749:1;86740:11;;;;;;86722:56;86689:17;:30;86707:8;;86716:1;86707:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;86689:30:0;;;;;;;;;;;;-1:-1:-1;86689:30:0;:89;86811:41;86831:17;;86849:1;86831:20;;;;;;;;;;;;;86811:15;:19;;:41;;;;:::i;:::-;86793:59;-1:-1:-1;86527:3:0;;86486:378;;;-1:-1:-1;86878:14:0;;86874:110;;86909:63;;-1:-1:-1;;;86909:63:0;;-1:-1:-1;;;;;;;;;;;61121:42:0;86909:25;;:63;;86935:10;;86955:4;;86962:9;;86909:63;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;86909:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;86909:63:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;86909:63:0;;;;;;;;;;86874:110;86998:20;;86994:119;;87035:66;;-1:-1:-1;;;87035:66:0;;61568:42;;87035:22;;:66;;87058:10;;87078:4;;87085:15;;87035:66;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;87035:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;87035:66:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;87035:66:0;;;;;;;;;;86994:119;86093:1027;;;;;;;;;:::o;61939:74::-;-1:-1:-1;;;;;;;;;;;61939:74:0;:::o;94690:200::-;94793:18;94836:46;94853:7;94862:19;:17;:19::i;:::-;94836:16;:46::i;61620:73::-;61651:42;61620:73;:::o;65993:64::-;;;;;;;;;;;;;:::o;65098:20::-;;;-1:-1:-1;;;65098:20:0;;;;;:::o;97968:145::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;98080:25;:16;98099:6;;98080:25;:::i;65486:72::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;73140:162::-;73264:30;73272:6;73280;73288:5;73264:7;:30::i;94449:233::-;94578:18;94647:26;;;:14;:26;;;;;;;;94621:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94638:7;;94621:16;:53::i;98121:211::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;98260:4;98242:14;:22;;98234:49;;;;-1:-1:-1;;;98234:49:0;;;;;;;;;98294:13;:30;98121:211::o;97829:131::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;97932:8;:20;;-1:-1:-1;;;;;;97932:20:0;-1:-1:-1;;;;;97932:20:0;;;;;;;;;;97829:131::o;61859:73::-;61890:42;61859:73;:::o;70980:158::-;71102:28;71108:6;71116;71124:5;71102;:28::i;67942:475::-;68084:117;;-1:-1:-1;;;68084:117:0;;68036:7;;;;63038:42;;68084:61;;:117;;63146:3;;68185:4;;68084:117;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68084:117:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68084:117:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68084:117:0;;;;;;;;;68061:140;;68221:188;-1:-1:-1;;;;;;;;;;;68274:5:0;68294:32;-1:-1:-1;;;;;;;;;;;68320:5:0;68294:16;:32::i;:::-;-1:-1:-1;;;;;;;;;;;68368:29:0;;:20;:29;;;;68341:57;;:22;:12;68358:4;68341:22;:16;:22;:::i;:57::-;68221:18;:188::i;66695:36::-;;;;:::o;67724:146::-;67805:16;67846;67839:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67839:23:0;;;;;;;;;;;;;;;;;;;;;;;67724:146;:::o;62338:63::-;62393:8;62338:63;:::o;63158:47::-;63201:4;63158:47;:::o;66586:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66586:46:0;;-1:-1:-1;66586:46:0;;-1:-1:-1;66586:46:0:o;61700:72::-;61730:42;61700:72;:::o;76249:320::-;67677:8;;76361:31;;-1:-1:-1;;;67677:8:0;;;;67676:9;67668:28;;;;-1:-1:-1;;;67668:28:0;;;;;;;;;79134:18;;79199:24;;76331:10;;79134:18;79104:27;;;;79361:114;76331:10;79134:18;79199:24;79361:7;:114::i;:::-;-1:-1:-1;;;;;79486:32:0;;;;;;:23;:32;;;;;;;;:54;;;79551:29;:38;;;;;:66;;;79682:11;:20;;;;;:41;;;79734:17;:26;;;;;:53;;;79236:239;;-1:-1:-1;79236:239:0;;-1:-1:-1;79236:239:0;-1:-1:-1;79236:239:0;-1:-1:-1;79853:187:0;79510:7;79236:239;;;;79853:12;:187::i;:::-;-1:-1:-1;;;;;79801:20:0;;;;;;:11;:20;;;;;;;;79823:17;:26;;;;;79800:240;;;;;;;;80051:15;:24;;;;80078:15;80051:42;;76436:12;:10;:12::i;:::-;76410:38;;76486:10;-1:-1:-1;;;;;76466:95:0;;76511:1;76527:23;76466:95;;;;;;;;78508:537;78622:16;;;78636:1;78622:16;;;;;;;;;78596:23;;78622:16;;;17:15:-1;;105:10;78622:16:0;88:34:-1;-1:-1;;78675:16:0;;;78689:1;78675:16;;;;;;;;;78596:42;;-1:-1:-1;78649:23:0;;78675:16;-1:-1:-1;78675:16:0;;;17:15:-1;;105:10;78675:16:0;88:34:-1;136:17;;-1:-1;78675:16:0;78649:42;;61283;78702:6;78709:1;78702:9;;;;;;;;;;;;;:17;-1:-1:-1;;;;;78702:17:0;;;-1:-1:-1;;;;;78702:17:0;;;;;-1:-1:-1;;;;;;;;;;;78730:6:0;78737:1;78730:9;;;;;;;;;;;;;:19;-1:-1:-1;;;;;78730:19:0;;;-1:-1:-1;;;;;78730:19:0;;;;;61202:42;78760:6;78767:1;78760:9;;;;;;;;;;;;;:17;-1:-1:-1;;;;;78760:17:0;;;-1:-1:-1;;;;;78760:17:0;;;;;-1:-1:-1;;;;;;;;;;;78788:6:0;78795:1;78788:9;;;;;;;;;;;;;:16;-1:-1:-1;;;;;78788:16:0;;;-1:-1:-1;;;;;78788:16:0;;;;;-1:-1:-1;;78815:6:0;78822:1;78815:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;78849:6:0;78856:1;78849:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;78883:6:0;78890:1;78883:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;78917:6:0;78924:1;78917:9;;;;;;;;;;;;;:23;;;;;78961:29;78969:6;78977;78985:4;78961:7;:29::i;:::-;79024:13;79031:5;79024:6;:13::i;:::-;;;78508:537;;:::o;65599:33::-;;;;:::o;92691:564::-;92855:17;;61202:42;92768:14;92809:27;;;:20;:27;;;;92768:14;;92809:88;;92892:4;;92809:64;;:27;:64;:45;:64;:::i;:88::-;-1:-1:-1;;;;;;;;;;;92919:26:0;;:20;:26;;-1:-1:-1;;;;;;;;;;;92919:26:0;92800:97;;-1:-1:-1;92919:52:0;;92800:97;92919:52;:44;:52;:::i;:::-;93039:17;;61283:42;92993:27;;:20;:27;;;;92910:61;;-1:-1:-1;92993:114:0;;92910:61;;92993:88;;-1:-1:-1;;;93076:4:0;92993:64;;:27;:64;:45;:64;:::i;:114::-;93177:19;;-1:-1:-1;;;;;;;;;;;93129:29:0;;:20;:29;;;;92984:123;;-1:-1:-1;93129:118:0;;92984:123;;93129:92;;93216:4;;93129:68;;:29;:68;:47;:68;:::i;:118::-;93120:127;;92691:564;:::o;60052:109::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;60125:28;60144:8;60125:18;:28::i;:::-;60052:109;:::o;61090:73::-;-1:-1:-1;;;;;;;;;;;61090:73:0;:::o;87188:507::-;67677:8;;-1:-1:-1;;;67677:8:0;;;;67676:9;67668:28;;;;-1:-1:-1;;;67668:28:0;;;;;;;;;87325:12;;;;:34;;-1:-1:-1;87341:18:0;;;87325:34;87321:367;;;87376:35;87388:7;87397:13;87376:11;:35::i;:::-;87430:12;;87426:114;;87463:61;;-1:-1:-1;;;87463:61:0;;-1:-1:-1;;;;;;;;;;;61121:42:0;87463:25;;:61;;87489:10;;87509:4;;87516:7;;87463:61;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;87463:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;87463:61:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;87463:61:0;;;;;;;;;;87426:114;87558:18;;87554:123;;87597:64;;-1:-1:-1;;;87597:64:0;;61568:42;;87597:22;;:64;;87620:10;;87640:4;;87647:13;;87597:64;;;;81354:3143;-1:-1:-1;;;;;81703:32:0;;81518:25;81703:32;;;:23;:32;;;;;;81518:25;;;;;;;;81685:51;;:13;;:51;:17;:51;:::i;:::-;-1:-1:-1;;;;;81806:38:0;;81747:32;81806:38;;;:29;:38;;;;;;81656:80;;-1:-1:-1;81747:32:0;81782:63;;:19;;:63;:23;:63;:::i;:::-;-1:-1:-1;;;;;81878:20:0;;;;;;:11;:20;;;;;;;;;81935:17;:26;;;;;;81993:11;:20;;;;;;82051:17;:26;;;;;;;;81878:20;;-1:-1:-1;81935:26:0;-1:-1:-1;81993:20:0;-1:-1:-1;82051:26:0;-1:-1:-1;81747:98:0;-1:-1:-1;82094:23:0;;;;:56;;-1:-1:-1;82121:29:0;;;82094:56;82090:2400;;;82167:13;82195:18;82228:16;82262:21;82285:22;82311:24;82327:7;82311:15;:24::i;:::-;82261:74;;-1:-1:-1;82261:74:0;-1:-1:-1;82360:55:0;82261:74;82396:18;82360:55;:35;:55;:::i;:::-;-1:-1:-1;;;82430:13:0;;;-1:-1:-1;82478:46:0;82430:13;82506:17;82478:27;:46::i;:::-;82458:66;-1:-1:-1;82549:61:0;:13;82585:24;82549:61;:35;:61;:::i;:::-;-1:-1:-1;;;82625:13:0;;;-1:-1:-1;82679:52:0;82625:13;82707:23;82679:27;:52::i;:::-;82653:78;-1:-1:-1;82752:19:0;;;;;:46;;-1:-1:-1;82775:23:0;;;82752:46;82748:800;;;82879:60;:14;82920:18;82879:60;:40;:60;:::i;:::-;-1:-1:-1;;;82958:13:0;;;-1:-1:-1;83011:51:0;:18;82958:13;83011:44;:51::i;:::-;-1:-1:-1;;;;;83162:24:0;;;;;;:15;:24;;;;;;82990:72;;-1:-1:-1;83162:24:0;;-1:-1:-1;83218:123:0;;-1:-1:-1;;;83263:4:0;83162:24;83218:22;:123::i;:::-;83205:136;-1:-1:-1;83368:43:0;:5;83205:136;83368:43;:31;:43;:::i;:::-;-1:-1:-1;;;83430:13:0;;;-1:-1:-1;83482:50:0;:17;83430:13;83482:43;:50::i;:::-;83462:70;;82748:800;83566:19;;;;;:52;;-1:-1:-1;83589:29:0;;;83566:52;83562:917;;;83699:66;:14;83740:24;83699:66;:40;:66;:::i;:::-;-1:-1:-1;;;83784:13:0;;;-1:-1:-1;83843:57:0;:24;83784:13;83843:50;:57::i;:::-;83816:84;-1:-1:-1;83993:13:0;83989:272;;-1:-1:-1;;;;;84042:24:0;;;;;;:15;:24;;;;;;;-1:-1:-1;84102:139:0;;-1:-1:-1;;;84151:4:0;84042:24;84102:22;:139::i;:::-;84089:152;;83989:272;84287:43;:5;84319:10;84287:43;:31;:43;:::i;:::-;-1:-1:-1;;;84349:13:0;;;-1:-1:-1;84407:56:0;:23;84349:13;84407:49;:56::i;:::-;84381:82;;83562:917;82090:2400;;;;;;81354:3143;;;;;;;;;:::o;84505:1520::-;-1:-1:-1;;;;;84822:24:0;;84762:7;84822:24;;;:15;:24;;;;;;84762:7;;84882:15;84863:34;;84859:1095;;84914:21;84950:18;84971:128;-1:-1:-1;;;85035:15:0;85069;84971:22;:128::i;:::-;84950:149;-1:-1:-1;85120:23:0;;85116:221;;85180:88;-1:-1:-1;;;85180:56:0;:18;85225:10;85180:56;:44;:56;:::i;:88::-;85287:34;;;;85164:104;-1:-1:-1;85116:221:0;85357:29;;85353:239;;85423:94;-1:-1:-1;;;85423:62:0;:24;85474:10;85423:62;:50;:62;:::i;:94::-;85536:40;;;;85407:110;-1:-1:-1;85353:239:0;-1:-1:-1;;;;;85631:33:0;;85608:20;85631:33;;;-1:-1:-1;;;;;;;;;;;85631:24:0;:33;:24;:33;;;85683:17;;85679:264;;85792:82;-1:-1:-1;;;85792:50:0;:12;85831:10;85792:50;:38;:50;:::i;:82::-;85893:34;;;;85776:98;-1:-1:-1;85679:264:0;84859:1095;;;;-1:-1:-1;85974:17:0;;85993:23;;-1:-1:-1;84505:1520:0;;-1:-1:-1;;;;84505:1520:0:o;2414:471::-;2472:7;2717:6;2713:47;;-1:-1:-1;2747:1:0;2740:8;;2713:47;2784:5;;;2788:1;2784;:5;:1;2808:5;;;;;:10;2800:56;;;;-1:-1:-1;;;2800:56:0;;;;;;;;3353:132;3411:7;3438:39;3442:1;3445;3438:39;;;;;;;;;;;;;;;;;:3;:39::i;1498:136::-;1556:7;1583:43;1587:1;1590;1583:43;;;;;;;;;;;;;;;;;:3;:43::i;95359:372::-;95438:20;;:::i;:::-;95483:240;;;;;;;;95544:1;95526:15;:19;95483:240;;;;95573:18;:16;:18::i;:::-;95483:240;;95621:31;;-1:-1:-1;;;95621:31:0;;95483:240;;;;;-1:-1:-1;;;;;;;;;;;61121:42:0;95621:22;;:31;;-1:-1:-1;;;;;;;;;;;61366:42:0;95621:31;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;95621:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;95621:31:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;95621:31:0;;;;;;;;;95483:240;;;;-1:-1:-1;;;;;;;;;;;;;;;;95682:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;95682:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;95682:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;95682:29:0;;;;;;;;;95483:240;;95476:247;-1:-1:-1;95359:372:0;:::o;95739:1765::-;-1:-1:-1;;;;;95945:24:0;;95882:18;95945:24;;;:15;:24;;;;;;95984:21;;:26;;:74;;-1:-1:-1;96033:21:0;;-1:-1:-1;;96033:25:0;96014:44;;95984:74;95980:115;;;96082:1;96075:8;;;;;95980:115;-1:-1:-1;;;;;96131:33:0;;96107:21;96131:33;;;-1:-1:-1;;;;;;;;;;;96131:24:0;:33;:24;:33;;;96179:18;;96175:744;;96290:321;62952:12;96290:294;96371:194;62952:12;96493:1;96521:8;:21;;;96371:22;:194::i;:::-;96290:13;;62952:12;96326:239;96290:294;:35;:294;:::i;:321::-;96277:334;;96747:160;96896:10;96747:144;96788:13;96820:16;96855:8;:21;;;96747:22;:144::i;:160::-;96734:173;;96175:744;-1:-1:-1;;;;;96995:20:0;;;;;;:11;:20;;;;;;;;;-1:-1:-1;;;;;;;;;;;96944:32:0;;;;;;;:143;;97076:10;;96944:72;;:50;:72::i;:143::-;97165:20;;;;;-1:-1:-1;;;;;97113:33:0;;:24;:33;;;:24;:33;;;:24;:33;;;;96931:156;;-1:-1:-1;97113:127:0;;96931:156;;97113:97;;-1:-1:-1;;;97205:4:0;97113:73;;:33;:73;:51;:73;:::i;:127::-;97443:22;;;;-1:-1:-1;;;;;97388:35:0;;:26;:35;;;:26;;:35;:26;:35;;;;;97347:22;;;;97100:140;;-1:-1:-1;97347:149:0;;97100:140;;97347:119;;97443:22;;97347:77;;;:40;:77;:::i;:149::-;97334:162;95739:1765;-1:-1:-1;;;;;95739:1765:0:o;76577:377::-;76653:25;76680:31;76749:19;76760:7;76749:10;:19::i;:::-;76729:39;;76805:12;:10;:12::i;:::-;76779:38;;76855:10;-1:-1:-1;;;;;76835:111:0;;76880:17;76912:23;76835:111;;;;;;;;;;;;;;;;76577:377;;;:::o;88708:812::-;88785:19;-1:-1:-1;;;;;88807:14:0;;-1:-1:-1;;;;;;;;;;;88807:14:0;:32;;88834:5;88807:32;;;-1:-1:-1;;;;;;;;;;;88807:32:0;-1:-1:-1;;;;;88874:33:0;;88852:19;88874:33;;;:20;:33;;;;;;88785:54;;-1:-1:-1;88926:16:0;88918:40;;;;-1:-1:-1;;;88918:40:0;;;;;;;;;-1:-1:-1;;;;;89054:23:0;;88971:31;89054:23;;;:16;:23;;;;;;;;89017:60;;;;;;;;;;;;;;;;;:34;;:60;;89054:23;89017:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89119:1;89092:17;:24;:28;89088:134;;;89163:17;89208:1;89181:17;:24;:28;89163:47;;;;;;;;;;;;;;89137:73;;89088:134;89234:34;89271:33;89292:11;89271:16;:6;89282:4;89271:16;:10;:16;:::i;:33::-;89234:70;-1:-1:-1;89315:24:0;89342:55;89234:70;89373:23;89342:55;:30;:55;:::i;:::-;-1:-1:-1;;;;;89408:23:0;;;;;;:16;:23;;;;;;;;27:10:-1;;39:1;23:18;;45:23;;89408:46:0;;;;;;;;;;;89472:40;89315:82;;-1:-1:-1;89408:23:0;89486:10;;89472:40;;;;89505:6;;89472:40;;;;;;;;;;88708:812;;;;;;;;:::o;76962:737::-;77117:10;77042:25;77105:23;;;:11;:23;;;;;;77143:22;;77139:553;;77194:10;77208:1;77182:23;;;:11;:23;;;;;:27;77224:457;;;;77256:104;77291:10;77324:17;77256:12;:104::i;:::-;77224:457;;;77405:37;;-1:-1:-1;;;77405:37:0;;77445:17;;-1:-1:-1;;;;;;;;;;;61121:42:0;77405:22;;:37;;77436:4;;77405:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77405:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77405:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;77405:37:0;;;;;;;;;:57;77401:192;;;61202:42;-1:-1:-1;;;;;77545:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77545:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77545:28:0;;;;77401:192;77613:52;;-1:-1:-1;;;77613:52:0;;-1:-1:-1;;;;;;;;;;;61121:42:0;77613:21;;:52;;77635:10;;77647:17;;77613:52;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77613:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77613:52:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;77613:52:0;;;;;;;;;;76962:737;;;:::o;11991:176::-;12100:58;;12074:85;;12093:5;;-1:-1:-1;;;12123:23:0;12100:58;;12148:2;;12152:5;;12100:58;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;12100:58:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;12100:58:0;;;179:29:-1;;;;160:49;;;12074:18:0;:85::i;68689:1345::-;-1:-1:-1;;;;;68907:23:0;;68845:7;68907:23;;;:16;:23;;;;;;;;68870:60;;;;;;;;;;;;;;;;;:34;;:60;;68907:23;68870:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68965:24:0;;68870:60;;-1:-1:-1;;;69004:18:0;;69000:45;;-1:-1:-1;69000:45:0;;69044:1;69037:8;;;;;;69000:45;69062:15;69058:42;;69099:1;69092:8;;;;;;69058:42;-1:-1:-1;;;;;69141:27:0;;69113:25;69141:27;;;:20;:27;;;;;;69218:34;;69141:27;;69113:25;69218:58;;69257:18;;69218:17;;-1:-1:-1;;69236:15:0;;;69218:34;;;;;;;;;;;;:38;;:58;;;;:::i;:::-;69179:97;-1:-1:-1;69323:22:0;69319:152;;69369:90;69454:4;69369:62;:10;69402:28;69369:62;:32;:62;:::i;:90::-;69362:97;;;;;;;;69319:152;-1:-1:-1;;69543:15:0;;;;69481:19;;;;69646:34;;;69642:75;;;69704:1;69697:8;;;;;;;;69642:75;69729:34;69766:17;69784;69766:36;;;;;;;;;;;;;;69729:73;;69813:23;69839:44;69854:28;69839:10;:14;;:44;;;;:::i;:::-;69813:70;-1:-1:-1;69894:22:0;69919:42;:10;69934:26;69919:42;:14;:42;:::i;:::-;69894:67;-1:-1:-1;69979:47:0;70021:4;69980:35;:15;69894:67;69980:35;:19;:35;:::i;69979:47::-;69972:54;;;;;;;;;68689:1345;;;;;;;:::o;70042:543::-;-1:-1:-1;;;;;;;;;;;70251:23:0;;:16;:23;;;;;70212:62;;70251:23;70212:62;;;;;;;;;;;;;;;:36;;:62;;70251:23;70212:62;;;70251:23;70212:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70318:1;70289:19;:26;:30;70285:119;;;70366:26;;-1:-1:-1;;;;;70336:27:0;;;;;;:20;:27;;;;;:56;70285:119;70420:17;;70416:160;;70454:47;-1:-1:-1;;;;;;;;;;;70481:5:0;70488:12;70454:47;:26;:47;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;70521:43:0;70537:5;-1:-1:-1;;;;;70521:43:0;;70551:12;70521:43;;;;;;;;;;;;;;;70042:543;;;:::o;1042:181::-;1100:7;1132:5;;;1156:6;;;;1148:46;;;;-1:-1:-1;;;1148:46:0;;;;;;;;15871:115;15934:7;15966:2;15961;:7;:17;;15976:2;15961:17;;;-1:-1:-1;15971:2:0;;15871:115;-1:-1:-1;15871:115:0:o;90534:218::-;90612:7;90644:100;61283:42;-1:-1:-1;;;;;90716:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;90716:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;90716:27:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;90716:27:0;;;;;;;;;90644:29;;-1:-1:-1;;;90644:29:0;;:53;;-1:-1:-1;;;90692:4:0;-1:-1:-1;;;;;;;;;;;61121:42:0;90644:22;;:29;;61283:42;;90644:29;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;90644:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;90644:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;90644:29:0;;;;;;;;;:47;:53;:47;:53;:::i;57737:98::-;57817:10;57737:98;:::o;12175:204::-;12302:68;;12276:95;;12295:5;;-1:-1:-1;;;12325:27:0;12302:68;;12354:4;;12360:2;;12364:5;;12302:68;;;;77707:345;77859:10;77766:31;77841:29;;;:17;:29;;;;;;77885:28;;77881:164;;77948:10;77962:1;77930:29;;;:17;:29;;;;;;:33;;;;77978:55;-1:-1:-1;;;77978:55:0;;61568:42;;77978:18;;:55;;77948:10;78009:23;;77978:55;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77978:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77978:55:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;77978:55:0;;;;;;;;;;77707:345;:::o;60267:229::-;-1:-1:-1;;;;;60341:22:0;;60333:73;;;;-1:-1:-1;;;60333:73:0;;;;;;;;;60443:6;;;60422:38;;-1:-1:-1;;;;;60422:38:0;;;;60443:6;;;60422:38;;;60471:6;:17;;-1:-1:-1;;;;;;60471:17:0;-1:-1:-1;;;;;60471:17:0;;;;;;;;;;60267:229::o;87703:761::-;87879:20;:18;:20::i;:::-;87856:19;87817:82;87837:17;87817:82;87818:17;87817:82;87818:17;87934:19;:17;:19::i;:::-;87912:41;-1:-1:-1;87972:16:0;87964:43;;;;-1:-1:-1;;;87964:43:0;;;;;;;;;88122:18;;88041:100;;:62;88091:11;88041:31;:7;-1:-1:-1;;;88041:31:0;:25;:31;:::i;:100::-;88020:18;:121;88268:24;;88181:112;;:68;88237:11;88181:37;:13;-1:-1:-1;;;88181:37:0;:31;:37;:::i;:112::-;88154:24;:139;88327:15;88306:18;:36;88360:96;;88385:10;;88360:96;;;;88410:7;;88432:13;;88360:96;;;;;;;;;;87703:761;;;:::o;4015:345::-;4101:7;4203:12;4196:5;4188:28;;;;-1:-1:-1;;;4188:28:0;;;;;;;;;;;4227:9;4243:1;4239;:5;;;;1971:192;2057:7;2093:12;2085:6;;;;2077:29;;;;-1:-1:-1;;;2077:29:0;;;;;;;;;;-1:-1:-1;;;2129:5:0;;;1971:192::o;78060:440::-;-1:-1:-1;;;;;78203:32:0;;:23;:32;;;-1:-1:-1;;;;;;;;;;;78203:23:0;:32;:23;:32;;;:58;;78254:6;78203:58;:50;:58;:::i;:::-;-1:-1:-1;;;;;78168:32:0;;:23;:32;;;-1:-1:-1;;;;;;;;;;;78168:23:0;:32;;;:23;:32;;:93;;;;-1:-1:-1;;;;;;;;;;;78303:26:0;;:20;:26;;-1:-1:-1;;;;;;;;;;;78303:26:0;:52;;78348:6;78303:52;:44;:52;:::i;:::-;-1:-1:-1;;;;;;;;;;;78274:26:0;;;;:20;:26;;-1:-1:-1;;;;;;;;;;;78274:81:0;;;;:26;78373:119;-1:-1:-1;;;;;78373:119:0;;;61121:42;78373:119;;;;;;78475:6;;78373:119;;;;;;;;;;78060:440;;:::o;14030:1114::-;14634:27;14642:5;-1:-1:-1;;;;;14634:25:0;;:27::i;:::-;14626:71;;;;-1:-1:-1;;;14626:71:0;;;;;;;;;14771:12;14785:23;14820:5;-1:-1:-1;;;;;14812:19:0;14832:4;14812:25;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;14770:67:0;;;;14856:7;14848:52;;;;-1:-1:-1;;;14848:52:0;;;;;;;;;14917:17;;:21;14913:224;;15059:10;15048:30;;;;;;;;;;;;;;15040:85;;;;-1:-1:-1;;;15040:85:0;;;;;;;;9115:619;9175:4;9643:20;;9486:66;9683:23;;;;;;:42;;-1:-1:-1;;9710:15:0;;;9675:51;-1:-1:-1;;9115:619:0:o;67432:31658::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;67432:31658:0;-1:-1:-1;;;;;67432:31658:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;67432:31658:0;;;;-1:-1:-1;67432:31658:0;;;;;;;;;;-1:-1:-1;;;;;;67432:31658:0;;;;;;;5:130:-1;72:20;;97:33;72:20;97:33;;160:352;;;290:3;283:4;275:6;271:17;267:27;257:2;;308:1;305;298:12;257:2;-1:-1;328:20;;368:18;357:30;;354:2;;;400:1;397;390:12;354:2;434:4;426:6;422:17;410:29;;485:3;477:4;469:6;465:17;455:8;451:32;448:41;445:2;;;502:1;499;492:12;445:2;250:262;;;;;;538:707;;655:3;648:4;640:6;636:17;632:27;622:2;;673:1;670;663:12;622:2;710:6;697:20;732:80;747:64;804:6;747:64;;;732:80;;;723:89;;829:5;854:6;847:5;840:21;884:4;876:6;872:17;862:27;;906:4;901:3;897:14;890:21;;959:6;1006:3;998:4;990:6;986:17;981:3;977:27;974:36;971:2;;;1023:1;1020;1013:12;971:2;1048:1;1033:206;1058:6;1055:1;1052:13;1033:206;;;1116:3;1138:37;1171:3;1159:10;1138:37;;;1126:50;;-1:-1;1199:4;1190:14;;;;1218;;;;;1080:1;1073:9;1033:206;;;1037:14;615:630;;;;;;;;1649:707;;1766:3;1759:4;1751:6;1747:17;1743:27;1733:2;;1784:1;1781;1774:12;1733:2;1821:6;1808:20;1843:80;1858:64;1915:6;1858:64;;1843:80;1834:89;;1940:5;1965:6;1958:5;1951:21;1995:4;1987:6;1983:17;1973:27;;2017:4;2012:3;2008:14;2001:21;;2070:6;2117:3;2109:4;2101:6;2097:17;2092:3;2088:27;2085:36;2082:2;;;2134:1;2131;2124:12;2082:2;2159:1;2144:206;2169:6;2166:1;2163:13;2144:206;;;2227:3;2249:37;2282:3;2270:10;2249:37;;;2237:50;;-1:-1;2310:4;2301:14;;;;2329;;;;;2191:1;2184:9;2144:206;;2364:124;2428:20;;2453:30;2428:20;2453:30;;2495:128;2570:13;;2588:30;2570:13;2588:30;;2669:509;;2795:4;2783:9;2778:3;2774:19;2770:30;2767:2;;;2813:1;2810;2803:12;2767:2;2831:20;2846:4;2831:20;;;2822:29;-1:-1;2903:1;2935:60;2991:3;2971:9;2935:60;;;2910:86;;-1:-1;3063:2;3096:60;3152:3;3128:22;;;3096:60;;;3089:4;3082:5;3078:16;3071:86;3017:151;2761:417;;;;;3185:130;3252:20;;3277:33;3252:20;3277:33;;3322:134;3400:13;;3418:33;3400:13;3418:33;;3463:241;;3567:2;3555:9;3546:7;3542:23;3538:32;3535:2;;;3583:1;3580;3573:12;3535:2;3618:1;3635:53;3680:7;3660:9;3635:53;;3711:366;;;3832:2;3820:9;3811:7;3807:23;3803:32;3800:2;;;3848:1;3845;3838:12;3800:2;3883:1;3900:53;3945:7;3925:9;3900:53;;;3890:63;;3862:97;3990:2;4008:53;4053:7;4044:6;4033:9;4029:22;4008:53;;;3998:63;;3969:98;3794:283;;;;;;4084:366;;;4205:2;4193:9;4184:7;4180:23;4176:32;4173:2;;;4221:1;4218;4211:12;4173:2;4256:1;4273:53;4318:7;4298:9;4273:53;;;4263:63;;4235:97;4363:2;4381:53;4426:7;4417:6;4406:9;4402:22;4381:53;;4457:397;;;4596:2;4584:9;4575:7;4571:23;4567:32;4564:2;;;4612:1;4609;4602:12;4564:2;4647:31;;4698:18;4687:30;;4684:2;;;4730:1;4727;4720:12;4684:2;4758:80;4830:7;4821:6;4810:9;4806:22;4758:80;;;4748:90;;;;4626:218;4558:296;;;;;;4861:959;;;;;;;5104:2;5092:9;5083:7;5079:23;5075:32;5072:2;;;5120:1;5117;5110:12;5072:2;5155:31;;5206:18;5195:30;;5192:2;;;5238:1;5235;5228:12;5192:2;5266:80;5338:7;5329:6;5318:9;5314:22;5266:80;;;5256:90;;;;5134:218;5411:2;5400:9;5396:18;5383:32;5435:18;5427:6;5424:30;5421:2;;;5467:1;5464;5457:12;5421:2;5495:80;5567:7;5558:6;5547:9;5543:22;5495:80;;;5485:90;;;;5362:219;5640:2;5629:9;5625:18;5612:32;5664:18;5656:6;5653:30;5650:2;;;5696:1;5693;5686:12;5650:2;5724:80;5796:7;5787:6;5776:9;5772:22;5724:80;;;5714:90;;;;5591:219;5066:754;;;;;;;;;5827:638;;;5998:2;5986:9;5977:7;5973:23;5969:32;5966:2;;;6014:1;6011;6004:12;5966:2;6049:31;;6100:18;6089:30;;6086:2;;;6132:1;6129;6122:12;6086:2;6152:78;6222:7;6213:6;6202:9;6198:22;6152:78;;;6142:88;;6028:208;6295:2;6284:9;6280:18;6267:32;6319:18;6311:6;6308:30;6305:2;;;6351:1;6348;6341:12;6305:2;6371:78;6441:7;6432:6;6421:9;6417:22;6371:78;;6472:757;;;;6657:2;6645:9;6636:7;6632:23;6628:32;6625:2;;;6673:1;6670;6663:12;6625:2;6708:31;;6759:18;6748:30;;6745:2;;;6791:1;6788;6781:12;6745:2;6811:78;6881:7;6872:6;6861:9;6857:22;6811:78;;;6801:88;;6687:208;6954:2;6943:9;6939:18;6926:32;6978:18;6970:6;6967:30;6964:2;;;7010:1;7007;7000:12;6964:2;7030:78;7100:7;7091:6;7080:9;7076:22;7030:78;;;7020:88;;6905:209;7145:2;7163:50;7205:7;7196:6;7185:9;7181:22;7163:50;;;7153:60;;7124:95;6619:610;;;;;;7236:235;;7337:2;7325:9;7316:7;7312:23;7308:32;7305:2;;;7353:1;7350;7343:12;7305:2;7388:1;7405:50;7447:7;7427:9;7405:50;;7478:257;;7590:2;7578:9;7569:7;7565:23;7561:32;7558:2;;;7606:1;7603;7596:12;7558:2;7641:1;7658:61;7711:7;7691:9;7658:61;;7742:315;;7883:2;7871:9;7862:7;7858:23;7854:32;7851:2;;;7899:1;7896;7889:12;7851:2;7934:1;7951:90;8033:7;8013:9;7951:90;;8064:241;;8168:2;8156:9;8147:7;8143:23;8139:32;8136:2;;;8184:1;8181;8174:12;8136:2;8219:1;8236:53;8281:7;8261:9;8236:53;;8312:263;;8427:2;8415:9;8406:7;8402:23;8398:32;8395:2;;;8443:1;8440;8433:12;8395:2;8478:1;8495:64;8551:7;8531:9;8495:64;;8582:366;;;8703:2;8691:9;8682:7;8678:23;8674:32;8671:2;;;8719:1;8716;8709:12;8671:2;8754:1;8771:53;8816:7;8796:9;8771:53;;8955:491;;;;9093:2;9081:9;9072:7;9068:23;9064:32;9061:2;;;9109:1;9106;9099:12;9061:2;9144:1;9161:53;9206:7;9186:9;9161:53;;;9151:63;;9123:97;9251:2;9269:53;9314:7;9305:6;9294:9;9290:22;9269:53;;;9259:63;;9230:98;9359:2;9377:53;9422:7;9413:6;9402:9;9398:22;9377:53;;9454:173;;9541:46;9583:3;9575:6;9541:46;;;-1:-1;;9616:4;9607:14;;9534:93;9635:142;9726:45;9765:5;9726:45;;;9721:3;9714:58;9708:69;;;9784:103;9857:24;9875:5;9857:24;;10045:690;;10190:54;10238:5;10190:54;;;10257:86;10336:6;10331:3;10257:86;;;10250:93;;10364:56;10414:5;10364:56;;;10440:7;10468:1;10453:260;10478:6;10475:1;10472:13;10453:260;;;10545:6;10539:13;10566:63;10625:3;10610:13;10566:63;;;10559:70;;10646:60;10699:6;10646:60;;;10636:70;-1:-1;;10500:1;10493:9;10453:260;;;-1:-1;10726:3;;10169:566;-1:-1;;;;;10169:566;10743:104;10820:21;10835:5;10820:21;;10854:356;;10982:38;11014:5;10982:38;;;11032:88;11113:6;11108:3;11032:88;;;11025:95;;11125:52;11170:6;11165:3;11158:4;11151:5;11147:16;11125:52;;;11189:16;;;;;10962:248;-1:-1;;10962:248;11217:152;11313:50;11357:5;11313:50;;11893:142;11984:45;12023:5;11984:45;;12042:347;;12154:39;12187:5;12154:39;;;12205:71;12269:6;12264:3;12205:71;;;12198:78;;12281:52;12326:6;12321:3;12314:4;12307:5;12303:16;12281:52;;;12354:29;12376:6;12354:29;;;12345:39;;;;12134:255;-1:-1;;;12134:255;12397:375;;12557:67;12621:2;12616:3;12557:67;;;12657:34;12637:55;;-1:-1;;;12721:2;12712:12;;12705:30;12763:2;12754:12;;12543:229;-1:-1;;12543:229;12781:327;;12941:67;13005:2;13000:3;12941:67;;;13041:29;13021:50;;13099:2;13090:12;;12927:181;-1:-1;;12927:181;13117:311;;13277:67;13341:2;13336:3;13277:67;;;-1:-1;;;13357:34;;13419:2;13410:12;;13263:165;-1:-1;;13263:165;13437:332;;13597:67;13661:2;13656:3;13597:67;;;13697:34;13677:55;;13760:2;13751:12;;13583:186;-1:-1;;13583:186;13778:314;;13938:67;14002:2;13997:3;13938:67;;;-1:-1;;;14018:37;;14083:2;14074:12;;13924:168;-1:-1;;13924:168;14101:315;;14261:67;14325:2;14320:3;14261:67;;;-1:-1;;;14341:38;;14407:2;14398:12;;14247:169;-1:-1;;14247:169;14425:314;;14585:67;14649:2;14644:3;14585:67;;;-1:-1;;;14665:37;;14730:2;14721:12;;14571:168;-1:-1;;14571:168;14748:370;;14908:67;14972:2;14967:3;14908:67;;;15008:34;14988:55;;-1:-1;;;15072:2;15063:12;;15056:25;15109:2;15100:12;;14894:224;-1:-1;;14894:224;15127:313;;15287:67;15351:2;15346:3;15287:67;;;-1:-1;;;15367:36;;15431:2;15422:12;;15273:167;-1:-1;;15273:167;15449:312;;15609:67;15673:2;15668:3;15609:67;;;-1:-1;;;15689:35;;15752:2;15743:12;;15595:166;-1:-1;;15595:166;15770:332;;15930:67;15994:2;15989:3;15930:67;;;16030:34;16010:55;;16093:2;16084:12;;15916:186;-1:-1;;15916:186;16111:313;;16271:67;16335:2;16330:3;16271:67;;;-1:-1;;;16351:36;;16415:2;16406:12;;16257:167;-1:-1;;16257:167;16433:379;;16593:67;16657:2;16652:3;16593:67;;;16693:34;16673:55;;-1:-1;;;16757:2;16748:12;;16741:34;16803:2;16794:12;;16579:233;-1:-1;;16579:233;16821:305;;16981:66;17045:1;17040:3;16981:66;;;-1:-1;;;17060:29;;17117:2;17108:12;;16967:159;-1:-1;;16967:159;17135:331;;17295:67;17359:2;17354:3;17295:67;;;17395:33;17375:54;;17457:2;17448:12;;17281:185;-1:-1;;17281:185;17475:314;;17635:67;17699:2;17694:3;17635:67;;;-1:-1;;;17715:37;;17780:2;17771:12;;17621:168;-1:-1;;17621:168;17797:113;17880:24;17898:5;17880:24;;17917:262;;18061:93;18150:3;18141:6;18061:93;;18186:213;18304:2;18289:18;;18318:71;18293:9;18362:6;18318:71;;18406:451;18588:2;18573:18;;18602:79;18577:9;18654:6;18602:79;;;18692:72;18760:2;18749:9;18745:18;18736:6;18692:72;;;18775;18843:2;18832:9;18828:18;18819:6;18775:72;;18864:340;19018:2;19003:18;;19032:79;19007:9;19084:6;19032:79;;;19122:72;19190:2;19179:9;19175:18;19166:6;19122:72;;19211:435;19385:2;19370:18;;19399:71;19374:9;19443:6;19399:71;;19653:324;19799:2;19784:18;;19813:71;19788:9;19857:6;19813:71;;19984:361;20152:2;20166:47;;;20137:18;;20227:108;20137:18;20321:6;20227:108;;20352:201;20464:2;20449:18;;20478:65;20453:9;20516:6;20478:65;;20560:239;20691:2;20676:18;;20705:84;20680:9;20762:6;20705:84;;21584:340;21738:2;21723:18;;21752:79;21727:9;21804:6;21752:79;;21931:301;22069:2;22083:47;;;22054:18;;22144:78;22054:18;22208:6;22144:78;;22239:407;22430:2;22444:47;;;22415:18;;22505:131;22415:18;22505:131;;22653:407;22844:2;22858:47;;;22829:18;;22919:131;22829:18;22919:131;;23067:407;23258:2;23272:47;;;23243:18;;23333:131;23243:18;23333:131;;23481:407;23672:2;23686:47;;;23657:18;;23747:131;23657:18;23747:131;;23895:407;24086:2;24100:47;;;24071:18;;24161:131;24071:18;24161:131;;24309:407;24500:2;24514:47;;;24485:18;;24575:131;24485:18;24575:131;;24723:407;24914:2;24928:47;;;24899:18;;24989:131;24899:18;24989:131;;25137:407;25328:2;25342:47;;;25313:18;;25403:131;25313:18;25403:131;;25551:407;25742:2;25756:47;;;25727:18;;25817:131;25727:18;25817:131;;25965:407;26156:2;26170:47;;;26141:18;;26231:131;26141:18;26231:131;;26379:407;26570:2;26584:47;;;26555:18;;26645:131;26555:18;26645:131;;26793:407;26984:2;26998:47;;;26969:18;;27059:131;26969:18;27059:131;;27207:407;27398:2;27412:47;;;27383:18;;27473:131;27383:18;27473:131;;27621:407;27812:2;27826:47;;;27797:18;;27887:131;27797:18;27887:131;;28035:407;28226:2;28240:47;;;28211:18;;28301:131;28211:18;28301:131;;28449:407;28640:2;28654:47;;;28625:18;;28715:131;28625:18;28715:131;;28863:213;28981:2;28966:18;;28995:71;28970:9;29039:6;28995:71;;29083:324;29229:2;29214:18;;29243:71;29218:9;29287:6;29243:71;;;29325:72;29393:2;29382:9;29378:18;29369:6;29325:72;;29414:340;29568:2;29553:18;;29582:71;29557:9;29626:6;29582:71;;;29664:80;29740:2;29729:9;29725:18;29716:6;29664:80;;29761:324;29907:2;29892:18;;29921:71;29896:9;29965:6;29921:71;;30092:435;30266:2;30251:18;;30280:71;30255:9;30324:6;30280:71;;;30362:72;30430:2;30419:9;30415:18;30406:6;30362:72;;30534:547;30736:3;30721:19;;30751:71;30725:9;30795:6;30751:71;;;30833:72;30901:2;30890:9;30886:18;30877:6;30833:72;;;30916;30984:2;30973:9;30969:18;30960:6;30916:72;;;30999;31067:2;31056:9;31052:18;31043:6;30999:72;;31088:659;31318:3;31303:19;;31333:71;31307:9;31377:6;31333:71;;;31415:72;31483:2;31472:9;31468:18;31459:6;31415:72;;;31498;31566:2;31555:9;31551:18;31542:6;31498:72;;;31581;31649:2;31638:9;31634:18;31625:6;31581:72;;;31664:73;31732:3;31721:9;31717:19;31708:6;31664:73;;;31289:458;;;;;;;;;31754:256;31816:2;31810:9;31842:17;;;31917:18;31902:34;;31938:22;;;31899:62;31896:2;;;31974:1;31971;31964:12;31896:2;31990;31983:22;31794:216;;-1:-1;31794:216;32017:304;;32176:18;32168:6;32165:30;32162:2;;;32208:1;32205;32198:12;32162:2;-1:-1;32243:4;32231:17;;;32296:15;;32099:222;32639:151;32763:4;32754:14;;32711:79;32797:137;32900:12;;32871:63;33314:178;33432:19;;;33481:4;33472:14;;33425:67;33825:91;;33887:24;33905:5;33887:24;;33923:85;33989:13;33982:21;;33965:43;34015:121;-1:-1;;;;;34077:54;;34060:76;34222:129;;34309:37;34340:5;34358:147;;34450:50;34494:5;34450:50;;35546:116;;35633:24;35651:5;35633:24;;35913:268;35978:1;35985:101;35999:6;35996:1;35993:13;35985:101;;;36066:11;;;36060:18;36047:11;;;36040:39;36021:2;36014:10;35985:101;;;36101:6;36098:1;36095:13;36092:2;;;-1:-1;;36166:1;36148:16;;36141:27;35962:219;36189:97;36277:2;36257:14;-1:-1;;36253:28;;36237:49;36294:117;36363:24;36381:5;36363:24;;;36356:5;36353:35;36343:2;;36402:1;36399;36392:12;36418:111;36484:21;36499:5;36484:21;;36536:117;36605:24;36623:5;36605:24;
Swarm Source
bzzr://150eb5351e649782ad6b672327c0a6a52b450ffefab6188e5b408367acfdfc84
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.