Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
IdleTokenGovernance
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-05-13 */ // File: @openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @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; } } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.0; /** * @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); } // File: @openzeppelin/contracts-ethereum-package/contracts/utils/Address.sol pragma solidity ^0.5.5; /** * @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"); } } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol pragma solidity ^0.5.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for 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"); } } } // File: @openzeppelin/upgrades/contracts/Initializable.sol pragma solidity >=0.4.24 <0.7.0; /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; assembly { cs := extcodesize(self) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol pragma solidity ^0.5.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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 is Initializable { // 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; } } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol pragma solidity ^0.5.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20Mintable}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Initializable, Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal { require(account != address(0), "ERC20: mint to the zero address"); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal { require(account != address(0), "ERC20: burn from the zero address"); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Destroys `amount` tokens from `account`.`amount` is then deducted * from the caller's allowance. * * See {_burn} and {_approve}. */ function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance")); } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol pragma solidity ^0.5.0; /** * @dev Optional functions from the ERC20 standard. */ contract ERC20Detailed is Initializable, IERC20 { string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of * these values are immutable: they can only be set once during * construction. */ function initialize(string memory name, string memory symbol, uint8 decimals) public initializer { _name = name; _symbol = symbol; _decimals = decimals; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol pragma solidity ^0.5.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. */ contract ReentrancyGuard is Initializable { // counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; function initialize() public initializer { // The counter starts at one to prevent changing it from zero to a non-zero // value, which is a more expensive operation. _guardCounter = 1; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { _guardCounter += 1; uint256 localCounter = _guardCounter; _; require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call"); } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/ownership/Ownable.sol pragma solidity ^0.5.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be aplied to your functions to restrict their use to * the owner. */ contract Ownable is Initializable, Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function initialize(address sender) public initializer { _owner = sender; emit OwnershipTransferred(address(0), _owner); } /** * @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; } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/access/Roles.sol pragma solidity ^0.5.0; /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev Give an account access to this role. */ function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } /** * @dev Remove an account's access to this role. */ function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } /** * @dev Check if an account has this role. * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } } // File: @openzeppelin/contracts-ethereum-package/contracts/access/roles/PauserRole.sol pragma solidity ^0.5.0; contract PauserRole is Initializable, Context { using Roles for Roles.Role; event PauserAdded(address indexed account); event PauserRemoved(address indexed account); Roles.Role private _pausers; function initialize(address sender) public initializer { if (!isPauser(sender)) { _addPauser(sender); } } modifier onlyPauser() { require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role"); _; } function isPauser(address account) public view returns (bool) { return _pausers.has(account); } function addPauser(address account) public onlyPauser { _addPauser(account); } function renouncePauser() public { _removePauser(_msgSender()); } function _addPauser(address account) internal { _pausers.add(account); emit PauserAdded(account); } function _removePauser(address account) internal { _pausers.remove(account); emit PauserRemoved(account); } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/lifecycle/Pausable.sol pragma solidity ^0.5.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ contract Pausable is Initializable, Context, PauserRole { /** * @dev Emitted when the pause is triggered by a pauser (`account`). */ event Paused(address account); /** * @dev Emitted when the pause is lifted by a pauser (`account`). */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. Assigns the Pauser role * to the deployer. */ function initialize(address sender) public initializer { PauserRole.initialize(sender); _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!_paused, "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(_paused, "Pausable: not paused"); _; } /** * @dev Called by a pauser to pause, triggers stopped state. */ function pause() public onlyPauser whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Called by a pauser to unpause, returns to normal state. */ function unpause() public onlyPauser whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[50] private ______gap; } // File: contracts/interfaces/iERC20Fulcrum.sol pragma solidity 0.5.16; interface iERC20Fulcrum { function mint( address receiver, uint256 depositAmount) external returns (uint256 mintAmount); function burn( address receiver, uint256 burnAmount) external returns (uint256 loanAmountPaid); function tokenPrice() external view returns (uint256 price); function supplyInterestRate() external view returns (uint256); function rateMultiplier() external view returns (uint256); function baseRate() external view returns (uint256); function borrowInterestRate() external view returns (uint256); function avgBorrowInterestRate() external view returns (uint256); function protocolInterestRate() external view returns (uint256); function spreadMultiplier() external view returns (uint256); function totalAssetBorrow() external view returns (uint256); function totalAssetSupply() external view returns (uint256); function nextSupplyInterestRate(uint256) external view returns (uint256); function nextBorrowInterestRate(uint256) external view returns (uint256); function nextLoanInterestRate(uint256) external view returns (uint256); function totalSupplyInterestRate(uint256) external view returns (uint256); function claimLoanToken() external returns (uint256 claimedAmount); function dsr() external view returns (uint256); function chaiPrice() external view returns (uint256); } // File: contracts/interfaces/ILendingProtocol.sol pragma solidity 0.5.16; interface ILendingProtocol { function mint() external returns (uint256); function redeem(address account) external returns (uint256); function nextSupplyRate(uint256 amount) external view returns (uint256); function nextSupplyRateWithParams(uint256[] calldata params) external view returns (uint256); function getAPR() external view returns (uint256); function getPriceInToken() external view returns (uint256); function token() external view returns (address); function underlying() external view returns (address); function availableLiquidity() external view returns (uint256); } // File: contracts/interfaces/IGovToken.sol pragma solidity 0.5.16; interface IGovToken { function redeemGovTokens() external; } // File: contracts/interfaces/IIdleTokenV3_1.sol /** * @title: Idle Token interface * @author: Idle Labs Inc., idle.finance */ pragma solidity 0.5.16; interface IIdleTokenV3_1 { // view /** * IdleToken price calculation, in underlying * * @return : price in underlying token */ function tokenPrice() external view returns (uint256 price); /** * @return : underlying token address */ function token() external view returns (address); /** * Get APR of every ILendingProtocol * * @return addresses: array of token addresses * @return aprs: array of aprs (ordered in respect to the `addresses` array) */ function getAPRs() external view returns (address[] memory addresses, uint256[] memory aprs); // external // We should save the amount one has deposited to calc interests /** * Used to mint IdleTokens, given an underlying amount (eg. DAI). * This method triggers a rebalance of the pools if needed * NOTE: User should 'approve' _amount of tokens before calling mintIdleToken * NOTE 2: this method can be paused * * @param _amount : amount of underlying token to be lended * @param _skipRebalance : flag for skipping rebalance for lower gas price * @param _referral : referral address * @return mintedTokens : amount of IdleTokens minted */ function mintIdleToken(uint256 _amount, bool _skipRebalance, address _referral) external returns (uint256 mintedTokens); /** * Here we calc the pool share one can withdraw given the amount of IdleToken they want to burn * This method triggers a rebalance of the pools if needed * NOTE: If the contract is paused or iToken price has decreased one can still redeem but no rebalance happens. * NOTE 2: If iToken price has decresed one should not redeem (but can do it) otherwise he would capitalize the loss. * Ideally one should wait until the black swan event is terminated * * @param _amount : amount of IdleTokens to be burned * @return redeemedTokens : amount of underlying tokens redeemed */ function redeemIdleToken(uint256 _amount) external returns (uint256 redeemedTokens); /** * Here we calc the pool share one can withdraw given the amount of IdleToken they want to burn * and send interest-bearing tokens (eg. cDAI/iDAI) directly to the user. * Underlying (eg. DAI) is not redeemed here. * * @param _amount : amount of IdleTokens to be burned */ function redeemInterestBearingTokens(uint256 _amount) external; /** * @return : whether has rebalanced or not */ function rebalance() external returns (bool); } // File: contracts/interfaces/IERC3156FlashBorrower.sol pragma solidity 0.5.16; interface IERC3156FlashBorrower { /** * @dev Receive a flash loan. * @param initiator The initiator of the loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @param fee The additional amount of tokens to repay. * @param data Arbitrary data structure, intended to contain user-defined parameters. * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" */ function onFlashLoan( address initiator, address token, uint256 amount, uint256 fee, bytes calldata data ) external returns (bytes32); } // File: contracts/interfaces/IAaveIncentivesController.sol // SPDX-License-Identifier: agpl-3.0 pragma solidity 0.5.16; interface IAaveIncentivesController { /** * @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards * @param amount Amount of rewards to claim * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewards( address[] calldata assets, uint256 amount, address to ) external returns (uint256); /** * @dev returns the unclaimed rewards of the user * @param user the address of the user * @return the unclaimed user rewards */ function getUserUnclaimedRewards(address user) external view returns (uint256); } // File: contracts/interfaces/Comptroller.sol pragma solidity 0.5.16; interface Comptroller { function claimComp(address) external; function compSpeeds(address _cToken) external view returns (uint256); function claimComp(address[] calldata holders, address[] calldata cTokens, bool borrowers, bool suppliers) external; } // File: contracts/interfaces/CERC20.sol pragma solidity 0.5.16; interface CERC20 { function mint(uint256 mintAmount) external returns (uint256); function comptroller() external view returns (address); function redeem(uint256 redeemTokens) external returns (uint256); function exchangeRateStored() external view returns (uint256); function supplyRatePerBlock() external view returns (uint256); function borrowRatePerBlock() external view returns (uint256); function totalReserves() external view returns (uint256); function getCash() external view returns (uint256); function totalBorrows() external view returns (uint256); function reserveFactorMantissa() external view returns (uint256); function interestRateModel() external view returns (address); } // File: contracts/interfaces/AToken.sol pragma solidity 0.5.16; interface AToken { function getIncentivesController() external returns (address); function redeem(uint256 amount) external; function burn(address user, address receiverOfUnderlying, uint256 amount, uint256 index) external; } // File: contracts/interfaces/IdleController.sol pragma solidity 0.5.16; interface IdleController { function idleSpeeds(address _idleToken) external view returns (uint256); function claimIdle(address[] calldata holders, address[] calldata idleTokens) external; } // File: contracts/interfaces/PriceOracle.sol pragma solidity 0.5.16; interface PriceOracle { function getUnderlyingPrice(address _idleToken) external view returns (uint256); function getPriceUSD(address _asset) external view returns (uint256 price); function getPriceETH(address _asset) external view returns (uint256 price); function getPriceToken(address _asset, address _token) external view returns (uint256 price); function WETH() external view returns (address); function getCompApr(address cToken, address token) external view returns (uint256); function getStkAaveApr(address aToken, address token) external view returns (uint256); } // File: contracts/interfaces/IIdleTokenHelper.sol pragma solidity 0.5.16; interface IIdleTokenHelper { function setIdleTokens(address[] calldata _newIdleTokens) external; function getAPR(address _idleToken, address _cToken, address _aToken) external view returns (uint256 avgApr); function getCurrentAllocations(address _idleToken) external view returns (uint256[] memory amounts, uint256 total); function getAPRs(address _idleToken) external view returns (address[] memory addresses, uint256[] memory aprs); function sellGovTokens(address _idleToken, uint256[] calldata _minTokenOut) external; function emergencyWithdrawToken(address _token, address _to) external; } // File: contracts/interfaces/GasToken.sol pragma solidity 0.5.16; interface GasToken { function freeUpTo(uint256 value) external returns (uint256 freed); function freeFromUpTo(address from, uint256 value) external returns (uint256 freed); function balanceOf(address from) external returns (uint256 balance); } // File: contracts/GST2ConsumerV2.sol pragma solidity 0.5.16; contract GST2ConsumerV2 is Initializable { GasToken public gst2; // Kept for reference // // function initialize() initializer public { // gst2 = GasToken(0x0000000000b3F879cb30FE243b4Dfee438691c04); // } // // modifier gasDiscountFrom(address from) { // uint256 initialGasLeft = gasleft(); // _; // _makeGasDiscount(initialGasLeft - gasleft(), from); // } // // function _makeGasDiscount(uint256 gasSpent, address from) internal { // // For more info https://gastoken.io/ // // 14154 -> FREE_BASE -> base cost of freeing // // 41130 -> 2 * REIMBURSE - FREE_TOKEN -> 2 * 24000 - 6870 // uint256 tokens = (gasSpent + 14154) / 41130; // uint256 safeNumTokens; // uint256 gas = gasleft(); // // // For more info https://github.com/projectchicago/gastoken/blob/master/contract/gst2_free_example.sol // if (gas >= 27710) { // safeNumTokens = (gas - 27710) / 7020; // } // // if (tokens > safeNumTokens) { // tokens = safeNumTokens; // } // // if (tokens > 0) { // gst2.freeFromUpTo(from, tokens); // } // } } // File: contracts/IdleTokenGovernance.sol /** * @title: Idle Token Governance main contract * @summary: ERC20 that holds pooled user funds together * Each token rapresent a share of the underlying pools * and with each token user have the right to redeem a portion of these pools * @author: Idle Labs Inc., idle.finance */ pragma solidity 0.5.16; contract IdleTokenGovernance is Initializable, ERC20, ERC20Detailed, ReentrancyGuard, Ownable, Pausable, IIdleTokenV3_1, GST2ConsumerV2 { using SafeERC20 for IERC20; using SafeMath for uint256; uint256 private constant ONE_18 = 10**18; // State variables // eg. DAI address address public token; // eg. iDAI address address private iToken; // eg. cDAI address address private cToken; // Idle rebalancer current implementation address address public rebalancer; // Address collecting underlying fees address public feeAddress; // Last iToken price, used to pause contract in case of a black swan event uint256 public lastITokenPrice; // eg. 18 for DAI uint256 private tokenDecimals; // Max unlent assets percentage for gas friendly swaps uint256 public maxUnlentPerc; // 100000 == 100% -> 1000 == 1% // Current fee on interest gained uint256 public fee; // eg. [cTokenAddress, iTokenAddress, ...] address[] public allAvailableTokens; // eg. [COMPAddress, CRVAddress, ...] address[] public govTokens; // last fully applied allocations (ie when all liquidity has been correctly placed) // eg. [5000, 0, 5000, 0] for 50% in compound, 0% fulcrum, 50% aave, 0 dydx. same order of allAvailableTokens uint256[] public lastAllocations; // Map that saves avg idleToken price paid for each user, used to calculate earnings mapping(address => uint256) public userAvgPrices; // eg. cTokenAddress => IdleCompoundAddress mapping(address => address) public protocolWrappers; // array with last balance recorded for each gov tokens mapping (address => uint256) public govTokensLastBalances; // govToken -> user_address -> user_index eg. usersGovTokensIndexes[govTokens[0]][msg.sender] = 1111123; mapping (address => mapping (address => uint256)) public usersGovTokensIndexes; // global indices for each gov tokens used as a reference to calculate a fair share for each user mapping (address => uint256) public govTokensIndexes; // Map that saves amount with no fee for each user mapping(address => uint256) private userNoFeeQty; // variable used for avoid the call of mint and redeem in the same tx bytes32 private _minterBlock; // Events event Rebalance(address _rebalancer, uint256 _amount); event Referral(uint256 _amount, address _ref); // ########## IdleToken V4_1 updates // Idle governance token address public constant IDLE = address(0x875773784Af8135eA0ef43b5a374AaD105c5D39e); // Compound governance token address public constant COMP = address(0xc00e94Cb662C3520282E6f5717214004A7f26888); uint256 private constant FULL_ALLOC = 100000; // Idle distribution controller address public constant idleController = address(0x275DA8e61ea8E02d51EDd8d0DC5c0E62b4CDB0BE); // oracle used for calculating the avgAPR with gov tokens address public oracle; // eg cDAI -> COMP mapping(address => address) private protocolTokenToGov; // Whether openRebalance is enabled or not bool public isRiskAdjusted; // last allocations submitted by rebalancer uint256[] private lastRebalancerAllocations; // ########## IdleToken V5 updates // Fee for flash loan uint256 public flashLoanFee; // IdleToken helper address address public tokenHelper; /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param amount The amount flash borrowed * @param premium The flash loan fee **/ event FlashLoan( address indexed target, address indexed initiator, uint256 amount, uint256 premium ); // Addresses for stkAAVE distribution from Aave address public constant stkAAVE = address(0x4da27a545c0c5B758a6BA100e3a049001de870f5); address private aToken; // ########## End IdleToken V5 updates // ERROR MESSAGES: // 0 = is 0 // 1 = already initialized // 2 = length is different // 3 = Not greater then // 4 = lt // 5 = too high // 6 = not authorized // 7 = not equal // 8 = error on flash loan execution // 9 = Reentrancy function _init(address _tokenHelper, address _aToken, address _newOracle) external { require(tokenHelper == address(0), '1'); tokenHelper = _tokenHelper; flashLoanFee = 80; // 0.08% aToken = _aToken; oracle = _newOracle; } // onlyOwner /** * It allows owner to modify allAvailableTokens array in case of emergency * ie if a bug on a interest bearing token is discovered and reset protocolWrappers * associated with those tokens. * * @param protocolTokens : array of protocolTokens addresses (eg [cDAI, iDAI, ...]) * @param wrappers : array of wrapper addresses (eg [IdleCompound, IdleFulcrum, ...]) * @param _newGovTokens : array of governance token addresses * @param _newGovTokensEqualLen : array of governance token addresses for each * protocolToken (addr0 should be used for protocols with no govToken) */ function setAllAvailableTokensAndWrappers( address[] calldata protocolTokens, address[] calldata wrappers, address[] calldata _newGovTokens, address[] calldata _newGovTokensEqualLen ) external onlyOwner { require(protocolTokens.length == wrappers.length, "2"); require(_newGovTokensEqualLen.length >= protocolTokens.length, '3'); govTokens = _newGovTokens; address newGov; address protToken; for (uint256 i = 0; i < protocolTokens.length; i++) { protToken = protocolTokens[i]; require(protToken != address(0) && wrappers[i] != address(0), "0"); protocolWrappers[protToken] = wrappers[i]; // set protocol token to gov token mapping newGov = _newGovTokensEqualLen[i]; if (newGov != IDLE) { protocolTokenToGov[protToken] = newGov; } } allAvailableTokens = protocolTokens; } /** * It allows owner to set the flash loan fee * * @param _flashFee : new flash loan fee. Max is FULL_ALLOC */ function setFlashLoanFee(uint256 _flashFee) external onlyOwner { require((flashLoanFee = _flashFee) < FULL_ALLOC, "4"); } /** * It allows owner to set the cToken address * * @param _cToken : new cToken address */ function setCToken(address _cToken) external onlyOwner { require((cToken = _cToken) != address(0), "0"); } /** * It allows owner to set the aToken address * * @param _aToken : new aToken address */ function setAToken(address _aToken) external onlyOwner { require((aToken = _aToken) != address(0), "0"); } /** * It allows owner to set the IdleRebalancerV3_1 address * * @param _rebalancer : new IdleRebalancerV3_1 address */ function setRebalancer(address _rebalancer) external onlyOwner { require((rebalancer = _rebalancer) != address(0), "0"); } /** * It allows owner to set the fee (1000 == 10% of gained interest) * * @param _fee : fee amount where 100000 is 100%, max settable is 10% */ function setFee(uint256 _fee) external onlyOwner { // 100000 == 100% -> 10000 == 10% require((fee = _fee) <= FULL_ALLOC / 10, "5"); } /** * It allows owner to set the fee address * * @param _feeAddress : fee address */ function setFeeAddress(address _feeAddress) external onlyOwner { require((feeAddress = _feeAddress) != address(0), "0"); } /** * It allows owner to set the oracle address for getting avgAPR * * @param _oracle : new oracle address */ function setOracleAddress(address _oracle) external onlyOwner { require((oracle = _oracle) != address(0), "0"); } /** * It allows owner to set the max unlent asset percentage (1000 == 1% of unlent asset max) * * @param _perc : max unlent perc where 100000 is 100% */ function setMaxUnlentPerc(uint256 _perc) external onlyOwner { require((maxUnlentPerc = _perc) <= 100000, "5"); } /** * Used by Rebalancer to set the new allocations * * @param _allocations : array with allocations in percentages (100% => 100000) */ function setAllocations(uint256[] calldata _allocations) external { require(msg.sender == rebalancer || msg.sender == owner(), "6"); _setAllocations(_allocations); } /** * Used by Rebalancer or in openRebalance to set the new allocations * * @param _allocations : array with allocations in percentages (100% => 100000) */ function _setAllocations(uint256[] memory _allocations) internal { require(_allocations.length == allAvailableTokens.length, "2"); uint256 total; for (uint256 i = 0; i < _allocations.length; i++) { total = total.add(_allocations[i]); } lastRebalancerAllocations = _allocations; require(total == FULL_ALLOC, "7"); } // view /** * Get latest allocations submitted by rebalancer * * @return : array of allocations ordered as allAvailableTokens */ function getAllocations() external view returns (uint256[] memory) { return lastRebalancerAllocations; } /** * Get currently used gov tokens * * @return : array of govTokens supported */ function getGovTokens() external view returns (address[] memory) { return govTokens; } /** * Get currently used protocol tokens (cDAI, aDAI, ...) * * @return : array of protocol tokens supported */ function getAllAvailableTokens() external view returns (address[] memory) { return allAvailableTokens; } /** * Get gov token associated to a protocol token eg protocolTokenToGov[cDAI] = COMP * * @return : address of the gov token */ function getProtocolTokenToGov(address _protocolToken) external view returns (address) { return protocolTokenToGov[_protocolToken]; } /** * IdleToken price for a user considering fees, in underlying * this is useful when you need to redeem exactly X underlying * * @return : price in underlying token counting fees for a specific user */ function tokenPriceWithFee(address user) external view returns (uint256 priceWFee) { uint256 userAvgPrice = userAvgPrices[user]; priceWFee = _tokenPrice(); if (userAvgPrice != 0 && priceWFee > userAvgPrice) { priceWFee = priceWFee.mul(FULL_ALLOC).sub(fee.mul(priceWFee.sub(userAvgPrice))).div(FULL_ALLOC); } } /** * IdleToken price calculation, in underlying * * @return : price in underlying token */ function tokenPrice() external view returns (uint256) { return _tokenPrice(); } /** * Get APR of every ILendingProtocol * * @return addresses: array of token addresses * @return aprs: array of aprs (ordered in respect to the `addresses` array) */ function getAPRs() external view returns (address[] memory, uint256[] memory) { return IIdleTokenHelper(tokenHelper).getAPRs(address(this)); } /** * Get current avg APR of this IdleToken * * @return avgApr: current weighted avg apr */ function getAvgAPR() public view returns (uint256) { return IIdleTokenHelper(tokenHelper).getAPR(address(this), cToken, aToken); } /** * ERC20 modified transferFrom that also update the avgPrice paid for the recipient and * updates user gov idx * * @param sender : sender account * @param recipient : recipient account * @param amount : value to transfer * @return : flag whether transfer was successful or not */ function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _updateUserGovIdxTransfer(sender, recipient, amount); _transfer(sender, recipient, amount); _approve(sender, msg.sender, allowance(sender, msg.sender).sub(amount, "ERC20: transfer amount exceeds allowance")); _updateUserFeeInfo(recipient, amount, userAvgPrices[sender]); return true; } /** * ERC20 modified transfer that also update the avgPrice paid for the recipient and * updates user gov idx * * @param recipient : recipient account * @param amount : value to transfer * @return : flag whether transfer was successful or not */ function transfer(address recipient, uint256 amount) public returns (bool) { _updateUserGovIdxTransfer(msg.sender, recipient, amount); _transfer(msg.sender, recipient, amount); _updateUserFeeInfo(recipient, amount, userAvgPrices[msg.sender]); return true; } /** * Helper method for transfer and transferFrom, updates recipient gov indexes * * @param _from : sender account * @param _to : recipient account * @param amount : value to transfer */ function _updateUserGovIdxTransfer(address _from, address _to, uint256 amount) internal { address govToken; uint256 govTokenIdx; uint256 sharePerTokenFrom; uint256 shareTo; uint256 balanceTo = balanceOf(_to); for (uint256 i = 0; i < govTokens.length; i++) { govToken = govTokens[i]; if (balanceTo == 0) { usersGovTokensIndexes[govToken][_to] = usersGovTokensIndexes[govToken][_from]; } else { govTokenIdx = govTokensIndexes[govToken]; // calc 1 idleToken value in gov shares for user `_from` sharePerTokenFrom = govTokenIdx.sub(usersGovTokensIndexes[govToken][_from]); // calc current gov shares (before transfer) for user `_to` shareTo = balanceTo.mul(govTokenIdx.sub(usersGovTokensIndexes[govToken][_to])).div(ONE_18); // user `_to` should have -> shareTo + (sharePerTokenFrom * amount / 1e18) = (balanceTo + amount) * (govTokenIdx - userIdx) / 1e18 // so userIdx = govTokenIdx - ((shareTo * 1e18 + (sharePerTokenFrom * amount)) / (balanceTo + amount)) usersGovTokensIndexes[govToken][_to] = govTokenIdx.sub( shareTo.mul(ONE_18).add(sharePerTokenFrom.mul(amount)).div( balanceTo.add(amount) ) ); } } } /** * Get how many gov tokens a user is entitled to (this may not include eventual undistributed tokens) * * @param _usr : user address * @return : array of amounts for each gov token */ function getGovTokensAmounts(address _usr) external view returns (uint256[] memory _amounts) { address govToken; uint256 usrBal = balanceOf(_usr); _amounts = new uint256[](govTokens.length); for (uint256 i = 0; i < _amounts.length; i++) { govToken = govTokens[i]; _amounts[i] = usrBal.mul(govTokensIndexes[govToken].sub(usersGovTokensIndexes[govToken][_usr])).div(ONE_18); } } // external /** * Used to mint IdleTokens, given an underlying amount (eg. DAI). * This method triggers a rebalance of the pools if _skipRebalance is set to false * NOTE: User should 'approve' _amount of tokens before calling mintIdleToken * NOTE 2: this method can be paused * * @param _amount : amount of underlying token to be lended * @param : not used anymore * @param _referral : referral address * @return mintedTokens : amount of IdleTokens minted */ function mintIdleToken(uint256 _amount, bool, address _referral) external nonReentrant whenNotPaused returns (uint256 mintedTokens) { _minterBlock = keccak256(abi.encodePacked(tx.origin, block.number)); _redeemGovTokens(msg.sender); // Get current IdleToken price uint256 idlePrice = _tokenPrice(); // transfer tokens to this contract IERC20(token).safeTransferFrom(msg.sender, address(this), _amount); mintedTokens = _amount.mul(ONE_18).div(idlePrice); _mint(msg.sender, mintedTokens); // Update avg price and user idx for each gov tokens _updateUserInfo(msg.sender, mintedTokens); _updateUserFeeInfo(msg.sender, mintedTokens, idlePrice); if (_referral != address(0)) { emit Referral(_amount, _referral); } } /** * Helper method for mintIdleToken, updates minter gov indexes and avg price * * @param _to : minter account * @param _mintedTokens : number of newly minted tokens */ function _updateUserInfo(address _to, uint256 _mintedTokens) internal { address govToken; uint256 usrBal = balanceOf(_to); uint256 _usrIdx; for (uint256 i = 0; i < govTokens.length; i++) { govToken = govTokens[i]; _usrIdx = usersGovTokensIndexes[govToken][_to]; // calculate user idx usersGovTokensIndexes[govToken][_to] = _usrIdx.add( _mintedTokens.mul(govTokensIndexes[govToken].sub(_usrIdx)).div(usrBal) ); } } /** * Here we calc the pool share one can withdraw given the amount of IdleToken they want to burn * * @param _amount : amount of IdleTokens to be burned * @return redeemedTokens : amount of underlying tokens redeemed */ function redeemIdleToken(uint256 _amount) external returns (uint256) { return _redeemIdleToken(_amount, new bool[](govTokens.length)); } /** * Here we calc the pool share one can withdraw given the amount of IdleToken they want to burn * WARNING: if elements in the `_skipGovTokenRedeem` are set to `true` then the rewards will be GIFTED to the pool * * @param _amount : amount of IdleTokens to be burned * @param _skipGovTokenRedeem : array of flags whether to redeem or not specific gov tokens * @return redeemedTokens : amount of underlying tokens redeemed */ function redeemIdleTokenSkipGov(uint256 _amount, bool[] calldata _skipGovTokenRedeem) external returns (uint256) { return _redeemIdleToken(_amount, _skipGovTokenRedeem); } /** * Here we calc the pool share one can withdraw given the amount of IdleToken they want to burn * * @param _amount : amount of IdleTokens to be burned * @param _skipGovTokenRedeem : array of flag for redeeming or not gov tokens. Funds will be gifted to the pool * @return redeemedTokens : amount of underlying tokens redeemed */ function _redeemIdleToken(uint256 _amount, bool[] memory _skipGovTokenRedeem) internal nonReentrant returns (uint256 redeemedTokens) { _checkMintRedeemSameTx(); _redeemGovTokensInternal(msg.sender, _skipGovTokenRedeem); if (_amount != 0) { uint256 price = _tokenPrice(); uint256 valueToRedeem = _amount.mul(price).div(ONE_18); uint256 balanceUnderlying = _contractBalanceOf(token); if (valueToRedeem > balanceUnderlying) { redeemedTokens = _redeemHelper(_amount, balanceUnderlying); } else { redeemedTokens = valueToRedeem; } // get eventual performance fee redeemedTokens = _getFee(_amount, redeemedTokens, price); // burn idleTokens _burn(msg.sender, _amount); // send underlying minus fee to msg.sender _transferTokens(token, msg.sender, redeemedTokens); } } function _redeemHelper(uint256 _amount, uint256 _balanceUnderlying) private returns (uint256 redeemedTokens) { address currToken; uint256 idleSupply = totalSupply(); address[] memory _allAvailableTokens = allAvailableTokens; for (uint256 i = 0; i < _allAvailableTokens.length; i++) { currToken = _allAvailableTokens[i]; redeemedTokens = redeemedTokens.add( _redeemProtocolTokens( currToken, // _amount * protocolPoolBalance / idleSupply _amount.mul(_contractBalanceOf(currToken)).div(idleSupply) // amount to redeem ) ); } // and get a portion of the eventual unlent balance redeemedTokens = redeemedTokens.add(_amount.mul(_balanceUnderlying).div(idleSupply)); } /** * Here we calc the pool share one can withdraw given the amount of IdleToken they want to burn * and send interest-bearing tokens (eg. cDAI/iDAI) directly to the user. * Underlying (eg. DAI) is not redeemed here. * * @param _amount : amount of IdleTokens to be burned */ function redeemInterestBearingTokens(uint256 _amount) external nonReentrant whenPaused { _checkMintRedeemSameTx(); _redeemGovTokens(msg.sender); for (uint256 i = 0; i < allAvailableTokens.length; i++) { _transferTokens(allAvailableTokens[i], msg.sender, _amount.mul(_contractBalanceOf(allAvailableTokens[i])).div(totalSupply())); } // Get a portion of the eventual unlent balance _transferTokens(token, msg.sender, _amount.mul(_contractBalanceOf(token)).div(totalSupply())); _burn(msg.sender, _amount); } /** * Dynamic allocate all the pool across different lending protocols if needed, * rebalance without params * * NOTE: this method can be paused * * @return : whether has rebalanced or not */ function rebalance() external returns (bool) { return _rebalance(); } /** * @dev The fee to be charged for a given loan. * @param _token The loan currency. * @param _amount The amount of tokens lent. * @return The amount of `token` to be charged for the loan, on top of the returned principal. */ function flashFee(address _token, uint256 _amount) public view returns (uint256) { require(_token == token, '7'); return _amount.mul(flashLoanFee).div(FULL_ALLOC); } /** * @dev The amount of currency available to be lent. * @param _token The loan currency. * @return The amount of `token` that can be borrowed. */ function maxFlashLoan(address _token) external view returns (uint256) { if (_token == token) { return _tokenPrice().mul(totalSupply()).div(ONE_18); } } /** * Allow any users to borrow funds inside a tx if they return the same amount + `flashLoanFee` * * @param _receiver : flash loan receiver, should have the IERC3156FlashBorrower interface * @param _token : used to check that the requested token is the correct one * @param _amount : amount of `token` to borrow * @param _params : params that should be passed to the _receiverAddress in the `executeOperation` call */ function flashLoan( IERC3156FlashBorrower _receiver, address _token, uint256 _amount, bytes calldata _params ) external whenNotPaused nonReentrant returns (bool) { address receiverAddr = address(_receiver); require(_token == token, "7"); require(receiverAddr != address(0) && _amount > 0, "0"); // get current underlying unlent balance uint256 balance = _contractBalanceOf(token); if (_amount > balance) { // Unlent is not enough, some funds needs to be redeemed from underlying protocols uint256 toRedeem = _amount.sub(balance); uint256 _toRedeemAux; address currToken; uint256 currBalanceUnderlying; uint256 availableLiquidity; uint256 redeemed; uint256 protocolTokenPrice; ILendingProtocol protocol; bool isEnough; bool haveWeInvestedEnough; // We cycle through interest bearing tokens currently in use (eg [cDAI, aDAI]) // (ie we cycle each lending protocol where we have some funds currently deposited) for (uint256 i = 0; i < allAvailableTokens.length; i++) { currToken = allAvailableTokens[i]; protocol = ILendingProtocol(protocolWrappers[currToken]); protocolTokenPrice = protocol.getPriceInToken(); availableLiquidity = protocol.availableLiquidity(); currBalanceUnderlying = _contractBalanceOf(currToken).mul(protocolTokenPrice).div(ONE_18); // We need to check: // 1. if Idle has invested enough in that protocol to cover the user request haveWeInvestedEnough = currBalanceUnderlying >= toRedeem; // 2. if the current lending protocol has enough liquidity available (not borrowed) to cover the user requested amount isEnough = availableLiquidity >= toRedeem; // in order to calculate `_toRedeemAux` which is the amount of underlying (eg DAI) // that we have to redeem from that lending protocol _toRedeemAux = haveWeInvestedEnough ? // if we lent enough and that protocol has enough liquidity we redeem `toRedeem` and we are done, otherwise we redeem `availableLiquidity` (isEnough ? toRedeem : availableLiquidity) : // if we did not lent enough and that liquidity is available then we redeem all what we deposited, otherwise we redeem `availableLiquidity` (currBalanceUnderlying <= availableLiquidity ? currBalanceUnderlying : availableLiquidity); // do the actual redeem on the lending protocol redeemed = _redeemProtocolTokens( currToken, // convert amount from underlying to protocol token _toRedeemAux.mul(ONE_18).div(protocolTokenPrice) ); // tokens are now in this contract if (haveWeInvestedEnough && isEnough) { break; } toRedeem = toRedeem.sub(redeemed); } } require(_contractBalanceOf(token) >= _amount, "3"); // transfer funds _transferTokens(token, receiverAddr, _amount); // calculate fee uint256 _flashFee = flashFee(token, _amount); // call _receiver `onFlashLoan` require( _receiver.onFlashLoan(msg.sender, token, _amount, _flashFee, _params) == keccak256("ERC3156FlashBorrower.onFlashLoan"), "8" ); // transfer _amount + _flashFee from _receiver IERC20(token).safeTransferFrom(receiverAddr, address(this), _amount.add(_flashFee)); // Put underlyings in lending once again with rebalance _rebalance(); emit FlashLoan(receiverAddr, msg.sender, _amount, _flashFee); return true; } // internal /** * Get current idleToken price based on net asset value and totalSupply * * @return price: value of 1 idleToken in underlying */ function _tokenPrice() internal view returns (uint256 price) { uint256 totSupply = totalSupply(); if (totSupply == 0) { return 10**(tokenDecimals); } address currToken; uint256 totNav = _contractBalanceOf(token).mul(ONE_18); // eventual underlying unlent balance address[] memory _allAvailableTokens = allAvailableTokens; for (uint256 i = 0; i < _allAvailableTokens.length; i++) { currToken = _allAvailableTokens[i]; totNav = totNav.add( // NAV = price * poolSupply _getPriceInToken(protocolWrappers[currToken]).mul( _contractBalanceOf(currToken) ) ); } price = totNav.div(totSupply); // idleToken price in token wei } /** * Dynamic allocate all the pool across different lending protocols if needed * * NOTE: this method can be paused * * @return : whether has rebalanced or not */ function _rebalance() internal whenNotPaused returns (bool) { // check if we need to rebalance by looking at the last allocations submitted by rebalancer uint256[] memory rebalancerLastAllocations = lastRebalancerAllocations; uint256[] memory _lastAllocations = lastAllocations; uint256 lastLen = _lastAllocations.length; bool areAllocationsEqual = rebalancerLastAllocations.length == lastLen; if (areAllocationsEqual) { for (uint256 i = 0; i < lastLen || !areAllocationsEqual; i++) { if (_lastAllocations[i] != rebalancerLastAllocations[i]) { areAllocationsEqual = false; break; } } } uint256 balance = _contractBalanceOf(token); if (areAllocationsEqual && balance == 0) { return false; } uint256 maxUnlentBalance = _getCurrentPoolValue().mul(maxUnlentPerc).div(FULL_ALLOC); if (areAllocationsEqual) { if (balance > maxUnlentBalance) { // mint the difference _mintWithAmounts(rebalancerLastAllocations, balance.sub(maxUnlentBalance)); } return false; } // Instead of redeeming everything during rebalance we redeem and mint only what needs // to be reallocated // get current allocations in underlying (it does not count unlent underlying) (uint256[] memory amounts, uint256 totalInUnderlying) = _getCurrentAllocations(); // calculate the total amount in underlying that needs to be reallocated totalInUnderlying = totalInUnderlying.add(balance); if (totalInUnderlying > maxUnlentPerc) { totalInUnderlying = totalInUnderlying.sub(maxUnlentBalance); } (uint256[] memory toMintAllocations, uint256 totalToMint, bool lowLiquidity) = _redeemAllNeeded( amounts, // calculate new allocations given the total (not counting unlent balance) _amountsFromAllocations(rebalancerLastAllocations, totalInUnderlying) ); // if some protocol has liquidity that we should redeem, we do not update // lastAllocations to force another rebalance next time if (!lowLiquidity) { // Update lastAllocations with rebalancerLastAllocations delete lastAllocations; lastAllocations = rebalancerLastAllocations; } uint256 totalRedeemd = _contractBalanceOf(token); if (totalRedeemd <= maxUnlentBalance) { return false; } // Do not mint directly using toMintAllocations check with totalRedeemd uint256[] memory tempAllocations = new uint256[](toMintAllocations.length); for (uint256 i = 0; i < toMintAllocations.length; i++) { // Calc what would have been the correct allocations percentage if all was available tempAllocations[i] = toMintAllocations[i].mul(FULL_ALLOC).div(totalToMint); } // partial amounts _mintWithAmounts(tempAllocations, totalRedeemd.sub(maxUnlentBalance)); emit Rebalance(msg.sender, totalInUnderlying.add(maxUnlentBalance)); return true; // hasRebalanced } /** * Redeem unclaimed governance tokens and update governance global index and user index if needed * if called during redeem it will send all gov tokens accrued by a user to the user * * @param _to : user address */ function _redeemGovTokens(address _to) internal { _redeemGovTokensInternal(_to, new bool[](govTokens.length)); } /** * Redeem unclaimed governance tokens and update governance global index and user index if needed * if called during redeem it will send all gov tokens accrued by a user to the user * * @param _to : user address * @param _skipGovTokenRedeem : array of flag for redeeming or not gov tokens */ function _redeemGovTokensInternal(address _to, bool[] memory _skipGovTokenRedeem) internal { address[] memory _govTokens = govTokens; if (_govTokens.length == 0) { return; } uint256 supply = totalSupply(); uint256 usrBal = balanceOf(_to); address govToken; if (supply > 0) { for (uint256 i = 0; i < _govTokens.length; i++) { govToken = _govTokens[i]; _redeemGovTokensFromProtocol(govToken); // get current gov token balance uint256 govBal = _contractBalanceOf(govToken); if (govBal > 0) { // update global index with ratio of govTokens per idleToken govTokensIndexes[govToken] = govTokensIndexes[govToken].add( // check how much gov tokens for each idleToken we gained since last update govBal.sub(govTokensLastBalances[govToken]).mul(ONE_18).div(supply) ); // update global var with current govToken balance govTokensLastBalances[govToken] = govBal; } if (usrBal > 0) { uint256 usrIndex = usersGovTokensIndexes[govToken][_to]; // check if user has accrued something uint256 delta = govTokensIndexes[govToken].sub(usrIndex); if (delta != 0) { uint256 share = usrBal.mul(delta).div(ONE_18); uint256 bal = _contractBalanceOf(govToken); // To avoid rounding issue if (share > bal) { share = bal; } if (_skipGovTokenRedeem[i]) { // -> gift govTokens[i] accrued to the pool // update global index with ratio of govTokens per idleToken govTokensIndexes[govToken] = govTokensIndexes[govToken].add( // check how much gov tokens for each idleToken we gained since last update share.mul(ONE_18).div(supply.sub(usrBal)) ); } else { uint256 feeDue; // no fee for IDLE governance token if (feeAddress != address(0) && fee > 0 && govToken != IDLE) { feeDue = share.mul(fee).div(FULL_ALLOC); // Transfer gov token fee to feeAddress _transferTokens(govToken, feeAddress, feeDue); } // Transfer gov token to user _transferTokens(govToken, _to, share.sub(feeDue)); // Update last balance govTokensLastBalances[govToken] = _contractBalanceOf(govToken); } } } // save current index for this gov token usersGovTokensIndexes[govToken][_to] = govTokensIndexes[govToken]; } } } /** * Redeem a specific gov token * * @param _govToken : address of the gov token to redeem */ function _redeemGovTokensFromProtocol(address _govToken) internal { // In case new Gov tokens will be supported this should be updated if (_govToken == COMP || _govToken == IDLE || _govToken == stkAAVE) { address[] memory holders = new address[](1); holders[0] = address(this); if (_govToken == IDLE) { // For IDLE, the distribution is done only to IdleTokens, so `holders` and // `tokens` parameters are the same and equal to address(this) IdleController(idleController).claimIdle(holders, holders); return; } address[] memory tokens = new address[](1); if (_govToken == stkAAVE && aToken != address(0)) { tokens[0] = aToken; IAaveIncentivesController _ctrl = IAaveIncentivesController(AToken(tokens[0]).getIncentivesController()); _ctrl.claimRewards(tokens, _ctrl.getUserUnclaimedRewards(address(this)), address(this)); return; } if (cToken != address(0)) { tokens[0] = cToken; Comptroller(CERC20(tokens[0]).comptroller()).claimComp(holders, tokens, false, true); } } } /** * Update receiver userAvgPrice paid for each idle token, * receiver will pay fees accrued * * @param usr : user that should have balance update * @param qty : new amount deposited / transferred, in idleToken * @param price : sender userAvgPrice */ function _updateUserFeeInfo(address usr, uint256 qty, uint256 price) private { uint256 usrBal = balanceOf(usr); // ((avgPrice * oldBalance) + (senderAvgPrice * newQty)) / totBalance userAvgPrices[usr] = userAvgPrices[usr].mul(usrBal.sub(qty)).add(price.mul(qty)).div(usrBal); } /** * Calculate fee in underlyings and send them to feeAddress * * @param amount : in idleTokens * @param redeemed : in underlying * @param currPrice : current idleToken price * @return : net value in underlying */ function _getFee(uint256 amount, uint256 redeemed, uint256 currPrice) internal returns (uint256) { uint256 avgPrice = userAvgPrices[msg.sender]; if (currPrice < avgPrice) { return redeemed; } // 10**23 -> ONE_18 * FULL_ALLOC uint256 feeDue = amount.mul(currPrice.sub(avgPrice)).mul(fee).div(10**23); _transferTokens(token, feeAddress, feeDue); return redeemed.sub(feeDue); } /** * Mint specific amounts of protocols tokens * * @param allocations : array of amounts to be minted * @param total : total amount * @return : net value in underlying */ function _mintWithAmounts(uint256[] memory allocations, uint256 total) internal { // mint for each protocol and update currentTokensUsed uint256[] memory protocolAmounts = _amountsFromAllocations(allocations, total); uint256 currAmount; address protWrapper; address[] memory _tokens = allAvailableTokens; for (uint256 i = 0; i < protocolAmounts.length; i++) { currAmount = protocolAmounts[i]; if (currAmount != 0) { protWrapper = protocolWrappers[_tokens[i]]; // Transfer _amount underlying token (eg. DAI) to protWrapper _transferTokens(token, protWrapper, currAmount); ILendingProtocol(protWrapper).mint(); } } } /** * Calculate amounts from percentage allocations (100000 => 100%) * * @param allocations : array of protocol allocations in percentage * @param total : total amount * @return : array with amounts */ function _amountsFromAllocations(uint256[] memory allocations, uint256 total) internal pure returns (uint256[] memory newAmounts) { newAmounts = new uint256[](allocations.length); uint256 currBalance; uint256 allocatedBalance; for (uint256 i = 0; i < allocations.length; i++) { if (i == allocations.length - 1) { newAmounts[i] = total.sub(allocatedBalance); } else { currBalance = total.mul(allocations[i]).div(FULL_ALLOC); allocatedBalance = allocatedBalance.add(currBalance); newAmounts[i] = currBalance; } } return newAmounts; } /** * Redeem all underlying needed from each protocol * * @param amounts : array with current allocations in underlying * @param newAmounts : array with new allocations in underlying * @return toMintAllocations : array with amounts to be minted * @return totalToMint : total amount that needs to be minted */ function _redeemAllNeeded( uint256[] memory amounts, uint256[] memory newAmounts ) internal returns ( uint256[] memory toMintAllocations, uint256 totalToMint, bool lowLiquidity ) { toMintAllocations = new uint256[](amounts.length); ILendingProtocol protocol; uint256 currAmount; uint256 newAmount; address currToken; address[] memory _tokens = allAvailableTokens; // check the difference between amounts and newAmounts for (uint256 i = 0; i < amounts.length; i++) { currToken = _tokens[i]; newAmount = newAmounts[i]; currAmount = amounts[i]; protocol = ILendingProtocol(protocolWrappers[currToken]); if (currAmount > newAmount) { uint256 toRedeem = currAmount.sub(newAmount); uint256 availableLiquidity = protocol.availableLiquidity(); if (availableLiquidity < toRedeem) { lowLiquidity = true; toRedeem = availableLiquidity; } // redeem the difference _redeemProtocolTokens( currToken, // convert amount from underlying to protocol token toRedeem.mul(ONE_18).div(protocol.getPriceInToken()) ); // tokens are now in this contract } else { toMintAllocations[i] = newAmount.sub(currAmount); totalToMint = totalToMint.add(toMintAllocations[i]); } } } /** * Get the contract balance of every protocol currently used * * @return amounts : array with all amounts for each protocol in order, * eg [amountCompoundInUnderlying, amountFulcrumInUnderlying] * @return total : total AUM in underlying */ function _getCurrentAllocations() internal view returns (uint256[] memory amounts, uint256 total) { // Get balance of every protocol implemented address currentToken; address[] memory _tokens = allAvailableTokens; uint256 tokensLen = _tokens.length; amounts = new uint256[](tokensLen); for (uint256 i = 0; i < tokensLen; i++) { currentToken = _tokens[i]; amounts[i] = _getPriceInToken(protocolWrappers[currentToken]).mul( _contractBalanceOf(currentToken) ).div(ONE_18); total = total.add(amounts[i]); } } /** * Get the current pool value in underlying * * @return total : total AUM in underlying */ function _getCurrentPoolValue() internal view returns (uint256 total) { // Get balance of every protocol implemented address currentToken; address[] memory _tokens = allAvailableTokens; for (uint256 i = 0; i < _tokens.length; i++) { currentToken = _tokens[i]; total = total.add(_getPriceInToken(protocolWrappers[currentToken]).mul( _contractBalanceOf(currentToken) ).div(ONE_18)); } // add unlent balance total = total.add(_contractBalanceOf(token)); } /** * Get contract balance of _token * * @param _token : address of the token to read balance * @return total : balance of _token in this contract */ function _contractBalanceOf(address _token) private view returns (uint256) { // Original implementation: // // return IERC20(_token).balanceOf(address(this)); // Optimized implementation inspired by uniswap https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/UniswapV3Pool.sol#L144 // // 0x70a08231 -> selector for 'function balanceOf(address) returns (uint256)' (bool success, bytes memory data) = _token.staticcall(abi.encodeWithSelector(0x70a08231, address(this))); require(success); return abi.decode(data, (uint256)); } /** * Get price of 1 protocol token in underlyings * * @param _token : address of the protocol token * @return price : price of protocol token */ function _getPriceInToken(address _token) private view returns (uint256) { return ILendingProtocol(_token).getPriceInToken(); } /** * Check that no mint has been made in the same block from the same EOA */ function _checkMintRedeemSameTx() private view { require(keccak256(abi.encodePacked(tx.origin, block.number)) != _minterBlock, "9"); } // ILendingProtocols calls /** * Redeem underlying tokens through protocol wrapper * * @param _amount : amount of `_token` to redeem * @param _token : protocol token address * @return tokens : new tokens minted */ function _redeemProtocolTokens(address _token, uint256 _amount) internal returns (uint256 tokens) { if (_amount != 0) { // Transfer _amount of _protocolToken (eg. cDAI) to _wrapperAddr address _wrapperAddr = protocolWrappers[_token]; _transferTokens(_token, _wrapperAddr, _amount); tokens = ILendingProtocol(_wrapperAddr).redeem(address(this)); } } function _transferTokens(address _token, address _to, uint256 _amount) internal { IERC20(_token).safeTransfer(_to, _amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"address","name":"initiator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"premium","type":"uint256"}],"name":"FlashLoan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"PauserAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"PauserRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_rebalancer","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Rebalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_ref","type":"address"}],"name":"Referral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"constant":true,"inputs":[],"name":"COMP","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"IDLE","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_tokenHelper","type":"address"},{"internalType":"address","name":"_aToken","type":"address"},{"internalType":"address","name":"_newOracle","type":"address"}],"name":"_init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addPauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allAvailableTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"feeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"_receiver","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_params","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"flashLoanFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAPRs","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAllAvailableTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAllocations","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAvgAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getGovTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_usr","type":"address"}],"name":"getGovTokensAmounts","outputs":[{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_protocolToken","type":"address"}],"name":"getProtocolTokenToGov","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"govTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"govTokensIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"govTokensLastBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gst2","outputs":[{"internalType":"contract GasToken","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"idleController","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isPauser","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isRiskAdjusted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastAllocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastITokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxUnlentPerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"address","name":"_referral","type":"address"}],"name":"mintIdleToken","outputs":[{"internalType":"uint256","name":"mintedTokens","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"protocolWrappers","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"rebalance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rebalancer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"redeemIdleToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool[]","name":"_skipGovTokenRedeem","type":"bool[]"}],"name":"redeemIdleTokenSkipGov","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"redeemInterestBearingTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renouncePauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_aToken","type":"address"}],"name":"setAToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"protocolTokens","type":"address[]"},{"internalType":"address[]","name":"wrappers","type":"address[]"},{"internalType":"address[]","name":"_newGovTokens","type":"address[]"},{"internalType":"address[]","name":"_newGovTokensEqualLen","type":"address[]"}],"name":"setAllAvailableTokensAndWrappers","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"_allocations","type":"uint256[]"}],"name":"setAllocations","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_cToken","type":"address"}],"name":"setCToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_feeAddress","type":"address"}],"name":"setFeeAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_flashFee","type":"uint256"}],"name":"setFlashLoanFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_perc","type":"uint256"}],"name":"setMaxUnlentPerc","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracleAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_rebalancer","type":"address"}],"name":"setRebalancer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stkAAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenHelper","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"tokenPriceWithFee","outputs":[{"internalType":"uint256","name":"priceWFee","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userAvgPrices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"usersGovTokensIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052615fea806100136000396000f3fe608060405234801561001057600080fd5b50600436106103595760003560e01c806301d22ccd1461035e57806306fdde0314610382578063095ea7b3146103ff5780630b56d1571461043f5780630df94ef21461045e57806312ea5c7e146104965780631624f6c6146104ee57806318160ddd1461061c578063194a62a8146106245780631f80b18a146106415780631fc29c011461064957806323b872dd1461065157806323d39ab5146106875780632b1b4bb01461068f5780632befabbf146106b55780632fdc91ee146106e9578063313ce567146106f157806336a000821461070f578063395093511461072c5780633f4ba83a14610758578063412753581461076057806345c8026c1461076857806346fbf68e1461078e5780634847cdc8146107b45780634c69c00f146107bc5780634cb71222146107e257806350b28af7146108085780635478786c1461082e57806354924507146108365780635c975abb1461083e5780635cffe9de146108465780635f09d84c146108d4578063613255ab146108fa5780636287fe211461092057806365ed6e231461094657806369fe0e2d1461094e5780636cfd15531461096b5780636ef8d66d1461099157806370a0823114610999578063715018a6146109bf578063746daa4e146109c75780637d7c2a1c146109e45780637dc0d1d0146109ec5780637ff9b596146109f45780638129fc1c146109fc57806382dc1ec414610a045780638456cb5914610a2a5780638705fcd414610a325780638a279e8a14610a585780638b30b51614610a865780638cba144414610aa35780638da5cb5b14610ac95780638f32d59b14610ad157806395d89b4114610ad95780639602e9f814610ae1578063a457c2d714610ae9578063a6ea311c14610b15578063a9059cbb14610b1d578063aaa48e9f14610b49578063ad3879ad14610b6f578063afdd3fc314610ba7578063b13bd49114610bc4578063b616b63d14610c65578063b71501bc14610cda578063c498c51514610ce2578063c4d66de814610d50578063cb390f9714610d76578063d9d98ce414610d7e578063dd62ed3e14610daa578063ddca3f4314610dd8578063e92d0d5d14610de0578063f16c88db14610dfd578063f2d50ba614610f5b578063f2fde38b14610f63578063fc0c546a14610f89575b600080fd5b610366610f91565b604080516001600160a01b039092168252519081900360200190f35b61038a610fa1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61042b6004803603604081101561041557600080fd5b506001600160a01b038135169060200135611038565b604080519115158252519081900360200190f35b61045c6004803603602081101561045557600080fd5b5035611056565b005b6104846004803603602081101561047457600080fd5b50356001600160a01b03166110e2565b60408051918252519081900360200190f35b61049e6110f5565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104da5781810151838201526020016104c2565b505050509050019250505060405180910390f35b61045c6004803603606081101561050457600080fd5b810190602081018135600160201b81111561051e57600080fd5b82018360208201111561053057600080fd5b803590602001918460018302840111600160201b8311171561055157600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156105a357600080fd5b8201836020820111156105b557600080fd5b803590602001918460018302840111600160201b831117156105d657600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff1691506111579050565b610484611233565b61045c6004803603602081101561063a57600080fd5b5035611239565b6104846113cf565b610366611467565b61042b6004803603606081101561066757600080fd5b506001600160a01b0381358116916020810135909116906040013561147f565b610366611507565b610366600480360360208110156106a557600080fd5b50356001600160a01b0316611517565b610484600480360360608110156106cb57600080fd5b508035906020810135151590604001356001600160a01b0316611539565b6103666116dc565b6106f96116ec565b6040805160ff9092168252519081900360200190f35b6103666004803603602081101561072557600080fd5b50356116f5565b61042b6004803603604081101561074257600080fd5b506001600160a01b03813516906020013561171d565b61045c611771565b61036661185c565b6103666004803603602081101561077e57600080fd5b50356001600160a01b031661186c565b61042b600480360360208110156107a457600080fd5b50356001600160a01b0316611888565b61048461189c565b61045c600480360360208110156107d257600080fd5b50356001600160a01b03166118a3565b61045c600480360360208110156107f857600080fd5b50356001600160a01b031661193e565b61049e6004803603602081101561081e57600080fd5b50356001600160a01b03166119d9565b610366611ac9565b610484611ae1565b61042b611ae8565b61042b6004803603608081101561085c57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561089657600080fd5b8201836020820111156108a857600080fd5b803590602001918460018302840111600160201b831117156108c957600080fd5b509092509050611af2565b61045c600480360360208110156108ea57600080fd5b50356001600160a01b03166120b8565b6104846004803603602081101561091057600080fd5b50356001600160a01b0316612153565b6104846004803603602081101561093657600080fd5b50356001600160a01b0316612193565b61049e6121a6565b61045c6004803603602081101561096457600080fd5b50356121fe565b61045c6004803603602081101561098157600080fd5b50356001600160a01b0316612286565b61045c612321565b610484600480360360208110156109af57600080fd5b50356001600160a01b0316612333565b61045c61234e565b610366600480360360208110156109dd57600080fd5b50356123cd565b61042b6123db565b6103666123ea565b6104846123fa565b61045c612404565b61045c60048036036020811015610a1a57600080fd5b50356001600160a01b03166124aa565b61045c6124f9565b61045c60048036036020811015610a4857600080fd5b50356001600160a01b03166125c2565b61048460048036036040811015610a6e57600080fd5b506001600160a01b038135811691602001351661265d565b61048460048036036020811015610a9c57600080fd5b503561267b565b61048460048036036020811015610ab957600080fd5b50356001600160a01b03166126b7565b610366612743565b61042b612752565b61038a612778565b6103666127d9565b61042b60048036036040811015610aff57600080fd5b506001600160a01b0381351690602001356127f1565b61049e61285f565b61042b60048036036040811015610b3357600080fd5b506001600160a01b0381351690602001356128c0565b61048460048036036020811015610b5f57600080fd5b50356001600160a01b03166128f6565b61045c60048036036060811015610b8557600080fd5b506001600160a01b038135811691602081013582169160409091013516612909565b61048460048036036020811015610bbd57600080fd5b5035612994565b610bcc6129b3565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610c10578181015183820152602001610bf8565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610c4f578181015183820152602001610c37565b5050505090500194505050505060405180910390f35b61048460048036036040811015610c7b57600080fd5b81359190810190604081016020820135600160201b811115610c9c57600080fd5b820183602082011115610cae57600080fd5b803590602001918460208302840111600160201b83111715610ccf57600080fd5b509092509050612b59565b610366612ba0565b61045c60048036036020811015610cf857600080fd5b810190602081018135600160201b811115610d1257600080fd5b820183602082011115610d2457600080fd5b803590602001918460208302840111600160201b83111715610d4557600080fd5b509092509050612bb8565b61045c60048036036020811015610d6657600080fd5b50356001600160a01b0316612c5b565b61042b612d11565b61048460048036036040811015610d9457600080fd5b506001600160a01b038135169060200135612d1b565b61048460048036036040811015610dc057600080fd5b506001600160a01b0381358116916020013516612d82565b610484612dad565b61045c60048036036020811015610df657600080fd5b5035612db4565b61045c60048036036080811015610e1357600080fd5b810190602081018135600160201b811115610e2d57600080fd5b820183602082011115610e3f57600080fd5b803590602001918460208302840111600160201b83111715610e6057600080fd5b919390929091602081019035600160201b811115610e7d57600080fd5b820183602082011115610e8f57600080fd5b803590602001918460208302840111600160201b83111715610eb057600080fd5b919390929091602081019035600160201b811115610ecd57600080fd5b820183602082011115610edf57600080fd5b803590602001918460208302840111600160201b83111715610f0057600080fd5b919390929091602081019035600160201b811115610f1d57600080fd5b820183602082011115610f2f57600080fd5b803590602001918460208302840111600160201b83111715610f5057600080fd5b509092509050612e3c565b61048461308c565b61045c60048036036020811015610f7957600080fd5b50356001600160a01b0316613093565b6103666130e3565b61016d546001600160a01b031681565b60688054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561102d5780601f106110025761010080835404028352916020019161102d565b820191906000526020600020905b81548152906001019060200180831161101057829003601f168201915b505050505090505b90565b600061104c6110456130f3565b84846130f7565b5060015b92915050565b61105e612752565b61109d576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b620186a08161017181905511156110df576040805162461bcd60e51b81526020600482015260016024820152603560f81b604482015290519081900360640190fd5b50565b6101766020526000908152604090205481565b606061017380548060200260200160405190810160405280929190818152602001828054801561102d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611130575050505050905090565b600054610100900460ff168061117057506111706131e3565b8061117e575060005460ff16155b6111b95760405162461bcd60e51b815260040180806020018281038252602e815260200180615eaf602e913960400191505060405180910390fd5b600054610100900460ff161580156111e4576000805460ff1961ff0019909116610100171660011790555b83516111f7906068906020870190615b6c565b50825161120b906069906020860190615b6c565b50606a805460ff191660ff8416179055801561122d576000805461ff00191690555b50505050565b60355490565b609d8054600101908190556101365460ff16611293576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b61129b6131e9565b6112a433613268565b60005b610173548110156113385761133061017382815481106112c357fe5b6000918252602090912001546001600160a01b03163361132b6112e4611233565b61131f61131261017388815481106112f857fe5b6000918252602090912001546001600160a01b03166132a2565b899063ffffffff6133af16565b9063ffffffff61340816565b613447565b6001016112a7565b5061016a5461137d906001600160a01b03163361132b611356611233565b61016a5461131f90611370906001600160a01b03166132a2565b889063ffffffff6133af16565b6113873383613466565b609d5481146113cb576040805162461bcd60e51b815260206004820152601f6024820152600080516020615d03833981519152604482015290519081900360640190fd5b5050565b6101825461016c546101835460408051635ad5aadf60e01b81523060048201526001600160a01b0393841660248201529183166044830152516000939290921691635ad5aadf91606480820192602092909190829003018186803b15801561143657600080fd5b505afa15801561144a573d6000803e3d6000fd5b505050506040513d602081101561146057600080fd5b5051905090565b734da27a545c0c5b758a6ba100e3a049001de870f581565b600061148c848484613550565b6114978484846136fb565b6114d584336114d085604051806060016040528060288152602001615e25602891396114c38a33612d82565b919063ffffffff61384716565b6130f7565b6001600160a01b038416600090815261017660205260409020546114fc90849084906138de565b5060015b9392505050565b610169546001600160a01b031681565b6001600160a01b03808216600090815261017e6020526040902054165b919050565b609d805460010190819055610136546000919060ff1615611594576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b604080513260601b60208083019190915243603480840191909152835180840390910181526054909201909252805191012061017c556115d333613268565b60006115dd61395e565b61016a549091506115ff906001600160a01b031633308963ffffffff613a9216565b61161b8161131f88670de0b6b3a764000063ffffffff6133af16565b92506116273384613aec565b6116313384613bcc565b61163c3384836138de565b6001600160a01b0384161561168f57604080518781526001600160a01b038616602082015281517f496d589d8b7eb829a8d7b30e24a326ac33991f5cea96429b69231a6b15b54b1d929181900390910190a15b50609d5481146116d4576040805162461bcd60e51b815260206004820152601f6024820152600080516020615d03833981519152604482015290519081900360640190fd5b509392505050565b610182546001600160a01b031681565b606a5460ff1690565b610173818154811061170357fe5b6000918252602090912001546001600160a01b0316905081565b600061104c61172a6130f3565b846114d0856034600061173b6130f3565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff613c9c16565b61178161177c6130f3565b611888565b6117bc5760405162461bcd60e51b8152600401808060200182810382526030815260200180615d456030913960400191505060405180910390fd5b6101365460ff1661180b576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b610136805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61183f6130f3565b604080516001600160a01b039092168252519081900360200190a1565b61016e546001600160a01b031681565b610177602052600090815260409020546001600160a01b031681565b60006110506101038363ffffffff613cf416565b6101815481565b6118ab612752565b6118ea576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61017d80546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b611946612752565b611985576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61016c80546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b60606000806119e784612333565b610174546040805182815260208084028201019091529192508015611a16578160200160208202803883390190505b50925060005b8351811015611ac1576101748181548110611a3357fe5b60009182526020808320909101546001600160a01b0390811680845261017983526040808520928a1685529183528184205481855261017a909352922054919450611aa291670de0b6b3a76400009161131f91611a959163ffffffff613d5b16565b859063ffffffff6133af16565b848281518110611aae57fe5b6020908102919091010152600101611a1c565b505050919050565b73875773784af8135ea0ef43b5a374aad105c5d39e81565b6101715481565b6101365460ff1690565b6101365460009060ff1615611b41576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b609d80546001019081905561016a5487906001600160a01b03888116911614611b95576040805162461bcd60e51b81526020600482015260016024820152603760f81b604482015290519081900360640190fd5b6001600160a01b03811615801590611bad5750600086115b611be2576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b61016a54600090611bfb906001600160a01b03166132a2565b905080871115611dfb576000611c17888363ffffffff613d5b16565b905060008080808080808080805b61017354811015611def576101738181548110611c3e57fe5b60009182526020808320909101546001600160a01b03908116808452610177835260409384902054845163015de72360e11b81529451919d50909116965086926302bbce46926004808301939192829003018186803b158015611ca057600080fd5b505afa158015611cb4573d6000803e3d6000fd5b505050506040513d6020811015611cca57600080fd5b505160408051637437535960e01b815290519196506001600160a01b03861691637437535991600480820192602092909190829003018186803b158015611d1057600080fd5b505afa158015611d24573d6000803e3d6000fd5b505050506040513d6020811015611d3a57600080fd5b50519650611d63670de0b6b3a764000061131f87611d578d6132a2565b9063ffffffff6133af16565b97508a88101591508a871015925081611d8b5786881115611d845786611d86565b875b611d98565b82611d965786611d98565b8a5b9950611dbf89611dba8761131f8e670de0b6b3a764000063ffffffff6133af16565b613d9d565b9550818015611dcb5750825b15611dd557611def565b611de58b8763ffffffff613d5b16565b9a50600101611c25565b50505050505050505050505b61016a548790611e13906001600160a01b03166132a2565b1015611e4a576040805162461bcd60e51b81526020600482015260016024820152603360f81b604482015290519081900360640190fd5b61016a54611e62906001600160a01b03168389613447565b61016a54600090611e7c906001600160a01b031689612d1b565b905060405180807f45524333313536466c617368426f72726f7765722e6f6e466c6173684c6f616e815250602001905060405180910390208a6001600160a01b03166323e30c8b3361016a60009054906101000a90046001600160a01b03168c868d8d6040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050602060405180830381600087803b158015611f8057600080fd5b505af1158015611f94573d6000803e3d6000fd5b505050506040513d6020811015611faa57600080fd5b505114611fe2576040805162461bcd60e51b81526020600482015260016024820152600760fb1b604482015290519081900360640190fd5b6120128330611ff78b8563ffffffff613c9c16565b61016a546001600160a01b031692919063ffffffff613a9216565b61201a613e3e565b506040805189815260208101839052815133926001600160a01b038716927f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f0929081900390910190a360019450505050609d5481146120ae576040805162461bcd60e51b815260206004820152601f6024820152600080516020615d03833981519152604482015290519081900360640190fd5b5095945050505050565b6120c0612752565b6120ff576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61018380546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b61016a546000906001600160a01b03838116911614156115345761218c670de0b6b3a764000061131f612184611233565b611d5761395e565b9050611534565b6101786020526000908152604090205481565b606061018080548060200260200160405190810160405280929190818152602001828054801561102d57602002820191906000526020600020905b8154815260200190600101908083116121e1575050505050905090565b612206612752565b612245576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b6101728190556127108111156110df576040805162461bcd60e51b81526020600482015260016024820152603560f81b604482015290519081900360640190fd5b61228e612752565b6122cd576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61016d80546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b61233161232c6130f3565b6141e9565b565b6001600160a01b031660009081526033602052604090205490565b612356612752565b612395576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b60d0546040516000916001600160a01b031690600080516020615e6d833981519152908390a360d080546001600160a01b0319169055565b610174818154811061170357fe5b60006123e5613e3e565b905090565b61017d546001600160a01b031681565b60006123e561395e565b600054610100900460ff168061241d575061241d6131e3565b8061242b575060005460ff16155b6124665760405162461bcd60e51b815260040180806020018281038252602e815260200180615eaf602e913960400191505060405180910390fd5b600054610100900460ff16158015612491576000805460ff1961ff0019909116610100171660011790555b6001609d5580156110df576000805461ff001916905550565b6124b561177c6130f3565b6124f05760405162461bcd60e51b8152600401808060200182810382526030815260200180615d456030913960400191505060405180910390fd5b6110df81614232565b61250461177c6130f3565b61253f5760405162461bcd60e51b8152600401808060200182810382526030815260200180615d456030913960400191505060405180910390fd5b6101365460ff161561258b576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b610136805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861183f6130f3565b6125ca612752565b612609576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61016e80546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b61017960209081526000928352604080842090915290825290205481565b600061105082610174805490506040519080825280602002602001820160405280156126b1578160200160208202803883390190505b5061427b565b6001600160a01b038116600090815261017660205260408120546126d961395e565b915080158015906126e957508082115b1561273d5761273a620186a061131f61271b61270b868663ffffffff613d5b16565b610172549063ffffffff6133af16565b61272e86620186a063ffffffff6133af16565b9063ffffffff613d5b16565b91505b50919050565b60d0546001600160a01b031690565b60d0546000906001600160a01b03166127696130f3565b6001600160a01b031614905090565b60698054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561102d5780601f106110025761010080835404028352916020019161102d565b73275da8e61ea8e02d51edd8d0dc5c0e62b4cdb0be81565b600061104c6127fe6130f3565b846114d085604051806060016040528060258152602001615f9160259139603460006128286130f3565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61384716565b606061017480548060200260200160405190810160405280929190818152602001828054801561102d576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311611130575050505050905090565b60006128cd338484613550565b6128d83384846136fb565b336000908152610176602052604090205461104c90849084906138de565b61017a6020526000908152604090205481565b610182546001600160a01b03161561294c576040805162461bcd60e51b81526020600482015260016024820152603160f81b604482015290519081900360640190fd5b61018280546001600160a01b039485166001600160a01b03199182161790915560506101815561018380549385169382169390931790925561017d8054919093169116179055565b61017581815481106129a257fe5b600091825260209091200154905081565b6101825460408051634a4b15d160e01b8152306004820152905160609283926001600160a01b0390911691634a4b15d191602480820192600092909190829003018186803b158015612a0457600080fd5b505afa158015612a18573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015612a4157600080fd5b8101908080516040519392919084600160201b821115612a6057600080fd5b908301906020820185811115612a7557600080fd5b82518660208202830111600160201b82111715612a9157600080fd5b82525081516020918201928201910280838360005b83811015612abe578181015183820152602001612aa6565b5050505090500160405260200180516040519392919084600160201b821115612ae657600080fd5b908301906020820185811115612afb57600080fd5b82518660208202830111600160201b82111715612b1757600080fd5b82525081516020918201928201910280838360005b83811015612b44578181015183820152602001612b2c565b50505050905001604052505050915091509091565b6000612b988484848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061427b92505050565b949350505050565b73c00e94cb662c3520282e6f5717214004a7f2688881565b61016d546001600160a01b0316331480612bea5750612bd5612743565b6001600160a01b0316336001600160a01b0316145b612c1f576040805162461bcd60e51b81526020600482015260016024820152601b60f91b604482015290519081900360640190fd5b6113cb82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061438492505050565b600054610100900460ff1680612c745750612c746131e3565b80612c82575060005460ff16155b612cbd5760405162461bcd60e51b815260040180806020018281038252602e815260200180615eaf602e913960400191505060405180910390fd5b600054610100900460ff16158015612ce8576000805460ff1961ff0019909116610100171660011790555b612cf18261444e565b610136805460ff1916905580156113cb576000805461ff00191690555050565b61017f5460ff1681565b61016a546000906001600160a01b03848116911614612d65576040805162461bcd60e51b81526020600482015260016024820152603760f81b604482015290519081900360640190fd5b611500620186a061131f61018154856133af90919063ffffffff16565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b6101725481565b612dbc612752565b612dfb576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b620186a081610181819055106110df576040805162461bcd60e51b81526020600482015260016024820152600d60fa1b604482015290519081900360640190fd5b612e44612752565b612e83576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b868514612ebb576040805162461bcd60e51b81526020600482015260016024820152601960f91b604482015290519081900360640190fd5b86811015612ef4576040805162461bcd60e51b81526020600482015260016024820152603360f81b604482015290519081900360640190fd5b612f016101748585615bea565b50600080805b89811015613071578a8a82818110612f1b57fe5b905060200201356001600160a01b0316915060006001600160a01b0316826001600160a01b031614158015612f7557506000898983818110612f5957fe5b905060200201356001600160a01b03166001600160a01b031614155b612faa576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b888882818110612fb657fe5b6001600160a01b0385811660009081526101776020908152604090912080546001600160a01b031916939091029490940135161790915550848482818110612ffa57fe5b905060200201356001600160a01b0316925073875773784af8135ea0ef43b5a374aad105c5d39e6001600160a01b0316836001600160a01b031614613069576001600160a01b03828116600090815261017e6020526040902080546001600160a01b0319169185169190911790555b600101612f07565b5061307f6101738b8b615bea565b5050505050505050505050565b61016f5481565b61309b612752565b6130da576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b6110df81614506565b61016a546001600160a01b031681565b3390565b6001600160a01b03831661313c5760405162461bcd60e51b8152600401808060200182810382526024815260200180615f436024913960400191505060405180910390fd5b6001600160a01b0382166131815760405162461bcd60e51b8152600401808060200182810382526022815260200180615d9b6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260346020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b303b1590565b61017c54324360405160200180836001600160a01b03166001600160a01b031660601b815260140182815260200192505050604051602081830303815290604052805190602001201415612331576040805162461bcd60e51b81526020600482015260016024820152603960f81b604482015290519081900360640190fd5b6110df816101748054905060405190808252806020026020018201604052801561329c578160200160208202803883390190505b50614595565b604080513060248083019190915282518083039091018152604490910182526020810180516001600160e01b03166370a0823160e01b1781529151815160009384936060936001600160a01b03881693919290918291908083835b6020831061331c5780518252601f1990920191602091820191016132fd565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461337c576040519150601f19603f3d011682016040523d82523d6000602084013e613381565b606091505b50915091508161339057600080fd5b8080602001905160208110156133a557600080fd5b5051949350505050565b6000826133be57506000611050565b828202828482816133cb57fe5b04146115005760405162461bcd60e51b8152600401808060200182810382526021815260200180615e046021913960400191505060405180910390fd5b600061150083836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b81525061491e565b6134616001600160a01b038416838363ffffffff61498316565b505050565b6001600160a01b0382166134ab5760405162461bcd60e51b8152600401808060200182810382526021815260200180615efd6021913960400191505060405180910390fd5b6134ee81604051806060016040528060228152602001615d23602291396001600160a01b038516600090815260336020526040902054919063ffffffff61384716565b6001600160a01b03831660009081526033602052604090205560355461351a908263ffffffff613d5b16565b6035556040805182815290516000916001600160a01b03851691600080516020615edd8339815191529181900360200190a35050565b600080600080600061356187612333565b905060005b610174548110156136f057610174818154811061357f57fe5b6000918252602090912001546001600160a01b03169550816135d1576001600160a01b038681166000908152610179602090815260408083208d8516845290915280822054928b1682529020556136e8565b6001600160a01b03808716600090815261017a60209081526040808320546101798352818420948e1684529390915290205490955061361790869063ffffffff613d5b16565b6001600160a01b03808816600090815261017960209081526040808320938d168352929052205490945061366490670de0b6b3a76400009061131f90611a9590899063ffffffff613d5b16565b92506136c06136b361367c848a63ffffffff613c9c16565b61131f61368f888c63ffffffff6133af16565b6136a788670de0b6b3a764000063ffffffff6133af16565b9063ffffffff613c9c16565b869063ffffffff613d5b16565b6001600160a01b03808816600090815261017960209081526040808320938d16835292905220555b600101613566565b505050505050505050565b6001600160a01b0383166137405760405162461bcd60e51b8152600401808060200182810382526025815260200180615f1e6025913960400191505060405180910390fd5b6001600160a01b0382166137855760405162461bcd60e51b8152600401808060200182810382526023815260200180615ce06023913960400191505060405180910390fd5b6137c881604051806060016040528060268152602001615dbd602691396001600160a01b038616600090815260336020526040902054919063ffffffff61384716565b6001600160a01b0380851660009081526033602052604080822093909355908416815220546137fd908263ffffffff613c9c16565b6001600160a01b038084166000818152603360209081526040918290209490945580518581529051919392871692600080516020615edd83398151915292918290030190a3505050565b600081848411156138d65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561389b578181015183820152602001613883565b50505050905090810190601f1680156138c85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60006138e984612333565b905061393b8161131f613902858763ffffffff6133af16565b6136a7613915868963ffffffff613d5b16565b6001600160a01b038a16600090815261017660205260409020549063ffffffff6133af16565b6001600160a01b0390941660009081526101766020526040902093909355505050565b600080613969611233565b90508061397e57505061017054600a0a611035565b61016a5460009081906139a790670de0b6b3a764000090611d57906001600160a01b03166132a2565b90506060610173805480602002602001604051908101604052809291908181526020018280548015613a0257602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116139e4575b50939450600093505050505b8151811015613a7857818181518110613a2357fe5b60200260200101519350613a6e613a61613a3c866132a2565b6001600160a01b0380881660009081526101776020526040902054611d5791166149d5565b849063ffffffff613c9c16565b9250600101613a0e565b50613a89828563ffffffff61340816565b94505050505090565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261122d908590614a42565b6001600160a01b038216613b47576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b603554613b5a908263ffffffff613c9c16565b6035556001600160a01b038216600090815260336020526040902054613b86908263ffffffff613c9c16565b6001600160a01b0383166000818152603360209081526040808320949094558351858152935192939192600080516020615edd8339815191529281900390910190a35050565b600080613bd884612333565b90506000805b61017454811015613c94576101748181548110613bf757fe5b60009182526020808320909101546001600160a01b0390811680845261017983526040808520928b1685529183528184205481855261017a9093529220549195509250613c6590613c5890859061131f90611312908763ffffffff613d5b16565b839063ffffffff613c9c16565b6001600160a01b03808616600090815261017960209081526040808320938b1683529290522055600101613bde565b505050505050565b600082820183811015611500576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b60006001600160a01b038216613d3b5760405162461bcd60e51b8152600401808060200182810382526022815260200180615e8d6022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b600061150083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613847565b60008115611050576001600160a01b038084166000908152610177602052604090205416613dcc848285613447565b604080516395a2251f60e01b815230600482015290516001600160a01b038316916395a2251f9160248083019260209291908290030181600087803b158015613e1457600080fd5b505af1158015613e28573d6000803e3d6000fd5b505050506040513d60208110156133a557600080fd5b6101365460009060ff1615613e8d576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6060610180805480602002602001604051908101604052809291908181526020018280548015613edc57602002820191906000526020600020905b815481526020019060010190808311613ec8575b505050505090506060610175805480602002602001604051908101604052809291908181526020018280548015613f3257602002820191906000526020600020905b815481526020019060010190808311613f1e575b50508351865194955093841492505081159050613f9d5760005b82811080613f58575081155b15613f9b57848181518110613f6957fe5b6020026020010151848281518110613f7d57fe5b602002602001015114613f935760009150613f9b565b600101613f4c565b505b61016a54600090613fb6906001600160a01b03166132a2565b9050818015613fc3575080155b15613fd657600095505050505050611035565b6000613fee620186a061131f61017154611d57614bfa565b9050821561402657808211156140175761401786614012848463ffffffff613d5b16565b614cfa565b60009650505050505050611035565b60606000614032614e54565b9092509050614047818563ffffffff613c9c16565b90506101715481111561406757614064818463ffffffff613d5b16565b90505b606060008061407f8561407a8d87614f75565b615058565b925092509250806140ad576140976101756000615c49565b8a516140ab906101759060208e0190615c67565b505b61016a546000906140c6906001600160a01b03166132a2565b90508681116140e45760009c50505050505050505050505050611035565b60608451604051908082528060200260200182016040528015614111578160200160208202803883390190505b50905060005b855181101561416c5761414d8561131f620186a089858151811061413757fe5b60200260200101516133af90919063ffffffff16565b82828151811061415957fe5b6020908102919091010152600101614117565b5061418181614012848b63ffffffff613d5b16565b7f4217d9fab39dbadacf1dad6c889aec1caa02e8a6cb59ddd4ce34f3e0ef158b55336141b3888b63ffffffff613c9c16565b604080516001600160a01b03909316835260208301919091528051918290030190a160019d505050505050505050505050505090565b6141fb6101038263ffffffff6152ed16565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b6142446101038263ffffffff61535416565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b609d8054600101908190556000906142916131e9565b61429b3384614595565b83156143395760006142ab61395e565b905060006142cb670de0b6b3a764000061131f888563ffffffff6133af16565b61016a549091506000906142e7906001600160a01b03166132a2565b905080821115614302576142fb87826153d5565b9450614306565b8194505b6143118786856154c5565b945061431d3388613466565b61016a54614335906001600160a01b03163387613447565b5050505b609d54811461437d576040805162461bcd60e51b815260206004820152601f6024820152600080516020615d03833981519152604482015290519081900360640190fd5b5092915050565b610173548151146143c0576040805162461bcd60e51b81526020600482015260016024820152601960f91b604482015290519081900360640190fd5b6000805b82518110156143fd576143f38382815181106143dc57fe5b602002602001015183613c9c90919063ffffffff16565b91506001016143c4565b50815161441290610180906020850190615c67565b50620186a081146113cb576040805162461bcd60e51b81526020600482015260016024820152603760f81b604482015290519081900360640190fd5b600054610100900460ff168061446757506144676131e3565b80614475575060005460ff16155b6144b05760405162461bcd60e51b815260040180806020018281038252602e815260200180615eaf602e913960400191505060405180910390fd5b600054610100900460ff161580156144db576000805460ff1961ff0019909116610100171660011790555b6144e482611888565b6144f1576144f182614232565b80156113cb576000805461ff00191690555050565b6001600160a01b03811661454b5760405162461bcd60e51b8152600401808060200182810382526026815260200180615d756026913960400191505060405180910390fd5b60d0546040516001600160a01b03808416921690600080516020615e6d83398151915290600090a360d080546001600160a01b0319166001600160a01b0392909216919091179055565b60606101748054806020026020016040519081016040528092919081815260200182805480156145ee57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116145d0575b5050505050905080516000141561460557506113cb565b600061460f611233565b9050600061461c85612333565b905060008215613c945760005b84518110156149155784818151811061463e57fe5b6020026020010151915061465182615553565b600061465c836132a2565b905080156146f7576001600160a01b038316600090815261017860205260409020546146cd906146a790879061131f90670de0b6b3a764000090611d5790879063ffffffff613d5b16565b6001600160a01b038516600090815261017a60205260409020549063ffffffff613c9c16565b6001600160a01b038416600090815261017a60209081526040808320939093556101789052208190555b83156148da576001600160a01b03808416600081815261017960209081526040808320948d1683529381528382205492825261017a905291822054909190614745908363ffffffff613d5b16565b905080156148d757600061476b670de0b6b3a764000061131f898563ffffffff6133af16565b90506000614778876132a2565b905080821115614786578091505b8a868151811061479257fe5b602002602001015115614812576147f36147cd6147b58b8b63ffffffff613d5b16565b61131f85670de0b6b3a764000063ffffffff6133af16565b6001600160a01b038916600090815261017a60205260409020549063ffffffff613c9c16565b6001600160a01b038816600090815261017a60205260409020556148d4565b61016e546000906001600160a01b0316158015906148335750600061017254115b801561485c57506001600160a01b03881673875773784af8135ea0ef43b5a374aad105c5d39e14155b1561489a5761487e620186a061131f61017254866133af90919063ffffffff16565b61016e5490915061489a9089906001600160a01b031683613447565b6148af888e61132b868563ffffffff613d5b16565b6148b8886132a2565b6001600160a01b03891660009081526101786020526040902055505b50505b50505b506001600160a01b03808316600090815261017a60209081526040808320546101798352818420948c16845293909152902055600101614629565b50505050505050565b6000818361496d5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561389b578181015183820152602001613883565b50600083858161497957fe5b0495945050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613461908490614a42565b6000816001600160a01b03166302bbce466040518163ffffffff1660e01b815260040160206040518083038186803b158015614a1057600080fd5b505afa158015614a24573d6000803e3d6000fd5b505050506040513d6020811015614a3a57600080fd5b505192915050565b614a54826001600160a01b0316615b33565b614aa5576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310614ae35780518252601f199092019160209182019101614ac4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614b45576040519150601f19603f3d011682016040523d82523d6000602084013e614b4a565b606091505b509150915081614ba1576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561122d57808060200190516020811015614bbd57600080fd5b505161122d5760405162461bcd60e51b815260040180806020018281038252602a815260200180615f67602a913960400191505060405180910390fd5b6000806060610173805480602002602001604051908101604052809291908181526020018280548015614c5657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614c38575b50939450600093505050505b8151811015614cd857818181518110614c7757fe5b60200260200101519250614cce614cc1670de0b6b3a764000061131f614c9c876132a2565b6001600160a01b0380891660009081526101776020526040902054611d5791166149d5565b859063ffffffff613c9c16565b9350600101614c62565b5061016a54614cf390613a61906001600160a01b03166132a2565b9250505090565b6060614d068383614f75565b90506000806060610173805480602002602001604051908101604052809291908181526020018280548015614d6457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614d46575b50939450600093505050505b845181101561491557848181518110614d8557fe5b6020026020010151935083600014614e4c576101776000838381518110614da857fe5b6020908102919091018101516001600160a01b039081168352908201929092526040016000205461016a549082169450614de491168486613447565b826001600160a01b0316631249c58b6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614e1f57600080fd5b505af1158015614e33573d6000803e3d6000fd5b505050506040513d6020811015614e4957600080fd5b50505b600101614d70565b60606000806060610173805480602002602001604051908101604052809291908181526020018280548015614eb257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614e94575b5050505050905060008151905080604051908082528060200260200182016040528015614ee9578160200160208202803883390190505b50945060005b81811015614f6d57828181518110614f0357fe5b60200260200101519350614f25670de0b6b3a764000061131f614c9c876132a2565b868281518110614f3157fe5b602002602001018181525050614f63868281518110614f4c57fe5b602002602001015186613c9c90919063ffffffff16565b9450600101614eef565b505050509091565b60608251604051908082528060200260200182016040528015614fa2578160200160208202803883390190505b509050600080805b855181101561504f576001865103811415614fec57614fcf858363ffffffff613d5b16565b848281518110614fdb57fe5b602002602001018181525050615047565b615019620186a061131f88848151811061500257fe5b6020026020010151886133af90919063ffffffff16565b925061502b828463ffffffff613c9c16565b91508284828151811061503a57fe5b6020026020010181815250505b600101614faa565b50505092915050565b60606000808451604051908082528060200260200182016040528015615088578160200160208202803883390190505b50925060008060008060606101738054806020026020016040519081016040528092919081815260200182805480156150ea57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116150cc575b50939450600093505050505b8a518110156152e05781818151811061510b57fe5b6020026020010151925089818151811061512157fe5b602002602001015193508a818151811061513757fe5b6020908102919091018101516001600160a01b0380861660009081526101779093526040909220549091169650945083851115615287576000615180868663ffffffff613d5b16565b90506000876001600160a01b031663743753596040518163ffffffff1660e01b815260040160206040518083038186803b1580156151bd57600080fd5b505afa1580156151d1573d6000803e3d6000fd5b505050506040513d60208110156151e757600080fd5b50519050818110156151fb57600198508091505b61527f85611dba8a6001600160a01b03166302bbce466040518163ffffffff1660e01b815260040160206040518083038186803b15801561523b57600080fd5b505afa15801561524f573d6000803e3d6000fd5b505050506040513d602081101561526557600080fd5b505161131f86670de0b6b3a764000063ffffffff6133af16565b5050506152d8565b615297848663ffffffff613d5b16565b8982815181106152a357fe5b6020026020010181815250506152d58982815181106152be57fe5b602002602001015189613c9c90919063ffffffff16565b97505b6001016150f6565b5050505050509250925092565b6152f78282613cf4565b6153325760405162461bcd60e51b8152600401808060200182810382526021815260200180615de36021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b61535e8282613cf4565b156153b0576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008060006153e2611233565b9050606061017380548060200260200160405190810160405280929190818152602001828054801561543d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161541f575b50939450600093505050505b81518110156154a35781818151811061545e57fe5b6020026020010151935061549961548c85611dba8661131f61547f8a6132a2565b8d9063ffffffff6133af16565b869063ffffffff613c9c16565b9450600101615449565b506154bb614cc18361131f898963ffffffff6133af16565b9695505050505050565b3360009081526101766020526040812054808310156154e75783915050611500565b600061552169152d02c7e14af680000061131f61017254611d57615514878a613d5b90919063ffffffff16565b8b9063ffffffff6133af16565b61016a5461016e54919250615543916001600160a01b03918216911683613447565b6154bb858263ffffffff613d5b16565b6001600160a01b03811673c00e94cb662c3520282e6f5717214004a7f26888148061559a57506001600160a01b03811673875773784af8135ea0ef43b5a374aad105c5d39e145b806155c157506001600160a01b038116734da27a545c0c5b758a6ba100e3a049001de870f5145b156110df576040805160018082528183019092526060916020808301908038833901905050905030816000815181106155f657fe5b6001600160a01b039283166020918202929092010152821673875773784af8135ea0ef43b5a374aad105c5d39e141561571c5760408051637e122ea560e11b81526004810191825282516044820152825173275da8e61ea8e02d51edd8d0dc5c0e62b4cdb0be9263fc245d4a92859283929182916024820191606401906020808701910280838360005b83811015615698578181015183820152602001615680565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156156d75781810151838201526020016156bf565b50505050905001945050505050600060405180830381600087803b1580156156fe57600080fd5b505af1158015615712573d6000803e3d6000fd5b50505050506110df565b604080516001808252818301909252606091602080830190803883390190505090506001600160a01b038316734da27a545c0c5b758a6ba100e3a049001de870f51480156157755750610183546001600160a01b031615155b15615973576101835481516001600160a01b0390911690829060009061579757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506000816000815181106157c657fe5b60200260200101516001600160a01b03166375d264136040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561580857600080fd5b505af115801561581c573d6000803e3d6000fd5b505050506040513d602081101561583257600080fd5b505160408051630cc7d40f60e11b815230600482015290519192506001600160a01b03831691633111e7b3918591849163198fa81e916024808301926020929190829003018186803b15801561588757600080fd5b505afa15801561589b573d6000803e3d6000fd5b505050506040513d60208110156158b157600080fd5b50516040516001600160e01b031960e085901b168152602481018290523060448201819052606060048301908152845160648401528451919290918291608401906020878101910280838360005b838110156159175781810151838201526020016158ff565b50505050905001945050505050602060405180830381600087803b15801561593e57600080fd5b505af1158015615952573d6000803e3d6000fd5b505050506040513d602081101561596857600080fd5b506110df9350505050565b61016c546001600160a01b0316156134615761016c5481516001600160a01b039091169082906000906159a257fe5b60200260200101906001600160a01b031690816001600160a01b031681525050806000815181106159cf57fe5b60200260200101516001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015615a0f57600080fd5b505afa158015615a23573d6000803e3d6000fd5b505050506040513d6020811015615a3957600080fd5b50516040516334086fd360e11b81526000604482018190526001606483018190526080600484019081528651608485015286516001600160a01b0390951694636810dfa694889488949093909290918291602482019160a40190602089810191028083838a5b83811015615ab7578181015183820152602001615a9f565b50505050905001838103825286818151815260200191508051906020019060200280838360005b83811015615af6578181015183820152602001615ade565b505050509050019650505050505050600060405180830381600087803b158015615b1f57600080fd5b505af1158015614915573d6000803e3d6000fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612b98575050151592915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615bad57805160ff1916838001178555615bda565b82800160010185558215615bda579182015b82811115615bda578251825591602001919060010190615bbf565b50615be6929150615ca1565b5090565b828054828255906000526020600020908101928215615c3d579160200282015b82811115615c3d5781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190615c0a565b50615be6929150615cbb565b50805460008255906000526020600020908101906110df9190615ca1565b828054828255906000526020600020908101928215615bda5791602002820182811115615bda578251825591602001919060010190615bbf565b61103591905b80821115615be65760008155600101615ca7565b61103591905b80821115615be65780546001600160a01b0319168155600101615cc156fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573735265656e7472616e637947756172643a207265656e7472616e742063616c6c0045524332303a206275726e20616d6f756e7420657863656564732062616c616e6365506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65728be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef45524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820fd747cb213c95855899fc35208dc11f88f530fbf5bfddafb5d2ccd64b39e9b3264736f6c63430005100032
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103595760003560e01c806301d22ccd1461035e57806306fdde0314610382578063095ea7b3146103ff5780630b56d1571461043f5780630df94ef21461045e57806312ea5c7e146104965780631624f6c6146104ee57806318160ddd1461061c578063194a62a8146106245780631f80b18a146106415780631fc29c011461064957806323b872dd1461065157806323d39ab5146106875780632b1b4bb01461068f5780632befabbf146106b55780632fdc91ee146106e9578063313ce567146106f157806336a000821461070f578063395093511461072c5780633f4ba83a14610758578063412753581461076057806345c8026c1461076857806346fbf68e1461078e5780634847cdc8146107b45780634c69c00f146107bc5780634cb71222146107e257806350b28af7146108085780635478786c1461082e57806354924507146108365780635c975abb1461083e5780635cffe9de146108465780635f09d84c146108d4578063613255ab146108fa5780636287fe211461092057806365ed6e231461094657806369fe0e2d1461094e5780636cfd15531461096b5780636ef8d66d1461099157806370a0823114610999578063715018a6146109bf578063746daa4e146109c75780637d7c2a1c146109e45780637dc0d1d0146109ec5780637ff9b596146109f45780638129fc1c146109fc57806382dc1ec414610a045780638456cb5914610a2a5780638705fcd414610a325780638a279e8a14610a585780638b30b51614610a865780638cba144414610aa35780638da5cb5b14610ac95780638f32d59b14610ad157806395d89b4114610ad95780639602e9f814610ae1578063a457c2d714610ae9578063a6ea311c14610b15578063a9059cbb14610b1d578063aaa48e9f14610b49578063ad3879ad14610b6f578063afdd3fc314610ba7578063b13bd49114610bc4578063b616b63d14610c65578063b71501bc14610cda578063c498c51514610ce2578063c4d66de814610d50578063cb390f9714610d76578063d9d98ce414610d7e578063dd62ed3e14610daa578063ddca3f4314610dd8578063e92d0d5d14610de0578063f16c88db14610dfd578063f2d50ba614610f5b578063f2fde38b14610f63578063fc0c546a14610f89575b600080fd5b610366610f91565b604080516001600160a01b039092168252519081900360200190f35b61038a610fa1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61042b6004803603604081101561041557600080fd5b506001600160a01b038135169060200135611038565b604080519115158252519081900360200190f35b61045c6004803603602081101561045557600080fd5b5035611056565b005b6104846004803603602081101561047457600080fd5b50356001600160a01b03166110e2565b60408051918252519081900360200190f35b61049e6110f5565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104da5781810151838201526020016104c2565b505050509050019250505060405180910390f35b61045c6004803603606081101561050457600080fd5b810190602081018135600160201b81111561051e57600080fd5b82018360208201111561053057600080fd5b803590602001918460018302840111600160201b8311171561055157600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156105a357600080fd5b8201836020820111156105b557600080fd5b803590602001918460018302840111600160201b831117156105d657600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050903560ff1691506111579050565b610484611233565b61045c6004803603602081101561063a57600080fd5b5035611239565b6104846113cf565b610366611467565b61042b6004803603606081101561066757600080fd5b506001600160a01b0381358116916020810135909116906040013561147f565b610366611507565b610366600480360360208110156106a557600080fd5b50356001600160a01b0316611517565b610484600480360360608110156106cb57600080fd5b508035906020810135151590604001356001600160a01b0316611539565b6103666116dc565b6106f96116ec565b6040805160ff9092168252519081900360200190f35b6103666004803603602081101561072557600080fd5b50356116f5565b61042b6004803603604081101561074257600080fd5b506001600160a01b03813516906020013561171d565b61045c611771565b61036661185c565b6103666004803603602081101561077e57600080fd5b50356001600160a01b031661186c565b61042b600480360360208110156107a457600080fd5b50356001600160a01b0316611888565b61048461189c565b61045c600480360360208110156107d257600080fd5b50356001600160a01b03166118a3565b61045c600480360360208110156107f857600080fd5b50356001600160a01b031661193e565b61049e6004803603602081101561081e57600080fd5b50356001600160a01b03166119d9565b610366611ac9565b610484611ae1565b61042b611ae8565b61042b6004803603608081101561085c57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561089657600080fd5b8201836020820111156108a857600080fd5b803590602001918460018302840111600160201b831117156108c957600080fd5b509092509050611af2565b61045c600480360360208110156108ea57600080fd5b50356001600160a01b03166120b8565b6104846004803603602081101561091057600080fd5b50356001600160a01b0316612153565b6104846004803603602081101561093657600080fd5b50356001600160a01b0316612193565b61049e6121a6565b61045c6004803603602081101561096457600080fd5b50356121fe565b61045c6004803603602081101561098157600080fd5b50356001600160a01b0316612286565b61045c612321565b610484600480360360208110156109af57600080fd5b50356001600160a01b0316612333565b61045c61234e565b610366600480360360208110156109dd57600080fd5b50356123cd565b61042b6123db565b6103666123ea565b6104846123fa565b61045c612404565b61045c60048036036020811015610a1a57600080fd5b50356001600160a01b03166124aa565b61045c6124f9565b61045c60048036036020811015610a4857600080fd5b50356001600160a01b03166125c2565b61048460048036036040811015610a6e57600080fd5b506001600160a01b038135811691602001351661265d565b61048460048036036020811015610a9c57600080fd5b503561267b565b61048460048036036020811015610ab957600080fd5b50356001600160a01b03166126b7565b610366612743565b61042b612752565b61038a612778565b6103666127d9565b61042b60048036036040811015610aff57600080fd5b506001600160a01b0381351690602001356127f1565b61049e61285f565b61042b60048036036040811015610b3357600080fd5b506001600160a01b0381351690602001356128c0565b61048460048036036020811015610b5f57600080fd5b50356001600160a01b03166128f6565b61045c60048036036060811015610b8557600080fd5b506001600160a01b038135811691602081013582169160409091013516612909565b61048460048036036020811015610bbd57600080fd5b5035612994565b610bcc6129b3565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610c10578181015183820152602001610bf8565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610c4f578181015183820152602001610c37565b5050505090500194505050505060405180910390f35b61048460048036036040811015610c7b57600080fd5b81359190810190604081016020820135600160201b811115610c9c57600080fd5b820183602082011115610cae57600080fd5b803590602001918460208302840111600160201b83111715610ccf57600080fd5b509092509050612b59565b610366612ba0565b61045c60048036036020811015610cf857600080fd5b810190602081018135600160201b811115610d1257600080fd5b820183602082011115610d2457600080fd5b803590602001918460208302840111600160201b83111715610d4557600080fd5b509092509050612bb8565b61045c60048036036020811015610d6657600080fd5b50356001600160a01b0316612c5b565b61042b612d11565b61048460048036036040811015610d9457600080fd5b506001600160a01b038135169060200135612d1b565b61048460048036036040811015610dc057600080fd5b506001600160a01b0381358116916020013516612d82565b610484612dad565b61045c60048036036020811015610df657600080fd5b5035612db4565b61045c60048036036080811015610e1357600080fd5b810190602081018135600160201b811115610e2d57600080fd5b820183602082011115610e3f57600080fd5b803590602001918460208302840111600160201b83111715610e6057600080fd5b919390929091602081019035600160201b811115610e7d57600080fd5b820183602082011115610e8f57600080fd5b803590602001918460208302840111600160201b83111715610eb057600080fd5b919390929091602081019035600160201b811115610ecd57600080fd5b820183602082011115610edf57600080fd5b803590602001918460208302840111600160201b83111715610f0057600080fd5b919390929091602081019035600160201b811115610f1d57600080fd5b820183602082011115610f2f57600080fd5b803590602001918460208302840111600160201b83111715610f5057600080fd5b509092509050612e3c565b61048461308c565b61045c60048036036020811015610f7957600080fd5b50356001600160a01b0316613093565b6103666130e3565b61016d546001600160a01b031681565b60688054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561102d5780601f106110025761010080835404028352916020019161102d565b820191906000526020600020905b81548152906001019060200180831161101057829003601f168201915b505050505090505b90565b600061104c6110456130f3565b84846130f7565b5060015b92915050565b61105e612752565b61109d576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b620186a08161017181905511156110df576040805162461bcd60e51b81526020600482015260016024820152603560f81b604482015290519081900360640190fd5b50565b6101766020526000908152604090205481565b606061017380548060200260200160405190810160405280929190818152602001828054801561102d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611130575050505050905090565b600054610100900460ff168061117057506111706131e3565b8061117e575060005460ff16155b6111b95760405162461bcd60e51b815260040180806020018281038252602e815260200180615eaf602e913960400191505060405180910390fd5b600054610100900460ff161580156111e4576000805460ff1961ff0019909116610100171660011790555b83516111f7906068906020870190615b6c565b50825161120b906069906020860190615b6c565b50606a805460ff191660ff8416179055801561122d576000805461ff00191690555b50505050565b60355490565b609d8054600101908190556101365460ff16611293576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b61129b6131e9565b6112a433613268565b60005b610173548110156113385761133061017382815481106112c357fe5b6000918252602090912001546001600160a01b03163361132b6112e4611233565b61131f61131261017388815481106112f857fe5b6000918252602090912001546001600160a01b03166132a2565b899063ffffffff6133af16565b9063ffffffff61340816565b613447565b6001016112a7565b5061016a5461137d906001600160a01b03163361132b611356611233565b61016a5461131f90611370906001600160a01b03166132a2565b889063ffffffff6133af16565b6113873383613466565b609d5481146113cb576040805162461bcd60e51b815260206004820152601f6024820152600080516020615d03833981519152604482015290519081900360640190fd5b5050565b6101825461016c546101835460408051635ad5aadf60e01b81523060048201526001600160a01b0393841660248201529183166044830152516000939290921691635ad5aadf91606480820192602092909190829003018186803b15801561143657600080fd5b505afa15801561144a573d6000803e3d6000fd5b505050506040513d602081101561146057600080fd5b5051905090565b734da27a545c0c5b758a6ba100e3a049001de870f581565b600061148c848484613550565b6114978484846136fb565b6114d584336114d085604051806060016040528060288152602001615e25602891396114c38a33612d82565b919063ffffffff61384716565b6130f7565b6001600160a01b038416600090815261017660205260409020546114fc90849084906138de565b5060015b9392505050565b610169546001600160a01b031681565b6001600160a01b03808216600090815261017e6020526040902054165b919050565b609d805460010190819055610136546000919060ff1615611594576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b604080513260601b60208083019190915243603480840191909152835180840390910181526054909201909252805191012061017c556115d333613268565b60006115dd61395e565b61016a549091506115ff906001600160a01b031633308963ffffffff613a9216565b61161b8161131f88670de0b6b3a764000063ffffffff6133af16565b92506116273384613aec565b6116313384613bcc565b61163c3384836138de565b6001600160a01b0384161561168f57604080518781526001600160a01b038616602082015281517f496d589d8b7eb829a8d7b30e24a326ac33991f5cea96429b69231a6b15b54b1d929181900390910190a15b50609d5481146116d4576040805162461bcd60e51b815260206004820152601f6024820152600080516020615d03833981519152604482015290519081900360640190fd5b509392505050565b610182546001600160a01b031681565b606a5460ff1690565b610173818154811061170357fe5b6000918252602090912001546001600160a01b0316905081565b600061104c61172a6130f3565b846114d0856034600061173b6130f3565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff613c9c16565b61178161177c6130f3565b611888565b6117bc5760405162461bcd60e51b8152600401808060200182810382526030815260200180615d456030913960400191505060405180910390fd5b6101365460ff1661180b576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b610136805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61183f6130f3565b604080516001600160a01b039092168252519081900360200190a1565b61016e546001600160a01b031681565b610177602052600090815260409020546001600160a01b031681565b60006110506101038363ffffffff613cf416565b6101815481565b6118ab612752565b6118ea576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61017d80546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b611946612752565b611985576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61016c80546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b60606000806119e784612333565b610174546040805182815260208084028201019091529192508015611a16578160200160208202803883390190505b50925060005b8351811015611ac1576101748181548110611a3357fe5b60009182526020808320909101546001600160a01b0390811680845261017983526040808520928a1685529183528184205481855261017a909352922054919450611aa291670de0b6b3a76400009161131f91611a959163ffffffff613d5b16565b859063ffffffff6133af16565b848281518110611aae57fe5b6020908102919091010152600101611a1c565b505050919050565b73875773784af8135ea0ef43b5a374aad105c5d39e81565b6101715481565b6101365460ff1690565b6101365460009060ff1615611b41576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b609d80546001019081905561016a5487906001600160a01b03888116911614611b95576040805162461bcd60e51b81526020600482015260016024820152603760f81b604482015290519081900360640190fd5b6001600160a01b03811615801590611bad5750600086115b611be2576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b61016a54600090611bfb906001600160a01b03166132a2565b905080871115611dfb576000611c17888363ffffffff613d5b16565b905060008080808080808080805b61017354811015611def576101738181548110611c3e57fe5b60009182526020808320909101546001600160a01b03908116808452610177835260409384902054845163015de72360e11b81529451919d50909116965086926302bbce46926004808301939192829003018186803b158015611ca057600080fd5b505afa158015611cb4573d6000803e3d6000fd5b505050506040513d6020811015611cca57600080fd5b505160408051637437535960e01b815290519196506001600160a01b03861691637437535991600480820192602092909190829003018186803b158015611d1057600080fd5b505afa158015611d24573d6000803e3d6000fd5b505050506040513d6020811015611d3a57600080fd5b50519650611d63670de0b6b3a764000061131f87611d578d6132a2565b9063ffffffff6133af16565b97508a88101591508a871015925081611d8b5786881115611d845786611d86565b875b611d98565b82611d965786611d98565b8a5b9950611dbf89611dba8761131f8e670de0b6b3a764000063ffffffff6133af16565b613d9d565b9550818015611dcb5750825b15611dd557611def565b611de58b8763ffffffff613d5b16565b9a50600101611c25565b50505050505050505050505b61016a548790611e13906001600160a01b03166132a2565b1015611e4a576040805162461bcd60e51b81526020600482015260016024820152603360f81b604482015290519081900360640190fd5b61016a54611e62906001600160a01b03168389613447565b61016a54600090611e7c906001600160a01b031689612d1b565b905060405180807f45524333313536466c617368426f72726f7765722e6f6e466c6173684c6f616e815250602001905060405180910390208a6001600160a01b03166323e30c8b3361016a60009054906101000a90046001600160a01b03168c868d8d6040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050602060405180830381600087803b158015611f8057600080fd5b505af1158015611f94573d6000803e3d6000fd5b505050506040513d6020811015611faa57600080fd5b505114611fe2576040805162461bcd60e51b81526020600482015260016024820152600760fb1b604482015290519081900360640190fd5b6120128330611ff78b8563ffffffff613c9c16565b61016a546001600160a01b031692919063ffffffff613a9216565b61201a613e3e565b506040805189815260208101839052815133926001600160a01b038716927f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f0929081900390910190a360019450505050609d5481146120ae576040805162461bcd60e51b815260206004820152601f6024820152600080516020615d03833981519152604482015290519081900360640190fd5b5095945050505050565b6120c0612752565b6120ff576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61018380546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b61016a546000906001600160a01b03838116911614156115345761218c670de0b6b3a764000061131f612184611233565b611d5761395e565b9050611534565b6101786020526000908152604090205481565b606061018080548060200260200160405190810160405280929190818152602001828054801561102d57602002820191906000526020600020905b8154815260200190600101908083116121e1575050505050905090565b612206612752565b612245576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b6101728190556127108111156110df576040805162461bcd60e51b81526020600482015260016024820152603560f81b604482015290519081900360640190fd5b61228e612752565b6122cd576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61016d80546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b61233161232c6130f3565b6141e9565b565b6001600160a01b031660009081526033602052604090205490565b612356612752565b612395576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b60d0546040516000916001600160a01b031690600080516020615e6d833981519152908390a360d080546001600160a01b0319169055565b610174818154811061170357fe5b60006123e5613e3e565b905090565b61017d546001600160a01b031681565b60006123e561395e565b600054610100900460ff168061241d575061241d6131e3565b8061242b575060005460ff16155b6124665760405162461bcd60e51b815260040180806020018281038252602e815260200180615eaf602e913960400191505060405180910390fd5b600054610100900460ff16158015612491576000805460ff1961ff0019909116610100171660011790555b6001609d5580156110df576000805461ff001916905550565b6124b561177c6130f3565b6124f05760405162461bcd60e51b8152600401808060200182810382526030815260200180615d456030913960400191505060405180910390fd5b6110df81614232565b61250461177c6130f3565b61253f5760405162461bcd60e51b8152600401808060200182810382526030815260200180615d456030913960400191505060405180910390fd5b6101365460ff161561258b576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b610136805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861183f6130f3565b6125ca612752565b612609576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b61016e80546001600160a01b0319166001600160a01b0383169081179091556110df576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b61017960209081526000928352604080842090915290825290205481565b600061105082610174805490506040519080825280602002602001820160405280156126b1578160200160208202803883390190505b5061427b565b6001600160a01b038116600090815261017660205260408120546126d961395e565b915080158015906126e957508082115b1561273d5761273a620186a061131f61271b61270b868663ffffffff613d5b16565b610172549063ffffffff6133af16565b61272e86620186a063ffffffff6133af16565b9063ffffffff613d5b16565b91505b50919050565b60d0546001600160a01b031690565b60d0546000906001600160a01b03166127696130f3565b6001600160a01b031614905090565b60698054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561102d5780601f106110025761010080835404028352916020019161102d565b73275da8e61ea8e02d51edd8d0dc5c0e62b4cdb0be81565b600061104c6127fe6130f3565b846114d085604051806060016040528060258152602001615f9160259139603460006128286130f3565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61384716565b606061017480548060200260200160405190810160405280929190818152602001828054801561102d576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311611130575050505050905090565b60006128cd338484613550565b6128d83384846136fb565b336000908152610176602052604090205461104c90849084906138de565b61017a6020526000908152604090205481565b610182546001600160a01b03161561294c576040805162461bcd60e51b81526020600482015260016024820152603160f81b604482015290519081900360640190fd5b61018280546001600160a01b039485166001600160a01b03199182161790915560506101815561018380549385169382169390931790925561017d8054919093169116179055565b61017581815481106129a257fe5b600091825260209091200154905081565b6101825460408051634a4b15d160e01b8152306004820152905160609283926001600160a01b0390911691634a4b15d191602480820192600092909190829003018186803b158015612a0457600080fd5b505afa158015612a18573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015612a4157600080fd5b8101908080516040519392919084600160201b821115612a6057600080fd5b908301906020820185811115612a7557600080fd5b82518660208202830111600160201b82111715612a9157600080fd5b82525081516020918201928201910280838360005b83811015612abe578181015183820152602001612aa6565b5050505090500160405260200180516040519392919084600160201b821115612ae657600080fd5b908301906020820185811115612afb57600080fd5b82518660208202830111600160201b82111715612b1757600080fd5b82525081516020918201928201910280838360005b83811015612b44578181015183820152602001612b2c565b50505050905001604052505050915091509091565b6000612b988484848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061427b92505050565b949350505050565b73c00e94cb662c3520282e6f5717214004a7f2688881565b61016d546001600160a01b0316331480612bea5750612bd5612743565b6001600160a01b0316336001600160a01b0316145b612c1f576040805162461bcd60e51b81526020600482015260016024820152601b60f91b604482015290519081900360640190fd5b6113cb82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061438492505050565b600054610100900460ff1680612c745750612c746131e3565b80612c82575060005460ff16155b612cbd5760405162461bcd60e51b815260040180806020018281038252602e815260200180615eaf602e913960400191505060405180910390fd5b600054610100900460ff16158015612ce8576000805460ff1961ff0019909116610100171660011790555b612cf18261444e565b610136805460ff1916905580156113cb576000805461ff00191690555050565b61017f5460ff1681565b61016a546000906001600160a01b03848116911614612d65576040805162461bcd60e51b81526020600482015260016024820152603760f81b604482015290519081900360640190fd5b611500620186a061131f61018154856133af90919063ffffffff16565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b6101725481565b612dbc612752565b612dfb576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b620186a081610181819055106110df576040805162461bcd60e51b81526020600482015260016024820152600d60fa1b604482015290519081900360640190fd5b612e44612752565b612e83576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b868514612ebb576040805162461bcd60e51b81526020600482015260016024820152601960f91b604482015290519081900360640190fd5b86811015612ef4576040805162461bcd60e51b81526020600482015260016024820152603360f81b604482015290519081900360640190fd5b612f016101748585615bea565b50600080805b89811015613071578a8a82818110612f1b57fe5b905060200201356001600160a01b0316915060006001600160a01b0316826001600160a01b031614158015612f7557506000898983818110612f5957fe5b905060200201356001600160a01b03166001600160a01b031614155b612faa576040805162461bcd60e51b81526020600482015260016024820152600360fc1b604482015290519081900360640190fd5b888882818110612fb657fe5b6001600160a01b0385811660009081526101776020908152604090912080546001600160a01b031916939091029490940135161790915550848482818110612ffa57fe5b905060200201356001600160a01b0316925073875773784af8135ea0ef43b5a374aad105c5d39e6001600160a01b0316836001600160a01b031614613069576001600160a01b03828116600090815261017e6020526040902080546001600160a01b0319169185169190911790555b600101612f07565b5061307f6101738b8b615bea565b5050505050505050505050565b61016f5481565b61309b612752565b6130da576040805162461bcd60e51b81526020600482018190526024820152600080516020615e4d833981519152604482015290519081900360640190fd5b6110df81614506565b61016a546001600160a01b031681565b3390565b6001600160a01b03831661313c5760405162461bcd60e51b8152600401808060200182810382526024815260200180615f436024913960400191505060405180910390fd5b6001600160a01b0382166131815760405162461bcd60e51b8152600401808060200182810382526022815260200180615d9b6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260346020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b303b1590565b61017c54324360405160200180836001600160a01b03166001600160a01b031660601b815260140182815260200192505050604051602081830303815290604052805190602001201415612331576040805162461bcd60e51b81526020600482015260016024820152603960f81b604482015290519081900360640190fd5b6110df816101748054905060405190808252806020026020018201604052801561329c578160200160208202803883390190505b50614595565b604080513060248083019190915282518083039091018152604490910182526020810180516001600160e01b03166370a0823160e01b1781529151815160009384936060936001600160a01b03881693919290918291908083835b6020831061331c5780518252601f1990920191602091820191016132fd565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461337c576040519150601f19603f3d011682016040523d82523d6000602084013e613381565b606091505b50915091508161339057600080fd5b8080602001905160208110156133a557600080fd5b5051949350505050565b6000826133be57506000611050565b828202828482816133cb57fe5b04146115005760405162461bcd60e51b8152600401808060200182810382526021815260200180615e046021913960400191505060405180910390fd5b600061150083836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b81525061491e565b6134616001600160a01b038416838363ffffffff61498316565b505050565b6001600160a01b0382166134ab5760405162461bcd60e51b8152600401808060200182810382526021815260200180615efd6021913960400191505060405180910390fd5b6134ee81604051806060016040528060228152602001615d23602291396001600160a01b038516600090815260336020526040902054919063ffffffff61384716565b6001600160a01b03831660009081526033602052604090205560355461351a908263ffffffff613d5b16565b6035556040805182815290516000916001600160a01b03851691600080516020615edd8339815191529181900360200190a35050565b600080600080600061356187612333565b905060005b610174548110156136f057610174818154811061357f57fe5b6000918252602090912001546001600160a01b03169550816135d1576001600160a01b038681166000908152610179602090815260408083208d8516845290915280822054928b1682529020556136e8565b6001600160a01b03808716600090815261017a60209081526040808320546101798352818420948e1684529390915290205490955061361790869063ffffffff613d5b16565b6001600160a01b03808816600090815261017960209081526040808320938d168352929052205490945061366490670de0b6b3a76400009061131f90611a9590899063ffffffff613d5b16565b92506136c06136b361367c848a63ffffffff613c9c16565b61131f61368f888c63ffffffff6133af16565b6136a788670de0b6b3a764000063ffffffff6133af16565b9063ffffffff613c9c16565b869063ffffffff613d5b16565b6001600160a01b03808816600090815261017960209081526040808320938d16835292905220555b600101613566565b505050505050505050565b6001600160a01b0383166137405760405162461bcd60e51b8152600401808060200182810382526025815260200180615f1e6025913960400191505060405180910390fd5b6001600160a01b0382166137855760405162461bcd60e51b8152600401808060200182810382526023815260200180615ce06023913960400191505060405180910390fd5b6137c881604051806060016040528060268152602001615dbd602691396001600160a01b038616600090815260336020526040902054919063ffffffff61384716565b6001600160a01b0380851660009081526033602052604080822093909355908416815220546137fd908263ffffffff613c9c16565b6001600160a01b038084166000818152603360209081526040918290209490945580518581529051919392871692600080516020615edd83398151915292918290030190a3505050565b600081848411156138d65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561389b578181015183820152602001613883565b50505050905090810190601f1680156138c85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60006138e984612333565b905061393b8161131f613902858763ffffffff6133af16565b6136a7613915868963ffffffff613d5b16565b6001600160a01b038a16600090815261017660205260409020549063ffffffff6133af16565b6001600160a01b0390941660009081526101766020526040902093909355505050565b600080613969611233565b90508061397e57505061017054600a0a611035565b61016a5460009081906139a790670de0b6b3a764000090611d57906001600160a01b03166132a2565b90506060610173805480602002602001604051908101604052809291908181526020018280548015613a0257602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116139e4575b50939450600093505050505b8151811015613a7857818181518110613a2357fe5b60200260200101519350613a6e613a61613a3c866132a2565b6001600160a01b0380881660009081526101776020526040902054611d5791166149d5565b849063ffffffff613c9c16565b9250600101613a0e565b50613a89828563ffffffff61340816565b94505050505090565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261122d908590614a42565b6001600160a01b038216613b47576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b603554613b5a908263ffffffff613c9c16565b6035556001600160a01b038216600090815260336020526040902054613b86908263ffffffff613c9c16565b6001600160a01b0383166000818152603360209081526040808320949094558351858152935192939192600080516020615edd8339815191529281900390910190a35050565b600080613bd884612333565b90506000805b61017454811015613c94576101748181548110613bf757fe5b60009182526020808320909101546001600160a01b0390811680845261017983526040808520928b1685529183528184205481855261017a9093529220549195509250613c6590613c5890859061131f90611312908763ffffffff613d5b16565b839063ffffffff613c9c16565b6001600160a01b03808616600090815261017960209081526040808320938b1683529290522055600101613bde565b505050505050565b600082820183811015611500576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b60006001600160a01b038216613d3b5760405162461bcd60e51b8152600401808060200182810382526022815260200180615e8d6022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b600061150083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613847565b60008115611050576001600160a01b038084166000908152610177602052604090205416613dcc848285613447565b604080516395a2251f60e01b815230600482015290516001600160a01b038316916395a2251f9160248083019260209291908290030181600087803b158015613e1457600080fd5b505af1158015613e28573d6000803e3d6000fd5b505050506040513d60208110156133a557600080fd5b6101365460009060ff1615613e8d576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6060610180805480602002602001604051908101604052809291908181526020018280548015613edc57602002820191906000526020600020905b815481526020019060010190808311613ec8575b505050505090506060610175805480602002602001604051908101604052809291908181526020018280548015613f3257602002820191906000526020600020905b815481526020019060010190808311613f1e575b50508351865194955093841492505081159050613f9d5760005b82811080613f58575081155b15613f9b57848181518110613f6957fe5b6020026020010151848281518110613f7d57fe5b602002602001015114613f935760009150613f9b565b600101613f4c565b505b61016a54600090613fb6906001600160a01b03166132a2565b9050818015613fc3575080155b15613fd657600095505050505050611035565b6000613fee620186a061131f61017154611d57614bfa565b9050821561402657808211156140175761401786614012848463ffffffff613d5b16565b614cfa565b60009650505050505050611035565b60606000614032614e54565b9092509050614047818563ffffffff613c9c16565b90506101715481111561406757614064818463ffffffff613d5b16565b90505b606060008061407f8561407a8d87614f75565b615058565b925092509250806140ad576140976101756000615c49565b8a516140ab906101759060208e0190615c67565b505b61016a546000906140c6906001600160a01b03166132a2565b90508681116140e45760009c50505050505050505050505050611035565b60608451604051908082528060200260200182016040528015614111578160200160208202803883390190505b50905060005b855181101561416c5761414d8561131f620186a089858151811061413757fe5b60200260200101516133af90919063ffffffff16565b82828151811061415957fe5b6020908102919091010152600101614117565b5061418181614012848b63ffffffff613d5b16565b7f4217d9fab39dbadacf1dad6c889aec1caa02e8a6cb59ddd4ce34f3e0ef158b55336141b3888b63ffffffff613c9c16565b604080516001600160a01b03909316835260208301919091528051918290030190a160019d505050505050505050505050505090565b6141fb6101038263ffffffff6152ed16565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b6142446101038263ffffffff61535416565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b609d8054600101908190556000906142916131e9565b61429b3384614595565b83156143395760006142ab61395e565b905060006142cb670de0b6b3a764000061131f888563ffffffff6133af16565b61016a549091506000906142e7906001600160a01b03166132a2565b905080821115614302576142fb87826153d5565b9450614306565b8194505b6143118786856154c5565b945061431d3388613466565b61016a54614335906001600160a01b03163387613447565b5050505b609d54811461437d576040805162461bcd60e51b815260206004820152601f6024820152600080516020615d03833981519152604482015290519081900360640190fd5b5092915050565b610173548151146143c0576040805162461bcd60e51b81526020600482015260016024820152601960f91b604482015290519081900360640190fd5b6000805b82518110156143fd576143f38382815181106143dc57fe5b602002602001015183613c9c90919063ffffffff16565b91506001016143c4565b50815161441290610180906020850190615c67565b50620186a081146113cb576040805162461bcd60e51b81526020600482015260016024820152603760f81b604482015290519081900360640190fd5b600054610100900460ff168061446757506144676131e3565b80614475575060005460ff16155b6144b05760405162461bcd60e51b815260040180806020018281038252602e815260200180615eaf602e913960400191505060405180910390fd5b600054610100900460ff161580156144db576000805460ff1961ff0019909116610100171660011790555b6144e482611888565b6144f1576144f182614232565b80156113cb576000805461ff00191690555050565b6001600160a01b03811661454b5760405162461bcd60e51b8152600401808060200182810382526026815260200180615d756026913960400191505060405180910390fd5b60d0546040516001600160a01b03808416921690600080516020615e6d83398151915290600090a360d080546001600160a01b0319166001600160a01b0392909216919091179055565b60606101748054806020026020016040519081016040528092919081815260200182805480156145ee57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116145d0575b5050505050905080516000141561460557506113cb565b600061460f611233565b9050600061461c85612333565b905060008215613c945760005b84518110156149155784818151811061463e57fe5b6020026020010151915061465182615553565b600061465c836132a2565b905080156146f7576001600160a01b038316600090815261017860205260409020546146cd906146a790879061131f90670de0b6b3a764000090611d5790879063ffffffff613d5b16565b6001600160a01b038516600090815261017a60205260409020549063ffffffff613c9c16565b6001600160a01b038416600090815261017a60209081526040808320939093556101789052208190555b83156148da576001600160a01b03808416600081815261017960209081526040808320948d1683529381528382205492825261017a905291822054909190614745908363ffffffff613d5b16565b905080156148d757600061476b670de0b6b3a764000061131f898563ffffffff6133af16565b90506000614778876132a2565b905080821115614786578091505b8a868151811061479257fe5b602002602001015115614812576147f36147cd6147b58b8b63ffffffff613d5b16565b61131f85670de0b6b3a764000063ffffffff6133af16565b6001600160a01b038916600090815261017a60205260409020549063ffffffff613c9c16565b6001600160a01b038816600090815261017a60205260409020556148d4565b61016e546000906001600160a01b0316158015906148335750600061017254115b801561485c57506001600160a01b03881673875773784af8135ea0ef43b5a374aad105c5d39e14155b1561489a5761487e620186a061131f61017254866133af90919063ffffffff16565b61016e5490915061489a9089906001600160a01b031683613447565b6148af888e61132b868563ffffffff613d5b16565b6148b8886132a2565b6001600160a01b03891660009081526101786020526040902055505b50505b50505b506001600160a01b03808316600090815261017a60209081526040808320546101798352818420948c16845293909152902055600101614629565b50505050505050565b6000818361496d5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561389b578181015183820152602001613883565b50600083858161497957fe5b0495945050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613461908490614a42565b6000816001600160a01b03166302bbce466040518163ffffffff1660e01b815260040160206040518083038186803b158015614a1057600080fd5b505afa158015614a24573d6000803e3d6000fd5b505050506040513d6020811015614a3a57600080fd5b505192915050565b614a54826001600160a01b0316615b33565b614aa5576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310614ae35780518252601f199092019160209182019101614ac4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614b45576040519150601f19603f3d011682016040523d82523d6000602084013e614b4a565b606091505b509150915081614ba1576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561122d57808060200190516020811015614bbd57600080fd5b505161122d5760405162461bcd60e51b815260040180806020018281038252602a815260200180615f67602a913960400191505060405180910390fd5b6000806060610173805480602002602001604051908101604052809291908181526020018280548015614c5657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614c38575b50939450600093505050505b8151811015614cd857818181518110614c7757fe5b60200260200101519250614cce614cc1670de0b6b3a764000061131f614c9c876132a2565b6001600160a01b0380891660009081526101776020526040902054611d5791166149d5565b859063ffffffff613c9c16565b9350600101614c62565b5061016a54614cf390613a61906001600160a01b03166132a2565b9250505090565b6060614d068383614f75565b90506000806060610173805480602002602001604051908101604052809291908181526020018280548015614d6457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614d46575b50939450600093505050505b845181101561491557848181518110614d8557fe5b6020026020010151935083600014614e4c576101776000838381518110614da857fe5b6020908102919091018101516001600160a01b039081168352908201929092526040016000205461016a549082169450614de491168486613447565b826001600160a01b0316631249c58b6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614e1f57600080fd5b505af1158015614e33573d6000803e3d6000fd5b505050506040513d6020811015614e4957600080fd5b50505b600101614d70565b60606000806060610173805480602002602001604051908101604052809291908181526020018280548015614eb257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614e94575b5050505050905060008151905080604051908082528060200260200182016040528015614ee9578160200160208202803883390190505b50945060005b81811015614f6d57828181518110614f0357fe5b60200260200101519350614f25670de0b6b3a764000061131f614c9c876132a2565b868281518110614f3157fe5b602002602001018181525050614f63868281518110614f4c57fe5b602002602001015186613c9c90919063ffffffff16565b9450600101614eef565b505050509091565b60608251604051908082528060200260200182016040528015614fa2578160200160208202803883390190505b509050600080805b855181101561504f576001865103811415614fec57614fcf858363ffffffff613d5b16565b848281518110614fdb57fe5b602002602001018181525050615047565b615019620186a061131f88848151811061500257fe5b6020026020010151886133af90919063ffffffff16565b925061502b828463ffffffff613c9c16565b91508284828151811061503a57fe5b6020026020010181815250505b600101614faa565b50505092915050565b60606000808451604051908082528060200260200182016040528015615088578160200160208202803883390190505b50925060008060008060606101738054806020026020016040519081016040528092919081815260200182805480156150ea57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116150cc575b50939450600093505050505b8a518110156152e05781818151811061510b57fe5b6020026020010151925089818151811061512157fe5b602002602001015193508a818151811061513757fe5b6020908102919091018101516001600160a01b0380861660009081526101779093526040909220549091169650945083851115615287576000615180868663ffffffff613d5b16565b90506000876001600160a01b031663743753596040518163ffffffff1660e01b815260040160206040518083038186803b1580156151bd57600080fd5b505afa1580156151d1573d6000803e3d6000fd5b505050506040513d60208110156151e757600080fd5b50519050818110156151fb57600198508091505b61527f85611dba8a6001600160a01b03166302bbce466040518163ffffffff1660e01b815260040160206040518083038186803b15801561523b57600080fd5b505afa15801561524f573d6000803e3d6000fd5b505050506040513d602081101561526557600080fd5b505161131f86670de0b6b3a764000063ffffffff6133af16565b5050506152d8565b615297848663ffffffff613d5b16565b8982815181106152a357fe5b6020026020010181815250506152d58982815181106152be57fe5b602002602001015189613c9c90919063ffffffff16565b97505b6001016150f6565b5050505050509250925092565b6152f78282613cf4565b6153325760405162461bcd60e51b8152600401808060200182810382526021815260200180615de36021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b61535e8282613cf4565b156153b0576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008060006153e2611233565b9050606061017380548060200260200160405190810160405280929190818152602001828054801561543d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161541f575b50939450600093505050505b81518110156154a35781818151811061545e57fe5b6020026020010151935061549961548c85611dba8661131f61547f8a6132a2565b8d9063ffffffff6133af16565b869063ffffffff613c9c16565b9450600101615449565b506154bb614cc18361131f898963ffffffff6133af16565b9695505050505050565b3360009081526101766020526040812054808310156154e75783915050611500565b600061552169152d02c7e14af680000061131f61017254611d57615514878a613d5b90919063ffffffff16565b8b9063ffffffff6133af16565b61016a5461016e54919250615543916001600160a01b03918216911683613447565b6154bb858263ffffffff613d5b16565b6001600160a01b03811673c00e94cb662c3520282e6f5717214004a7f26888148061559a57506001600160a01b03811673875773784af8135ea0ef43b5a374aad105c5d39e145b806155c157506001600160a01b038116734da27a545c0c5b758a6ba100e3a049001de870f5145b156110df576040805160018082528183019092526060916020808301908038833901905050905030816000815181106155f657fe5b6001600160a01b039283166020918202929092010152821673875773784af8135ea0ef43b5a374aad105c5d39e141561571c5760408051637e122ea560e11b81526004810191825282516044820152825173275da8e61ea8e02d51edd8d0dc5c0e62b4cdb0be9263fc245d4a92859283929182916024820191606401906020808701910280838360005b83811015615698578181015183820152602001615680565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156156d75781810151838201526020016156bf565b50505050905001945050505050600060405180830381600087803b1580156156fe57600080fd5b505af1158015615712573d6000803e3d6000fd5b50505050506110df565b604080516001808252818301909252606091602080830190803883390190505090506001600160a01b038316734da27a545c0c5b758a6ba100e3a049001de870f51480156157755750610183546001600160a01b031615155b15615973576101835481516001600160a01b0390911690829060009061579757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506000816000815181106157c657fe5b60200260200101516001600160a01b03166375d264136040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561580857600080fd5b505af115801561581c573d6000803e3d6000fd5b505050506040513d602081101561583257600080fd5b505160408051630cc7d40f60e11b815230600482015290519192506001600160a01b03831691633111e7b3918591849163198fa81e916024808301926020929190829003018186803b15801561588757600080fd5b505afa15801561589b573d6000803e3d6000fd5b505050506040513d60208110156158b157600080fd5b50516040516001600160e01b031960e085901b168152602481018290523060448201819052606060048301908152845160648401528451919290918291608401906020878101910280838360005b838110156159175781810151838201526020016158ff565b50505050905001945050505050602060405180830381600087803b15801561593e57600080fd5b505af1158015615952573d6000803e3d6000fd5b505050506040513d602081101561596857600080fd5b506110df9350505050565b61016c546001600160a01b0316156134615761016c5481516001600160a01b039091169082906000906159a257fe5b60200260200101906001600160a01b031690816001600160a01b031681525050806000815181106159cf57fe5b60200260200101516001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015615a0f57600080fd5b505afa158015615a23573d6000803e3d6000fd5b505050506040513d6020811015615a3957600080fd5b50516040516334086fd360e11b81526000604482018190526001606483018190526080600484019081528651608485015286516001600160a01b0390951694636810dfa694889488949093909290918291602482019160a40190602089810191028083838a5b83811015615ab7578181015183820152602001615a9f565b50505050905001838103825286818151815260200191508051906020019060200280838360005b83811015615af6578181015183820152602001615ade565b505050509050019650505050505050600060405180830381600087803b158015615b1f57600080fd5b505af1158015614915573d6000803e3d6000fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612b98575050151592915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615bad57805160ff1916838001178555615bda565b82800160010185558215615bda579182015b82811115615bda578251825591602001919060010190615bbf565b50615be6929150615ca1565b5090565b828054828255906000526020600020908101928215615c3d579160200282015b82811115615c3d5781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190615c0a565b50615be6929150615cbb565b50805460008255906000526020600020908101906110df9190615ca1565b828054828255906000526020600020908101928215615bda5791602002820182811115615bda578251825591602001919060010190615bbf565b61103591905b80821115615be65760008155600101615ca7565b61103591905b80821115615be65780546001600160a01b0319168155600101615cc156fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573735265656e7472616e637947756172643a207265656e7472616e742063616c6c0045524332303a206275726e20616d6f756e7420657863656564732062616c616e6365506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65728be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef45524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820fd747cb213c95855899fc35208dc11f88f530fbf5bfddafb5d2ccd64b39e9b3264736f6c63430005100032
Deployed Bytecode Sourcemap
49600:43566:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49600:43566:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50072:25;;;:::i;:::-;;;;-1:-1:-1;;;;;50072:25:0;;;;;;;;;;;;;;27927:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;27927:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21370:152;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;21370:152:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;57627:127;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57627:127:0;;:::i;:::-;;51007:48;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51007:48:0;-1:-1:-1;;;;;51007:48:0;;:::i;:::-;;;;;;;;;;;;;;;;59226:112;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;59226:112:0;;;;;;;;;;;;;;;;;27671:186;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;27671:186:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;27671:186:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;27671:186:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;27671:186:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;27671:186:0;;;;;;;;-1:-1:-1;27671:186:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;27671:186:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;27671:186:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;27671:186:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;27671:186:0;;-1:-1:-1;;;27671:186:0;;;;;-1:-1:-1;27671:186:0;;-1:-1:-1;27671:186:0:i;20391:91::-;;;:::i;69948:574::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69948:574:0;;:::i;60907:148::-;;;:::i;53369:85::-;;;:::i;61379:410::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;61379:410:0;;;;;;;;;;;;;;;;;:::i;48059:20::-;;;:::i;59487:141::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59487:141:0;-1:-1:-1;;;;;59487:141:0;;:::i;65011:800::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65011:800:0;;;;;;;;;;;;;-1:-1:-1;;;;;65011:800:0;;:::i;52896:26::-;;;:::i;28779:83::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;50570:35;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50570:35:0;;:::i;22707:210::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;22707:210:0;;;;;;;;:::i;37573:120::-;;;:::i;50143:25::-;;;:::i;51107:51::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51107:51:0;-1:-1:-1;;;;;51107:51:0;;:::i;34897:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;34897:109:0;-1:-1:-1;;;;;34897:109:0;;:::i;52833:27::-;;;:::i;57321:128::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57321:128:0;-1:-1:-1;;;;;57321:128:0;;:::i;55976:121::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55976:121:0;-1:-1:-1;;;;;55976:121:0;;:::i;64082:418::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64082:418:0;-1:-1:-1;;;;;64082:418:0;;:::i;52039:82::-;;;:::i;50399:28::-;;;:::i;36780:78::-;;;:::i;72062:3641::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;72062:3641:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;72062:3641:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72062:3641:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;72062:3641:0;;-1:-1:-1;72062:3641:0;-1:-1:-1;72062:3641:0;:::i;56213:121::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56213:121:0;-1:-1:-1;;;;;56213:121:0;;:::i;71435:171::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71435:171:0;-1:-1:-1;;;;;71435:171:0;;:::i;51222:57::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51222:57:0;-1:-1:-1;;;;;51222:57:0;;:::i;58785:112::-;;;:::i;56784:155::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56784:155:0;;:::i;56478:137::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56478:137:0;-1:-1:-1;;;;;56478:137:0;;:::i;35114:79::-;;;:::i;20545:110::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20545:110:0;-1:-1:-1;;;;;20545:110:0;;:::i;32370:140::-;;;:::i;50651:26::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50651:26:0;;:::i;70751:77::-;;;:::i;52489:21::-;;;:::i;60337:97::-;;;:::i;29723:218::-;;;:::i;35014:92::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;35014:92:0;-1:-1:-1;;;;;35014:92:0;;:::i;37360:118::-;;;:::i;57049:137::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57049:137:0;-1:-1:-1;;;;;57049:137:0;;:::i;51392:78::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;51392:78:0;;;;;;;;;;:::i;66749:156::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66749:156:0;;:::i;59861:359::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59861:359:0;-1:-1:-1;;;;;59861:359:0;;:::i;31557:79::-;;;:::i;31923:94::-;;;:::i;28129:87::-;;;:::i;52331:92::-;;;:::i;23420:261::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;23420:261:0;;;;;;;;:::i;59000:94::-;;;:::i;62072:280::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;62072:280:0;;;;;;;;:::i;51576:52::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51576:52:0;-1:-1:-1;;;;;51576:52:0;;:::i;53794:250::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;53794:250:0;;;;;;;;;;;;;;;;;;;:::i;50882:32::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50882:32:0;;:::i;60630:160::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;60630:160:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;60630:160:0;;;;;;;;;;;;;;;;;;;67368:191;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;67368:191:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;67368:191:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;67368:191:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;67368:191:0;;-1:-1:-1;67368:191:0;-1:-1:-1;67368:191:0;:::i;52158:82::-;;;:::i;57915:178::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;57915:178:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;57915:178:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;57915:178:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;57915:178:0;;-1:-1:-1;57915:178:0;-1:-1:-1;57915:178:0;:::i;36549:131::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36549:131:0;-1:-1:-1;;;;;36549:131:0;;:::i;52642:26::-;;;:::i;71084:178::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;71084:178:0;;;;;;;;:::i;21089:134::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;21089:134:0;;;;;;;;;;:::i;50501:18::-;;;:::i;55724:136::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55724:136:0;;:::i;54685:902::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;54685:902:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;54685:902:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;54685:902:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;54685:902:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;54685:902:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;54685:902:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;54685:902:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;54685:902:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;54685:902:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;54685:902:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;54685:902:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;54685:902:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;54685:902:0;;-1:-1:-1;54685:902:0;-1:-1:-1;54685:902:0;:::i;50251:30::-;;;:::i;32665:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32665:109:0;-1:-1:-1;;;;;32665:109:0;;:::i;49894:20::-;;;:::i;50072:25::-;;;-1:-1:-1;;;;;50072:25:0;;:::o;27927:83::-;27997:5;27990:12;;;;;;;;-1:-1:-1;;27990:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27964:13;;27990:12;;27997:5;;27990:12;;27997:5;27990:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27927:83;;:::o;21370:152::-;21436:4;21453:39;21462:12;:10;:12::i;:::-;21476:7;21485:6;21453:8;:39::i;:::-;-1:-1:-1;21510:4:0;21370:152;;;;;:::o;57627:127::-;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;57736:6;57726:5;57710:13;:21;;;57709:33;;57701:47;;;;;-1:-1:-1;;;57701:47:0;;;;;;;;;;;;-1:-1:-1;;;57701:47:0;;;;;;;;;;;;;;;57627:127;:::o;51007:48::-;;;;;;;;;;;;;:::o;59226:112::-;59282:16;59314:18;59307:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59307:25:0;;;;;;;;;;;;;;;;;;;;;;59226:112;:::o;27671:186::-;16510:12;;;;;;;;:31;;;16526:15;:13;:15::i;:::-;16510:47;;;-1:-1:-1;16546:11:0;;;;16545:12;16510:47;16502:106;;;;-1:-1:-1;;;16502:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16617:19;16640:12;;;;;;16639:13;16659:83;;;;16688:12;:19;;-1:-1:-1;;;;16688:19:0;;;;;16716:18;16703:4;16716:18;;;16659:83;27779:12;;;;:5;;:12;;;;;:::i;:::-;-1:-1:-1;27802:16:0;;;;:7;;:16;;;;;:::i;:::-;-1:-1:-1;27829:9:0;:20;;-1:-1:-1;;27829:20:0;;;;;;;16760:57;;;;16804:5;16789:20;;-1:-1:-1;;16789:20:0;;;16760:57;27671:186;;;;:::o;20391:91::-;20462:12;;20391:91;:::o;69948:574::-;30360:13;:18;;30377:1;30360:18;;;;;37216:7;;;;37208:40;;;;;-1:-1:-1;;;37208:40:0;;;;;;;;;;;;-1:-1:-1;;;37208:40:0;;;;;;;;;;;;;;;70049:24;:22;:24::i;:::-;70084:28;70101:10;70084:16;:28::i;:::-;70128:9;70123:202;70147:18;:25;70143:29;;70123:202;;;70190:125;70206:18;70225:1;70206:21;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70206:21:0;70229:10;70241:73;70300:13;:11;:13::i;:::-;70241:54;70253:41;70272:18;70291:1;70272:21;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70272:21:0;70253:18;:41::i;:::-;70241:7;;:54;:11;:54;:::i;:::-;:58;:73;:58;:73;:::i;:::-;70190:15;:125::i;:::-;70174:3;;70123:202;;;-1:-1:-1;70404:5:0;;70388:93;;-1:-1:-1;;;;;70404:5:0;70411:10;70423:57;70466:13;:11;:13::i;:::-;70454:5;;70423:38;;70435:25;;-1:-1:-1;;;;;70454:5:0;70435:18;:25::i;:::-;70423:7;;:38;:11;:38;:::i;70388:93::-;70490:26;70496:10;70508:7;70490:5;:26::i;:::-;30472:13;;30456:12;:29;30448:73;;;;;-1:-1:-1;;;30448:73:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30448:73:0;;;;;;;;;;;;;;;69948:574;;:::o;60907:148::-;60999:11;;61034:6;;61042;;60982:67;;;-1:-1:-1;;;60982:67:0;;61027:4;60982:67;;;;-1:-1:-1;;;;;61034:6:0;;;60982:67;;;;61042:6;;;60982:67;;;;;60959:7;;60999:11;;;;;60982:36;;:67;;;;;;;;;;;;;;;60999:11;60982:67;;;5:2:-1;;;;30:1;27;20:12;5:2;60982:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60982:67:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60982:67:0;;-1:-1:-1;60907:148:0;:::o;53369:85::-;53411:42;53369:85;:::o;61379:410::-;61468:4;61481:52;61507:6;61515:9;61526:6;61481:25;:52::i;:::-;61540:36;61550:6;61558:9;61569:6;61540:9;:36::i;:::-;61583:115;61592:6;61600:10;61612:85;61646:6;61612:85;;;;;;;;;;;;;;;;;:29;61622:6;61630:10;61612:9;:29::i;:::-;:33;:85;;:33;:85;:::i;:::-;61583:8;:115::i;:::-;-1:-1:-1;;;;;61743:21:0;;;;;;:13;:21;;;;;;61705:60;;61724:9;;61735:6;;61705:18;:60::i;:::-;-1:-1:-1;61779:4:0;61379:410;;;;;;:::o;48059:20::-;;;-1:-1:-1;;;;;48059:20:0;;:::o;59487:141::-;-1:-1:-1;;;;;59588:34:0;;;59565:7;59588:34;;;:18;:34;;;;;;;59487:141;;;;:::o;65011:800::-;30360:13;:18;;30377:1;30360:18;;;;;37017:7;;65131:20;;30360:18;37017:7;;37016:8;37008:37;;;;;-1:-1:-1;;;37008:37:0;;;;;;;;;;;;-1:-1:-1;;;37008:37:0;;;;;;;;;;;;;;;65185:41;;;65202:9;65185:41;;;;;;;;;;65213:12;65185:41;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;65185:41:0;;;;;;;65175:52;;;;;65160:12;:67;65234:28;65251:10;65234:16;:28::i;:::-;65305:17;65325:13;:11;:13::i;:::-;65393:5;;65305:33;;-1:-1:-1;65386:66:0;;-1:-1:-1;;;;;65393:5:0;65417:10;65437:4;65444:7;65386:66;:30;:66;:::i;:::-;65476:34;65500:9;65476:19;:7;49839:6;65476:19;:11;:19;:::i;:34::-;65461:49;;65517:31;65523:10;65535:12;65517:5;:31::i;:::-;65615:41;65631:10;65643:12;65615:15;:41::i;:::-;65663:55;65682:10;65694:12;65708:9;65663:18;:55::i;:::-;-1:-1:-1;;;;;65731:23:0;;;65727:79;;65770:28;;;;;;-1:-1:-1;;;;;65770:28:0;;;;;;;;;;;;;;;;;;;65727:79;37056:1;30472:13;;30456:12;:29;30448:73;;;;;-1:-1:-1;;;30448:73:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30448:73:0;;;;;;;;;;;;;;;65011:800;;;;;;:::o;52896:26::-;;;-1:-1:-1;;;;;52896:26:0;;:::o;28779:83::-;28845:9;;;;28779:83;:::o;50570:35::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50570:35:0;;-1:-1:-1;50570:35:0;:::o;22707:210::-;22787:4;22804:83;22813:12;:10;:12::i;:::-;22827:7;22836:50;22875:10;22836:11;:25;22848:12;:10;:12::i;:::-;-1:-1:-1;;;;;22836:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;22836:25:0;;;:34;;;;;;;;;;;:50;:38;:50;:::i;37573:120::-;34794:22;34803:12;:10;:12::i;:::-;34794:8;:22::i;:::-;34786:83;;;;-1:-1:-1;;;34786:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37216:7;;;;37208:40;;;;;-1:-1:-1;;;37208:40:0;;;;;;;;;;;;-1:-1:-1;;;37208:40:0;;;;;;;;;;;;;;;37632:7;:15;;-1:-1:-1;;37632:15:0;;;37663:22;37672:12;:10;:12::i;:::-;37663:22;;;-1:-1:-1;;;;;37663:22:0;;;;;;;;;;;;;;37573:120::o;50143:25::-;;;-1:-1:-1;;;;;50143:25:0;;:::o;51107:51::-;;;;;;;;;;;;-1:-1:-1;;;;;51107:51:0;;:::o;34897:109::-;34953:4;34977:21;:8;34990:7;34977:21;:12;:21;:::i;52833:27::-;;;;:::o;57321:128::-;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;57406:6;:16;;-1:-1:-1;;;;;;57406:16:0;-1:-1:-1;;;;;57406:16:0;;;;;;;;57397:46;;;;;-1:-1:-1;;;57397:46:0;;;;;;;;;;;;-1:-1:-1;;;57397:46:0;;;;;;;;;;;;;;55976:121;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;56054:6;:16;;-1:-1:-1;;;;;;56054:16:0;-1:-1:-1;;;;;56054:16:0;;;;;;;;56045:46;;;;;-1:-1:-1;;;56045:46:0;;;;;;;;;;;;-1:-1:-1;;;56045:46:0;;;;;;;;;;;;;;64082:418;64148:25;64182:16;64205:14;64222:15;64232:4;64222:9;:15::i;:::-;64269:9;:16;64255:31;;;;;;;;;;;;;;;;64205:32;;-1:-1:-1;64255:31:0;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;64255:31:0;-1:-1:-1;64244:42:0;-1:-1:-1;64298:9:0;64293:202;64317:8;:15;64313:1;:19;64293:202;;;64359:9;64369:1;64359:12;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64359:12:0;;;64436:31;;;:21;:31;;;;;;:37;;;;;;;;;;;;64405:26;;;:16;:26;;;;;;64359:12;;-1:-1:-1;64394:93:0;;49839:6;;64394:81;;64405:69;;;:30;:69;:::i;:::-;64394:6;;:81;:10;:81;:::i;:93::-;64380:8;64389:1;64380:11;;;;;;;;;;;;;;;;;:107;64334:3;;64293:202;;;;64082:418;;;;;:::o;52039:82::-;52078:42;52039:82;:::o;50399:28::-;;;;:::o;36780:78::-;36843:7;;;;36780:78;:::o;72062:3641::-;37017:7;;72241:4;;37017:7;;37016:8;37008:37;;;;;-1:-1:-1;;;37008:37:0;;;;;;;;;;;;-1:-1:-1;;;37008:37:0;;;;;;;;;;;;;;;30360:13;:18;;30377:1;30360:18;;;;;72320:5;;72285:9;;-1:-1:-1;;;;;72310:15:0;;;72320:5;;72310:15;72302:29;;;;;-1:-1:-1;;;72302:29:0;;;;;;;;;;;;-1:-1:-1;;;72302:29:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;72346:26:0;;;;;;:41;;;72386:1;72376:7;:11;72346:41;72338:55;;;;;-1:-1:-1;;;72338:55:0;;;;;;;;;;;;-1:-1:-1;;;72338:55:0;;;;;;;;;;;;;;;72485:5;;72448:15;;72466:25;;-1:-1:-1;;;;;72485:5:0;72466:18;:25::i;:::-;72448:43;;72514:7;72504;:17;72500:2481;;;72622:16;72641:20;:7;72653;72641:20;:11;:20;:::i;:::-;72622:39;-1:-1:-1;72670:20:0;;;;;;;;;;73127:1847;73151:18;:25;73147:29;;73127:1847;;;73206:18;73225:1;73206:21;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;73206:21:0;;;73266:27;;;:16;:27;;;;;;;;73326:26;;-1:-1:-1;;;73326:26:0;;;;73206:21;;-1:-1:-1;73266:27:0;;;;-1:-1:-1;73266:27:0;;73326:24;;:26;;;;;73206:21;;73326:26;;;;;73266:27;73326:26;;;5:2:-1;;;;30:1;27;20:12;5:2;73326:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73326:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73326:26:0;73384:29;;;-1:-1:-1;;;73384:29:0;;;;73326:26;;-1:-1:-1;;;;;;73384:27:0;;;;;:29;;;;;73326:26;;73384:29;;;;;;;;:27;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;73384:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73384:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73384:29:0;;-1:-1:-1;73448:65:0;49839:6;73448:53;73482:18;73448:29;73467:9;73448:18;:29::i;:::-;:33;:53;:33;:53;:::i;:65::-;73424:89;;73688:8;73663:21;:33;;73640:56;;73868:8;73846:18;:30;;73835:41;;74056:20;:481;;74473:18;74448:21;:43;;:88;;74518:18;74448:88;;;74494:21;74448:88;74056:481;;;74241:8;:40;;74263:18;74241:40;;;74252:8;74241:40;74041:496;-1:-1:-1;74618:178:0;74652:9;74737:48;74766:18;74737:24;74041:496;49839:6;74737:24;:16;:24;:::i;:48::-;74618:21;:178::i;:::-;74607:189;;74855:20;:32;;;;;74879:8;74855:32;74851:68;;;74902:5;;74851:68;74942:22;:8;74955;74942:22;:12;:22;:::i;:::-;74931:33;-1:-1:-1;73178:3:0;;73127:1847;;;;72500:2481;;;;;;;;;;;75016:5;;75026:7;;74997:25;;-1:-1:-1;;;;;75016:5:0;74997:18;:25::i;:::-;:36;;74989:50;;;;;-1:-1:-1;;;74989:50:0;;;;;;;;;;;;-1:-1:-1;;;74989:50:0;;;;;;;;;;;;;;;75085:5;;75069:45;;-1:-1:-1;;;;;75085:5:0;75092:12;75106:7;75069:15;:45::i;:::-;75172:5;;75143:17;;75163:24;;-1:-1:-1;;;;;75172:5:0;75179:7;75163:8;:24::i;:::-;75143:44;;75320:45;;;;;;;;;;;;;;;;;;;75247:9;-1:-1:-1;;;;;75247:21:0;;75269:10;75281:5;;;;;;;;;-1:-1:-1;;;;;75281:5:0;75288:7;75297:9;75308:7;;75247:69;;;;;;;;;;;;;-1:-1:-1;;;;;75247:69:0;-1:-1:-1;;;;;75247:69:0;;;;;;-1:-1:-1;;;;;75247:69:0;-1:-1:-1;;;;;75247:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;75247:69:0;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;75247:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75247:69:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75247:69:0;:118;75231:153;;;;;-1:-1:-1;;;75231:153:0;;;;;;;;;;;;-1:-1:-1;;;75231:153:0;;;;;;;;;;;;;;;75443:83;75474:12;75496:4;75503:22;:7;75515:9;75503:22;:11;:22;:::i;:::-;75450:5;;-1:-1:-1;;;;;75450:5:0;;75443:83;;;:30;:83;:::i;:::-;75596:12;:10;:12::i;:::-;-1:-1:-1;75622:55:0;;;;;;;;;;;;;;75646:10;;-1:-1:-1;;;;;75622:55:0;;;;;;;;;;;;;;75693:4;75686:11;;;;;30472:13;;30456:12;:29;30448:73;;;;;-1:-1:-1;;;30448:73:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30448:73:0;;;;;;;;;;;;;;;37056:1;72062:3641;;;;;;;:::o;56213:121::-;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;56291:6;:16;;-1:-1:-1;;;;;;56291:16:0;-1:-1:-1;;;;;56291:16:0;;;;;;;;56282:46;;;;;-1:-1:-1;;;56282:46:0;;;;;;;;;;;;-1:-1:-1;;;56282:46:0;;;;;;;;;;;;;;71435:171;71526:5;;71496:7;;-1:-1:-1;;;;;71516:15:0;;;71526:5;;71516:15;71512:89;;;71549:44;49839:6;71549:32;71567:13;:11;:13::i;:::-;71549;:11;:13::i;:44::-;71542:51;;;;51222:57;;;;;;;;;;;;;:::o;58785:112::-;58834:16;58866:25;58859:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58785:112;:::o;56784:155::-;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;56897:3;:10;;;56912:15;56896:31;;;56888:45;;;;;-1:-1:-1;;;56888:45:0;;;;;;;;;;;;-1:-1:-1;;;56888:45:0;;;;;;;;;;;;;;56478:137;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;56564:10;:24;;-1:-1:-1;;;;;;56564:24:0;-1:-1:-1;;;;;56564:24:0;;;;;;;;56555:54;;;;;-1:-1:-1;;;56555:54:0;;;;;;;;;;;;-1:-1:-1;;;56555:54:0;;;;;;;;;;;;;;35114:79;35158:27;35172:12;:10;:12::i;:::-;35158:13;:27::i;:::-;35114:79::o;20545:110::-;-1:-1:-1;;;;;20629:18:0;20602:7;20629:18;;;:9;:18;;;;;;;20545:110::o;32370:140::-;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;32453:6;;32432:40;;32469:1;;-1:-1:-1;;;;;32453:6:0;;-1:-1:-1;;;;;;;;;;;32432:40:0;32469:1;;32432:40;32483:6;:19;;-1:-1:-1;;;;;;32483:19:0;;;32370:140::o;50651:26::-;;;;;;;;;;70751:77;70790:4;70810:12;:10;:12::i;:::-;70803:19;;70751:77;:::o;52489:21::-;;;-1:-1:-1;;;;;52489:21:0;;:::o;60337:97::-;60392:7;60415:13;:11;:13::i;29723:218::-;16510:12;;;;;;;;:31;;;16526:15;:13;:15::i;:::-;16510:47;;;-1:-1:-1;16546:11:0;;;;16545:12;16510:47;16502:106;;;;-1:-1:-1;;;16502:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16617:19;16640:12;;;;;;16639:13;16659:83;;;;16688:12;:19;;-1:-1:-1;;;;16688:19:0;;;;;16716:18;16703:4;16716:18;;;16659:83;29932:1;29916:13;:17;16760:57;;;;16804:5;16789:20;;-1:-1:-1;;16789:20:0;;;29723:218;:::o;35014:92::-;34794:22;34803:12;:10;:12::i;34794:22::-;34786:83;;;;-1:-1:-1;;;34786:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35079:19;35090:7;35079:10;:19::i;37360:118::-;34794:22;34803:12;:10;:12::i;34794:22::-;34786:83;;;;-1:-1:-1;;;34786:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37017:7;;;;37016:8;37008:37;;;;;-1:-1:-1;;;37008:37:0;;;;;;;;;;;;-1:-1:-1;;;37008:37:0;;;;;;;;;;;;;;;37420:7;:14;;-1:-1:-1;;37420:14:0;37430:4;37420:14;;;37450:20;37457:12;:10;:12::i;57049:137::-;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;57135:10;:24;;-1:-1:-1;;;;;;57135:24:0;-1:-1:-1;;;;;57135:24:0;;;;;;;;57126:54;;;;;-1:-1:-1;;;57126:54:0;;;;;;;;;;;;-1:-1:-1;;;57126:54:0;;;;;;;;;;;;;;51392:78;;;;;;;;;;;;;;;;;;;;;;;;:::o;66749:156::-;66819:7;66844:55;66861:7;66881:9;:16;;;;66870:28;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;66870:28:0;;66844:16;:55::i;59861:359::-;-1:-1:-1;;;;;59986:19:0;;59935:17;59986:19;;;:13;:19;;;;;;60026:13;:11;:13::i;:::-;60014:25;-1:-1:-1;60052:17:0;;;;;:45;;;60085:12;60073:9;:24;60052:45;60048:167;;;60122:83;52283:6;60122:67;60152:36;60160:27;:9;60174:12;60160:27;:13;:27;:::i;:::-;60152:3;;;:36;:7;:36;:::i;:::-;60122:25;:9;52283:6;60122:25;:13;:25;:::i;:::-;:29;:67;:29;:67;:::i;:83::-;60110:95;;60048:167;59861:359;;;;:::o;31557:79::-;31622:6;;-1:-1:-1;;;;;31622:6:0;31557:79;:::o;31923:94::-;32003:6;;31963:4;;-1:-1:-1;;;;;32003:6:0;31987:12;:10;:12::i;:::-;-1:-1:-1;;;;;31987:22:0;;31980:29;;31923:94;:::o;28129:87::-;28201:7;28194:14;;;;;;;;-1:-1:-1;;28194:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28168:13;;28194:14;;28201:7;;28194:14;;28201:7;28194:14;;;;;;;;;;;;;;;;;;;;;;;;52331:92;52380:42;52331:92;:::o;23420:261::-;23505:4;23522:129;23531:12;:10;:12::i;:::-;23545:7;23554:96;23593:15;23554:96;;;;;;;;;;;;;;;;;:11;:25;23566:12;:10;:12::i;:::-;-1:-1:-1;;;;;23554:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;23554:25:0;;;:34;;;;;;;;;;;:96;;:38;:96;:::i;59000:94::-;59047:16;59079:9;59072:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59072:16:0;;;;;;;;;;;;;;;;;;;;;;59000:94;:::o;62072:280::-;62141:4;62154:56;62180:10;62192:9;62203:6;62154:25;:56::i;:::-;62217:40;62227:10;62239:9;62250:6;62217:9;:40::i;:::-;62316:10;62302:25;;;;:13;:25;;;;;;62264:64;;62283:9;;62294:6;;62264:18;:64::i;51576:52::-;;;;;;;;;;;;;:::o;53794:250::-;53892:11;;-1:-1:-1;;;;;53892:11:0;:25;53884:39;;;;;-1:-1:-1;;;53884:39:0;;;;;;;;;;;;-1:-1:-1;;;53884:39:0;;;;;;;;;;;;;;;53930:11;:26;;-1:-1:-1;;;;;53930:26:0;;;-1:-1:-1;;;;;;53930:26:0;;;;;;;53978:2;53963:12;:17;53996:6;:16;;;;;;;;;;;;;;;54019:6;:19;;;;;;;;;;;53794:250::o;50882:32::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50882:32:0;:::o;60630:160::-;60749:11;;60732:52;;;-1:-1:-1;;;60732:52:0;;60778:4;60732:52;;;;;;60682:16;;;;-1:-1:-1;;;;;60749:11:0;;;;60732:37;;:52;;;;;60749:11;;60732:52;;;;;;;;60749:11;60732:52;;;5:2:-1;;;;30:1;27;20:12;5:2;60732:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60732:52:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;60732:52:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;;;5:11;;2:2;;;29:1;26;19:12;2:2;60732:52:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;60732:52:0;;421:4:-1;412:14;;;;60732:52:0;;;;;412:14:-1;60732:52:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;60732:52:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;60732:52:0;;421:4:-1;412:14;;;;60732:52:0;;;;;412:14:-1;60732:52:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;60732:52:0;;;;;;;;;;;60725:59;;;;60630:160;;:::o;67368:191::-;67482:7;67507:46;67524:7;67533:19;;67507:46;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;67507:16:0;;-1:-1:-1;;;67507:46:0:i;:::-;67500:53;67368:191;-1:-1:-1;;;;67368:191:0:o;52158:82::-;52197:42;52158:82;:::o;57915:178::-;58010:10;;-1:-1:-1;;;;;58010:10:0;57996;:24;;:49;;;58038:7;:5;:7::i;:::-;-1:-1:-1;;;;;58024:21:0;:10;-1:-1:-1;;;;;58024:21:0;;57996:49;57988:63;;;;;-1:-1:-1;;;57988:63:0;;;;;;;;;;;;-1:-1:-1;;;57988:63:0;;;;;;;;;;;;;;;58058:29;58074:12;;58058:29;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;58058:15:0;;-1:-1:-1;;;58058:29:0:i;36549:131::-;16510:12;;;;;;;;:31;;;16526:15;:13;:15::i;:::-;16510:47;;;-1:-1:-1;16546:11:0;;;;16545:12;16510:47;16502:106;;;;-1:-1:-1;;;16502:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16617:19;16640:12;;;;;;16639:13;16659:83;;;;16688:12;:19;;-1:-1:-1;;;;16688:19:0;;;;;16716:18;16703:4;16716:18;;;16659:83;36615:29;36637:6;36615:21;:29::i;:::-;36657:7;:15;;-1:-1:-1;;36657:15:0;;;16760:57;;;;16804:5;16789:20;;-1:-1:-1;;16789:20:0;;;36549:131;;:::o;52642:26::-;;;;;;:::o;71084:178::-;71190:5;;71156:7;;-1:-1:-1;;;;;71180:15:0;;;71190:5;;71180:15;71172:29;;;;;-1:-1:-1;;;71172:29:0;;;;;;;;;;;;-1:-1:-1;;;71172:29:0;;;;;;;;;;;;;;;71215:41;52283:6;71215:25;71227:12;;71215:7;:11;;:25;;;;:::i;21089:134::-;-1:-1:-1;;;;;21188:18:0;;;21161:7;21188:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;21089:134::o;50501:18::-;;;;:::o;55724:136::-;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;52283:6;55825:9;55810:12;:24;;;55809:39;55801:53;;;;;-1:-1:-1;;;55801:53:0;;;;;;;;;;;;-1:-1:-1;;;55801:53:0;;;;;;;;;;;;;;54685:902;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;54926:40;;;54918:54;;;;;-1:-1:-1;;;54918:54:0;;;;;;;;;;;;-1:-1:-1;;;54918:54:0;;;;;;;;;;;;;;;54987:53;;;;54979:67;;;;;-1:-1:-1;;;54979:67:0;;;;;;;;;;;;-1:-1:-1;;;54979:67:0;;;;;;;;;;;;;;;55055:25;:9;55067:13;;55055:25;:::i;:::-;-1:-1:-1;55089:14:0;;;55134:404;55154:25;;;55134:404;;;55207:14;;55222:1;55207:17;;;;;;;;;;;;;-1:-1:-1;;;;;55207:17:0;55195:29;;55262:1;-1:-1:-1;;;;;55241:23:0;:9;-1:-1:-1;;;;;55241:23:0;;;:52;;;;-1:-1:-1;55291:1:0;55268:8;;55277:1;55268:11;;;;;;;;;;;;;-1:-1:-1;;;;;55268:11:0;-1:-1:-1;;;;;55268:25:0;;;55241:52;55233:66;;;;;-1:-1:-1;;;55233:66:0;;;;;;;;;;;;-1:-1:-1;;;55233:66:0;;;;;;;;;;;;;;;55338:8;;55347:1;55338:11;;;;;;;-1:-1:-1;;;;;55308:27:0;;;;;;;:16;55338:11;55308:27;;;;;;;:41;;-1:-1:-1;;;;;;55308:41:0;55338:11;;;;;;;;;;55308:41;;;;-1:-1:-1;55419:21:0;;55441:1;55419:24;;;;;;;;;;;;;-1:-1:-1;;;;;55419:24:0;55410:33;;52078:42;-1:-1:-1;;;;;55456:14:0;:6;-1:-1:-1;;;;;55456:14:0;;55452:79;;-1:-1:-1;;;;;55483:29:0;;;;;;;:18;:29;;;;;:38;;-1:-1:-1;;;;;;55483:38:0;;;;;;;;;;55452:79;55181:3;;55134:404;;;-1:-1:-1;55546:35:0;:18;55567:14;;55546:35;:::i;:::-;;31826:1;;54685:902;;;;;;;;:::o;50251:30::-;;;;:::o;32665:109::-;31769:9;:7;:9::i;:::-;31761:54;;;;;-1:-1:-1;;;31761:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;31761:54:0;;;;;;;;;;;;;;;32738:28;32757:8;32738:18;:28::i;49894:20::-;;;-1:-1:-1;;;;;49894:20:0;;:::o;18438:98::-;18518:10;18438:98;:::o;26351:338::-;-1:-1:-1;;;;;26445:19:0;;26437:68;;;;-1:-1:-1;;;26437:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26524:21:0;;26516:68;;;;-1:-1:-1;;;26516:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26597:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;26649:32;;;;;;;;;;;;;;;;;26351:338;;;:::o;16911:508::-;17328:4;17374:17;17406:7;16911:508;:::o;92220:142::-;92338:12;;92309:9;92320:12;92292:41;;;;;;-1:-1:-1;;;;;92292:41:0;-1:-1:-1;;;;;92292:41:0;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;92292:41:0;;;92282:52;;;;;;:68;;92274:82;;;;;-1:-1:-1;;;92274:82:0;;;;;;;;;;;;-1:-1:-1;;;92274:82:0;;;;;;;;;;;;;;80227:120;80282:59;80307:3;80323:9;:16;;;;80312:28;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;80312:28:0;;80282:24;:59::i;91219:594::-;91693:49;;;91736:4;91693:49;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;91693::0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;91675:68:0;;;;91285:7;;;;91645:17;;-1:-1:-1;;;;;91675:17:0;;;91693:49;;91675:68;;;;25:18:-1;91675:68:0;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;91675:68:0;;;;;;;;;;;;;;;;;;;;;;;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;;91630:113:0;;;;91758:7;91750:16;;;;;;91791:4;91780:27;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;91780:27:0;;91219:594;-1:-1:-1;;;;91219:594:0:o;2312:471::-;2370:7;2615:6;2611:47;;-1:-1:-1;2645:1:0;2638:8;;2611:47;2682:5;;;2686:1;2682;:5;:1;2706:5;;;;;:10;2698:56;;;;-1:-1:-1;;;2698:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3251:132;3309:7;3336:39;3340:1;3343;3336:39;;;;;;;;;;;;;-1:-1:-1;;;3336:39:0;;;:3;:39::i;93029:134::-;93116:41;-1:-1:-1;;;;;93116:27:0;;93144:3;93149:7;93116:41;:27;:41;:::i;:::-;93029:134;;;:::o;25563:348::-;-1:-1:-1;;;;;25639:21:0;;25631:67;;;;-1:-1:-1;;;25631:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25732:68;25755:6;25732:68;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;25732:18:0;;;;;;:9;:18;;;;;;;:68;;:22;:68;:::i;:::-;-1:-1:-1;;;;;25711:18:0;;;;;;:9;:18;;;;;:89;25826:12;;:24;;25843:6;25826:24;:16;:24;:::i;:::-;25811:12;:39;25866:37;;;;;;;;25892:1;;-1:-1:-1;;;;;25866:37:0;;;-1:-1:-1;;;;;;;;;;;25866:37:0;;;;;;;;25563:348;;:::o;62572:1294::-;62667:16;62690:19;62716:25;62748:15;62770:17;62790:14;62800:3;62790:9;:14::i;:::-;62770:34;-1:-1:-1;62816:9:0;62811:1050;62835:9;:16;62831:20;;62811:1050;;;62878:9;62888:1;62878:12;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62878:12:0;;-1:-1:-1;62903:14:0;62899:955;;-1:-1:-1;;;;;62969:31:0;;;;;;;:21;:31;;;;;;;;:38;;;;;;;;;;;;62930:36;;;;;;;:77;62899:955;;;-1:-1:-1;;;;;63048:26:0;;;;;;;:16;:26;;;;;;;;;63187:21;:31;;;;;:38;;;;;;;;;;;;63048:26;;-1:-1:-1;63171:55:0;;63048:26;;63171:55;:15;:55;:::i;:::-;-1:-1:-1;;;;;63346:31:0;;;;;;;:21;:31;;;;;;;;:36;;;;;;;;;;63151:75;;-1:-1:-1;63316:80:0;;49839:6;;63316:68;;63330:53;;:11;;:53;:15;:53;:::i;63316:80::-;63306:90;-1:-1:-1;63698:146:0;63726:107;63799:21;:9;63813:6;63799:21;:13;:21;:::i;:::-;63726:54;63750:29;:17;63772:6;63750:29;:21;:29;:::i;:::-;63726:19;:7;49839:6;63726:19;:11;:19;:::i;:::-;:23;:54;:23;:54;:::i;:107::-;63698:11;;:146;:15;:146;:::i;:::-;-1:-1:-1;;;;;63659:31:0;;;;;;;:21;:31;;;;;;;;:36;;;;;;;;;:185;62899:955;62853:3;;62811:1050;;;;62572:1294;;;;;;;;:::o;24171:471::-;-1:-1:-1;;;;;24269:20:0;;24261:70;;;;-1:-1:-1;;;24261:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;24350:23:0;;24342:71;;;;-1:-1:-1;;;24342:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24446;24468:6;24446:71;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;24446:17:0;;;;;;:9;:17;;;;;;;:71;;:21;:71;:::i;:::-;-1:-1:-1;;;;;24426:17:0;;;;;;;:9;:17;;;;;;:91;;;;24551:20;;;;;;;:32;;24576:6;24551:32;:24;:32;:::i;:::-;-1:-1:-1;;;;;24528:20:0;;;;;;;:9;:20;;;;;;;;;:55;;;;24599:35;;;;;;;24528:20;;24599:35;;;;-1:-1:-1;;;;;;;;;;;24599:35:0;;;;;;;;24171:471;;;:::o;1869:192::-;1955:7;1991:12;1983:6;;;;1975:29;;;;-1:-1:-1;;;1975:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1975:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2027:5:0;;;1869:192::o;84950:295::-;85034:14;85051;85061:3;85051:9;:14::i;:::-;85034:31;-1:-1:-1;85168:71:0;85034:31;85168:59;85212:14;:5;85222:3;85212:14;:9;:14;:::i;:::-;85168:39;85191:15;:6;85202:3;85191:15;:10;:15;:::i;:::-;-1:-1:-1;;;;;85168:18:0;;;;;;:13;:18;;;;;;;:39;:22;:39;:::i;:71::-;-1:-1:-1;;;;;85147:18:0;;;;;;;:13;:18;;;;;:92;;;;-1:-1:-1;;;84950:295:0:o;75875:736::-;75921:13;75943:17;75963:13;:11;:13::i;:::-;75943:33;-1:-1:-1;75987:14:0;75983:63;;-1:-1:-1;;76024:13:0;;76019:2;:19;76012:26;;75983:63;76114:5;;76054:17;;;;76095:37;;49839:6;;76095:25;;-1:-1:-1;;;;;76114:5:0;76095:18;:25::i;:37::-;76078:54;;76177:36;76216:18;76177:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;76177:57:0;;;;;;;;;;;;;;;;-1:-1:-1;76177:57:0;;-1:-1:-1;76246:9:0;;-1:-1:-1;;;;76241:295:0;76265:19;:26;76261:1;:30;76241:295;;;76319:19;76339:1;76319:22;;;;;;;;;;;;;;76307:34;;76359:169;76417:102;76479:29;76498:9;76479:18;:29::i;:::-;-1:-1:-1;;;;;76434:27:0;;;;;;;:16;:27;;;;;;76417:45;;76434:27;76417:16;:45::i;:102::-;76359:6;;:169;:10;:169;:::i;:::-;76350:178;-1:-1:-1;76293:3:0;;76241:295;;;-1:-1:-1;76552:21:0;:6;76563:9;76552:21;:10;:21;:::i;:::-;76544:29;;75875:736;;;;;:::o;12416:204::-;12543:68;;;-1:-1:-1;;;;;12543:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12543:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;12517:95:0;;12536:5;;12517:18;:95::i;24923:308::-;-1:-1:-1;;;;;24999:21:0;;24991:65;;;;;-1:-1:-1;;;24991:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;25084:12;;:24;;25101:6;25084:24;:16;:24;:::i;:::-;25069:12;:39;-1:-1:-1;;;;;25140:18:0;;;;;;:9;:18;;;;;;:30;;25163:6;25140:30;:22;:30;:::i;:::-;-1:-1:-1;;;;;25119:18:0;;;;;;:9;:18;;;;;;;;:51;;;;25186:37;;;;;;;25119:18;;;;-1:-1:-1;;;;;;;;;;;25186:37:0;;;;;;;;;24923:308;;:::o;66010:489::-;66087:16;66110:14;66127;66137:3;66127:9;:14::i;:::-;66110:31;-1:-1:-1;66148:15:0;;66172:322;66196:9;:16;66192:20;;66172:322;;;66239:9;66249:1;66239:12;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66239:12:0;;;66270:31;;;:21;:31;;;;;;:36;;;;;;;;;;;;66425:26;;;:16;:26;;;;;;66239:12;;-1:-1:-1;66270:36:0;-1:-1:-1;66385:101:0;;66407:70;;66470:6;;66407:58;;66425:39;;66270:36;66425:39;:30;:39;:::i;66407:70::-;66385:7;;:101;:11;:101;:::i;:::-;-1:-1:-1;;;;;66346:31:0;;;;;;;:21;:31;;;;;;;;:36;;;;;;;;;:140;66214:3;;66172:322;;;;66010:489;;;;;:::o;940:181::-;998:7;1030:5;;;1054:6;;;;1046:46;;;;;-1:-1:-1;;;1046:46:0;;;;;;;;;;;;-1:-1:-1;;;1046:46:0;;;;;;;;;;;;;;34044:203;34116:4;-1:-1:-1;;;;;34141:21:0;;34133:68;;;;-1:-1:-1;;;34133:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;34219:20:0;:11;:20;;;;;;;;;;;;;;;34044:203::o;1396:136::-;1454:7;1481:43;1485:1;1488;1481:43;;;;;;;;;;;;;;;;;:3;:43::i;92612:411::-;92704:14;92733:12;;92729:289;;-1:-1:-1;;;;;92855:24:0;;;92832:20;92855:24;;;:16;:24;;;;;;;92890:46;92872:6;92855:24;92928:7;92890:15;:46::i;:::-;92956:52;;;-1:-1:-1;;;92956:52:0;;93002:4;92956:52;;;;;;-1:-1:-1;;;;;92956:37:0;;;;;:52;;;;;;;;;;;;;;-1:-1:-1;92956:37:0;:52;;;5:2:-1;;;;30:1;27;20:12;5:2;92956:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;92956:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;76808:3172:0;37017:7;;76872:4;;37017:7;;37016:8;37008:37;;;;;-1:-1:-1;;;37008:37:0;;;;;;;;;;;;-1:-1:-1;;;37008:37:0;;;;;;;;;;;;;;;76986:42;77031:25;76986:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77065:33;77101:15;77065:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;77143:23:0;;77202:32;;77065:51;;-1:-1:-1;77143:23:0;77202:43;;;-1:-1:-1;;77254:264:0;;;-1:-1:-1;77254:264:0;;77295:9;77290:219;77314:7;77310:1;:11;:35;;;;77326:19;77325:20;77310:35;77290:219;;;77392:25;77418:1;77392:28;;;;;;;;;;;;;;77369:16;77386:1;77369:19;;;;;;;;;;;;;;:51;77365:133;;77459:5;77437:27;;77479:5;;77365:133;77347:3;;77290:219;;;;77254:264;77565:5;;77528:15;;77546:25;;-1:-1:-1;;;;;77565:5:0;77546:18;:25::i;:::-;77528:43;;77586:19;:35;;;;-1:-1:-1;77609:12:0;;77586:35;77582:74;;;77641:5;77634:12;;;;;;;;;77582:74;77666:24;77693:57;52283:6;77693:41;77720:13;;77693:22;:20;:22::i;:57::-;77666:84;;77765:19;77761:233;;;77811:16;77801:7;:26;77797:165;;;77876:74;77893:25;77920:29;:7;77932:16;77920:29;:11;:29;:::i;:::-;77876:16;:74::i;:::-;77979:5;77972:12;;;;;;;;;;77761:233;78215:24;78241:25;78270:24;:22;:24::i;:::-;78214:80;;-1:-1:-1;78214:80:0;-1:-1:-1;78405:30:0;78214:80;78427:7;78405:30;:21;:30;:::i;:::-;78385:50;;78470:13;;78450:17;:33;78446:119;;;78516:39;:17;78538:16;78516:39;:21;:39;:::i;:::-;78496:59;;78446:119;78576:34;78612:19;78633:17;78654:207;78681:7;78783:69;78807:25;78834:17;78783:23;:69::i;:::-;78654:16;:207::i;:::-;78575:286;;;;;;79019:12;79014:182;;79110:22;79117:15;;79110:22;:::i;:::-;79143:43;;;;:15;;:43;;;;;:::i;:::-;;79014:182;79248:5;;79206:20;;79229:25;;-1:-1:-1;;;;;79248:5:0;79229:18;:25::i;:::-;79206:48;;79285:16;79269:12;:32;79265:71;;79321:5;79314:12;;;;;;;;;;;;;;;;79265:71;79425:32;79474:17;:24;79460:39;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;79460:39:0;-1:-1:-1;79425:74:0;-1:-1:-1;79513:9:0;79508:244;79532:17;:24;79528:1;:28;79508:244;;;79689:53;79730:11;79689:36;52283:6;79689:17;79707:1;79689:20;;;;;;;;;;;;;;:24;;:36;;;;:::i;:53::-;79668:15;79684:1;79668:18;;;;;;;;;;;;;;;;;:74;79558:3;;79508:244;;;-1:-1:-1;79788:69:0;79805:15;79822:34;:12;79839:16;79822:34;:16;:34;:::i;79788:69::-;79873:62;79883:10;79895:39;:17;79917:16;79895:39;:21;:39;:::i;:::-;79873:62;;;-1:-1:-1;;;;;79873:62:0;;;;;;;;;;;;;;;;;;;;;79953:4;79946:11;;;;;;;;;;;;;;;76808:3172;:::o;35331:130::-;35391:24;:8;35407:7;35391:24;:15;:24;:::i;:::-;35431:22;;-1:-1:-1;;;;;35431:22:0;;;;;;;;35331:130;:::o;35201:122::-;35258:21;:8;35271:7;35258:21;:12;:21;:::i;:::-;35295:20;;-1:-1:-1;;;;;35295:20:0;;;;;;;;35201:122;:::o;67924:936::-;30360:13;:18;;30377:1;30360:18;;;;;68043:22;;68076:24;:22;:24::i;:::-;68109:57;68134:10;68146:19;68109:24;:57::i;:::-;68181:12;;68177:678;;68206:13;68222;:11;:13::i;:::-;68206:29;-1:-1:-1;68246:21:0;68270:30;49839:6;68270:18;:7;68206:29;68270:18;:11;:18;:::i;:30::-;68358:5;;68246:54;;-1:-1:-1;68311:25:0;;68339;;-1:-1:-1;;;;;68358:5:0;68339:18;:25::i;:::-;68311:53;;68397:17;68381:13;:33;68377:183;;;68446:41;68460:7;68469:17;68446:13;:41::i;:::-;68429:58;;68377:183;;;68535:13;68518:30;;68377:183;68628:39;68636:7;68645:14;68661:5;68628:7;:39::i;:::-;68611:56;;68706:26;68712:10;68724:7;68706:5;:26::i;:::-;68811:5;;68795:50;;-1:-1:-1;;;;;68811:5:0;68818:10;68830:14;68795:15;:50::i;:::-;68177:678;;;;30472:13;;30456:12;:29;30448:73;;;;;-1:-1:-1;;;30448:73:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30448:73:0;;;;;;;;;;;;;;;67924:936;;;;;:::o;58274:354::-;58377:18;:25;58354:19;;:48;58346:62;;;;;-1:-1:-1;;;58346:62:0;;;;;;;;;;;;-1:-1:-1;;;58346:62:0;;;;;;;;;;;;;;;58415:13;;58435:101;58459:12;:19;58455:1;:23;58435:101;;;58502:26;58512:12;58525:1;58512:15;;;;;;;;;;;;;;58502:5;:9;;:26;;;;:::i;:::-;58494:34;-1:-1:-1;58480:3:0;;58435:101;;;-1:-1:-1;58542:40:0;;;;:25;;:40;;;;;:::i;:::-;;52283:6;58597:5;:19;58589:33;;;;;-1:-1:-1;;;58589:33:0;;;;;;;;;;;;-1:-1:-1;;;58589:33:0;;;;;;;;;;;;;;34604:141;16510:12;;;;;;;;:31;;;16526:15;:13;:15::i;:::-;16510:47;;;-1:-1:-1;16546:11:0;;;;16545:12;16510:47;16502:106;;;;-1:-1:-1;;;16502:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16617:19;16640:12;;;;;;16639:13;16659:83;;;;16688:12;:19;;-1:-1:-1;;;;16688:19:0;;;;;16716:18;16703:4;16716:18;;;16659:83;34675:16;34684:6;34675:8;:16::i;:::-;34670:68;;34708:18;34719:6;34708:10;:18::i;:::-;16764:14;16760:57;;;16804:5;16789:20;;-1:-1:-1;;16789:20:0;;;34604:141;;:::o;32880:229::-;-1:-1:-1;;;;;32954:22:0;;32946:73;;;;-1:-1:-1;;;32946:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33056:6;;33035:38;;-1:-1:-1;;;;;33035:38:0;;;;33056:6;;-1:-1:-1;;;;;;;;;;;33035:38:0;33056:6;;33035:38;33084:6;:17;;-1:-1:-1;;;;;;33084:17:0;-1:-1:-1;;;;;33084:17:0;;;;;;;;;;32880:229::o;80675:2720::-;80773:27;80803:9;80773:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;80773:39:0;;;;;;;;;;;;;;;;;;;;;;;80823:10;:17;80844:1;80823:22;80819:51;;;80856:7;;;80819:51;80876:14;80893:13;:11;:13::i;:::-;80876:30;;80913:14;80930;80940:3;80930:9;:14::i;:::-;80913:31;-1:-1:-1;80951:16:0;80980:10;;80976:2414;;81006:9;81001:2382;81025:10;:17;81021:1;:21;81001:2382;;;81071:10;81082:1;81071:13;;;;;;;;;;;;;;81060:24;;81097:38;81126:8;81097:28;:38::i;:::-;81190:14;81207:28;81226:8;81207:18;:28::i;:::-;81190:45;-1:-1:-1;81250:10:0;;81246:471;;-1:-1:-1;;;;;81521:31:0;;;;;;:21;:31;;;;;;81376:214;;81510:67;;81570:6;;81510:55;;49839:6;;81510:43;;:6;;:43;:10;:43;:::i;:67::-;-1:-1:-1;;;;;81376:26:0;;;;;;:16;:26;;;;;;;:214;:30;:214;:::i;:::-;-1:-1:-1;;;;;81347:26:0;;;;;;:16;:26;;;;;;;;:243;;;;81665:21;:31;;;:40;;;81246:471;81733:10;;81729:1519;;-1:-1:-1;;;;;81777:31:0;;;81758:16;81777:31;;;:21;:31;;;;;;;;:36;;;;;;;;;;;;81892:26;;;:16;:26;;;;;;81777:36;;81758:16;81892:40;;81777:36;81892:40;:30;:40;:::i;:::-;81876:56;-1:-1:-1;81949:10:0;;81945:1292;;81976:13;81992:29;49839:6;81992:17;:6;82003:5;81992:17;:10;:17;:::i;:29::-;81976:45;;82036:11;82050:28;82069:8;82050:18;:28::i;:::-;82036:42;;82145:3;82137:5;:11;82133:61;;;82175:3;82167:11;;82133:61;82212:19;82232:1;82212:22;;;;;;;;;;;;;;82208:1016;;;82402:200;82544:41;82566:18;:6;82577;82566:18;:10;:18;:::i;:::-;82544:17;:5;49839:6;82544:17;:9;:17;:::i;:41::-;-1:-1:-1;;;;;82402:26:0;;;;;;:16;:26;;;;;;;:200;:30;:200;:::i;:::-;-1:-1:-1;;;;;82373:26:0;;;;;;:16;:26;;;;;:229;82208:1016;;;82727:10;;82641:14;;-1:-1:-1;;;;;82727:10:0;:24;;;;:35;;;82761:1;82755:3;;:7;82727:35;:55;;;;-1:-1:-1;;;;;;82766:16:0;;52078:42;82766:16;;82727:55;82723:258;;;82812:30;52283:6;82812:14;82822:3;;82812:5;:9;;:14;;;;:::i;:30::-;82944:10;;82803:39;;-1:-1:-1;82918:45:0;;82934:8;;-1:-1:-1;;;;;82944:10:0;82803:39;82918:15;:45::i;:::-;83042:49;83058:8;83068:3;83073:17;:5;83083:6;83073:17;:9;:17;:::i;83042:49::-;83180:28;83199:8;83180:18;:28::i;:::-;-1:-1:-1;;;;;83146:31:0;;;;;;:21;:31;;;;;:62;-1:-1:-1;82208:1016:0;81945:1292;;;81729:1519;;;-1:-1:-1;;;;;;83347:26:0;;;;;;;:16;:26;;;;;;;;;83308:21;:31;;;;;:36;;;;;;;;;;;:65;81044:3;;81001:2382;;;;80675:2720;;;;;;:::o;3913:345::-;3999:7;4101:12;4094:5;4086:28;;;;-1:-1:-1;;;4086:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;4086:28:0;;4125:9;4141:1;4137;:5;;;;;;;3913:345;-1:-1:-1;;;;;3913:345:0:o;12232:176::-;12341:58;;;-1:-1:-1;;;;;12341:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12341:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;12315:85:0;;12334:5;;12315:18;:85::i;91990:135::-;92054:7;92094:6;-1:-1:-1;;;;;92077:40:0;;:42;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;92077:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;92077:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;92077:42:0;;91990:135;-1:-1:-1;;91990:135:0:o;14271:1114::-;14875:27;14883:5;-1:-1:-1;;;;;14875:25:0;;:27::i;:::-;14867:71;;;;;-1:-1:-1;;;14867:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;15012:12;15026:23;15061:5;-1:-1:-1;;;;;15053:19:0;15073:4;15053:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;15053:25:0;;;;;;;;;;;;;;;;;;;;;;;;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;;15011:67:0;;;;15097:7;15089:52;;;;;-1:-1:-1;;;15089:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15158:17;;:21;15154:224;;15300:10;15289:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15289:30:0;15281:85;;;;-1:-1:-1;;;15281:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90491:549;90551:13;90627:20;90656:24;90683:18;90656:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;90656:45:0;;;;;;;;;;;;;;;;-1:-1:-1;90656:45:0;;-1:-1:-1;90715:9:0;;-1:-1:-1;;;;90710:241:0;90734:7;:14;90730:1;:18;90710:241;;;90781:7;90789:1;90781:10;;;;;;;;;;;;;;90766:25;;90810:131;90820:120;49839:6;90820:108;90885:32;90904:12;90885:18;:32::i;:::-;-1:-1:-1;;;;;90837:30:0;;;;;;;:16;:30;;;;;;90820:48;;90837:30;90820:16;:48::i;:120::-;90810:5;;:131;:9;:131;:::i;:::-;90802:139;-1:-1:-1;90750:3:0;;90710:241;;;-1:-1:-1;91027:5:0;;90998:36;;91008:25;;-1:-1:-1;;;;;91027:5:0;91008:18;:25::i;90998:36::-;90990:44;;90491:549;;;:::o;86121:711::-;86268:32;86303:43;86327:11;86340:5;86303:23;:43::i;:::-;86268:78;;86355:18;86380:19;86406:24;86433:18;86406:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;86406:45:0;;;;;;;;;;;;;;;;-1:-1:-1;86406:45:0;;-1:-1:-1;86463:9:0;;-1:-1:-1;;;;86458:369:0;86482:15;:22;86478:1;:26;86458:369;;;86533:15;86549:1;86533:18;;;;;;;;;;;;;;86520:31;;86564:10;86578:1;86564:15;86560:260;;86606:16;:28;86623:7;86631:1;86623:10;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;86606:28:0;;;;;;;;;;;;;;-1:-1:-1;86606:28:0;;86732:5;;86606:28;;;;-1:-1:-1;86716:47:0;;86732:5;86606:28;86752:10;86716:15;:47::i;:::-;86791:11;-1:-1:-1;;;;;86774:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;86774:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;86774:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;86560:260:0;86506:3;;86458:369;;89764:608;89826:24;89852:13;89928:20;89957:24;89984:18;89957:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;89957:45:0;;;;;;;;;;;;;;;;;;;;;;;90011:17;90031:7;:14;90011:34;;90078:9;90064:24;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;90064:24:0;-1:-1:-1;90054:34:0;-1:-1:-1;90102:9:0;90097:270;90121:9;90117:1;:13;90097:270;;;90163:7;90171:1;90163:10;;;;;;;;;;;;;;90148:25;;90197:120;49839:6;90197:108;90262:32;90281:12;90262:18;:32::i;90197:120::-;90184:7;90192:1;90184:10;;;;;;;;;;;;;:133;;;;;90336:21;90346:7;90354:1;90346:10;;;;;;;;;;;;;;90336:5;:9;;:21;;;;:::i;:::-;90328:29;-1:-1:-1;90132:3:0;;90097:270;;;;89764:608;;;;;:::o;87067:628::-;87173:27;87236:11;:18;87222:33;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;87222:33:0;-1:-1:-1;87209:46:0;-1:-1:-1;87262:19:0;;;87321:345;87345:11;:18;87341:1;:22;87321:345;;;87409:1;87388:11;:18;:22;87383:1;:27;87379:280;;;87439:27;:5;87449:16;87439:27;:9;:27;:::i;:::-;87423:10;87434:1;87423:13;;;;;;;;;;;;;:43;;;;;87379:280;;;87507:41;52283:6;87507:25;87517:11;87529:1;87517:14;;;;;;;;;;;;;;87507:5;:9;;:25;;;;:::i;:41::-;87493:55;-1:-1:-1;87578:33:0;:16;87493:55;87578:33;:20;:33;:::i;:::-;87559:52;;87638:11;87622:10;87633:1;87622:13;;;;;;;;;;;;;:27;;;;;87379:280;87365:3;;87321:345;;;-1:-1:-1;;;87067:628:0;;;;:::o;88041:1429::-;88165:34;88208:19;88236:17;88302:7;:14;88288:29;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;88288:29:0;;88268:49;;88324:25;88356:18;88381:17;88405;88429:24;88456:18;88429:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;88429:45:0;;;;;;;;;;;;;;;;-1:-1:-1;88429:45:0;;-1:-1:-1;88546:9:0;;-1:-1:-1;;;;88541:924:0;88565:7;:14;88561:1;:18;88541:924;;;88607:7;88615:1;88607:10;;;;;;;;;;;;;;88595:22;;88638:10;88649:1;88638:13;;;;;;;;;;;;;;88626:25;;88673:7;88681:1;88673:10;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;88720:27:0;;;;;;;:16;:27;;;;;;;;;;;;-1:-1:-1;88673:10:0;-1:-1:-1;88761:22:0;;;88757:701;;;88796:16;88815:25;:10;88830:9;88815:25;:14;:25;:::i;:::-;88796:44;;88851:26;88880:8;-1:-1:-1;;;;;88880:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;88880:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88880:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;88880:29:0;;-1:-1:-1;88924:29:0;;;88920:121;;;88983:4;88968:19;;89011:18;89000:29;;88920:121;89085:182;89119:9;89204:52;89229:8;-1:-1:-1;;;;;89229:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;89229:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;89229:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;89229:26:0;89204:20;:8;49839:6;89204:20;:12;:20;:::i;89085:182::-;;88757:701;;;;;89361:25;:9;89375:10;89361:25;:13;:25;:::i;:::-;89338:17;89356:1;89338:20;;;;;;;;;;;;;:48;;;;;89411:37;89427:17;89445:1;89427:20;;;;;;;;;;;;;;89411:11;:15;;:37;;;;:::i;:::-;89397:51;;88757:701;88581:3;;88541:924;;;;88041:1429;;;;;;;;;;:::o;33766:183::-;33846:18;33850:4;33856:7;33846:3;:18::i;:::-;33838:64;;;;-1:-1:-1;;;33838:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33913:20:0;33936:5;33913:20;;;;;;;;;;;:28;;-1:-1:-1;;33913:28:0;;;33766:183::o;33508:178::-;33586:18;33590:4;33596:7;33586:3;:18::i;:::-;33585:19;33577:63;;;;;-1:-1:-1;;;33577:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33651:20:0;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;33651:27:0;33674:4;33651:27;;;33508:178::o;68866:774::-;68951:22;68982:17;69006:18;69027:13;:11;:13::i;:::-;69006:34;;69047:36;69086:18;69047:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;69047:57:0;;;;;;;;;;;;;;;;-1:-1:-1;69047:57:0;;-1:-1:-1;69118:9:0;;-1:-1:-1;;;;69113:374:0;69137:19;:26;69133:1;:30;69113:374;;;69191:19;69211:1;69191:22;;;;;;;;;;;;;;69179:34;;69239:240;69268:202;69302:9;69381:58;69428:10;69381:42;69393:29;69412:9;69393:18;:29::i;:::-;69381:7;;:42;:11;:42;:::i;69268:202::-;69239:14;;:240;:18;:240;:::i;:::-;69222:257;-1:-1:-1;69165:3:0;;69113:374;;;-1:-1:-1;69567:67:0;69586:47;69622:10;69586:31;:7;69598:18;69586:31;:11;:31;:::i;69567:67::-;69550:84;68866:774;-1:-1:-1;;;;;;68866:774:0:o;85497:419::-;85634:10;85585:7;85620:25;;;:13;:25;;;;;;85656:20;;;85652:58;;;85694:8;85687:15;;;;;85652:58;85754:14;85771:56;85820:6;85771:44;85811:3;;85771:35;85782:23;85796:8;85782:9;:13;;:23;;;;:::i;:::-;85771:6;;:35;:10;:35;:::i;:56::-;85850:5;;85857:10;;85754:73;;-1:-1:-1;85834:42:0;;-1:-1:-1;;;;;85850:5:0;;;;85857:10;85754:73;85834:15;:42::i;:::-;85890:20;:8;85903:6;85890:20;:12;:20;:::i;83515:1146::-;-1:-1:-1;;;;;83664:17:0;;52197:42;83664:17;;:38;;-1:-1:-1;;;;;;83685:17:0;;52078:42;83685:17;83664:38;:62;;;-1:-1:-1;;;;;;83706:20:0;;53411:42;83706:20;83664:62;83660:996;;;83764:16;;;83778:1;83764:16;;;;;;;;;83737:24;;83764:16;;;;;;105:10:-1;83764:16:0;88:34:-1;136:17;;-1:-1;83764:16:0;83737:43;;83810:4;83789:7;83797:1;83789:10;;;;;;;;-1:-1:-1;;;;;83789:26:0;;;:10;;;;;;;;;:26;83830:17;;52078:42;83830:17;83826:275;;;84016:58;;;-1:-1:-1;;;84016:58:0;;;;;;;;;;;;;;;;52380:42;;84016:40;;84057:7;;;;84016:58;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;84016:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;84016:58:0;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;84016:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84016:58:0;;;;84085:7;;;83826:275;84137:16;;;84151:1;84137:16;;;;;;;;;84111:23;;84137:16;;;;;;105:10:-1;84137:16:0;88:34:-1;136:17;;-1:-1;;84111:42:0;-1:-1:-1;;;;;;84166:20:0;;53411:42;84166:20;:44;;;;-1:-1:-1;84190:6:0;;-1:-1:-1;;;;;84190:6:0;:20;;84166:44;84162:319;;;84235:6;;84223:9;;-1:-1:-1;;;;;84235:6:0;;;;84223;;84235;;84223:9;;;;;;;;;:18;-1:-1:-1;;;;;84223:18:0;;;-1:-1:-1;;;;;84223:18:0;;;;;84252:31;84319:6;84326:1;84319:9;;;;;;;;;;;;;;-1:-1:-1;;;;;84312:41:0;;:43;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;84312:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84312:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84312:43:0;84394:44;;;-1:-1:-1;;;84394:44:0;;84432:4;84394:44;;;;;;84312:43;;-1:-1:-1;;;;;;84367:18:0;;;;;84386:6;;84367:18;;84394:29;;:44;;;;;84312:43;;84394:44;;;;;;;84367:18;84394:44;;;5:2:-1;;;;30:1;27;20:12;5:2;84394:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84394:44:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84394:44:0;84367:87;;-1:-1:-1;;;;;;84367:87:0;;;;;;;;;;;;;84448:4;84367:87;;;;;;;;;;;;;;;;;;;;;84448:4;;84367:87;;;;;;;84394:44;84367:87;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;84367:87:0;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;84367:87:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84367:87:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84465:7:0;;-1:-1:-1;;;;84465:7:0;84162:319;84493:6;;-1:-1:-1;;;;;84493:6:0;:20;84489:160;;84538:6;;84526:9;;-1:-1:-1;;;;;84538:6:0;;;;84526;;84538;;84526:9;;;;;;;;;:18;-1:-1:-1;;;;;84526:18:0;;;-1:-1:-1;;;;;84526:18:0;;;;;84574:6;84581:1;84574:9;;;;;;;;;;;;;;-1:-1:-1;;;;;84567:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;84567:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84567:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84567:31:0;84555:84;;-1:-1:-1;;;84555:84:0;;84627:5;84555:84;;;;;;84634:4;84555:84;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;84555:54:0;;;;;;84610:7;;84619:6;;84627:5;;84634:4;;84555:84;;;;;;;;;;;84567:31;84555:84;;;;;;;;84627:5;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;84555:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;84555:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;84555:84:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;9234:619:0;9294:4;9762:20;;9605:66;9802:23;;;;;;:42;;-1:-1:-1;;9829:15:0;;;9794:51;-1:-1:-1;;9234:619:0:o;49600:43566::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49600:43566:0;;;-1:-1:-1;49600:43566:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;49600:43566:0;-1:-1:-1;;;;;49600:43566:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;49600:43566:0;;;-1:-1:-1;49600:43566:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;49600:43566:0;;;;;;
Swarm Source
bzzr://fd747cb213c95855899fc35208dc11f88f530fbf5bfddafb5d2ccd64b39e9b32
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.