Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
EcoceliumDataManager
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "./Ecocelium_Initializer.sol";
/*
███████╗░█████╗░░█████╗░░█████╗░███████╗██╗░░░░░██╗██╗░░░██╗███╗░░░███╗
██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝██║░░░░░██║██║░░░██║████╗░████║
█████╗░░██║░░╚═╝██║░░██║██║░░╚═╝█████╗░░██║░░░░░██║██║░░░██║██╔████╔██║
██╔══╝░░██║░░██╗██║░░██║██║░░██╗██╔══╝░░██║░░░░░██║██║░░░██║██║╚██╔╝██║
███████╗╚█████╔╝╚█████╔╝╚█████╔╝███████╗███████╗██║╚██████╔╝██║░╚═╝░██║
╚══════╝░╚════╝░░╚════╝░░╚════╝░╚══════╝╚══════╝╚═╝░╚═════╝░╚═╝░░░░░╚═╝
Brought to you by Kryptual Team */
contract EcoceliumDataManager is Initializable {
IAbacusOracle abacus;
EcoMoneyManager EMM;
EcoceliumInit Init;
enum Status {OPENCREATOR, OPENBORROW, MATCHED, CLOSED}
/*============Mappings=============
----------------------------------*/
mapping (uint64 => uint64) private nextID; //Linked List Map for All Orders
mapping (string => uint64[6]) private hDID; // Head ID for Deposit
mapping (string => uint64[6]) private hBID; // Head ID for Borrow
mapping (address => User) public users;
mapping (uint64 => Status) public orderStatus;
mapping (uint64 => matchedOrder) public matchOrderMap;
mapping (uint64 => Order) public openOrderMap;
mapping (uint64 => uint) public orderUSDValue;
/*=========Structs and Initializer================
--------------------------------*/
struct freeStorage{ //USER DEPOSIT / BORROW STRUCTURE
uint amount;
uint time;
string wtoken;
uint usdvalue;
}
struct matchedOrder{ //RUNNING OR MATCHED ORDERS IN THIS FORM
address payable supplier;
address payable borrower;
uint time;
uint expiryDate;
uint duration;
uint amount;
uint usdvalue;
uint yield;
string wtoken;
uint duesPaid;
}
struct Order{ // PENDING ORDERS IN THIS FORMAT
address payable creator;
uint duration;
uint amount;
uint yield;
string wtoken;
}
struct User{
uint totalDeposit; //USD VALUE OF TOTAL DEPOSIT AT DEPOSIT TIME
uint totalBorrowed; //USD VALUE OF TOTAL DEPOSIT AT BORROW TIME
freeStorage [] myDeposits; //DEPOSIT DATA
freeStorage [] myBorrows; //BORROW DATA
mapping(string => uint) deposits; //CURRENCY-WISE TOTAL DEPOSIT COUNT FULL VALUE
mapping(string => uint) borrows; //CURRENCY-WISE TOTAL BORROW COUNT FULL VALUE
uint64 [] borrowedOrders; //BORROWED ORDER - ORDER ID
uint64 [] createdOrders; //CREATED ORDER - ORDER ID
uint64 [] myOrders; //MATCHED ORDR - ORDER ID
}
function initializeAddress(address payable EMMaddress,address AbacusAddress, address payable Initaddress) external initializer{
EMM = EcoMoneyManager(EMMaddress);
abacus = IAbacusOracle(AbacusAddress);
Init = EcoceliumInit(Initaddress);
}
/*============Main Functions===============
Key Notes -
1) Always call main functions of Data Manager with Wrapped Token
2) _status signifies (status == Status.OPENCREATOR) operation - Returns True for Deposit Functions and False for Borrow Function
3) require(Init.friendlyaddress(msg.sender) ,"Not Friendly Address"); - This is mentioned in the EcoceliumInit Contract
4) FreePusher/Popper are for Liquidity Pools and push/pop order and matchOrder is the Order Matching Engine
5) Fetch Token Price Returns Values in 10**8
6) Amounts are without setting off Token Decimals
---------------------------------*/
function freePusher(address userAddress, string memory token, uint _amount, bool _status) external { //_status signifies (status == Status.OPENCREATOR) operation
require(Init.friendlyaddress(msg.sender) ,"Not Friendly Address");
uint _usdValue = USDValue(_amount, token);
freeStorage memory newStorage = freeStorage({ amount: _amount,
time: now,
wtoken: token,
usdvalue: _usdValue });
if(_status){
users[userAddress].myDeposits.push(newStorage);
users[userAddress].totalDeposit += _usdValue;
users[userAddress].deposits[token] += _amount;
} else {
users[userAddress].myBorrows.push(newStorage);
users[userAddress].totalBorrowed += _usdValue;
users[userAddress].borrows[token] += _amount;
}
}
function freePopper(address userAddress, string memory _tokenSymbol, uint _amount, bool _status) public returns (uint dues) {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
if(_status) {
require(users[userAddress].deposits[_tokenSymbol]>=_amount, "Insufficient Deposits");
users[userAddress].deposits[_tokenSymbol] -= _amount;
} else {
require(users[userAddress].borrows[_tokenSymbol]>=_amount,"Insufficient Borrowings");
users[userAddress].borrows[_tokenSymbol] -= _amount;
}
uint amountLeft= _amount;
freeStorage [] storage mystorage = _status ? users[userAddress].myDeposits : users[userAddress].myBorrows;
for( uint i= mystorage.length-1; amountLeft >0 ; i--){
if(keccak256(abi.encodePacked(mystorage[i].wtoken)) != keccak256(abi.encodePacked(_tokenSymbol))) { continue; }
if (mystorage[i].amount <= amountLeft){
amountLeft -= mystorage[i].amount;
_status ? users[userAddress].totalDeposit -= mystorage[i].usdvalue : users[userAddress].totalBorrowed -= mystorage[i].usdvalue;
dues+= calculateECOEarning(USDValue(mystorage[i].amount,_tokenSymbol), _tokenSymbol, mystorage[i].time);
mystorage.pop();
} else {
_status ? users[userAddress].totalDeposit -= (mystorage[i].amount-amountLeft)*mystorage[i].usdvalue : users[userAddress].totalBorrowed -= (mystorage[i].amount-amountLeft)*mystorage[i].usdvalue;
mystorage[i].amount -= amountLeft;
dues += calculateECOEarning(USDValue(amountLeft,_tokenSymbol), _tokenSymbol, mystorage[i].time);
amountLeft = 0;
}
}
_status ? users[userAddress].myDeposits = mystorage : users[userAddress].myBorrows = mystorage;
}
function newOrder(address payable userAddress,string memory _tokenSymbol ,uint _amount,uint _dID, uint _yield, bool _status) external {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
uint amountLeft= _amount;
if(_status){
users[userAddress].deposits[_tokenSymbol] +=_amount;
users[userAddress].totalDeposit += USDValue(_amount, _tokenSymbol);
} else {
users[userAddress].borrows[_tokenSymbol] +=_amount;
users[userAddress].totalBorrowed += USDValue(_amount, _tokenSymbol);
}
while(amountLeft>0){
uint64 indexID = _status ? hBID[_tokenSymbol][_dID] : hDID[_tokenSymbol][_dID];
Order memory iOrder = openOrderMap[nextID[indexID]];
if((_status && _yield>iOrder.yield) || (!_status && _yield<iOrder.yield) || nextID[indexID] == 0){
pushOrder(userAddress, _tokenSymbol, amountLeft, (_dID+1)*6, _yield, _status);
break;
}
if(iOrder.amount>=amountLeft) {
iOrder.amount-=amountLeft;
if(iOrder.amount == amountLeft) {
poolSorter(nextID[indexID], _tokenSymbol, false, _dID);
}
matchOrder(userAddress, _tokenSymbol, amountLeft, (_dID+1)*6, iOrder.yield, indexID);
amountLeft=0;
} else {
pushOrder(userAddress, _tokenSymbol, amountLeft- iOrder.amount, (_dID+1)*6, _yield, _status);
matchOrder(userAddress, _tokenSymbol, amountLeft, (_dID+1)*6, iOrder.yield, indexID);
amountLeft -= openOrderMap[nextID[indexID]].amount;
}
}
}
function pushOrder(address payable userAddress,string memory _tokenSymbol ,uint _amount,uint _duration, uint _yield, bool _status) internal returns (uint){
(uint64 _orderId,uint newAmount,uint fee) = _ordersub(_amount, userAddress, _duration, _tokenSymbol);
openOrderMap[_orderId] = Order({
creator : userAddress,
duration : _duration,
amount : newAmount,
yield : _yield,
wtoken : _tokenSymbol
});
if(_status) {
orderStatus[_orderId] = Status.OPENCREATOR;
users[userAddress].createdOrders.push(_orderId);
if(nextID[hDID[_tokenSymbol][(_duration/6)-1]] == 0) { nextID[hDID[_tokenSymbol][(_duration/6)-1]] = _orderId; }
else { poolSorter(_orderId, _tokenSymbol, true, (_duration/6)-1); }
} else {
orderStatus[_orderId] = Status.OPENBORROW;
users[userAddress].borrowedOrders.push(_orderId);
if(nextID[hBID[_tokenSymbol][(_duration/6)-1]] == 0) { nextID[hBID[_tokenSymbol][(_duration/6)-1]] = _orderId; }
else { poolSorter(_orderId, _tokenSymbol, true, (_duration/6)-1); }
}
orderUSDValue[_orderId]=USDValue(_amount,_tokenSymbol);
return fee;
}
function poolSorter(uint64 _orderId, string memory _tokenSymbol, bool _status, uint dID) public { //Status here signifies Insertion if True, and Deletion if false
bool task = false;
uint64 index = orderStatus[_orderId] == Status.OPENCREATOR ? hDID[_tokenSymbol][dID] : hBID[_tokenSymbol][dID];
while(task || (index == uint64(0))) {
if(_status && (orderStatus[_orderId] == Status.OPENCREATOR && openOrderMap[nextID[index]].yield >= openOrderMap[_orderId].yield) || (orderStatus[_orderId] == Status.OPENBORROW && openOrderMap[nextID[index]].yield <= openOrderMap[_orderId].yield)) {
nextID[_orderId] = nextID[index];
nextID[index] = _orderId;
task = true;
}
if(!_status && nextID[index]==_orderId) {
nextID[index] = nextID[_orderId];
delete nextID[_orderId];
task = true;
}
index = nextID[index];
}
}
function matchOrder(address payable userAddress, string memory _tokenSymbol ,uint _amount,uint _duration,uint _yield, uint64 _orderId) internal {
matchOrderMap[_orderId] = matchedOrder({
supplier : (orderStatus[_orderId] == Status.OPENBORROW) ? userAddress : openOrderMap[_orderId].creator,
borrower : (orderStatus[_orderId] == Status.OPENCREATOR) ? userAddress : openOrderMap[_orderId].creator,
time : now,
expiryDate : now + _duration*(30 days),
duration : _duration,
amount : _amount,
usdvalue : USDValue(_amount,_tokenSymbol),
yield : _yield,
wtoken : _tokenSymbol,
duesPaid : 0
});
for((uint i,uint j)=(0,0); i<users[matchOrderMap[_orderId].supplier].createdOrders.length; (i++,j++)) {
if(users[matchOrderMap[_orderId].supplier].createdOrders[i] == _orderId) { --j; continue; }
users[matchOrderMap[_orderId].supplier].createdOrders[j] = users[matchOrderMap[_orderId].supplier].createdOrders[i];
}
for((uint i,uint j)=(0,0); i<users[matchOrderMap[_orderId].borrower].borrowedOrders.length; (i++,j++)) {
if(users[matchOrderMap[_orderId].borrower].borrowedOrders[i] == _orderId) { continue; }
users[matchOrderMap[_orderId].borrower].borrowedOrders[j] = users[matchOrderMap[_orderId].borrower].borrowedOrders[i];
}
delete openOrderMap[_orderId];
poolSorter(_orderId, _tokenSymbol, false, (_duration/6)-1);
orderStatus[_orderId]=Status.MATCHED;
orderUSDValue[_orderId]=USDValue(_amount,_tokenSymbol);
users[matchOrderMap[_orderId].supplier].myOrders.push(_orderId);
users[matchOrderMap[_orderId].borrower].myOrders.push(_orderId);
scheduleExpiry(_orderId);
scheduleCheck(_orderId,matchOrderMap[_orderId].borrower,1);
EMM.WithdrawManager(EMM.wtormap(_tokenSymbol), _amount, matchOrderMap[_orderId].borrower);
Init.emitOrderCreated(userAddress,_duration,_yield,_amount,_tokenSymbol);
}
function orderExpired (uint64 _orderId) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
require (matchOrderMap[_orderId].expiryDate <= now);
EMM.releaseWrappedToken(matchOrderMap[_orderId].supplier,matchOrderMap[_orderId].amount, matchOrderMap[_orderId].wtoken);
EMM.burnWrappedFrom(matchOrderMap[_orderId].supplier,matchOrderMap[_orderId].amount, matchOrderMap[_orderId].wtoken);
EMM.WithdrawManager(EMM.wtormap(matchOrderMap[_orderId].wtoken), matchOrderMap[_orderId].amount, matchOrderMap[_orderId].supplier);
users[matchOrderMap[_orderId].supplier].totalDeposit -= matchOrderMap[_orderId].usdvalue;
users[matchOrderMap[_orderId].borrower].totalBorrowed -= matchOrderMap[_orderId].usdvalue;
orderStatus[_orderId] = Status.CLOSED;
//Init.OrderExpired(_orderId,msgSender,orderMonthlyDue(_orderId,msgSender,_duration));
}
function payDue(uint64 _orderId,uint _duration,address msgSender) external returns (uint due){
due = orderMonthlyDue(_orderId,_duration);
uint fee = (due*Init.rewardFee())/100;
EMM.DepositManager(Init.ECO(), due+fee, msgSender);
Init.setOwnerFeeVault(Init.WRAP_ECO_SYMBOL(), fee);
matchOrderMap[_orderId].duesPaid += 1;
matchOrderMap[_orderId].duesPaid >= uint((now - matchOrderMap[_orderId].time)/30 days) ? Init.setUserLocked(msgSender,false) : Init.setUserLocked(msgSender,true);
Init.emitDuePaid(_orderId,msgSender,orderMonthlyDue(_orderId,_duration));
}
function dueCheck(uint64 _orderId,address borrower,uint month) external returns(uint) {
require (Init.friendlyaddress(msg.sender) && now >= matchOrderMap[_orderId].time + matchOrderMap[_orderId].duesPaid * 30 days);
uint due = orderMonthlyDue(_orderId,1);
EMM.mintECO(matchOrderMap[_orderId].supplier,due*(100-Init.rewardFee())/100);
EMM.lockECO(matchOrderMap[_orderId].supplier,due*(100-Init.rewardFee())/100);
if(matchOrderMap[_orderId].duesPaid < month && !Init.isRegistrar(borrower) && !Init.isUserLocked(borrower)){
Init.setUserLocked(borrower,true);
orderExpired(_orderId);
} else {
Init.emitDuePaid(_orderId,borrower,orderMonthlyDue(_orderId,month+1));
scheduleCheck(_orderId,borrower,month+1);
}
}
function scheduleExpiry(uint64 _orderId) internal{
uint time = matchOrderMap[_orderId].expiryDate - matchOrderMap[_orderId].time;
bytes memory data = abi.encodeWithSelector(bytes4(keccak256('orderExpired(uint256)')),_orderId);
uint callCost = 300000*1e9 + abacus.callFee();
abacus.scheduleFunc{value:callCost}(address(this), time ,data , abacus.callFee() ,300000 , 1e9 );
}
function scheduleCheck(uint _orderId,address borrower,uint month) internal{
bytes memory data = abi.encodeWithSelector(bytes4(keccak256('dueCheck(uint256,address,uint256)')),_orderId,borrower,month);
uint callCost = 300000*1e9 + abacus.callFee();
abacus.scheduleFunc{value:callCost}(address(this), 30 days ,data , abacus.callFee() ,300000 , 1e9 );
}
function cancelOrder(uint64 _orderId) external{
require(Init.friendlyaddress(msg.sender));
if(orderStatus[_orderId]==Status.OPENCREATOR) {
EMM.releaseWrappedToken(openOrderMap[_orderId].creator,openOrderMap[_orderId].amount, openOrderMap[_orderId].wtoken);
EMM.burnWrappedFrom(openOrderMap[_orderId].creator,openOrderMap[_orderId].amount, openOrderMap[_orderId].wtoken);
EMM.WithdrawManager(EMM.wtormap(openOrderMap[_orderId].wtoken),openOrderMap[_orderId].amount, openOrderMap[_orderId].creator);
users[openOrderMap[_orderId].creator].deposits[openOrderMap[_orderId].wtoken] -=openOrderMap[_orderId].amount;
users[openOrderMap[_orderId].creator].totalDeposit -= orderUSDValue[_orderId];
for((uint i,uint j)=(0,0); i<users[openOrderMap[_orderId].creator].createdOrders.length; (i++,j++)) {
if(users[openOrderMap[_orderId].creator].createdOrders[i] == _orderId) { --j; continue; }
users[openOrderMap[_orderId].creator].createdOrders[j] = users[openOrderMap[_orderId].creator].createdOrders[i];
}
} else if(orderStatus[_orderId]==Status.OPENBORROW){
users[openOrderMap[_orderId].creator].borrows[openOrderMap[_orderId].wtoken] -=openOrderMap[_orderId].amount;
users[openOrderMap[_orderId].creator].totalBorrowed -= orderUSDValue[_orderId];
for((uint i,uint j)=(0,0); i<users[openOrderMap[_orderId].creator].borrowedOrders.length; (i++,j++)) {
if(users[openOrderMap[_orderId].creator].borrowedOrders[i] == _orderId) { continue; }
users[openOrderMap[_orderId].creator].borrowedOrders[j] = users[openOrderMap[_orderId].creator].borrowedOrders[i];
}
}
poolSorter(_orderId, openOrderMap[_orderId].wtoken,false,(openOrderMap[_orderId].duration/6)-1);
delete openOrderMap[_orderId];
if(orderUSDValue[_orderId] > 0) { delete orderUSDValue[_orderId]; }
orderStatus[_orderId] = Status.CLOSED;
}
/*==============Helpers============
---------------------------------*/
function USDValue(uint amount, string memory _token) public view returns (uint usdvalue) {
usdvalue = amount*fetchTokenPrice(_token)/(10**8)/(10**uint(wERC20(EMM.getwTokenAddress(_token)).decimals()));
}
function orderMonthlyDue(uint64 _orderId, uint _duration) public view returns(uint due){
orderStatus[_orderId] == Status.MATCHED ? due = USDValue (matchOrderMap[_orderId].amount, matchOrderMap[_orderId].wtoken) * matchOrderMap[_orderId].yield * _duration*30 days*fetchTokenPrice(Init.WRAP_ECO_SYMBOL())/3153600000/(10**8) : due = 0;
}
function fetchTokenPrice(string memory _tokenSymbol) public view returns(uint){ //Put any Token Wrapped or Direct
uint response = uint(abacus.getJobResponse(EMM.getFetchId(_tokenSymbol))[0]);
return response > 0 ? response : 0;
}
/*function issueReward(address userAddress, string memory _tokenSymbol, uint time, uint tokenUsdValue) internal {
uint reward = calculateECOEarning(tokenUsdValue, _tokenSymbol, time);
EMM.mintECO(userAddress, reward);
}*/
function calculateECOEarning(uint usdvalue, string memory _tokenSymbol, uint time) private view returns (uint){
uint _amount = usdvalue*(10**16)/fetchTokenPrice(Init.WRAP_ECO_SYMBOL());
uint reward = (_amount * Init.slabRateDeposit(_tokenSymbol) * (now - time))/3153600000; //decimal from Abacus is setoff by decimal from Eco
return reward;
}
function getECOEarnings(address userAddress) public view returns (uint){
uint ecobalance;
for(uint i=0; i<users[userAddress].myDeposits.length; i++) {
ecobalance += calculateECOEarning(users[userAddress].myDeposits[i].usdvalue, users[userAddress].myDeposits[i].wtoken, users[userAddress].myDeposits[i].time);
}
for(uint i=0; i<users[userAddress].myBorrows.length; i++) {
ecobalance -= calculateECOEarning(users[userAddress].myBorrows[i].usdvalue, users[userAddress].myBorrows[i].wtoken, users[userAddress].myBorrows[i].time);
}
if(ecobalance > EMM.ecoWithdrawls(userAddress)) { return ecobalance - EMM.ecoWithdrawls(userAddress); } else {
return uint(0);
}
}
function _ordersub(uint amount,address userAddress,uint _duration,string memory _tokenSymbol) internal view returns (uint64, uint, uint){
uint newAmount = amount - (amount*Init.tradeFee())/100;
uint fee = (amount*Init.tradeFee())/100;
uint64 _orderId = uint64(uint(keccak256(abi.encodePacked(userAddress,_tokenSymbol,_duration,now))));
return (_orderId,newAmount,fee);
}
function getUserDepositsbyToken(address userAddress, string memory wtoken) public view returns(uint) {
return users[userAddress].deposits[wtoken];
}
function getUserBorrowedOrderbyToken(address userAddress, string memory wtoken) public view returns(uint) {
return users[userAddress].borrows[wtoken];
}
function getUserBorrowed(address userAddress) public view returns(uint) {
return users[userAddress].totalBorrowed;
}
function getUserBorrowedOrder(address userAddress) public view returns (uint64 [] memory) {
return users[userAddress].borrowedOrders;
}
function getUserDepositOrder(address userAddress) public view returns (uint64 [] memory) {
return users[userAddress].createdOrders;
}
function getUserMatchOrder(address userAddress) public view returns (uint64 [] memory) {
return users[userAddress].myOrders;
}
function getbuyPower(address userAddress) public view returns (uint buyPower){
if(Init.isRegistrar(userAddress)) { return (10**30); }
if(Init.isUserLocked(userAddress)) { return 0; }
if(users[userAddress].totalBorrowed > 0) {
return users[userAddress].totalDeposit - ((users[userAddress].totalDeposit*Init.CDSpercent())/100) - users[userAddress].totalBorrowed;
} else {
return users[userAddress].totalDeposit;
}
}
function pushTreasuryEarnings(address Sponsor, uint _amount) internal {
Init.updateTreasuryEarnings(Sponsor, (Init.usertreasuryearnings(Sponsor) + _amount));
}
function updateHeads(string memory token, uint dID, bool status) external {
status ? hDID[token][dID] = 0 : hBID[token][dID] = 0 ;
}
}
/*function deleteUserData(address userAddress) external {
if(Init.friendlyaddress(msg.sender)==true) {
delete users[userAddress];
}
}*/
contract Ecocelium is Initializable{
address public owner;
address payable EMMAddress;
IAbacusOracle abacus;
EcoMoneyManager EMM;
EcoceliumDataManager EDM;
EcoceliumInit Init;
function initialize(address _owner,address payable EMMaddress,address payable AbacusAddress,address EDMaddress, address payable Initaddress)public payable initializer {
owner = _owner;
EMM = EcoMoneyManager(EMMaddress);
EMMAddress = EMMaddress;
abacus = IAbacusOracle(AbacusAddress);//0x323f81D9F57d2c3d5555b14d90651aCDc03F9d52
EDM = EcoceliumDataManager(EDMaddress);
Init = EcoceliumInit(Initaddress);
}
function changeOwner(address _owner) public{
require(msg.sender==owner);
owner = _owner;
}
function updateContracts() public{
require(msg.sender==owner);
EMM = EcoMoneyManager(Init.MONEYMANAGER());
abacus = IAbacusOracle(Init.ABACUS());
EDM = EcoceliumDataManager(Init.DATAMANAGER());
}
/*===========Main functions============
-------------------------------------*/
function Deposit(string memory rtoken, uint _amount) external payable {
address _msgSender = msg.sender;
string memory wtoken = EMM.getWrapped(rtoken);
_deposit(rtoken, _amount, _msgSender, wtoken);
EDM.freePusher(_msgSender, wtoken, _amount, true);
EMM.mintWrappedToken(_msgSender, _amount, wtoken);
EMM.lockWrappedToken(_msgSender, _amount,wtoken);
}
function _deposit(string memory rtoken,uint _amount, address msgSender, string memory wtoken) internal {
require(EMM.getwTokenAddress(wtoken) != address(0),"not supported");
if(keccak256(abi.encodePacked(rtoken)) == keccak256(abi.encodePacked(Init.ETH_SYMBOL()))) {
require(msg.value >= _amount);
EMM.DepositManager{value:msg.value}(rtoken, _amount, msgSender);
}else {
EMM.DepositManager(rtoken, _amount, msgSender); }
Init.emitSwap(msgSender,rtoken,wtoken,_amount);
}
function depositAndOrder(address payable userAddress,string memory rtoken ,uint _amount,uint _duration,uint _yield) external payable {
require(msg.sender == userAddress);
string memory wtoken = EMM.getWrapped(rtoken);
_deposit(rtoken, _amount, userAddress, wtoken);
EMM.mintWrappedToken(userAddress, _amount, wtoken);
EMM.lockWrappedToken(userAddress, _amount,wtoken);
EDM.newOrder(userAddress, EMM.getWrapped(rtoken), _amount, (_duration/6)-1, _yield, true);
}
function createOrder(address payable userAddress,string memory _tokenSymbol ,uint _amount,uint _duration,uint _yield) external payable {
require(msg.sender == userAddress);
require(_duration>=6, "Duration should be atleast 6 Months");
string memory wtoken = EMM.getWrapped(_tokenSymbol);
require(EDM.getUserDepositsbyToken(userAddress, wtoken) >= _amount, "Insufficient Balance");
uint ecoEarnings = EDM.freePopper(userAddress, wtoken , _amount, true);
if(ecoEarnings > EMM.ecoWithdrawls(userAddress)) {
ecoEarnings-=EMM.ecoWithdrawls(userAddress);
EMM.adjustEcoEarning(userAddress, EMM.ecoWithdrawls(userAddress));
EMM.WithdrawManager(Init.ECO(), ecoEarnings, userAddress);
} else {
EMM.adjustEcoEarning(userAddress, ecoEarnings); }
EDM.newOrder(userAddress, wtoken, _amount, (_duration/6)-1, _yield, true);
}
function getAggEcoBalance(address userAddress) public view returns(uint) {
return wERC20(EMM.getwTokenAddress(Init.WRAP_ECO_SYMBOL())).balanceOf(userAddress) + EDM.getECOEarnings(userAddress);
}
function borrowOrder(address userAddress, string memory rtoken, uint amount, uint duration, uint yield) public {//Rewrite this part
require(isWithdrawEligible(userAddress, rtoken, amount));
EDM.newOrder(msg.sender,rtoken, amount,duration,yield,false);
}
function payDueOrder(uint64 _orderId,uint _duration) external {
EDM.payDue(_orderId,_duration,msg.sender);
}
function clearBorrow(string memory rtoken, uint _amount) external payable{
address msgSender = msg.sender;
string memory wtoken = EMM.getWrapped(rtoken);
uint dues = EDM.freePopper(msgSender, wtoken, _amount, false);
EMM.DepositManager(Init.ECO(), dues, msgSender);
if(keccak256(abi.encodePacked(rtoken)) == keccak256(abi.encodePacked(Init.ETH_SYMBOL()))) {
require(msg.value == _amount);
EMM.DepositManager{value:_amount}(rtoken, _amount, msgSender);
}else {
EMM.DepositManager(rtoken, _amount, msgSender); }
}
function Borrow(uint _amount, string memory _tokenSymbol) public {
require(isWithdrawEligible(msg.sender, _tokenSymbol, _amount));
EDM.freePusher(msg.sender, EMM.getWrapped(_tokenSymbol), _amount,false);
EMM.WithdrawManager(_tokenSymbol, _amount, msg.sender);
}
function SwapWrapToWrap(string memory token1,string memory token2, uint token1amount) external returns(uint) {
address payable msgSender = msg.sender;
uint token2price = fetchTokenPrice(token2);
uint token2amount = EDM.USDValue(token1amount,token1)*(100-Init.swapFee())*(10**uint(wERC20(EMM.getwTokenAddress(token2)).decimals()))*(10**8)/token2price/100;
EMM.w2wswap(msgSender, token1, token1amount, token2amount, token2);
uint ecoEarnings = EDM.freePopper(msgSender,token1,token1amount,true);
if(ecoEarnings>0) {
if(ecoEarnings > EMM.ecoWithdrawls(msgSender)) {
ecoEarnings-=EMM.ecoWithdrawls(msgSender);
if(EMM.ecoWithdrawls(msgSender) > 0) { EMM.adjustEcoEarning(msgSender, EMM.ecoWithdrawls(msgSender)); }
EMM.WithdrawManager(Init.ECO(), ecoEarnings, msgSender);
} else {
EMM.adjustEcoEarning(msgSender, ecoEarnings); }
}
Init.setOwnerFeeVault(token1, token1amount*Init.swapFee()/100);
EDM.freePusher(msgSender, token2,token2amount,true);
Init.emitSwap(msgSender,token1,token2,token2amount);
return token2amount;
}
function cancelOrder(uint64 _orderId) public{
(address creator,,,,) = EDM.openOrderMap(_orderId);
require(msg.sender==creator);
EDM.cancelOrder(_orderId);
}
receive() external payable { }
/*==============Helpers============
---------------------------------*/
function orderMonthlyDue(uint64 _orderId,uint _duration) public view returns(uint){
return EDM.orderMonthlyDue(_orderId,_duration);
}
function updateFees(uint _swapFee,uint _tradeFee,uint _rewardFee) public{
require(msg.sender == owner);
Init.updateFees(_swapFee,_tradeFee,_rewardFee);
}
/*function getOrderIds(string memory wtoken) public view returns(uint64 [] memory){
return EDM.getOrderIds(wtoken);
}*/
function fetchTokenPrice(string memory _tokenSymbol) public view returns(uint){
return EDM.fetchTokenPrice(_tokenSymbol);
}
function Withdraw(string memory to, uint _amount) external {
address payable msgSender = msg.sender;
string memory from = EMM.getWrapped(to);
require(!Init.isUserLocked(msgSender), "Your Address is Locked Pay Dues");
if( EDM.getUserBorrowed(msgSender) > 0) { require(isWithdrawEligible(msgSender, to, _amount) , "Not Eligible for Withdraw"); }
if(keccak256(abi.encodePacked(to)) == keccak256(abi.encodePacked(Init.ECO()))) {
require( getAggEcoBalance(msgSender) >= _amount,"Insufficient Balance");
if(getAggEcoBalance(msgSender) - EDM.getUserDepositsbyToken(msgSender, from) >= _amount) {
EMM.redeemEcoEarning(msgSender,_amount);
} else {
uint diffAmount = _amount + EDM.getUserDepositsbyToken(msgSender, from) - getAggEcoBalance(msgSender);
EMM.redeemEcoEarning(msgSender,(getAggEcoBalance(msgSender) - EDM.getUserDepositsbyToken(msgSender, from)));
_withdraw(msgSender, from, diffAmount, to); }
} else {
require(EDM.getUserDepositsbyToken(msgSender, from)>=_amount,"Insufficient balance");
_withdraw(msgSender, from, _amount, to);
}
Init.emitSwap(msgSender,from,to,_amount);
}
function _withdraw(address payable msgSender, string memory from, uint amount, string memory to) internal {
EMM.releaseWrappedToken(msgSender,amount, from);
EMM.burnWrappedFrom(msgSender, amount, from);
Init.setOwnerFeeVault(to,(amount*Init.rewardFee())/100);
uint ecoEarnings = EDM.freePopper(msgSender,from,amount, true);
if(ecoEarnings>0) {
if(ecoEarnings > EMM.ecoWithdrawls(msgSender)) {
ecoEarnings-=EMM.ecoWithdrawls(msgSender);
if(EMM.ecoWithdrawls(msgSender) > 0) { EMM.adjustEcoEarning(msgSender, EMM.ecoWithdrawls(msgSender)); }
EMM.WithdrawManager(Init.ECO(), ecoEarnings, msgSender);
} else {
EMM.adjustEcoEarning(msgSender, ecoEarnings); }
}
uint newAmount = amount - (amount*Init.rewardFee())/100;
EMM.WithdrawManager(to,newAmount, msgSender);
}
function isWithdrawEligible(address userAddress, string memory to, uint amount) public view returns (bool Eligible){
return (EDM.getbuyPower(userAddress) > EDM.USDValue(amount,EMM.getWrapped(to)));
}
function setSponsor(address userAddress, address Sponsor) external {
require(msg.sender == userAddress, "Invalid User");
Init.setSponsor(userAddress, Sponsor);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "./helpers.sol";
contract IAbacusOracle{
uint public callFee;
function getJobResponse(uint64 _jobId) public view returns(uint64[] memory _values){ }
function scheduleFunc(address to ,uint callTime, bytes memory data , uint fee , uint gaslimit ,uint gasprice)public payable{}
}
contract EcoceliumInit is Initializable {
address payable owner;
address payable public MONEYMANAGER;
address payable public DATAMANAGER;
address payable public ECOCELIUM;
address payable public ABACUS;
string public WRAP_ECO_SYMBOL;
string public ECO;
string public ETH_SYMBOL;
string public WRAP_ETH_SYMBOL;
uint public swapFee;
uint public rewardFee;
uint public tradeFee;
uint public CDSpercent;
string [] rtokenlist;
string [] wtokenlist;
mapping (string => uint) public rcurrencyID;
mapping (string => uint) public wcurrencyID;
mapping (address => bool) public isRegistrar;
mapping (address => bool) public isUserLocked;
mapping (string => uint ) public ownerFeeVault;
mapping (string => uint) public slabRateDeposit;
mapping (address => bool) public friendlyaddress;
mapping (address => address) public SponsorAddress;
mapping (address => uint) public usertreasuryearnings;
event OrderCreated(
address userAddress,
uint duration,
uint yield,
uint amount,
string token
);
event Swap(
address userAddress,
string from,
string to,
uint amount
);
event Borrowed(
uint64 orderId,
address borrower,
uint amount,
uint duration
);
event Deposit(
address userAddress,
string token,
uint tokenAmount,
uint collateralValue
);
event DuePaid(
uint64 orderId,
address borrower,
uint amount
);
event WrapTokenCreated(
address TokenAddress,
string TokenName,
string TokenSymbol,
uint Decimals
);
receive() payable external { }
function initializeAddress(address payable _owner) public initializer {
friendlyaddress[_owner] = true;
owner = _owner;
}
function addRealCurrency(string memory rtoken) public{
require(friendlyaddress[msg.sender],"Not Friendly Address");
if(rcurrencyID[rtoken] == 0) {
rtokenlist.push(rtoken);
rcurrencyID[rtoken] = rtokenlist.length; }
}
function addWrapCurrency (string memory wtoken) public{
require(friendlyaddress[msg.sender],"Not Friendly Address");
if(wcurrencyID[wtoken] == 0) {
wtokenlist.push(wtoken);
wcurrencyID[wtoken] = wtokenlist.length; }
}
function setSlabRate(string memory WToken, uint rate) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
slabRateDeposit[WToken] = rate;
}
function setUserLocked(address userAddress, bool value) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
isUserLocked[userAddress] = value;
}
function setFriendlyAddress(address Address) public {
(msg.sender == owner,"not owner");
friendlyaddress[Address] = true;
}
function addRegistrar(address _registrar) public{
require(friendlyaddress[msg.sender],"Not Friendly Address");
isRegistrar[_registrar] = true;
}
function setOwnerFeeVault(string memory add,uint value) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
ownerFeeVault[add] += value;
}
function emitOrderCreated(address userAddress, uint _duration, uint _yield, uint newAmount,string memory _tokenSymbol) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
emit OrderCreated(userAddress,_duration,_yield,newAmount,_tokenSymbol);
}
function emitSwap(address msgSender, string memory from, string memory to,uint _amount) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
emit Swap(msgSender,from,to,_amount);
}
function emitBorrowed(uint64 _orderId, address msgSender, uint _amount,uint _duration) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
emit Borrowed(_orderId,msgSender,_amount,_duration);
}
function emitWrappedCreated(address tokenAddress,string memory name, string memory symbol,uint8 decimals) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
emit WrapTokenCreated(tokenAddress,name,symbol,decimals);
}
function emitDeposit(address msgSender, string memory _tokenSymbol, uint amount, uint tokenUsdValue) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
emit Deposit(msgSender,_tokenSymbol,amount,tokenUsdValue);
}
function emitDuePaid(uint64 _orderId, address msgSender, uint due) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
emit DuePaid(_orderId,msgSender,due);
}
function setCONSTSYMBOLS(string[4] memory _symbolCONST) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
WRAP_ECO_SYMBOL = _symbolCONST[0];
ECO = _symbolCONST[1];
ETH_SYMBOL = _symbolCONST[2];
WRAP_ETH_SYMBOL = _symbolCONST[3];
}
function updateFees(uint _swapFee,uint _tradeFee,uint _rewardFee) public{
require(friendlyaddress[msg.sender],"Not Friendly Address");
(swapFee,tradeFee,rewardFee) = (_swapFee,_tradeFee,_rewardFee);
}
function setCSDpercent(uint percent) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
CDSpercent = percent;
}
function changeAbacusaddress(address payable Abacusaddress) public{
require(msg.sender == owner,"not owner");
ABACUS = Abacusaddress;
}
function changeEcoceliumaddress(address payable Ecocelium) public{
require(msg.sender == owner,"not owner");
ECOCELIUM = Ecocelium;
}
function changeDMaddress(address payable DMAddress) public{
require(msg.sender == owner,"not owner");
DATAMANAGER = DMAddress;
}
function changeMMaddress(address payable MMaddress) public{
require(msg.sender == owner,"not owner");
MONEYMANAGER = MMaddress;
}
function changeOwner(address payable _owner) public{
require(msg.sender==owner);
owner = _owner;
}
function setSponsor(address userAddress, address _sponsorAddress) external {
require(friendlyaddress[msg.sender],"Not Friendly Address");
SponsorAddress[userAddress] = _sponsorAddress;
}
function updateTreasuryEarnings(address userAddress, uint _amount) public {
require(friendlyaddress[msg.sender],"Not Friendly Address");
usertreasuryearnings[userAddress] = _amount;
}
}
contract EcoMoneyManager is Initializable {
EcoceliumInit Init;
address public owner;
address [] public TokenAddresses;
address [] public wTokenAddresses;
mapping (string => address) rTokens;
mapping (string => string) public wtormap;
mapping (string => string) public rTokensTowToken;
mapping (string => TokenConfig) wTokens;
mapping (address => uint) public ecoWithdrawls;
mapping (string => uint) public WGains;
mapping (string => uint) public WLoss;
receive() payable external { }
struct TokenConfig{
address tokenAddress;
uint64 fetchId;
}
function initialize(address _owner, address payable _Init) public initializer{
owner = _owner;
Init = EcoceliumInit(_Init);
}
function updateAdminAddress(address adminAddress) public {
require(msg.sender == owner);
for(uint i = 0;i<wTokenAddresses.length;i++){
wERC20(wTokenAddresses[i]).changeAdmin(adminAddress);
}
}
function addTokenWithAddress(address tokenAddress) public {
require(msg.sender == owner);
ERC20Basic token = ERC20Basic(tokenAddress);
require(getrTokenAddress(token.symbol())== address(0),"token exist");
rTokens[token.symbol()] = tokenAddress;
TokenAddresses.push(tokenAddress);
}
function createWrapToken(string memory name,string memory symbol,uint64 _fetchId, uint8 decimal, string memory wrapOf) public returns(address TokenAddress){
require(msg.sender == owner);
wERC20 token = new wERC20(name,symbol,decimal, address(this), address(this));
rTokensTowToken[wrapOf] = symbol;
TokenAddresses.push(address(token));
wTokenAddresses.push(address(token));
wTokens[symbol] = TokenConfig({
tokenAddress:address(token),
fetchId : _fetchId
});
Init.emitWrappedCreated(address(token),name,symbol,token.decimals());
return address(token);
}
function changeOwner(address _owner) public{
require(owner == msg.sender);
owner =_owner;
}
function updatertoken (string memory WToken, string memory RToken) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wtormap[WToken] = RToken;
}
function getwTokenAddress(string memory symbol) public view returns(address){
return wTokens[symbol].tokenAddress;
}
function getFetchId(string memory symbol ) public view returns(uint64){
if( wTokens[symbol].tokenAddress == address(0)) {
symbol = rTokensTowToken[symbol];
}
return wTokens[symbol].fetchId;
}
function getrTokenAddress(string memory symbol) public view returns(address){
return rTokens[symbol];
}
function getTokenAddresses() public view returns(address[] memory){
return TokenAddresses;
}
function getWrapped(string memory symbol) public view returns(string memory){
return rTokensTowToken[symbol];
}
function getTokenID(string memory symbol) public view returns(uint){
for(uint i=0; i< TokenAddresses.length; i++) {
if(TokenAddresses[i] == wTokens[symbol].tokenAddress) {
return i;
}
}
}
function releaseWrappedToken (address _userAddress, uint amount, string memory WToken) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wERC20(getwTokenAddress(WToken)).release(_userAddress,amount);
}
function mintWrappedToken (address _userAddress, uint amount, string memory WToken) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wERC20(getwTokenAddress(WToken)).mint(_userAddress,amount);
}
function lockWrappedToken (address _userAddress, uint amount, string memory WToken) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wERC20(getwTokenAddress(WToken)).lock(_userAddress,amount);
}
function burnWrappedFrom(address userAddress, uint amount, string memory WToken) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wERC20(getwTokenAddress(WToken)).burnFrom(userAddress,amount);
}
function mintECO(address userAddress, uint amount) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wERC20(getwTokenAddress(Init.WRAP_ECO_SYMBOL())).mint(userAddress,amount);
}
function lockECO(address userAddress, uint amount) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wERC20(getwTokenAddress(Init.WRAP_ECO_SYMBOL())).lock(userAddress,amount);
}
function releaseECO(address userAddress, uint amount) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wERC20(getwTokenAddress(Init.WRAP_ECO_SYMBOL())).release(userAddress,amount);
}
function burnECOFrom(address userAddress, uint amount) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
wERC20(getwTokenAddress(Init.WRAP_ECO_SYMBOL())).burnFrom(userAddress,amount);
}
function DepositManager(string memory _rtoken, uint amount, address userAddress) public payable {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
if(Init.rcurrencyID(_rtoken) == Init.rcurrencyID(Init.ETH_SYMBOL()))
{ require(msg.value >= amount,"Invalid Amount"); }
else {ERC20Basic rtoken = ERC20Basic(getrTokenAddress(_rtoken));
require(rtoken.allowance(userAddress, address(this)) >= amount,"set allowance");
rtoken.transferFrom(userAddress,address(this),amount);}
}
function WithdrawManager(string memory _rtoken, uint amount, address payable userAddress) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
if(Init.rcurrencyID(_rtoken) == Init.rcurrencyID(Init.ETH_SYMBOL()))
{ userAddress.transfer(amount); }
else {
ERC20Basic rtoken = ERC20Basic(getrTokenAddress(_rtoken));
rtoken.transfer(userAddress,amount);}
}
function redeemEcoEarning(address payable userAddress, uint amount) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
ecoWithdrawls[userAddress] = ecoWithdrawls[userAddress] + amount;
WithdrawManager(Init.ECO(), amount, userAddress);
}
function adjustEcoEarning(address userAddress, uint amount) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
ecoWithdrawls[userAddress] = ecoWithdrawls[userAddress] - amount;
}
function updateFetchID (string memory wtoken, uint64 _fetchID) external {
require(owner == msg.sender);
wTokens[wtoken].fetchId = _fetchID;
}
function w2wswap (address msgSender, string memory token1, uint token1amount, uint token2amount, string memory token2) external {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
releaseWrappedToken(msgSender, token1amount, token1);
burnWrappedFrom(msgSender,token1amount,token1);
WGains[token1]=token1amount;
mintWrappedToken(msgSender,token2amount, token2);
lockWrappedToken(msgSender, token2amount, token2);
WLoss[token2]=token2amount;
}
function updateWrapAddress (string memory wtoken, address wAddress) external {
require(owner == msg.sender);
wTokens[wtoken].tokenAddress = wAddress;
}
function updatewtoken (string memory RToken, string memory WToken) public {
require(Init.friendlyaddress(msg.sender),"Not Friendly Address");
rTokensTowToken[RToken] = WToken;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
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;
}
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
abstract contract AccessControl is Context {
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
struct RoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view returns (bool) {
return _roles[role].members.contains(account);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
return _roles[role].members.length();
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
return _roles[role].members.at(index);
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function _grantRole(bytes32 role, address account) private {
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}
contract ERC20Basic {
uint public _totalSupply;
string public name;
string public symbol;
uint public decimals;
function totalSupply() public view returns (uint){}
function balanceOf(address who) public view returns (uint){}
function transfer(address to, uint value) public {}
function transferFrom(address _from, address _to, uint _value) public{}
function approve(address spender, uint amount) public {}
function allowance(address _owner, address _spender) public view returns (uint remaining) {}
event Transfer(address indexed from, address indexed to, uint value);
}
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);
}
contract ERC20 is Context, IERC20 {
using SafeMath for uint256;
using Address for address;
mapping (address => uint256) private _balances;
mapping (address => uint256) public lockedAmount;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/
constructor (string memory name, string memory symbol,uint8 decimals) public {
_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. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* 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;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20};
*
* Requirements:
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_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 availableAmount(address owner) public view returns(uint256){
return balanceOf(owner).sub(lockedAmount[owner]);
}
function increaseAllowance(address spender, uint256 addedValue) public virtual 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 virtual 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 virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(amount <= availableAmount(sender),"ERC20 : amount exceeds available amount");
_beforeTokenTransfer(sender, recipient, amount);
_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 virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_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 virtual {
require(account != address(0), "ERC20: burn from the zero address");
require(amount <= availableAmount(account),"ERC20 : burn exceeds available amount");
_beforeTokenTransfer(account, address(0), amount);
_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 virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
require(amount <= availableAmount(owner),"ERC20 : approve amount exceeds available amount");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _lock(address owner,uint256 amount) internal virtual {
require(owner != address(0), "ERC20: lock for zero address");
require(amount <= availableAmount(owner),"ERC20: lock value more tha available amount");
lockedAmount[owner] = lockedAmount[owner].add(amount);
}
function _release(address owner,uint256 amount) internal virtual{
require(owner != address(0), "ERC20: release for zero address");
require(amount <= lockedAmount[owner],"ERC20 : release value more then locked value");
lockedAmount[owner] = lockedAmount[owner].sub(amount);
}
/**
* @dev Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/
function _setupDecimals(uint8 decimals_) internal {
_decimals = decimals_;
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
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 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].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
return _functionCallWithValue(target, data, value, errorMessage);
}
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(value)));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(value)));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(value)));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint256(_at(set._inner, index)));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
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.
*/
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.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
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.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor () internal {
_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.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!_paused, "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(_paused, "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
abstract contract ERC20Pausable is ERC20, Pausable {
/**
* @dev See {ERC20-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC20Pausable: token transfer while paused");
}
}
contract wERC20 is Context, AccessControl, ERC20, ERC20Pausable {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant ETMOWNER_ROLE = keccak256("ETM_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* See {ERC20-constructor}.
*/
constructor(string memory name, string memory symbol,uint8 decimals,address admin,address etmOwner) public ERC20(name, symbol,decimals) {
_setupRole(DEFAULT_ADMIN_ROLE, admin);
_setupRole(ETMOWNER_ROLE, etmOwner);
_setupRole(MINTER_ROLE, admin);
_setupRole(PAUSER_ROLE, admin);
}
/**
* @dev Creates `amount` new tokens for `to`.
*
* See {ERC20-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 amount) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint");
_mint(to, amount);
}
function burnFrom(address _from,uint256 amount) public virtual{
require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have admin role to burn");
_burn(_from,amount);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause");
_pause();
}
function changeAdmin(address admin) public virtual{
require(hasRole(ETMOWNER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have admin role");
_setupRole(DEFAULT_ADMIN_ROLE, admin);
_setupRole(MINTER_ROLE, admin);
_setupRole(PAUSER_ROLE, admin);
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause");
_unpause();
}
function lock(address account , uint256 amount) public virtual{
require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have admin role to lock");
_lock(account,amount);
}
function release(address account , uint256 amount) public virtual{
require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have admin role to release");
_release(account,amount);
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(ERC20, ERC20Pausable) {
super._beforeTokenTransfer(from, to, amount);
}
}
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"_token","type":"string"}],"name":"USDValue","outputs":[{"internalType":"uint256","name":"usdvalue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_orderId","type":"uint64"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_orderId","type":"uint64"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"month","type":"uint256"}],"name":"dueCheck","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_tokenSymbol","type":"string"}],"name":"fetchTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"freePopper","outputs":[{"internalType":"uint256","name":"dues","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"string","name":"token","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"freePusher","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getECOEarnings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getUserBorrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getUserBorrowedOrder","outputs":[{"internalType":"uint64[]","name":"","type":"uint64[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"string","name":"wtoken","type":"string"}],"name":"getUserBorrowedOrderbyToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getUserDepositOrder","outputs":[{"internalType":"uint64[]","name":"","type":"uint64[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"string","name":"wtoken","type":"string"}],"name":"getUserDepositsbyToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getUserMatchOrder","outputs":[{"internalType":"uint64[]","name":"","type":"uint64[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getbuyPower","outputs":[{"internalType":"uint256","name":"buyPower","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"EMMaddress","type":"address"},{"internalType":"address","name":"AbacusAddress","type":"address"},{"internalType":"address payable","name":"Initaddress","type":"address"}],"name":"initializeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"matchOrderMap","outputs":[{"internalType":"address payable","name":"supplier","type":"address"},{"internalType":"address payable","name":"borrower","type":"address"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"uint256","name":"expiryDate","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"usdvalue","type":"uint256"},{"internalType":"uint256","name":"yield","type":"uint256"},{"internalType":"string","name":"wtoken","type":"string"},{"internalType":"uint256","name":"duesPaid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"userAddress","type":"address"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_dID","type":"uint256"},{"internalType":"uint256","name":"_yield","type":"uint256"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"newOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"openOrderMap","outputs":[{"internalType":"address payable","name":"creator","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"yield","type":"uint256"},{"internalType":"string","name":"wtoken","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_orderId","type":"uint64"}],"name":"orderExpired","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_orderId","type":"uint64"},{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"orderMonthlyDue","outputs":[{"internalType":"uint256","name":"due","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"orderStatus","outputs":[{"internalType":"enum EcoceliumDataManager.Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"orderUSDValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_orderId","type":"uint64"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"address","name":"msgSender","type":"address"}],"name":"payDue","outputs":[{"internalType":"uint256","name":"due","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_orderId","type":"uint64"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"bool","name":"_status","type":"bool"},{"internalType":"uint256","name":"dID","type":"uint256"}],"name":"poolSorter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"token","type":"string"},{"internalType":"uint256","name":"dID","type":"uint256"},{"internalType":"bool","name":"status","type":"bool"}],"name":"updateHeads","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"users","outputs":[{"internalType":"uint256","name":"totalDeposit","type":"uint256"},{"internalType":"uint256","name":"totalBorrowed","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5061588c80620000216000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c8063a87430ba116100de578063e0059b3111610097578063e86ef40b11610071578063e86ef40b1461039c578063f1d80b89146103af578063f5da23ab146103c2578063fd90d097146103d55761018e565b8063e0059b3114610363578063e306687714610376578063e364db92146103895761018e565b8063a87430ba146102d2578063b43c12ce146102f3578063bb3dabe814610317578063c441d6161461032a578063c78cd5261461033d578063d542050b146103505761018e565b80634407f6c11161014b578063559fde5111610125578063559fde511461025657806362daeaa314610269578063835609db14610289578063a58c2a33146102a95761018e565b80634407f6c11461021d5780634631dfe514610230578063523eb537146102435761018e565b806313c9e8f514610193578063151230e3146101a85780631d9703f6146101bb578063254cff03146101e457806331b3d0df146101f757806334f2f3881461020a575b600080fd5b6101a66101a1366004614ec1565b6103e8565b005b6101a66101b636600461512f565b610640565b6101ce6101c9366004614e74565b6109b9565b6040516101db9190615729565b60405180910390f35b6101a66101f23660046151a7565b6109fd565b6101ce610205366004614d75565b610cb7565b6101ce610218366004614ff0565b6110b3565b6101ce61022b366004615239565b6111ec565b6101ce61023e366004614ec1565b6115d1565b6101a661025136600461512f565b611b77565b6101ce610264366004614d75565b612483565b61027c61027736600461512f565b6126c3565b6040516101db91906155b8565b61029c610297366004614d75565b6126d8565b6040516101db919061556b565b6102bc6102b736600461512f565b612779565b6040516101db9a99989796959493929190615423565b6102e56102e0366004614d75565b612863565b6040516101db929190615751565b61030661030136600461512f565b61287c565b6040516101db9594939291906154cd565b6101a6610325366004614dad565b61293e565b6101a6610338366004614df7565b612a01565b6101ce61034b366004614e74565b612e6d565b61029c61035e366004614d75565b612e99565b6101ce61037136600461520e565b612f0f565b6101a661038436600461509c565b6130c2565b6101ce610397366004615167565b613184565b6101ce6103aa366004614d75565b613690565b61029c6103bd366004614d75565b6136ae565b6101ce6103d036600461512f565b613724565b6101ce6103e3366004615101565b613736565b603554604051632f3c2fef60e01b81526001600160a01b0390911690632f3c2fef9061041890339060040161540f565b60206040518083038186803b15801561043057600080fd5b505afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104689190614fd4565b61048d5760405162461bcd60e51b8152600401610484906156fb565b60405180910390fd5b60006104998385613736565b90506104a3614aa7565b60405180608001604052808581526020014281526020018681526020018381525090508215610582576001600160a01b038616600090815260396020908152604080832060029081018054600181810183559186529484902086516004909602019485558584015190850155908401518051859493610526938501920190614acf565b50606091909101516003909101556001600160a01b038616600090815260396020526040908190208054840181559051859160040190610567908890615383565b90815260405190819003602001902080549091019055610638565b6001600160a01b0386166000908152603960209081526040808320600301805460018181018355918552938390208551600490950201938455848301519084015583015180518493926105dc926002850192910190614acf565b50606091909101516003909101556001600160a01b03861660009081526039602052604090819020600181018054850190559051859160050190610621908890615383565b908152604051908190036020019020805490910190555b505050505050565b603554604051632f3c2fef60e01b81526001600160a01b0390911690632f3c2fef9061067090339060040161540f565b60206040518083038186803b15801561068857600080fd5b505afa15801561069c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c09190614fd4565b6106dc5760405162461bcd60e51b8152600401610484906156fb565b6001600160401b0381166000908152603b602052604090206003015442101561070457600080fd5b6034546001600160401b0382166000908152603b602052604090819020805460058201549251631902763760e31b81526001600160a01b039485169463c813b1b89461075e949190931692916008909101906004016154a6565b600060405180830381600087803b15801561077857600080fd5b505af115801561078c573d6000803e3d6000fd5b50506034546001600160401b0384166000908152603b6020526040908190208054600582015492516318cb888160e31b81526001600160a01b03948516965063c65c440895506107e7949091169291600801906004016154a6565b600060405180830381600087803b15801561080157600080fd5b505af1158015610815573d6000803e3d6000fd5b50506034546001600160401b0384166000908152603b602052604090819020905163665fef1960e11b81526001600160a01b03909216935063d1f94af49250839163ccbfde329161086e91600890910190600401615634565b60006040518083038186803b15801561088657600080fd5b505afa15801561089a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c2919081019061502a565b6001600160401b0384166000908152603b6020526040908190206005810154905491516001600160e01b031960e086901b16815261090d93926001600160a01b031690600401615601565b600060405180830381600087803b15801561092757600080fd5b505af115801561093b573d6000803e3d6000fd5b505050506001600160401b0381166000818152603b6020908152604080832060068101805482546001600160a01b039081168752603986528487208054929092039091559054600192830154909116855282852082018054919091039055938352603a9091529020805460039260ff1990911690835b021790555050565b6001600160a01b03821660009081526039602052604080822090516004909101906109e5908490615383565b90815260200160405180910390205490505b92915050565b600080806001600160401b0387166000908152603a602052604090205460ff166003811115610a2857fe5b14610a7a57603885604051610a3d9190615383565b90815260200160405180910390208360068110610a5657fe5b600491828204019190066008029054906101000a90046001600160401b0316610ac3565b603785604051610a8a9190615383565b90815260200160405180910390208360068110610aa357fe5b600491828204019190066008029054906101000a90046001600160401b03165b90505b8180610ad957506001600160401b038116155b1561063857838015610b5557506001600160401b0386166000908152603a602052604081205460ff166003811115610b0d57fe5b148015610b5557506001600160401b038087166000908152603c6020818152604080842060039081015487871686526036845282862054909616855292909152909120015410155b80610bcc575060016001600160401b0387166000908152603a602052604090205460ff166003811115610b8457fe5b148015610bcc57506001600160401b038087166000908152603c6020818152604080842060039081015487871686526036845282862054909616855292909152909120015411155b15610c20576001600160401b0381811660008181526036602052604080822080548b861680855292842080549190961667ffffffffffffffff19918216179095559290915281549092169091179055600191505b83158015610c4a57506001600160401b038181166000908152603660205260409020548116908716145b15610c97576001600160401b038681166000818152603660205260408082208054868616845291832080549290951667ffffffffffffffff19928316179094559190528154169055600191505b6001600160401b0390811660009081526036602052604090205416610ac6565b60008060005b6001600160a01b038416600090815260396020526040902060020154811015610e3a576001600160a01b03841660009081526039602052604090206002018054610e2e919083908110610d0c57fe5b90600052602060002090600402016003015460396000876001600160a01b03166001600160a01b031681526020019081526020016000206002018381548110610d5157fe5b600091825260209182902060026004909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015610de95780601f10610dbe57610100808354040283529160200191610de9565b820191906000526020600020905b815481529060010190602001808311610dcc57829003601f168201915b5050506001600160a01b038916600090815260396020526040902060020180549092508691508110610e1757fe5b906000526020600020906004020160010154613854565b90910190600101610cbd565b5060005b6001600160a01b038416600090815260396020526040902060030154811015610f97576001600160a01b03841660009081526039602052604090206003018054610f8b919083908110610e8d57fe5b6000918252602080832060036004909302018201546001600160a01b03891684526039909152604090922001805484908110610ec557fe5b600091825260209182902060026004909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015610f5d5780601f10610f3257610100808354040283529160200191610f5d565b820191906000526020600020905b815481529060010190602001808311610f4057829003601f168201915b5050506001600160a01b038916600090815260396020526040902060030180549092508691508110610e1757fe5b90910390600101610e3e565b5060345460405163481343e360e01b81526001600160a01b039091169063481343e390610fc890869060040161540f565b60206040518083038186803b158015610fe057600080fd5b505afa158015610ff4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101891906150e9565b8111156110a85760345460405163481343e360e01b81526001600160a01b039091169063481343e39061104f90869060040161540f565b60206040518083038186803b15801561106757600080fd5b505afa15801561107b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109f91906150e9565b900390506110ae565b60009150505b919050565b603354603454604051633ce9babf60e01b815260009283926001600160a01b039182169263161adc839290911690633ce9babf906110f59088906004016155cc565b60206040518083038186803b15801561110d57600080fd5b505afa158015611121573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611145919061514b565b6040518263ffffffff1660e01b8152600401611161919061575f565b60006040518083038186803b15801561117957600080fd5b505afa15801561118d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111b59190810190614f2a565b6000815181106111c157fe5b60200260200101516001600160401b03169050600081116111e35760006111e5565b805b9392505050565b60006111f88484612f0f565b905060006064603560009054906101000a90046001600160a01b03166001600160a01b0316638b4242676040518163ffffffff1660e01b815260040160206040518083038186803b15801561124c57600080fd5b505afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128491906150e9565b83028161128d57fe5b6034546035546040805163059f833760e41b815290519490930494506001600160a01b039182169363483eb4ed9392909116916359f83370916004808301926000929190829003018186803b1580156112e557600080fd5b505afa1580156112f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611321919081019061502a565b838501866040518463ffffffff1660e01b815260040161134393929190615601565b600060405180830381600087803b15801561135d57600080fd5b505af1158015611371573d6000803e3d6000fd5b50506035546040805160016238880b60e11b0319815290516001600160a01b039092169350631a3aba979250839163ff8eefea91600480820192600092909190829003018186803b1580156113c557600080fd5b505afa1580156113d9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611401919081019061502a565b836040518363ffffffff1660e01b815260040161141f9291906155df565b600060405180830381600087803b15801561143957600080fd5b505af115801561144d573d6000803e3d6000fd5b505050506001600160401b0385166000908152603b602052604090206009810180546001019081905560029091015462278d0042919091030411156114f65760355460405163b0251e6d60e01b81526001600160a01b039091169063b0251e6d906114bf90869060019060040161550b565b600060405180830381600087803b1580156114d957600080fd5b505af11580156114ed573d6000803e3d6000fd5b5050505061155c565b60355460405163b0251e6d60e01b81526001600160a01b039091169063b0251e6d9061152990869060009060040161550b565b600060405180830381600087803b15801561154357600080fd5b505af1158015611557573d6000803e3d6000fd5b505050505b6035546001600160a01b03166380908fb086856115798289612f0f565b6040518463ffffffff1660e01b815260040161159793929190615773565b600060405180830381600087803b1580156115b157600080fd5b505af11580156115c5573d6000803e3d6000fd5b50505050509392505050565b603554604051632f3c2fef60e01b81526000916001600160a01b031690632f3c2fef9061160290339060040161540f565b60206040518083038186803b15801561161a57600080fd5b505afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614fd4565b61166e5760405162461bcd60e51b8152600401610484906156fb565b8115611717576001600160a01b0385166000908152603960205260409081902090518491600401906116a1908790615383565b90815260200160405180910390205410156116ce5760405162461bcd60e51b815260040161048490615647565b6001600160a01b0385166000908152603960205260409081902090518491600401906116fb908790615383565b90815260405190819003602001902080549190910390556117b6565b6001600160a01b038516600090815260396020526040908190209051849160050190611744908790615383565b90815260200160405180910390205410156117715760405162461bcd60e51b815260040161048490615676565b6001600160a01b03851660009081526039602052604090819020905184916005019061179e908790615383565b90815260405190819003602001902080549190910390555b826000836117de576001600160a01b03871660009081526039602052604090206003016117fa565b6001600160a01b03871660009081526039602052604090206002015b8054909150600019015b8215611b0f578660405160200161181b9190615383565b6040516020818303038152906040528051906020012082828154811061183d57fe5b906000526020600020906004020160020160405160200161185e919061539f565b604051602081830303815290604052805190602001201461187e57611b06565b8282828154811061188b57fe5b906000526020600020906004020160000154116119e8578181815481106118ae57fe5b9060005260206000209060040201600001548303925084611920578181815481106118d557fe5b906000526020600020906004020160030154603960008a6001600160a01b03166001600160a01b03168152602001908152602001600020600101600082825403925050819055611964565b81818154811061192c57fe5b60009182526020808320600360049093020191909101546001600160a01b038b16835260399091526040909120805491909103908190555b5061199c61198f83838154811061197757fe5b90600052602060002090600402016000015489613736565b88848481548110610e1757fe5b84019350818054806119aa57fe5b60008281526020812060046000199093019283020181815560018101829055906119d76002830182614b4d565b600382016000905550509055611b06565b84611a65578181815481106119f957fe5b90600052602060002090600402016003015483838381548110611a1857fe5b9060005260206000209060040201600001540302603960008a6001600160a01b03166001600160a01b03168152602001908152602001600020600101600082825403925050819055611aca565b818181548110611a7157fe5b90600052602060002090600402016003015483838381548110611a9057fe5b600091825260208083206004909202909101546001600160a01b038d16835260399091526040909120805492909103929092029003908190555b5082828281548110611ad857fe5b600091825260209091206004909102018054919091039055611afd61198f8489613736565b84019350600092505b60001901611804565b5083611b43576001600160a01b03871660009081526039602052604090208154611b3e91600301908390614b94565b611b6c565b6001600160a01b03871660009081526039602052604090208154611b6c91600201908390614b94565b505050949350505050565b603554604051632f3c2fef60e01b81526001600160a01b0390911690632f3c2fef90611ba790339060040161540f565b60206040518083038186803b158015611bbf57600080fd5b505afa158015611bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf79190614fd4565b611c0057600080fd5b6001600160401b0381166000908152603a602052604081205460ff166003811115611c2757fe5b141561209d576034546001600160401b0382166000908152603c602052604090819020805460028201549251631902763760e31b81526001600160a01b039485169463c813b1b894611c8594919093169291600491820191016154a6565b600060405180830381600087803b158015611c9f57600080fd5b505af1158015611cb3573d6000803e3d6000fd5b50506034546001600160401b0384166000908152603c6020526040908190208054600282015492516318cb888160e31b81526001600160a01b03948516965063c65c44089550611d0e949091169291600490810191016154a6565b600060405180830381600087803b158015611d2857600080fd5b505af1158015611d3c573d6000803e3d6000fd5b50506034546001600160401b0384166000908152603c602052604090819020905163665fef1960e11b81526001600160a01b03909216935063d1f94af49250839163ccbfde3291611d939160049182019101615634565b60006040518083038186803b158015611dab57600080fd5b505afa158015611dbf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611de7919081019061502a565b6001600160401b0384166000908152603c6020526040908190206002810154905491516001600160e01b031960e086901b168152611e3293926001600160a01b031690600401615601565b600060405180830381600087803b158015611e4c57600080fd5b505af1158015611e60573d6000803e3d6000fd5b5050506001600160401b0382166000818152603c60208181526040808420600281015481546001600160a01b0316865260398452828620969095529290915251919350600492830192611eb59291019061539f565b90815260408051602092819003830190208054939093039092556001600160401b0383166000908152603d825282812054603c8352838220546001600160a01b0316825260399092529182208054919091039055805b6001600160401b0383166000908152603c60209081526040808320546001600160a01b031683526039909152902060070154821015612096576001600160401b0383166000818152603c60209081526040808320546001600160a01b0316835260399091529020600701805484908110611f8157fe5b6000918252602090912060048204015460039091166008026101000a90046001600160401b03161415611fb7576000190161208a565b6001600160401b0383166000908152603c60209081526040808320546001600160a01b0316835260399091529020600701805483908110611ff457fe5b600091825260208083206004830401546001600160401b038781168552603c83526040808620546001600160a01b03168652603990935291909320600701805460039093166008026101000a9093041691908390811061205057fe5b90600052602060002090600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055505b60019182019101611f0b565b50506122ff565b60016001600160401b0382166000908152603a602052604090205460ff1660038111156120c657fe5b14156122ff576001600160401b0381166000818152603c60208181526040808420600281015481546001600160a01b031686526039845282862096909552929091525191926005019161211c916004019061539f565b90815260408051602092819003830190208054939093039092556001600160401b0383166000908152603d825282812054603c8352838220546001600160a01b0316825260399092529182206001018054919091039055805b6001600160401b0383166000908152603c60209081526040808320546001600160a01b0316835260399091529020600601548210156122fc576001600160401b0383166000818152603c60209081526040808320546001600160a01b03168352603990915290206006018054849081106121eb57fe5b6000918252602090912060048204015460039091166008026101000a90046001600160401b0316141561221d576122f0565b6001600160401b0383166000908152603c60209081526040808320546001600160a01b031683526039909152902060060180548390811061225a57fe5b600091825260208083206004830401546001600160401b038781168552603c83526040808620546001600160a01b03168652603990935291909320600601805460039093166008026101000a909304169190839081106122b657fe5b90600052602060002090600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055505b60019182019101612175565b50505b6001600160401b0381166000908152603c60209081526040918290206004018054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381526123d69385939192918301828280156123a55780601f1061237a576101008083540402835291602001916123a5565b820191906000526020600020905b81548152906001019060200180831161238857829003601f168201915b5050506001600160401b0386166000908152603c6020526040812060019081015491935091506006905b04036109fd565b6001600160401b0381166000908152603c6020526040812080546001600160a01b03191681556001810182905560028101829055600381018290559061241f6004830182614b4d565b50506001600160401b0381166000908152603d602052604090205415612459576001600160401b0381166000908152603d60205260408120555b6001600160401b0381166000908152603a6020526040902080546003919060ff19166001836109b1565b60355460405163d5db72eb60e01b81526000916001600160a01b03169063d5db72eb906124b490859060040161540f565b60206040518083038186803b1580156124cc57600080fd5b505afa1580156124e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125049190614fd4565b1561251d57506c0c9f2c9cd04674edea400000006110ae565b6035546040516330d0050560e01b81526001600160a01b03909116906330d005059061254d90859060040161540f565b60206040518083038186803b15801561256557600080fd5b505afa158015612579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259d9190614fd4565b156125aa575060006110ae565b6001600160a01b038216600090815260396020526040902060010154156126a4576001600160a01b0380831660009081526039602090815260409182902060010154603554835163cd68ea1960e01b81529351919460649491169263cd68ea1992600480840193829003018186803b15801561262557600080fd5b505afa158015612639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265d91906150e9565b6001600160a01b038516600090815260396020526040902054028161267e57fe5b6001600160a01b03851660009081526039602052604090205491900490030390506110ae565b506001600160a01b0381166000908152603960205260409020546110ae565b603a6020526000908152604090205460ff1681565b6001600160a01b03811660009081526039602090815260409182902060080180548351818402810184019094528084526060939283018282801561276d57602002820191906000526020600020906000905b82829054906101000a90046001600160401b03166001600160401b03168152602001906008019060208260070104928301926001038202915080841161272a5790505b50505050509050919050565b603b602090815260009182526040918290208054600180830154600280850154600386015460048701546005880154600689015460078a015460088b0180548e516101009b8216159b909b02600019011697909704601f81018d90048d028a018d01909d528c89526001600160a01b03998a169c999097169a949993989297919690959094919290918301828280156128535780601f1061282857610100808354040283529160200191612853565b820191906000526020600020905b81548152906001019060200180831161283657829003601f168201915b505050505090806009015490508a565b6039602052600090815260409020805460019091015482565b603c60209081526000918252604091829020805460018083015460028085015460038601546004870180548a516101009782161597909702600019011693909304601f81018990048902860189019099528885526001600160a01b0390951697929690959392908301828280156129345780601f1061290957610100808354040283529160200191612934565b820191906000526020600020905b81548152906001019060200180831161291757829003601f168201915b5050505050905085565b600054610100900460ff16806129575750612957613962565b80612965575060005460ff16155b6129815760405162461bcd60e51b8152600401610484906156ad565b600054610100900460ff161580156129ac576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b038087166001600160a01b03199283161790925560338054868416908316179055603580549285169290911691909117905580156129fb576000805461ff00191690555b50505050565b603554604051632f3c2fef60e01b81526001600160a01b0390911690632f3c2fef90612a3190339060040161540f565b60206040518083038186803b158015612a4957600080fd5b505afa158015612a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a819190614fd4565b612a9d5760405162461bcd60e51b8152600401610484906156fb565b838115612b15576001600160a01b038716600090815260396020526040908190209051869160040190612ad1908990615383565b90815260405190819003602001902080549091019055612af18587613736565b6001600160a01b038816600090815260396020526040902080549091019055612b85565b6001600160a01b038716600090815260396020526040908190209051869160050190612b42908990615383565b90815260405190819003602001902080549091019055612b628587613736565b6001600160a01b0388166000908152603960205260409020600101805490910190555b8015612e6457600082612bdf57603787604051612ba29190615383565b90815260200160405180910390208560068110612bbb57fe5b600491828204019190066008029054906101000a90046001600160401b0316612c28565b603887604051612bef9190615383565b90815260200160405180910390208560068110612c0857fe5b600491828204019190066008029054906101000a90046001600160401b03165b9050612c32614c24565b6001600160401b038281166000908152603660209081526040808320549093168252603c815290829020825160a08101845281546001600160a01b0316815260018083015482850152600280840154838701526003840154606084015260048401805487516101009482161594909402600019011691909104601f810186900486028301860190965285825291949293608086019391929190830182828015612d1c5780601f10612cf157610100808354040283529160200191612d1c565b820191906000526020600020905b815481529060010190602001808311612cff57829003601f168201915b5050505050815250509050838015612d375750806060015185115b80612d4e575083158015612d4e5750806060015185105b80612d7157506001600160401b0380831660009081526036602052604090205416155b15612d9257612d8a898985896001016006028989613968565b505050612e64565b82816040015110612dfa5760408101805184900390819052831415612dd9576001600160401b03808316600090815260366020526040812054612dd99216908a90896109fd565b612df189898589600101600602856060015187613d82565b60009250612e5d565b612e14898983604001518603896001016006028989613968565b50612e2d89898589600101600602856060015187613d82565b6001600160401b038083166000908152603660209081526040808320549093168252603c90522060020154909203915b5050612b85565b50505050505050565b6001600160a01b03821660009081526039602052604080822090516005909101906109e5908490615383565b6001600160a01b03811660009081526039602090815260409182902060070180548351818402810184019094528084526060939283018282801561276d57600091825260209182902080546001600160401b0316845290820283019290916008910180841161272a575094979650505050505050565b600060026001600160401b0384166000908152603a602052604090205460ff166003811115612f3a57fe5b14612f4857506000806130bb565b6305f5e10063bbf81e00612fdf603560009054906101000a90046001600160a01b03166001600160a01b031663ff8eefea6040518163ffffffff1660e01b815260040160006040518083038186803b158015612fa357600080fd5b505afa158015612fb7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610218919081019061502a565b6001600160401b0386166000908152603b602090815260409182902060078101546005820154600890920180548551601f600260001961010060018616150201909316929092049182018690048602810186019096528086528a95929461309f94939291908301828280156130955780601f1061306a57610100808354040283529160200191613095565b820191906000526020600020905b81548152906001019060200180831161307857829003601f168201915b5050505050613736565b020262278d000202816130ae57fe5b04816130b657fe5b049050805b5092915050565b806131255760006038846040516130d99190615383565b908152602001604051809103902083600681106130f257fe5b600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b0316021790556129fb565b60006037846040516131379190615383565b9081526020016040518091039020836006811061315057fe5b600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b03160217905550505050565b603554604051632f3c2fef60e01b81526000916001600160a01b031690632f3c2fef906131b590339060040161540f565b60206040518083038186803b1580156131cd57600080fd5b505afa1580156131e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132059190614fd4565b801561323b57506001600160401b0384166000908152603b60205260409020600981015460029091015462278d00909102014210155b61324457600080fd5b6000613251856001612f0f565b6034546001600160401b0387166000908152603b6020908152604091829020546035548351638b42426760e01b815293519596506001600160a01b039485169563d1b5c12c95928316946064949390921692638b4242679260048082019391829003018186803b1580156132c457600080fd5b505afa1580156132d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132fc91906150e9565b60640385028161330857fe5b046040518363ffffffff1660e01b815260040161332692919061548d565b600060405180830381600087803b15801561334057600080fd5b505af1158015613354573d6000803e3d6000fd5b50506034546001600160401b0388166000908152603b6020908152604091829020546035548351638b42426760e01b815293516001600160a01b03958616975063036c9641965091851694606494911692638b42426792600480840193829003018186803b1580156133c557600080fd5b505afa1580156133d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fd91906150e9565b60640385028161340957fe5b046040518363ffffffff1660e01b815260040161342792919061548d565b600060405180830381600087803b15801561344157600080fd5b505af1158015613455573d6000803e3d6000fd5b505050506001600160401b0385166000908152603b602052604090206009015483118015613500575060355460405163d5db72eb60e01b81526001600160a01b039091169063d5db72eb906134ae90879060040161540f565b60206040518083038186803b1580156134c657600080fd5b505afa1580156134da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134fe9190614fd4565b155b801561358957506035546040516330d0050560e01b81526001600160a01b03909116906330d005059061353790879060040161540f565b60206040518083038186803b15801561354f57600080fd5b505afa158015613563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135879190614fd4565b155b156136015760355460405163b0251e6d60e01b81526001600160a01b039091169063b0251e6d906135c190879060019060040161550b565b600060405180830381600087803b1580156135db57600080fd5b505af11580156135ef573d6000803e3d6000fd5b505050506135fc85610640565b613688565b6035546001600160a01b03166380908fb086866136218260018901612f0f565b6040518463ffffffff1660e01b815260040161363f93929190615773565b600060405180830381600087803b15801561365957600080fd5b505af115801561366d573d6000803e3d6000fd5b50505050613688856001600160401b03168585600101614560565b509392505050565b6001600160a01b031660009081526039602052604090206001015490565b6001600160a01b03811660009081526039602090815260409182902060060180548351818402810184019094528084526060939283018282801561276d57600091825260209182902080546001600160401b0316845290820283019290916008910180841161272a575094979650505050505050565b603d6020526000908152604090205481565b60345460405163383a1caf60e21b81526000916001600160a01b03169063e0e872bc906137679085906004016155cc565b60206040518083038186803b15801561377f57600080fd5b505afa158015613793573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137b79190614d91565b6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156137ef57600080fd5b505afa158015613803573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613827919061526f565b60ff16600a0a6305f5e10061383b846110b3565b85028161384457fe5b048161384c57fe5b049392505050565b6000806138a8603560009054906101000a90046001600160a01b03166001600160a01b031663ff8eefea6040518163ffffffff1660e01b815260040160006040518083038186803b158015612fa357600080fd5b85662386f26fc1000002816138b957fe5b603554604051632c9ad8ed60e11b815292909104925060009163bbf81e009142879003916001600160a01b0390911690635935b1da906138fd908a906004016155cc565b60206040518083038186803b15801561391557600080fd5b505afa158015613929573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061394d91906150e9565b8402028161395757fe5b049695505050505050565b303b1590565b60008060008061397a888b898c614729565b9250925092506040518060a001604052808b6001600160a01b031681526020018881526020018381526020018781526020018a815250603c6000856001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004019080519060200190613a3c929190614acf565b509050508415613bc2576001600160401b038381166000818152603a60209081526040808320805460ff191690556001600160a01b038f1683526039825280832060070180546001810182559084529183206004830401805460039093166008026101000a9586021990921694909302939093179092555160369190603790613ac6908d90615383565b9081526020016040518091039020600160068b81613ae057fe5b040360068110613aec57fe5b60048104919091015460039091166008026101000a90046001600160401b03908116825260208201929092526040016000205416613bad57826036600060378c604051613b399190615383565b9081526020016040518091039020600160068c81613b5357fe5b040360068110613b5f57fe5b60048104919091015460039091166008026101000a90046001600160401b0390811682526020820192909252604001600020805467ffffffffffffffff191692909116919091179055613bbd565b613bbd838a60018060068c6123cf565b613d4e565b6001600160401b0383166000908152603a6020526040902080546001919060ff1916828002179055506001600160a01b038a16600090815260396020908152604080832060060180546001810182559084529183206004830401805460039093166008026101000a6001600160401b038181021990941693881602929092179091555160369190603890613c57908d90615383565b9081526020016040518091039020600160068b81613c7157fe5b040360068110613c7d57fe5b60048104919091015460039091166008026101000a90046001600160401b03908116825260208201929092526040016000205416613d3e57826036600060388c604051613cca9190615383565b9081526020016040518091039020600160068c81613ce457fe5b040360068110613cf057fe5b60048104919091015460039091166008026101000a90046001600160401b0390811682526020820192909252604001600020805467ffffffffffffffff191692909116919091179055613d4e565b613d4e838a60018060068c6123cf565b613d58888a613736565b6001600160401b039093166000908152603d60205260409020929092555090509695505050505050565b6040805161014081019091528060016001600160401b0384166000908152603a602052604090205460ff166003811115613db857fe5b14613de4576001600160401b0383166000908152603c60205260409020546001600160a01b0316613de6565b875b6001600160a01b0316815260200160006001600160401b0384166000908152603a602052604090205460ff166003811115613e1d57fe5b14613e49576001600160401b0383166000908152603c60205260409020546001600160a01b0316613e4b565b875b6001600160a01b031681526020014281526020018462278d000242018152602001848152602001858152602001613e828688613736565b815260208082018590526040808301899052600060609384018190526001600160401b0386168152603b8352819020845181546001600160a01b039182166001600160a01b0319918216178355868501516001840180549190931691161790559084015160028201559183015160038301556080830151600483015560a0830151600583015560c0830151600683015560e083015160078301556101008301518051613f349260088501920190614acf565b5061012091909101516009909101556000805b6001600160401b0383166000908152603b60209081526040808320546001600160a01b0316835260399091529020600701548210156140d2576001600160401b0383166000818152603b60209081526040808320546001600160a01b0316835260399091529020600701805484908110613fbd57fe5b6000918252602090912060048204015460039091166008026101000a90046001600160401b03161415613ff357600019016140c6565b6001600160401b0383166000908152603b60209081526040808320546001600160a01b031683526039909152902060070180548390811061403057fe5b600091825260208083206004830401546001600160401b038781168552603b83526040808620546001600160a01b03168652603990935291909320600701805460039093166008026101000a9093041691908390811061408c57fe5b90600052602060002090600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055505b60019182019101613f47565b5060009050805b6001600160401b0383166000908152603b60209081526040808320600101546001600160a01b03168352603990915290206006015482101561426c576001600160401b0383166000818152603b60209081526040808320600101546001600160a01b031683526039909152902060060180548490811061415557fe5b6000918252602090912060048204015460039091166008026101000a90046001600160401b0316141561418757614260565b6001600160401b0383166000908152603b60209081526040808320600101546001600160a01b03168352603990915290206006018054839081106141c757fe5b600091825260208083206004830401546001600160401b038781168552603b83526040808620600101546001600160a01b03168652603990935291909320600601805460039093166008026101000a9093041691908390811061422657fe5b90600052602060002090600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055505b600191820191016140d9565b50506001600160401b0381166000908152603c6020526040812080546001600160a01b0319168155600181018290556002810182905560038101829055906142b76004830182614b4d565b50506142cc818660006001600688816123cf57fe5b6001600160401b0381166000908152603a60205260409020805460ff191660021790556142f98486613736565b6001600160401b038281166000818152603d6020908152604080832095909555603b815284822080546001600160a01b039081168452603983528684206008908101805460018082018355918752858720600480830490910180546003938416860261010090810a808e0219909216918c02919091179091559583015490941687529886208201805491820181558652939094209083040180549290961690920290910a928302191691021790556143b08161489d565b6001600160401b0381166000818152603b602052604090206001908101546143e492916001600160a01b0390911690614560565b60345460405163665fef1960e11b81526001600160a01b039091169063d1f94af490829063ccbfde329061441c908a906004016155cc565b60006040518083038186803b15801561443457600080fd5b505afa158015614448573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052614470919081019061502a565b6001600160401b0384166000908152603b6020526040908190206001015490516001600160e01b031960e085901b1681526144bc929189916001600160a01b0390911690600401615601565b600060405180830381600087803b1580156144d657600080fd5b505af11580156144ea573d6000803e3d6000fd5b5050603554604051637199812760e11b81526001600160a01b03909116925063e333024e9150614526908990879087908a908c906004016154cd565b600060405180830381600087803b15801561454057600080fd5b505af1158015614554573d6000803e3d6000fd5b50505050505050505050565b60607fe8a0d10254a080ce4a2461fadc237f17f7c822cb1f715ac1ddcb9c4e21ede58384848460405160240161459893929190615732565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199095169490941790935260335481516348190f0d60e11b815291519294506000936001600160a01b03909116926390321e1a926004808201939291829003018186803b15801561461057600080fd5b505afa158015614624573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061464891906150e9565b603354604080516348190f0d60e11b81529051660110d9316ec0009390930193506001600160a01b03909116916326bdbac9918491309162278d0091889187916390321e1a91600480820192602092909190829003018186803b1580156146ae57600080fd5b505afa1580156146c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e691906150e9565b620493e0633b9aca006040518863ffffffff1660e01b815260040161471096959493929190615526565b6000604051808303818588803b15801561454057600080fd5b6000806000806064603560009054906101000a90046001600160a01b03166001600160a01b03166324bcdfbd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561477f57600080fd5b505afa158015614793573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147b791906150e9565b8902816147c057fe5b048803905060006064603560009054906101000a90046001600160a01b03166001600160a01b03166324bcdfbd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561481757600080fd5b505afa15801561482b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061484f91906150e9565b8a028161485857fe5b049050600088878942604051602001614874949392919061533f565b60408051808303601f1901815291905280516020909101209a9299509097509095505050505050565b6001600160401b0381166000908152603b602052604090819020600281015460039091015491519103906060907f56c61527de4f31a967bf6467f57f70796b043e5585a4ff9d8ff9bfdbf6629571906148fa90859060240161575f565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199095169490941790935260335481516348190f0d60e11b815291519294506000936001600160a01b03909116926390321e1a926004808201939291829003018186803b15801561497257600080fd5b505afa158015614986573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149aa91906150e9565b603354604080516348190f0d60e11b81529051660110d9316ec0009390930193506001600160a01b03909116916326bdbac991849130918891889187916390321e1a91600480820192602092909190829003018186803b158015614a0d57600080fd5b505afa158015614a21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a4591906150e9565b620493e0633b9aca006040518863ffffffff1660e01b8152600401614a6f96959493929190615526565b6000604051808303818588803b158015614a8857600080fd5b505af1158015614a9c573d6000803e3d6000fd5b505050505050505050565b6040518060800160405280600081526020016000815260200160608152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614b1057805160ff1916838001178555614b3d565b82800160010185558215614b3d579182015b82811115614b3d578251825591602001919060010190614b22565b50614b49929150614c5c565b5090565b50805460018160011615610100020316600290046000825580601f10614b735750614b91565b601f016020900490600052602060002090810190614b919190614c5c565b50565b828054828255906000526020600020906004028101928215614c185760005260206000209160040282015b82811115614c185782548255600180840154818401556002808501805486938693614bfc9381860193909281161561010002600019011604614c71565b5060038201548160030155505091600401919060040190614bbf565b50614b49929150614ce6565b6040518060a0016040528060006001600160a01b03168152602001600081526020016000815260200160008152602001606081525090565b5b80821115614b495760008155600101614c5d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614caa5780548555614b3d565b82800160010185558215614b3d57600052602060002091601f016020900482015b82811115614b3d578254825591600101919060010190614ccb565b80821115614b4957600080825560018201819055614d076002830182614b4d565b5060006003820155600401614ce6565b600082601f830112614d27578081fd5b8135614d3a614d35826157c3565b61579d565b9150808252836020828501011115614d5157600080fd5b8060208401602084013760009082016020015292915050565b80516109f781615841565b600060208284031215614d86578081fd5b81356111e58161581e565b600060208284031215614da2578081fd5b81516111e58161581e565b600080600060608486031215614dc1578182fd5b8335614dcc8161581e565b92506020840135614ddc8161581e565b91506040840135614dec8161581e565b809150509250925092565b60008060008060008060c08789031215614e0f578182fd5b8635614e1a8161581e565b955060208701356001600160401b03811115614e34578283fd5b614e4089828a01614d17565b95505060408701359350606087013592506080870135915060a0870135614e6681615833565b809150509295509295509295565b60008060408385031215614e86578182fd5b8235614e918161581e565b915060208301356001600160401b03811115614eab578182fd5b614eb785828601614d17565b9150509250929050565b60008060008060808587031215614ed6578384fd5b8435614ee18161581e565b935060208501356001600160401b03811115614efb578384fd5b614f0787828801614d17565b935050604085013591506060850135614f1f81615833565b939692955090935050565b60006020808385031215614f3c578182fd5b82516001600160401b0380821115614f52578384fd5b818501915085601f830112614f65578384fd5b815181811115614f73578485fd5b8381029150614f8384830161579d565b8181528481019084860184860187018a1015614f9d578788fd5b8795505b83861015614fc757614fb38a82614d6a565b835260019590950194918601918601614fa1565b5098975050505050505050565b600060208284031215614fe5578081fd5b81516111e581615833565b600060208284031215615001578081fd5b81356001600160401b03811115615016578182fd5b61502284828501614d17565b949350505050565b60006020828403121561503b578081fd5b81516001600160401b03811115615050578182fd5b8201601f81018413615060578182fd5b805161506e614d35826157c3565b818152856020838501011115615082578384fd5b6150938260208301602086016157f2565b95945050505050565b6000806000606084860312156150b0578081fd5b83356001600160401b038111156150c5578182fd5b6150d186828701614d17565b935050602084013591506040840135614dec81615833565b6000602082840312156150fa578081fd5b5051919050565b60008060408385031215615113578182fd5b8235915060208301356001600160401b03811115614eab578182fd5b600060208284031215615140578081fd5b81356111e581615841565b60006020828403121561515c578081fd5b81516111e581615841565b60008060006060848603121561517b578081fd5b833561518681615841565b925060208401356151968161581e565b929592945050506040919091013590565b600080600080608085870312156151bc578182fd5b84356151c781615841565b935060208501356001600160401b038111156151e1578283fd5b6151ed87828801614d17565b93505060408501356151fe81615833565b9396929550929360600135925050565b60008060408385031215615220578182fd5b823561522b81615841565b946020939093013593505050565b60008060006060848603121561524d578081fd5b833561525881615841565b9250602084013591506040840135614dec8161581e565b600060208284031215615280578081fd5b815160ff811681146111e5578182fd5b600081518084526152a88160208601602086016157f2565b601f01601f19169290920160200192915050565b600081546001808216600081146152da57600181146152f857615336565b60028304607f16865260ff1983166020870152604086019350615336565b60028304808752615308866157e6565b60005b8281101561532c5781546020828b010152848201915060208101905061530b565b8801602001955050505b50505092915050565b60006bffffffffffffffffffffffff198660601b16825284516153698160148501602089016157f2565b909101601481019390935250603482015260540192915050565b600082516153958184602087016157f2565b9190910192915050565b60008083546001808216600081146153be57600181146153d557615404565b60ff198316865260028304607f1686019350615404565b600283048786526020808720875b838110156153fc5781548a8201529085019082016153e3565b505050860193505b509195945050505050565b6001600160a01b0391909116815260200190565b600061014060018060a01b03808e168452808d166020850152508a60408401528960608401528860808401528760a08401528660c08401528560e08401528061010084015261547481840186615290565b915050826101208301529b9a5050505050505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b03851682528360208301526060604083015261509360608301846152bc565b600060018060a01b038716825285602083015284604083015283606083015260a0608083015261550060a0830184615290565b979650505050505050565b6001600160a01b039290921682521515602082015260400190565b600060018060a01b038816825286602083015260c0604083015261554d60c0830187615290565b606083019590955250608081019290925260a0909101529392505050565b6020808252825182820181905260009190848201906040850190845b818110156155ac5783516001600160401b031683529284019291840191600101615587565b50909695505050505050565b60208101600483106155c657fe5b91905290565b6000602082526111e56020830184615290565b6000604082526155f26040830185615290565b90508260208301529392505050565b6000606082526156146060830186615290565b6020830194909452506001600160a01b0391909116604090910152919050565b6000602082526111e560208301846152bc565b602080825260159082015274496e73756666696369656e74204465706f7369747360581b604082015260600190565b60208082526017908201527f496e73756666696369656e7420426f72726f77696e6773000000000000000000604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601490820152734e6f7420467269656e646c79204164647265737360601b604082015260600190565b90815260200190565b9283526001600160a01b03919091166020830152604082015260600190565b918252602082015260400190565b6001600160401b0391909116815260200190565b6001600160401b039390931683526001600160a01b03919091166020830152604082015260600190565b6040518181016001600160401b03811182821017156157bb57600080fd5b604052919050565b60006001600160401b038211156157d8578081fd5b50601f01601f191660200190565b60009081526020902090565b60005b8381101561580d5781810151838201526020016157f5565b838111156129fb5750506000910152565b6001600160a01b0381168114614b9157600080fd5b8015158114614b9157600080fd5b6001600160401b0381168114614b9157600080fdfea264697066735822122090c9783d32ccab7fc7942b4bb7127b6ac07ff8a9b2682c53f197b0ab88e54ce864736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063a87430ba116100de578063e0059b3111610097578063e86ef40b11610071578063e86ef40b1461039c578063f1d80b89146103af578063f5da23ab146103c2578063fd90d097146103d55761018e565b8063e0059b3114610363578063e306687714610376578063e364db92146103895761018e565b8063a87430ba146102d2578063b43c12ce146102f3578063bb3dabe814610317578063c441d6161461032a578063c78cd5261461033d578063d542050b146103505761018e565b80634407f6c11161014b578063559fde5111610125578063559fde511461025657806362daeaa314610269578063835609db14610289578063a58c2a33146102a95761018e565b80634407f6c11461021d5780634631dfe514610230578063523eb537146102435761018e565b806313c9e8f514610193578063151230e3146101a85780631d9703f6146101bb578063254cff03146101e457806331b3d0df146101f757806334f2f3881461020a575b600080fd5b6101a66101a1366004614ec1565b6103e8565b005b6101a66101b636600461512f565b610640565b6101ce6101c9366004614e74565b6109b9565b6040516101db9190615729565b60405180910390f35b6101a66101f23660046151a7565b6109fd565b6101ce610205366004614d75565b610cb7565b6101ce610218366004614ff0565b6110b3565b6101ce61022b366004615239565b6111ec565b6101ce61023e366004614ec1565b6115d1565b6101a661025136600461512f565b611b77565b6101ce610264366004614d75565b612483565b61027c61027736600461512f565b6126c3565b6040516101db91906155b8565b61029c610297366004614d75565b6126d8565b6040516101db919061556b565b6102bc6102b736600461512f565b612779565b6040516101db9a99989796959493929190615423565b6102e56102e0366004614d75565b612863565b6040516101db929190615751565b61030661030136600461512f565b61287c565b6040516101db9594939291906154cd565b6101a6610325366004614dad565b61293e565b6101a6610338366004614df7565b612a01565b6101ce61034b366004614e74565b612e6d565b61029c61035e366004614d75565b612e99565b6101ce61037136600461520e565b612f0f565b6101a661038436600461509c565b6130c2565b6101ce610397366004615167565b613184565b6101ce6103aa366004614d75565b613690565b61029c6103bd366004614d75565b6136ae565b6101ce6103d036600461512f565b613724565b6101ce6103e3366004615101565b613736565b603554604051632f3c2fef60e01b81526001600160a01b0390911690632f3c2fef9061041890339060040161540f565b60206040518083038186803b15801561043057600080fd5b505afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104689190614fd4565b61048d5760405162461bcd60e51b8152600401610484906156fb565b60405180910390fd5b60006104998385613736565b90506104a3614aa7565b60405180608001604052808581526020014281526020018681526020018381525090508215610582576001600160a01b038616600090815260396020908152604080832060029081018054600181810183559186529484902086516004909602019485558584015190850155908401518051859493610526938501920190614acf565b50606091909101516003909101556001600160a01b038616600090815260396020526040908190208054840181559051859160040190610567908890615383565b90815260405190819003602001902080549091019055610638565b6001600160a01b0386166000908152603960209081526040808320600301805460018181018355918552938390208551600490950201938455848301519084015583015180518493926105dc926002850192910190614acf565b50606091909101516003909101556001600160a01b03861660009081526039602052604090819020600181018054850190559051859160050190610621908890615383565b908152604051908190036020019020805490910190555b505050505050565b603554604051632f3c2fef60e01b81526001600160a01b0390911690632f3c2fef9061067090339060040161540f565b60206040518083038186803b15801561068857600080fd5b505afa15801561069c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c09190614fd4565b6106dc5760405162461bcd60e51b8152600401610484906156fb565b6001600160401b0381166000908152603b602052604090206003015442101561070457600080fd5b6034546001600160401b0382166000908152603b602052604090819020805460058201549251631902763760e31b81526001600160a01b039485169463c813b1b89461075e949190931692916008909101906004016154a6565b600060405180830381600087803b15801561077857600080fd5b505af115801561078c573d6000803e3d6000fd5b50506034546001600160401b0384166000908152603b6020526040908190208054600582015492516318cb888160e31b81526001600160a01b03948516965063c65c440895506107e7949091169291600801906004016154a6565b600060405180830381600087803b15801561080157600080fd5b505af1158015610815573d6000803e3d6000fd5b50506034546001600160401b0384166000908152603b602052604090819020905163665fef1960e11b81526001600160a01b03909216935063d1f94af49250839163ccbfde329161086e91600890910190600401615634565b60006040518083038186803b15801561088657600080fd5b505afa15801561089a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c2919081019061502a565b6001600160401b0384166000908152603b6020526040908190206005810154905491516001600160e01b031960e086901b16815261090d93926001600160a01b031690600401615601565b600060405180830381600087803b15801561092757600080fd5b505af115801561093b573d6000803e3d6000fd5b505050506001600160401b0381166000818152603b6020908152604080832060068101805482546001600160a01b039081168752603986528487208054929092039091559054600192830154909116855282852082018054919091039055938352603a9091529020805460039260ff1990911690835b021790555050565b6001600160a01b03821660009081526039602052604080822090516004909101906109e5908490615383565b90815260200160405180910390205490505b92915050565b600080806001600160401b0387166000908152603a602052604090205460ff166003811115610a2857fe5b14610a7a57603885604051610a3d9190615383565b90815260200160405180910390208360068110610a5657fe5b600491828204019190066008029054906101000a90046001600160401b0316610ac3565b603785604051610a8a9190615383565b90815260200160405180910390208360068110610aa357fe5b600491828204019190066008029054906101000a90046001600160401b03165b90505b8180610ad957506001600160401b038116155b1561063857838015610b5557506001600160401b0386166000908152603a602052604081205460ff166003811115610b0d57fe5b148015610b5557506001600160401b038087166000908152603c6020818152604080842060039081015487871686526036845282862054909616855292909152909120015410155b80610bcc575060016001600160401b0387166000908152603a602052604090205460ff166003811115610b8457fe5b148015610bcc57506001600160401b038087166000908152603c6020818152604080842060039081015487871686526036845282862054909616855292909152909120015411155b15610c20576001600160401b0381811660008181526036602052604080822080548b861680855292842080549190961667ffffffffffffffff19918216179095559290915281549092169091179055600191505b83158015610c4a57506001600160401b038181166000908152603660205260409020548116908716145b15610c97576001600160401b038681166000818152603660205260408082208054868616845291832080549290951667ffffffffffffffff19928316179094559190528154169055600191505b6001600160401b0390811660009081526036602052604090205416610ac6565b60008060005b6001600160a01b038416600090815260396020526040902060020154811015610e3a576001600160a01b03841660009081526039602052604090206002018054610e2e919083908110610d0c57fe5b90600052602060002090600402016003015460396000876001600160a01b03166001600160a01b031681526020019081526020016000206002018381548110610d5157fe5b600091825260209182902060026004909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015610de95780601f10610dbe57610100808354040283529160200191610de9565b820191906000526020600020905b815481529060010190602001808311610dcc57829003601f168201915b5050506001600160a01b038916600090815260396020526040902060020180549092508691508110610e1757fe5b906000526020600020906004020160010154613854565b90910190600101610cbd565b5060005b6001600160a01b038416600090815260396020526040902060030154811015610f97576001600160a01b03841660009081526039602052604090206003018054610f8b919083908110610e8d57fe5b6000918252602080832060036004909302018201546001600160a01b03891684526039909152604090922001805484908110610ec557fe5b600091825260209182902060026004909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015610f5d5780601f10610f3257610100808354040283529160200191610f5d565b820191906000526020600020905b815481529060010190602001808311610f4057829003601f168201915b5050506001600160a01b038916600090815260396020526040902060030180549092508691508110610e1757fe5b90910390600101610e3e565b5060345460405163481343e360e01b81526001600160a01b039091169063481343e390610fc890869060040161540f565b60206040518083038186803b158015610fe057600080fd5b505afa158015610ff4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101891906150e9565b8111156110a85760345460405163481343e360e01b81526001600160a01b039091169063481343e39061104f90869060040161540f565b60206040518083038186803b15801561106757600080fd5b505afa15801561107b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109f91906150e9565b900390506110ae565b60009150505b919050565b603354603454604051633ce9babf60e01b815260009283926001600160a01b039182169263161adc839290911690633ce9babf906110f59088906004016155cc565b60206040518083038186803b15801561110d57600080fd5b505afa158015611121573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611145919061514b565b6040518263ffffffff1660e01b8152600401611161919061575f565b60006040518083038186803b15801561117957600080fd5b505afa15801561118d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111b59190810190614f2a565b6000815181106111c157fe5b60200260200101516001600160401b03169050600081116111e35760006111e5565b805b9392505050565b60006111f88484612f0f565b905060006064603560009054906101000a90046001600160a01b03166001600160a01b0316638b4242676040518163ffffffff1660e01b815260040160206040518083038186803b15801561124c57600080fd5b505afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128491906150e9565b83028161128d57fe5b6034546035546040805163059f833760e41b815290519490930494506001600160a01b039182169363483eb4ed9392909116916359f83370916004808301926000929190829003018186803b1580156112e557600080fd5b505afa1580156112f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611321919081019061502a565b838501866040518463ffffffff1660e01b815260040161134393929190615601565b600060405180830381600087803b15801561135d57600080fd5b505af1158015611371573d6000803e3d6000fd5b50506035546040805160016238880b60e11b0319815290516001600160a01b039092169350631a3aba979250839163ff8eefea91600480820192600092909190829003018186803b1580156113c557600080fd5b505afa1580156113d9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611401919081019061502a565b836040518363ffffffff1660e01b815260040161141f9291906155df565b600060405180830381600087803b15801561143957600080fd5b505af115801561144d573d6000803e3d6000fd5b505050506001600160401b0385166000908152603b602052604090206009810180546001019081905560029091015462278d0042919091030411156114f65760355460405163b0251e6d60e01b81526001600160a01b039091169063b0251e6d906114bf90869060019060040161550b565b600060405180830381600087803b1580156114d957600080fd5b505af11580156114ed573d6000803e3d6000fd5b5050505061155c565b60355460405163b0251e6d60e01b81526001600160a01b039091169063b0251e6d9061152990869060009060040161550b565b600060405180830381600087803b15801561154357600080fd5b505af1158015611557573d6000803e3d6000fd5b505050505b6035546001600160a01b03166380908fb086856115798289612f0f565b6040518463ffffffff1660e01b815260040161159793929190615773565b600060405180830381600087803b1580156115b157600080fd5b505af11580156115c5573d6000803e3d6000fd5b50505050509392505050565b603554604051632f3c2fef60e01b81526000916001600160a01b031690632f3c2fef9061160290339060040161540f565b60206040518083038186803b15801561161a57600080fd5b505afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614fd4565b61166e5760405162461bcd60e51b8152600401610484906156fb565b8115611717576001600160a01b0385166000908152603960205260409081902090518491600401906116a1908790615383565b90815260200160405180910390205410156116ce5760405162461bcd60e51b815260040161048490615647565b6001600160a01b0385166000908152603960205260409081902090518491600401906116fb908790615383565b90815260405190819003602001902080549190910390556117b6565b6001600160a01b038516600090815260396020526040908190209051849160050190611744908790615383565b90815260200160405180910390205410156117715760405162461bcd60e51b815260040161048490615676565b6001600160a01b03851660009081526039602052604090819020905184916005019061179e908790615383565b90815260405190819003602001902080549190910390555b826000836117de576001600160a01b03871660009081526039602052604090206003016117fa565b6001600160a01b03871660009081526039602052604090206002015b8054909150600019015b8215611b0f578660405160200161181b9190615383565b6040516020818303038152906040528051906020012082828154811061183d57fe5b906000526020600020906004020160020160405160200161185e919061539f565b604051602081830303815290604052805190602001201461187e57611b06565b8282828154811061188b57fe5b906000526020600020906004020160000154116119e8578181815481106118ae57fe5b9060005260206000209060040201600001548303925084611920578181815481106118d557fe5b906000526020600020906004020160030154603960008a6001600160a01b03166001600160a01b03168152602001908152602001600020600101600082825403925050819055611964565b81818154811061192c57fe5b60009182526020808320600360049093020191909101546001600160a01b038b16835260399091526040909120805491909103908190555b5061199c61198f83838154811061197757fe5b90600052602060002090600402016000015489613736565b88848481548110610e1757fe5b84019350818054806119aa57fe5b60008281526020812060046000199093019283020181815560018101829055906119d76002830182614b4d565b600382016000905550509055611b06565b84611a65578181815481106119f957fe5b90600052602060002090600402016003015483838381548110611a1857fe5b9060005260206000209060040201600001540302603960008a6001600160a01b03166001600160a01b03168152602001908152602001600020600101600082825403925050819055611aca565b818181548110611a7157fe5b90600052602060002090600402016003015483838381548110611a9057fe5b600091825260208083206004909202909101546001600160a01b038d16835260399091526040909120805492909103929092029003908190555b5082828281548110611ad857fe5b600091825260209091206004909102018054919091039055611afd61198f8489613736565b84019350600092505b60001901611804565b5083611b43576001600160a01b03871660009081526039602052604090208154611b3e91600301908390614b94565b611b6c565b6001600160a01b03871660009081526039602052604090208154611b6c91600201908390614b94565b505050949350505050565b603554604051632f3c2fef60e01b81526001600160a01b0390911690632f3c2fef90611ba790339060040161540f565b60206040518083038186803b158015611bbf57600080fd5b505afa158015611bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf79190614fd4565b611c0057600080fd5b6001600160401b0381166000908152603a602052604081205460ff166003811115611c2757fe5b141561209d576034546001600160401b0382166000908152603c602052604090819020805460028201549251631902763760e31b81526001600160a01b039485169463c813b1b894611c8594919093169291600491820191016154a6565b600060405180830381600087803b158015611c9f57600080fd5b505af1158015611cb3573d6000803e3d6000fd5b50506034546001600160401b0384166000908152603c6020526040908190208054600282015492516318cb888160e31b81526001600160a01b03948516965063c65c44089550611d0e949091169291600490810191016154a6565b600060405180830381600087803b158015611d2857600080fd5b505af1158015611d3c573d6000803e3d6000fd5b50506034546001600160401b0384166000908152603c602052604090819020905163665fef1960e11b81526001600160a01b03909216935063d1f94af49250839163ccbfde3291611d939160049182019101615634565b60006040518083038186803b158015611dab57600080fd5b505afa158015611dbf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611de7919081019061502a565b6001600160401b0384166000908152603c6020526040908190206002810154905491516001600160e01b031960e086901b168152611e3293926001600160a01b031690600401615601565b600060405180830381600087803b158015611e4c57600080fd5b505af1158015611e60573d6000803e3d6000fd5b5050506001600160401b0382166000818152603c60208181526040808420600281015481546001600160a01b0316865260398452828620969095529290915251919350600492830192611eb59291019061539f565b90815260408051602092819003830190208054939093039092556001600160401b0383166000908152603d825282812054603c8352838220546001600160a01b0316825260399092529182208054919091039055805b6001600160401b0383166000908152603c60209081526040808320546001600160a01b031683526039909152902060070154821015612096576001600160401b0383166000818152603c60209081526040808320546001600160a01b0316835260399091529020600701805484908110611f8157fe5b6000918252602090912060048204015460039091166008026101000a90046001600160401b03161415611fb7576000190161208a565b6001600160401b0383166000908152603c60209081526040808320546001600160a01b0316835260399091529020600701805483908110611ff457fe5b600091825260208083206004830401546001600160401b038781168552603c83526040808620546001600160a01b03168652603990935291909320600701805460039093166008026101000a9093041691908390811061205057fe5b90600052602060002090600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055505b60019182019101611f0b565b50506122ff565b60016001600160401b0382166000908152603a602052604090205460ff1660038111156120c657fe5b14156122ff576001600160401b0381166000818152603c60208181526040808420600281015481546001600160a01b031686526039845282862096909552929091525191926005019161211c916004019061539f565b90815260408051602092819003830190208054939093039092556001600160401b0383166000908152603d825282812054603c8352838220546001600160a01b0316825260399092529182206001018054919091039055805b6001600160401b0383166000908152603c60209081526040808320546001600160a01b0316835260399091529020600601548210156122fc576001600160401b0383166000818152603c60209081526040808320546001600160a01b03168352603990915290206006018054849081106121eb57fe5b6000918252602090912060048204015460039091166008026101000a90046001600160401b0316141561221d576122f0565b6001600160401b0383166000908152603c60209081526040808320546001600160a01b031683526039909152902060060180548390811061225a57fe5b600091825260208083206004830401546001600160401b038781168552603c83526040808620546001600160a01b03168652603990935291909320600601805460039093166008026101000a909304169190839081106122b657fe5b90600052602060002090600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055505b60019182019101612175565b50505b6001600160401b0381166000908152603c60209081526040918290206004018054835160026001831615610100026000190190921691909104601f81018490048402820184019094528381526123d69385939192918301828280156123a55780601f1061237a576101008083540402835291602001916123a5565b820191906000526020600020905b81548152906001019060200180831161238857829003601f168201915b5050506001600160401b0386166000908152603c6020526040812060019081015491935091506006905b04036109fd565b6001600160401b0381166000908152603c6020526040812080546001600160a01b03191681556001810182905560028101829055600381018290559061241f6004830182614b4d565b50506001600160401b0381166000908152603d602052604090205415612459576001600160401b0381166000908152603d60205260408120555b6001600160401b0381166000908152603a6020526040902080546003919060ff19166001836109b1565b60355460405163d5db72eb60e01b81526000916001600160a01b03169063d5db72eb906124b490859060040161540f565b60206040518083038186803b1580156124cc57600080fd5b505afa1580156124e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125049190614fd4565b1561251d57506c0c9f2c9cd04674edea400000006110ae565b6035546040516330d0050560e01b81526001600160a01b03909116906330d005059061254d90859060040161540f565b60206040518083038186803b15801561256557600080fd5b505afa158015612579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259d9190614fd4565b156125aa575060006110ae565b6001600160a01b038216600090815260396020526040902060010154156126a4576001600160a01b0380831660009081526039602090815260409182902060010154603554835163cd68ea1960e01b81529351919460649491169263cd68ea1992600480840193829003018186803b15801561262557600080fd5b505afa158015612639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265d91906150e9565b6001600160a01b038516600090815260396020526040902054028161267e57fe5b6001600160a01b03851660009081526039602052604090205491900490030390506110ae565b506001600160a01b0381166000908152603960205260409020546110ae565b603a6020526000908152604090205460ff1681565b6001600160a01b03811660009081526039602090815260409182902060080180548351818402810184019094528084526060939283018282801561276d57602002820191906000526020600020906000905b82829054906101000a90046001600160401b03166001600160401b03168152602001906008019060208260070104928301926001038202915080841161272a5790505b50505050509050919050565b603b602090815260009182526040918290208054600180830154600280850154600386015460048701546005880154600689015460078a015460088b0180548e516101009b8216159b909b02600019011697909704601f81018d90048d028a018d01909d528c89526001600160a01b03998a169c999097169a949993989297919690959094919290918301828280156128535780601f1061282857610100808354040283529160200191612853565b820191906000526020600020905b81548152906001019060200180831161283657829003601f168201915b505050505090806009015490508a565b6039602052600090815260409020805460019091015482565b603c60209081526000918252604091829020805460018083015460028085015460038601546004870180548a516101009782161597909702600019011693909304601f81018990048902860189019099528885526001600160a01b0390951697929690959392908301828280156129345780601f1061290957610100808354040283529160200191612934565b820191906000526020600020905b81548152906001019060200180831161291757829003601f168201915b5050505050905085565b600054610100900460ff16806129575750612957613962565b80612965575060005460ff16155b6129815760405162461bcd60e51b8152600401610484906156ad565b600054610100900460ff161580156129ac576000805460ff1961ff0019909116610100171660011790555b603480546001600160a01b038087166001600160a01b03199283161790925560338054868416908316179055603580549285169290911691909117905580156129fb576000805461ff00191690555b50505050565b603554604051632f3c2fef60e01b81526001600160a01b0390911690632f3c2fef90612a3190339060040161540f565b60206040518083038186803b158015612a4957600080fd5b505afa158015612a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a819190614fd4565b612a9d5760405162461bcd60e51b8152600401610484906156fb565b838115612b15576001600160a01b038716600090815260396020526040908190209051869160040190612ad1908990615383565b90815260405190819003602001902080549091019055612af18587613736565b6001600160a01b038816600090815260396020526040902080549091019055612b85565b6001600160a01b038716600090815260396020526040908190209051869160050190612b42908990615383565b90815260405190819003602001902080549091019055612b628587613736565b6001600160a01b0388166000908152603960205260409020600101805490910190555b8015612e6457600082612bdf57603787604051612ba29190615383565b90815260200160405180910390208560068110612bbb57fe5b600491828204019190066008029054906101000a90046001600160401b0316612c28565b603887604051612bef9190615383565b90815260200160405180910390208560068110612c0857fe5b600491828204019190066008029054906101000a90046001600160401b03165b9050612c32614c24565b6001600160401b038281166000908152603660209081526040808320549093168252603c815290829020825160a08101845281546001600160a01b0316815260018083015482850152600280840154838701526003840154606084015260048401805487516101009482161594909402600019011691909104601f810186900486028301860190965285825291949293608086019391929190830182828015612d1c5780601f10612cf157610100808354040283529160200191612d1c565b820191906000526020600020905b815481529060010190602001808311612cff57829003601f168201915b5050505050815250509050838015612d375750806060015185115b80612d4e575083158015612d4e5750806060015185105b80612d7157506001600160401b0380831660009081526036602052604090205416155b15612d9257612d8a898985896001016006028989613968565b505050612e64565b82816040015110612dfa5760408101805184900390819052831415612dd9576001600160401b03808316600090815260366020526040812054612dd99216908a90896109fd565b612df189898589600101600602856060015187613d82565b60009250612e5d565b612e14898983604001518603896001016006028989613968565b50612e2d89898589600101600602856060015187613d82565b6001600160401b038083166000908152603660209081526040808320549093168252603c90522060020154909203915b5050612b85565b50505050505050565b6001600160a01b03821660009081526039602052604080822090516005909101906109e5908490615383565b6001600160a01b03811660009081526039602090815260409182902060070180548351818402810184019094528084526060939283018282801561276d57600091825260209182902080546001600160401b0316845290820283019290916008910180841161272a575094979650505050505050565b600060026001600160401b0384166000908152603a602052604090205460ff166003811115612f3a57fe5b14612f4857506000806130bb565b6305f5e10063bbf81e00612fdf603560009054906101000a90046001600160a01b03166001600160a01b031663ff8eefea6040518163ffffffff1660e01b815260040160006040518083038186803b158015612fa357600080fd5b505afa158015612fb7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610218919081019061502a565b6001600160401b0386166000908152603b602090815260409182902060078101546005820154600890920180548551601f600260001961010060018616150201909316929092049182018690048602810186019096528086528a95929461309f94939291908301828280156130955780601f1061306a57610100808354040283529160200191613095565b820191906000526020600020905b81548152906001019060200180831161307857829003601f168201915b5050505050613736565b020262278d000202816130ae57fe5b04816130b657fe5b049050805b5092915050565b806131255760006038846040516130d99190615383565b908152602001604051809103902083600681106130f257fe5b600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b0316021790556129fb565b60006037846040516131379190615383565b9081526020016040518091039020836006811061315057fe5b600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b03160217905550505050565b603554604051632f3c2fef60e01b81526000916001600160a01b031690632f3c2fef906131b590339060040161540f565b60206040518083038186803b1580156131cd57600080fd5b505afa1580156131e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132059190614fd4565b801561323b57506001600160401b0384166000908152603b60205260409020600981015460029091015462278d00909102014210155b61324457600080fd5b6000613251856001612f0f565b6034546001600160401b0387166000908152603b6020908152604091829020546035548351638b42426760e01b815293519596506001600160a01b039485169563d1b5c12c95928316946064949390921692638b4242679260048082019391829003018186803b1580156132c457600080fd5b505afa1580156132d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132fc91906150e9565b60640385028161330857fe5b046040518363ffffffff1660e01b815260040161332692919061548d565b600060405180830381600087803b15801561334057600080fd5b505af1158015613354573d6000803e3d6000fd5b50506034546001600160401b0388166000908152603b6020908152604091829020546035548351638b42426760e01b815293516001600160a01b03958616975063036c9641965091851694606494911692638b42426792600480840193829003018186803b1580156133c557600080fd5b505afa1580156133d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fd91906150e9565b60640385028161340957fe5b046040518363ffffffff1660e01b815260040161342792919061548d565b600060405180830381600087803b15801561344157600080fd5b505af1158015613455573d6000803e3d6000fd5b505050506001600160401b0385166000908152603b602052604090206009015483118015613500575060355460405163d5db72eb60e01b81526001600160a01b039091169063d5db72eb906134ae90879060040161540f565b60206040518083038186803b1580156134c657600080fd5b505afa1580156134da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134fe9190614fd4565b155b801561358957506035546040516330d0050560e01b81526001600160a01b03909116906330d005059061353790879060040161540f565b60206040518083038186803b15801561354f57600080fd5b505afa158015613563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135879190614fd4565b155b156136015760355460405163b0251e6d60e01b81526001600160a01b039091169063b0251e6d906135c190879060019060040161550b565b600060405180830381600087803b1580156135db57600080fd5b505af11580156135ef573d6000803e3d6000fd5b505050506135fc85610640565b613688565b6035546001600160a01b03166380908fb086866136218260018901612f0f565b6040518463ffffffff1660e01b815260040161363f93929190615773565b600060405180830381600087803b15801561365957600080fd5b505af115801561366d573d6000803e3d6000fd5b50505050613688856001600160401b03168585600101614560565b509392505050565b6001600160a01b031660009081526039602052604090206001015490565b6001600160a01b03811660009081526039602090815260409182902060060180548351818402810184019094528084526060939283018282801561276d57600091825260209182902080546001600160401b0316845290820283019290916008910180841161272a575094979650505050505050565b603d6020526000908152604090205481565b60345460405163383a1caf60e21b81526000916001600160a01b03169063e0e872bc906137679085906004016155cc565b60206040518083038186803b15801561377f57600080fd5b505afa158015613793573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137b79190614d91565b6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156137ef57600080fd5b505afa158015613803573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613827919061526f565b60ff16600a0a6305f5e10061383b846110b3565b85028161384457fe5b048161384c57fe5b049392505050565b6000806138a8603560009054906101000a90046001600160a01b03166001600160a01b031663ff8eefea6040518163ffffffff1660e01b815260040160006040518083038186803b158015612fa357600080fd5b85662386f26fc1000002816138b957fe5b603554604051632c9ad8ed60e11b815292909104925060009163bbf81e009142879003916001600160a01b0390911690635935b1da906138fd908a906004016155cc565b60206040518083038186803b15801561391557600080fd5b505afa158015613929573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061394d91906150e9565b8402028161395757fe5b049695505050505050565b303b1590565b60008060008061397a888b898c614729565b9250925092506040518060a001604052808b6001600160a01b031681526020018881526020018381526020018781526020018a815250603c6000856001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004019080519060200190613a3c929190614acf565b509050508415613bc2576001600160401b038381166000818152603a60209081526040808320805460ff191690556001600160a01b038f1683526039825280832060070180546001810182559084529183206004830401805460039093166008026101000a9586021990921694909302939093179092555160369190603790613ac6908d90615383565b9081526020016040518091039020600160068b81613ae057fe5b040360068110613aec57fe5b60048104919091015460039091166008026101000a90046001600160401b03908116825260208201929092526040016000205416613bad57826036600060378c604051613b399190615383565b9081526020016040518091039020600160068c81613b5357fe5b040360068110613b5f57fe5b60048104919091015460039091166008026101000a90046001600160401b0390811682526020820192909252604001600020805467ffffffffffffffff191692909116919091179055613bbd565b613bbd838a60018060068c6123cf565b613d4e565b6001600160401b0383166000908152603a6020526040902080546001919060ff1916828002179055506001600160a01b038a16600090815260396020908152604080832060060180546001810182559084529183206004830401805460039093166008026101000a6001600160401b038181021990941693881602929092179091555160369190603890613c57908d90615383565b9081526020016040518091039020600160068b81613c7157fe5b040360068110613c7d57fe5b60048104919091015460039091166008026101000a90046001600160401b03908116825260208201929092526040016000205416613d3e57826036600060388c604051613cca9190615383565b9081526020016040518091039020600160068c81613ce457fe5b040360068110613cf057fe5b60048104919091015460039091166008026101000a90046001600160401b0390811682526020820192909252604001600020805467ffffffffffffffff191692909116919091179055613d4e565b613d4e838a60018060068c6123cf565b613d58888a613736565b6001600160401b039093166000908152603d60205260409020929092555090509695505050505050565b6040805161014081019091528060016001600160401b0384166000908152603a602052604090205460ff166003811115613db857fe5b14613de4576001600160401b0383166000908152603c60205260409020546001600160a01b0316613de6565b875b6001600160a01b0316815260200160006001600160401b0384166000908152603a602052604090205460ff166003811115613e1d57fe5b14613e49576001600160401b0383166000908152603c60205260409020546001600160a01b0316613e4b565b875b6001600160a01b031681526020014281526020018462278d000242018152602001848152602001858152602001613e828688613736565b815260208082018590526040808301899052600060609384018190526001600160401b0386168152603b8352819020845181546001600160a01b039182166001600160a01b0319918216178355868501516001840180549190931691161790559084015160028201559183015160038301556080830151600483015560a0830151600583015560c0830151600683015560e083015160078301556101008301518051613f349260088501920190614acf565b5061012091909101516009909101556000805b6001600160401b0383166000908152603b60209081526040808320546001600160a01b0316835260399091529020600701548210156140d2576001600160401b0383166000818152603b60209081526040808320546001600160a01b0316835260399091529020600701805484908110613fbd57fe5b6000918252602090912060048204015460039091166008026101000a90046001600160401b03161415613ff357600019016140c6565b6001600160401b0383166000908152603b60209081526040808320546001600160a01b031683526039909152902060070180548390811061403057fe5b600091825260208083206004830401546001600160401b038781168552603b83526040808620546001600160a01b03168652603990935291909320600701805460039093166008026101000a9093041691908390811061408c57fe5b90600052602060002090600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055505b60019182019101613f47565b5060009050805b6001600160401b0383166000908152603b60209081526040808320600101546001600160a01b03168352603990915290206006015482101561426c576001600160401b0383166000818152603b60209081526040808320600101546001600160a01b031683526039909152902060060180548490811061415557fe5b6000918252602090912060048204015460039091166008026101000a90046001600160401b0316141561418757614260565b6001600160401b0383166000908152603b60209081526040808320600101546001600160a01b03168352603990915290206006018054839081106141c757fe5b600091825260208083206004830401546001600160401b038781168552603b83526040808620600101546001600160a01b03168652603990935291909320600601805460039093166008026101000a9093041691908390811061422657fe5b90600052602060002090600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b031602179055505b600191820191016140d9565b50506001600160401b0381166000908152603c6020526040812080546001600160a01b0319168155600181018290556002810182905560038101829055906142b76004830182614b4d565b50506142cc818660006001600688816123cf57fe5b6001600160401b0381166000908152603a60205260409020805460ff191660021790556142f98486613736565b6001600160401b038281166000818152603d6020908152604080832095909555603b815284822080546001600160a01b039081168452603983528684206008908101805460018082018355918752858720600480830490910180546003938416860261010090810a808e0219909216918c02919091179091559583015490941687529886208201805491820181558652939094209083040180549290961690920290910a928302191691021790556143b08161489d565b6001600160401b0381166000818152603b602052604090206001908101546143e492916001600160a01b0390911690614560565b60345460405163665fef1960e11b81526001600160a01b039091169063d1f94af490829063ccbfde329061441c908a906004016155cc565b60006040518083038186803b15801561443457600080fd5b505afa158015614448573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052614470919081019061502a565b6001600160401b0384166000908152603b6020526040908190206001015490516001600160e01b031960e085901b1681526144bc929189916001600160a01b0390911690600401615601565b600060405180830381600087803b1580156144d657600080fd5b505af11580156144ea573d6000803e3d6000fd5b5050603554604051637199812760e11b81526001600160a01b03909116925063e333024e9150614526908990879087908a908c906004016154cd565b600060405180830381600087803b15801561454057600080fd5b505af1158015614554573d6000803e3d6000fd5b50505050505050505050565b60607fe8a0d10254a080ce4a2461fadc237f17f7c822cb1f715ac1ddcb9c4e21ede58384848460405160240161459893929190615732565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199095169490941790935260335481516348190f0d60e11b815291519294506000936001600160a01b03909116926390321e1a926004808201939291829003018186803b15801561461057600080fd5b505afa158015614624573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061464891906150e9565b603354604080516348190f0d60e11b81529051660110d9316ec0009390930193506001600160a01b03909116916326bdbac9918491309162278d0091889187916390321e1a91600480820192602092909190829003018186803b1580156146ae57600080fd5b505afa1580156146c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e691906150e9565b620493e0633b9aca006040518863ffffffff1660e01b815260040161471096959493929190615526565b6000604051808303818588803b15801561454057600080fd5b6000806000806064603560009054906101000a90046001600160a01b03166001600160a01b03166324bcdfbd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561477f57600080fd5b505afa158015614793573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147b791906150e9565b8902816147c057fe5b048803905060006064603560009054906101000a90046001600160a01b03166001600160a01b03166324bcdfbd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561481757600080fd5b505afa15801561482b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061484f91906150e9565b8a028161485857fe5b049050600088878942604051602001614874949392919061533f565b60408051808303601f1901815291905280516020909101209a9299509097509095505050505050565b6001600160401b0381166000908152603b602052604090819020600281015460039091015491519103906060907f56c61527de4f31a967bf6467f57f70796b043e5585a4ff9d8ff9bfdbf6629571906148fa90859060240161575f565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199095169490941790935260335481516348190f0d60e11b815291519294506000936001600160a01b03909116926390321e1a926004808201939291829003018186803b15801561497257600080fd5b505afa158015614986573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149aa91906150e9565b603354604080516348190f0d60e11b81529051660110d9316ec0009390930193506001600160a01b03909116916326bdbac991849130918891889187916390321e1a91600480820192602092909190829003018186803b158015614a0d57600080fd5b505afa158015614a21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a4591906150e9565b620493e0633b9aca006040518863ffffffff1660e01b8152600401614a6f96959493929190615526565b6000604051808303818588803b158015614a8857600080fd5b505af1158015614a9c573d6000803e3d6000fd5b505050505050505050565b6040518060800160405280600081526020016000815260200160608152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614b1057805160ff1916838001178555614b3d565b82800160010185558215614b3d579182015b82811115614b3d578251825591602001919060010190614b22565b50614b49929150614c5c565b5090565b50805460018160011615610100020316600290046000825580601f10614b735750614b91565b601f016020900490600052602060002090810190614b919190614c5c565b50565b828054828255906000526020600020906004028101928215614c185760005260206000209160040282015b82811115614c185782548255600180840154818401556002808501805486938693614bfc9381860193909281161561010002600019011604614c71565b5060038201548160030155505091600401919060040190614bbf565b50614b49929150614ce6565b6040518060a0016040528060006001600160a01b03168152602001600081526020016000815260200160008152602001606081525090565b5b80821115614b495760008155600101614c5d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614caa5780548555614b3d565b82800160010185558215614b3d57600052602060002091601f016020900482015b82811115614b3d578254825591600101919060010190614ccb565b80821115614b4957600080825560018201819055614d076002830182614b4d565b5060006003820155600401614ce6565b600082601f830112614d27578081fd5b8135614d3a614d35826157c3565b61579d565b9150808252836020828501011115614d5157600080fd5b8060208401602084013760009082016020015292915050565b80516109f781615841565b600060208284031215614d86578081fd5b81356111e58161581e565b600060208284031215614da2578081fd5b81516111e58161581e565b600080600060608486031215614dc1578182fd5b8335614dcc8161581e565b92506020840135614ddc8161581e565b91506040840135614dec8161581e565b809150509250925092565b60008060008060008060c08789031215614e0f578182fd5b8635614e1a8161581e565b955060208701356001600160401b03811115614e34578283fd5b614e4089828a01614d17565b95505060408701359350606087013592506080870135915060a0870135614e6681615833565b809150509295509295509295565b60008060408385031215614e86578182fd5b8235614e918161581e565b915060208301356001600160401b03811115614eab578182fd5b614eb785828601614d17565b9150509250929050565b60008060008060808587031215614ed6578384fd5b8435614ee18161581e565b935060208501356001600160401b03811115614efb578384fd5b614f0787828801614d17565b935050604085013591506060850135614f1f81615833565b939692955090935050565b60006020808385031215614f3c578182fd5b82516001600160401b0380821115614f52578384fd5b818501915085601f830112614f65578384fd5b815181811115614f73578485fd5b8381029150614f8384830161579d565b8181528481019084860184860187018a1015614f9d578788fd5b8795505b83861015614fc757614fb38a82614d6a565b835260019590950194918601918601614fa1565b5098975050505050505050565b600060208284031215614fe5578081fd5b81516111e581615833565b600060208284031215615001578081fd5b81356001600160401b03811115615016578182fd5b61502284828501614d17565b949350505050565b60006020828403121561503b578081fd5b81516001600160401b03811115615050578182fd5b8201601f81018413615060578182fd5b805161506e614d35826157c3565b818152856020838501011115615082578384fd5b6150938260208301602086016157f2565b95945050505050565b6000806000606084860312156150b0578081fd5b83356001600160401b038111156150c5578182fd5b6150d186828701614d17565b935050602084013591506040840135614dec81615833565b6000602082840312156150fa578081fd5b5051919050565b60008060408385031215615113578182fd5b8235915060208301356001600160401b03811115614eab578182fd5b600060208284031215615140578081fd5b81356111e581615841565b60006020828403121561515c578081fd5b81516111e581615841565b60008060006060848603121561517b578081fd5b833561518681615841565b925060208401356151968161581e565b929592945050506040919091013590565b600080600080608085870312156151bc578182fd5b84356151c781615841565b935060208501356001600160401b038111156151e1578283fd5b6151ed87828801614d17565b93505060408501356151fe81615833565b9396929550929360600135925050565b60008060408385031215615220578182fd5b823561522b81615841565b946020939093013593505050565b60008060006060848603121561524d578081fd5b833561525881615841565b9250602084013591506040840135614dec8161581e565b600060208284031215615280578081fd5b815160ff811681146111e5578182fd5b600081518084526152a88160208601602086016157f2565b601f01601f19169290920160200192915050565b600081546001808216600081146152da57600181146152f857615336565b60028304607f16865260ff1983166020870152604086019350615336565b60028304808752615308866157e6565b60005b8281101561532c5781546020828b010152848201915060208101905061530b565b8801602001955050505b50505092915050565b60006bffffffffffffffffffffffff198660601b16825284516153698160148501602089016157f2565b909101601481019390935250603482015260540192915050565b600082516153958184602087016157f2565b9190910192915050565b60008083546001808216600081146153be57600181146153d557615404565b60ff198316865260028304607f1686019350615404565b600283048786526020808720875b838110156153fc5781548a8201529085019082016153e3565b505050860193505b509195945050505050565b6001600160a01b0391909116815260200190565b600061014060018060a01b03808e168452808d166020850152508a60408401528960608401528860808401528760a08401528660c08401528560e08401528061010084015261547481840186615290565b915050826101208301529b9a5050505050505050505050565b6001600160a01b03929092168252602082015260400190565b600060018060a01b03851682528360208301526060604083015261509360608301846152bc565b600060018060a01b038716825285602083015284604083015283606083015260a0608083015261550060a0830184615290565b979650505050505050565b6001600160a01b039290921682521515602082015260400190565b600060018060a01b038816825286602083015260c0604083015261554d60c0830187615290565b606083019590955250608081019290925260a0909101529392505050565b6020808252825182820181905260009190848201906040850190845b818110156155ac5783516001600160401b031683529284019291840191600101615587565b50909695505050505050565b60208101600483106155c657fe5b91905290565b6000602082526111e56020830184615290565b6000604082526155f26040830185615290565b90508260208301529392505050565b6000606082526156146060830186615290565b6020830194909452506001600160a01b0391909116604090910152919050565b6000602082526111e560208301846152bc565b602080825260159082015274496e73756666696369656e74204465706f7369747360581b604082015260600190565b60208082526017908201527f496e73756666696369656e7420426f72726f77696e6773000000000000000000604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601490820152734e6f7420467269656e646c79204164647265737360601b604082015260600190565b90815260200190565b9283526001600160a01b03919091166020830152604082015260600190565b918252602082015260400190565b6001600160401b0391909116815260200190565b6001600160401b039390931683526001600160a01b03919091166020830152604082015260600190565b6040518181016001600160401b03811182821017156157bb57600080fd5b604052919050565b60006001600160401b038211156157d8578081fd5b50601f01601f191660200190565b60009081526020902090565b60005b8381101561580d5781810151838201526020016157f5565b838111156129fb5750506000910152565b6001600160a01b0381168114614b9157600080fd5b8015158114614b9157600080fd5b6001600160401b0381168114614b9157600080fdfea264697066735822122090c9783d32ccab7fc7942b4bb7127b6ac07ff8a9b2682c53f197b0ab88e54ce864736f6c634300060c0033
Deployed Bytecode Sourcemap
1470:22827:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4647:993;;;;;;:::i;:::-;;:::i;:::-;;14350:941;;;;;;:::i;:::-;;:::i;22488:162::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10819:1013;;;;;;:::i;:::-;;:::i;21291:762::-;;;;;;:::i;:::-;;:::i;20391:246::-;;;;;;:::i;:::-;;:::i;15300:628::-;;;;;;:::i;:::-;;:::i;5652:1905::-;;;;;;:::i;:::-;;:::i;17595:2102::-;;;;;;:::i;:::-;;:::i;23454:495::-;;;;;;:::i;:::-;;:::i;2023:45::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;23302:140::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2075:53::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;:::i;1978:38::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;2135:45::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;3695:283::-;;;;;;:::i;:::-;;:::i;7569:1743::-;;;;;;:::i;:::-;;:::i;22662:166::-;;;;;;:::i;:::-;;:::i;23143:147::-;;;;;;:::i;:::-;;:::i;20030:349::-;;;;;;:::i;:::-;;:::i;24146:146::-;;;;;;:::i;:::-;;:::i;15936:827::-;;;;;;:::i;:::-;;:::i;22840:130::-;;;;;;:::i;:::-;;:::i;22982:149::-;;;;;;:::i;:::-;;:::i;2187:45::-;;;;;;:::i;:::-;;:::i;19801:217::-;;;;;;:::i;:::-;;:::i;4647:993::-;4827:4;;:32;;-1:-1:-1;;;4827:32:0;;-1:-1:-1;;;;;4827:4:0;;;;:20;;:32;;4848:10;;4827:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4819:65;;;;-1:-1:-1;;;4819:65:0;;;;;;;:::i;:::-;;;;;;;;;4895:14;4912:24;4921:7;4930:5;4912:8;:24::i;:::-;4895:41;;4947:29;;:::i;:::-;4979:241;;;;;;;;5002:7;4979:241;;;;5070:3;4979:241;;;;5136:5;4979:241;;;;5206:9;4979:241;;;4947:273;;5234:7;5231:402;;;-1:-1:-1;;;;;5257:18:0;;;;;;:5;:18;;;;;;;;:29;;;;:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5292:10;;5257:46;;;;;;;;;:::i;:::-;-1:-1:-1;5257:46:0;;;;;;;;;;;-1:-1:-1;;;;;5318:18:0;;;;;;:5;:18;;;;;;;:44;;;;;;5377:34;;5415:7;;5377:27;;;:34;;5405:5;;5377:34;:::i;:::-;;;;;;;;;;;;;;:45;;;;;;;5231:402;;;-1:-1:-1;;;;;5457:18:0;;;;;;:5;:18;;;;;;;;:28;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5491:10;;5457:45;;;;;;;;;;;:::i;:::-;-1:-1:-1;5457:45:0;;;;;;;;;;;-1:-1:-1;;;;;5517:18:0;;;;;;:5;:18;;;;;;;:32;;;:45;;;;;;5577:33;;5614:7;;5577:26;;;:33;;5604:5;;5577:33;:::i;:::-;;;;;;;;;;;;;;:44;;;;;;;5231:402;4647:993;;;;;;:::o;14350:941::-;14417:4;;:32;;-1:-1:-1;;;14417:32:0;;-1:-1:-1;;;;;14417:4:0;;;;:20;;:32;;14438:10;;14417:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14409:64;;;;-1:-1:-1;;;14409:64:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;14493:23:0;;;;;;:13;:23;;;;;:34;;;14531:3;-1:-1:-1;14493:41:0;14484:51;;;;;;14546:3;;-1:-1:-1;;;;;14570:23:0;;14546:3;14570:23;;;:13;:23;;;;;;;:32;;14603:30;;;;14546:120;;-1:-1:-1;;;14546:120:0;;-1:-1:-1;;;;;14546:3:0;;;;:23;;:120;;14570:32;;;;;14603:30;14635;;;;;14546:120;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14681:3:0;;-1:-1:-1;;;;;14701:23:0;;14681:3;14701:23;;;:13;:23;;;;;;;:32;;14734:30;;;;14681:116;;-1:-1:-1;;;14681:116:0;;-1:-1:-1;;;;;14681:3:0;;;;-1:-1:-1;14681:19:0;;-1:-1:-1;14681:116:0;;14701:32;;;;14734:30;14766;;;14681:116;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14809:3:0;;-1:-1:-1;;;;;14841:23:0;;14809:3;14841:23;;;:13;:23;;;;;;;14829:43;;-1:-1:-1;;;14829:43:0;;-1:-1:-1;;;;;14809:3:0;;;;-1:-1:-1;14809:19:0;;-1:-1:-1;14809:3:0;;14829:11;;:43;;14841:30;;;;;14829:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14829:43:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14874:23:0;;;;;;:13;:23;;;;;;;:30;;;;14906:32;;14809:130;;-1:-1:-1;;;;;;14809:130:0;;;;;;;;;;-1:-1:-1;;;;;14906:32:0;;14809:130;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;15007:23:0;;;;;;:13;:23;;;;;;;;:32;;;;;14957;;-1:-1:-1;;;;;14957:32:0;;;14951:39;;:5;:39;;;;;:88;;;;;;;;;15107:32;;-1:-1:-1;15056:32:0;;;;;;;15050:39;;;;;:53;;:89;;;;;;;;15150:21;;;:11;:21;;;;;:37;;15174:13;;-1:-1:-1;;15150:37:0;;;;15174:13;15150:37;;;;;;14350:941;:::o;22488:162::-;-1:-1:-1;;;;;22607:18:0;;22583:4;22607:18;;;:5;:18;;;;;;:35;;:27;;;;;:35;;22635:6;;22607:35;:::i;:::-;;;;;;;;;;;;;;22600:42;;22488:162;;;;;:::o;10819:1013::-;10998:9;;;-1:-1:-1;;;;;11041:21:0;;;;;;:11;:21;;;;;;;;:43;;;;;;;;;:95;;11113:4;11118:12;11113:18;;;;;;:::i;:::-;;;;;;;;;;;;;11132:3;11113:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11113:23:0;11041:95;;;11087:4;11092:12;11087:18;;;;;;:::i;:::-;;;;;;;;;;;;;11106:3;11087:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11087:23:0;11041:95;11026:110;;11147:678;11153:4;:28;;;-1:-1:-1;;;;;;11162:18:0;;;11153:28;11147:678;;;11201:7;:125;;;;-1:-1:-1;;;;;;11213:21:0;;11238:18;11213:21;;;:11;:21;;;;;;;;:43;;;;;;;;;:112;;;;-1:-1:-1;;;;;;11297:22:0;;;;;;;:12;:22;;;;;;;;:28;;;;;11273:13;;;;;:6;:13;;;;;;;;;11260:27;;;;;;;;;:33;;:65;;11213:112;11201:242;;;-1:-1:-1;11356:17:0;-1:-1:-1;;;;;11331:21:0;;;;;;:11;:21;;;;;;;;:42;;;;;;;;;:111;;;;-1:-1:-1;;;;;;11414:22:0;;;;;;;:12;:22;;;;;;;;:28;;;;;11390:13;;;;;:6;:13;;;;;;;;;11377:27;;;;;;;;;:33;;:65;;11331:111;11198:387;;;-1:-1:-1;;;;;11483:13:0;;;;;;;:6;:13;;;;;;;;11464:16;;;;;;;;;:32;;11483:13;;;;-1:-1:-1;;11464:32:0;;;;;;;11515:13;;;;:24;;;;;;;;;;-1:-1:-1;;;11198:387:0;11603:7;11602:8;:35;;;;-1:-1:-1;;;;;;11614:13:0;;;;;;;:6;:13;;;;;;;;:23;;;;11602:35;11599:179;;;-1:-1:-1;;;;;11674:16:0;;;;;;;:6;:16;;;;;;;;11658:13;;;;;;;;:32;;11674:16;;;;-1:-1:-1;;11658:32:0;;;;;;;11716:16;;;11709:23;;;;;-1:-1:-1;;;11599:179:0;-1:-1:-1;;;;;11800:13:0;;;;;;;:6;:13;;;;;;;11147:678;;21291:762;21357:4;21373:15;21403:6;21399:242;-1:-1:-1;;;;;21415:18:0;;;;;;:5;:18;;;;;:29;;:36;21413:38;;21399:242;;;-1:-1:-1;;;;;21507:18:0;;;;;;:5;:18;;;;;:29;;:32;;21487:142;;21507:29;21537:1;;21507:32;;;;;;;;;;;;;;;;:41;;;21550:5;:18;21556:11;-1:-1:-1;;;;;21550:18:0;-1:-1:-1;;;;;21550:18:0;;;;;;;;;;;;:29;;21580:1;21550:32;;;;;;;;;;;;;;;;;:39;:32;;;;;:39;;21487:142;;;;;;-1:-1:-1;;21487:142:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21550:39;;21487:142;;;21550:39;21487:142;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;21591:18:0;;;;;;:5;:18;;;;;:29;;:32;;:29;;-1:-1:-1;21621:1:0;;-1:-1:-1;21591:32:0;;;;;;;;;;;;;;;;:37;;;21487:19;:142::i;:::-;21473:156;;;;21453:3;;21399:242;;;;21652:6;21648:238;-1:-1:-1;;;;;21664:18:0;;;;;;:5;:18;;;;;:28;;:35;21662:37;;21648:238;;;-1:-1:-1;;;;;21755:18:0;;;;;;:5;:18;;;;;:28;;:31;;21735:139;;21755:28;21784:1;;21755:31;;;;;;;;;;;;;;:40;:31;;;;;:40;;;-1:-1:-1;;;;;21797:18:0;;;;:5;:18;;;;;;;:28;:31;;21826:1;;21797:31;;;;;;;;;;;;;;;:38;:31;;;;;:38;;21735:139;;;;;;-1:-1:-1;;21735:139:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21797:38;;21735:139;;;21797:38;21735:139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;21837:18:0;;;;;;:5;:18;;;;;:28;;:31;;:28;;-1:-1:-1;21866:1:0;;-1:-1:-1;21837:31:0;;;;;21735:139;21721:153;;;;21701:3;;21648:238;;;-1:-1:-1;21912:3:0;;:30;;-1:-1:-1;;;21912:30:0;;-1:-1:-1;;;;;21912:3:0;;;;:17;;:30;;21930:11;;21912:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21899:10;:43;21896:150;;;21966:3;;:30;;-1:-1:-1;;;21966:30:0;;-1:-1:-1;;;;;21966:3:0;;;;:17;;:30;;21984:11;;21966:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21953:43;;;-1:-1:-1;21946:50:0;;21896:150;22032:1;22020:14;;;21291:762;;;;:::o;20391:246::-;20532:6;;20554:3;;:28;;-1:-1:-1;;;20554:28:0;;20464:4;;;;-1:-1:-1;;;;;20532:6:0;;;;:21;;20554:3;;;;:14;;:28;;20569:12;;20554:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20532:51;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;20532:51:0;;;;;;;;;;;;:::i;:::-;20584:1;20532:54;;;;;;;;;;;;;;-1:-1:-1;;;;;20527:60:0;20511:76;;20613:1;20602:8;:12;:27;;20628:1;20602:27;;;20617:8;20602:27;20595:34;20391:246;-1:-1:-1;;;20391:246:0:o;15300:628::-;15384:8;15410:35;15426:8;15435:9;15410:15;:35::i;:::-;15404:41;;15456:8;15490:3;15472:4;;;;;;;;;-1:-1:-1;;;;;15472:4:0;-1:-1:-1;;;;;15472:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15468:3;:20;15467:26;;;;;15504:3;;15523:4;;:10;;;-1:-1:-1;;;15523:10:0;;;;15467:26;;;;;-1:-1:-1;;;;;;15504:3:0;;;;:18;;15523:4;;;;;:8;;:10;;;;;15504:3;;15523:10;;;;;;;:4;:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15523:10:0;;;;;;;;;;;;:::i;:::-;15539:3;15535;:7;15544:9;15504:50;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15565:4:0;;15587:22;;;-1:-1:-1;;;;;;15587:22:0;;;;-1:-1:-1;;;;;15565:4:0;;;;-1:-1:-1;15565:21:0;;-1:-1:-1;15565:4:0;;15587:20;;:22;;;;;15565:4;;15587:22;;;;;;;;15565:4;15587:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15587:22:0;;;;;;;;;;;;:::i;:::-;15611:3;15565:50;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;15626:23:0;;;;;;:13;:23;;;;;:32;;;:37;;15662:1;15626:37;;;;;15722:28;;;;;15752:7;15716:3;:34;;;;15715:44;-1:-1:-1;15674:86:0;:163;;15803:4;;:34;;-1:-1:-1;;;15803:34:0;;-1:-1:-1;;;;;15803:4:0;;;;:18;;:34;;15822:9;;15803:4;;:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15674:163;;;15764:4;;:35;;-1:-1:-1;;;15764:35:0;;-1:-1:-1;;;;;15764:4:0;;;;:18;;:35;;15783:9;;15764:4;;:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15674:163;15848:4;;-1:-1:-1;;;;;15848:4:0;:16;15865:8;15874:9;15884:35;15865:8;15909:9;15884:15;:35::i;:::-;15848:72;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15300:628;;;;;;:::o;5652:1905::-;5795:4;;:32;;-1:-1:-1;;;5795:32:0;;5765:9;;-1:-1:-1;;;;;5795:4:0;;:20;;:32;;5816:10;;5795:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5787:64;;;;-1:-1:-1;;;5787:64:0;;;;;;;:::i;:::-;5865:7;5862:374;;;-1:-1:-1;;;;;5898:18:0;;;;;;:5;:18;;;;;;;:41;;5941:7;;5898:27;;;:41;;5926:12;;5898:41;:::i;:::-;;;;;;;;;;;;;;:50;;5890:84;;;;-1:-1:-1;;;5890:84:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;5989:18:0;;;;;;:5;:18;;;;;;;:41;;6034:7;;5989:27;;;:41;;6017:12;;5989:41;:::i;:::-;;;;;;;;;;;;;;:52;;;;;;;;5862:374;;;-1:-1:-1;;;;;6082:18:0;;;;;;:5;:18;;;;;;;:40;;6124:7;;6082:26;;;:40;;6109:12;;6082:40;:::i;:::-;;;;;;;;;;;;;;:49;;6074:84;;;;-1:-1:-1;;;6074:84:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;6173:18:0;;;;;;:5;:18;;;;;;;:40;;6217:7;;6173:26;;;:40;;6200:12;;6173:40;:::i;:::-;;;;;;;;;;;;;;:51;;;;;;;;5862:374;6263:7;6246:15;6316:7;:71;;-1:-1:-1;;;;;6359:18:0;;;;;;:5;:18;;;;;:28;;6316:71;;;-1:-1:-1;;;;;6327:18:0;;;;;;:5;:18;;;;;:29;;6316:71;6411:16;;6281:106;;-1:-1:-1;;;6411:18:0;6398:1044;6431:13;;6398:1044;;6548:12;6531:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;6521:41;;;;;;6496:9;6506:1;6496:12;;;;;;;;;;;;;;;;;;:19;;6479:37;;;;;;;;:::i;:::-;;;;;;;;;;;;;6469:48;;;;;;:93;6466:111;;6566:8;;6466:111;6618:10;6595:9;6605:1;6595:12;;;;;;;;;;;;;;;;;;:19;;;:33;6591:840;;6662:9;6672:1;6662:12;;;;;;;;;;;;;;;;;;:19;;;6648:33;;;;6700:7;:126;;6805:9;6815:1;6805:12;;;;;;;;;;;;;;;;;;:21;;;6769:5;:18;6775:11;-1:-1:-1;;;;;6769:18:0;-1:-1:-1;;;;;6769:18:0;;;;;;;;;;;;:32;;;:57;;;;;;;;;;6700:126;;;6745:9;6755:1;6745:12;;;;;;;;;;;;;;;;:21;:12;;;;;:21;;;;;-1:-1:-1;;;;;6710:18:0;;;;:5;:18;;;;;;;:56;;;;;;;;;;6700:126;;6852:96;6872:42;6881:9;6891:1;6881:12;;;;;;;;;;;;;;;;;;:19;;;6901:12;6872:8;:42::i;:::-;6916:12;6930:9;6940:1;6930:12;;;;;;;6852:96;6845:103;;;;6967:9;:15;;;;;;;;;;;;;;;-1:-1:-1;;6967:15:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;6591:840;;;7024:7;:192;;7195:9;7205:1;7195:12;;;;;;;;;;;;;;;;;;:21;;;7183:10;7163:9;7173:1;7163:12;;;;;;;;;;;;;;;;;;:19;;;:30;7162:54;7126:5;:18;7132:11;-1:-1:-1;;;;;7126:18:0;-1:-1:-1;;;;;7126:18:0;;;;;;;;;;;;:32;;;:90;;;;;;;;;;7024:192;;;7102:9;7112:1;7102:12;;;;;;;;;;;;;;;;;;:21;;;7090:10;7070:9;7080:1;7070:12;;;;;;;;;;;;;;;;;;;;;;;:19;-1:-1:-1;;;;;7034:18:0;;;;:5;:18;;;;;;;:89;;7070:30;;;;7069:54;;;;7034:89;;;;;;7024:192;;7258:10;7235:9;7245:1;7235:12;;;;;;;;;;;;;;;;;;;;;:33;;;;;;;;7295:87;7315:33;7324:10;7335:12;7315:8;:33::i;7295:87::-;7287:95;;;;7414:1;7401:14;;6591:840;-1:-1:-1;;6447:3:0;6398:1044;;;;7453:7;:96;;-1:-1:-1;;;;;7509:18:0;;;;;;:5;:18;;;;;:40;;;;:28;;;7540:9;;7509:40;:::i;:::-;7453:96;;;-1:-1:-1;;;;;7463:18:0;;;;;;:5;:18;;;;;:41;;;;:29;;;7495:9;;7463:41;:::i;:::-;7453:96;5652:1905;;;;;;;;:::o;17595:2102::-;17660:4;;:32;;-1:-1:-1;;;17660:32:0;;-1:-1:-1;;;;;17660:4:0;;;;:20;;:32;;17681:10;;17660:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17652:41;;;;;;-1:-1:-1;;;;;17707:21:0;;17730:18;17707:21;;;:11;:21;;;;;;;;:41;;;;;;;;;17704:1712;;;17765:3;;-1:-1:-1;;;;;17789:22:0;;17765:3;17789:22;;;:12;:22;;;;;;;:30;;17820:29;;;;17765:116;;-1:-1:-1;;;17765:116:0;;-1:-1:-1;;;;;17765:3:0;;;;:23;;:116;;17789:30;;;;;17820:29;17851;;;;;17765:116;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;17896:3:0;;-1:-1:-1;;;;;17916:22:0;;17896:3;17916:22;;;:12;:22;;;;;;;:30;;17947:29;;;;17896:112;;-1:-1:-1;;;17896:112:0;;-1:-1:-1;;;;;17896:3:0;;;;-1:-1:-1;17896:19:0;;-1:-1:-1;17896:112:0;;17916:30;;;;17947:29;17978;;;;;17896:112;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;18024:3:0;;-1:-1:-1;;;;;18056:22:0;;18024:3;18056:22;;;:12;:22;;;;;;;18044:42;;-1:-1:-1;;;18044:42:0;;-1:-1:-1;;;;;18024:3:0;;;;-1:-1:-1;18024:19:0;;-1:-1:-1;18024:3:0;;18044:11;;:42;;18056:29;;;;;18044:42;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;18044:42:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;18087:22:0;;;;;;:12;:22;;;;;;;:29;;;;18118:30;;18024:125;;-1:-1:-1;;;;;;18024:125:0;;;;;;;;;;-1:-1:-1;;;;;18118:30:0;;18024:125;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;18245:22:0;;;;;;:12;:22;;;;;;;;:29;;;;18171:30;;-1:-1:-1;;;;;18171:30:0;18165:37;;:5;:37;;;;;18212:22;;;;;;;;18165:77;18245:29;;-1:-1:-1;18165:46:0;;;;;:77;;18212:29;;;18165:77;:::i;:::-;;;;;;;;;;;;;;;;:109;;;;;;;;;-1:-1:-1;;;;;18343:23:0;;-1:-1:-1;18343:23:0;;;:13;:23;;;;;;18295:12;:22;;;;;:30;-1:-1:-1;;;;;18295:30:0;18289:37;;:5;:37;;;;;;:77;;;;;;;;-1:-1:-1;18381:357:0;-1:-1:-1;;;;;18416:22:0;;18410:37;18416:22;;;:12;:22;;;;;;;;:30;-1:-1:-1;;;;;18416:30:0;18410:37;;:5;:37;;;;;:51;;:58;18408:60;;18381:357;;;-1:-1:-1;;;;;18503:66:0;;:37;18509:22;;;:12;:22;;;;;;;;:30;-1:-1:-1;;;;;18509:30:0;18503:37;;:5;:37;;;;;:51;;:54;;18555:1;;18503:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18503:54:0;:66;18500:89;;;-1:-1:-1;;18573:3:0;18578:8;;18500:89;-1:-1:-1;;;;;18674:22:0;;18668:37;18674:22;;;:12;:22;;;;;;;;:30;-1:-1:-1;;;;;18674:30:0;18668:37;;:5;:37;;;;;:51;;:54;;18720:1;;18668:54;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18617:22:0;;;;;:12;:22;;;;;;:30;-1:-1:-1;;;;;18617:30:0;18611:37;;:5;:37;;;;;;;:51;;:54;;18668;;;;;;;;;;;;;18611:51;18663:1;;18611:54;;;;;;;;;;;;;;;;;;;;;;;;:111;;;;;-1:-1:-1;;;;;18611:111:0;;;;;-1:-1:-1;;;;;18611:111:0;;;;;;18381:357;18471:3;;;;;18475;18381:357;;;;;17704:1712;;;18783:17;-1:-1:-1;;;;;18760:21:0;;;;;;:11;:21;;;;;;;;:40;;;;;;;;;18757:659;;;-1:-1:-1;;;;;18899:22:0;;;;;;:12;:22;;;;;;;;:29;;;;18826:30;;-1:-1:-1;;;;;18826:30:0;18820:37;;:5;:37;;;;;18866:22;;;;;;;;18820:76;18899:29;;18820:45;;;:76;;18866:29;;;18820:76;:::i;:::-;;;;;;;;;;;;;;;;:108;;;;;;;;;-1:-1:-1;;;;;19002:23:0;;-1:-1:-1;19002:23:0;;;:13;:23;;;;;;18953:12;:22;;;;;:30;-1:-1:-1;;;;;18953:30:0;18947:37;;:5;:37;;;;;;-1:-1:-1;18947:51:0;:78;;;;;;;;-1:-1:-1;19044:361:0;-1:-1:-1;;;;;19079:22:0;;19073:37;19079:22;;;:12;:22;;;;;;;;:30;-1:-1:-1;;;;;19079:30:0;19073:37;;:5;:37;;;;;:52;;:59;19071:61;;19044:361;;;-1:-1:-1;;;;;19171:67:0;;:37;19177:22;;;:12;:22;;;;;;;;:30;-1:-1:-1;;;;;19177:30:0;19171:37;;:5;:37;;;;;:52;;:55;;19224:1;;19171:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19171:55:0;:67;19168:85;;;19242:8;;19168:85;-1:-1:-1;;;;;19339:22:0;;19333:37;19339:22;;;:12;:22;;;;;;;;:30;-1:-1:-1;;;;;19339:30:0;19333:37;;:5;:37;;;;;:52;;:55;;19386:1;;19333:55;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19281:22:0;;;;;:12;:22;;;;;;:30;-1:-1:-1;;;;;19281:30:0;19275:37;;:5;:37;;;;;;;:52;;:55;;19333;;;;;;;;;;;;;19275:52;19328:1;;19275:55;;;;;;;;;;;;;;;;;;;;;;;;:113;;;;;-1:-1:-1;;;;;19275:113:0;;;;;-1:-1:-1;;;;;19275:113:0;;;;;;19044:361;19135:3;;;;;19139;19044:361;;;;;18757:659;-1:-1:-1;;;;;19447:22:0;;;;;;:12;:22;;;;;;;;;:29;;19426:95;;;;;;;;;;;-1:-1:-1;;19426:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;19447:22;;19426:95;;19447:29;19426:95;;19447:29;19426:95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;19484:22:0;;19477:5;19484:22;;;:12;:22;;;;;19519:1;19484:31;;;;19477:5;;-1:-1:-1;19519:1:0;-1:-1:-1;19516:1:0;;19484:33;;19483:37;19426:10;:95::i;:::-;-1:-1:-1;;;;;19539:22:0;;;;;;:12;:22;;;;;19532:29;;-1:-1:-1;;;;;;19532:29:0;;;;;;;;;;;;;;;;;;;;;19539:22;19532:29;;;;19539:22;19532:29;:::i;:::-;-1:-1:-1;;;;;;;19575:23:0;;19601:1;19575:23;;;:13;:23;;;;;;:27;19572:70;;-1:-1:-1;;;;;19616:23:0;;;;;;:13;:23;;;;;19609:30;19572:70;-1:-1:-1;;;;;19652:21:0;;;;;;:11;:21;;;;;:37;;19676:13;;19652:21;-1:-1:-1;;19652:37:0;;19676:13;19652:37;;23454:495;23545:4;;:29;;-1:-1:-1;;;23545:29:0;;23517:13;;-1:-1:-1;;;;;23545:4:0;;:16;;:29;;23562:11;;23545:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23542:56;;;-1:-1:-1;23586:6:0;23578:15;;23542:56;23611:4;;:30;;-1:-1:-1;;;23611:30:0;;-1:-1:-1;;;;;23611:4:0;;;;:17;;:30;;23629:11;;23611:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23608:48;;;-1:-1:-1;23652:1:0;23645:8;;23608:48;-1:-1:-1;;;;;23669:18:0;;23704:1;23669:18;;;:5;:18;;;;;:32;;;:36;23666:276;;-1:-1:-1;;;;;23827:18:0;;;;;;;:5;:18;;;;;;;;;:32;;;23801:4;;:17;;-1:-1:-1;;;23801:17:0;;;;23827:32;;23820:3;;23801:4;;;:15;;:17;;;;;;;;;;:4;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;23769:18:0;;;;;;:5;:18;;;;;:31;:49;23768:55;;;;;-1:-1:-1;;;;;23733:18:0;;;;;;:5;:18;;;;;:31;23768:55;;;23733:91;;:126;;-1:-1:-1;23726:133:0;;23666:276;-1:-1:-1;;;;;;23899:18:0;;;;;;:5;:18;;;;;:31;23892:38;;2023:45;;;;;;;;;;;;;;;:::o;23302:140::-;-1:-1:-1;;;;;23407:18:0;;;;;;:5;:18;;;;;;;;;:27;;23400:34;;;;;;;;;;;;;;;;;23371:16;;23400:34;;;23407:27;23400:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23400:34:0;-1:-1:-1;;;;;23400:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23302:140;;;:::o;2075:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2075:53:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2075:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1978:38::-;;;;;;;;;;;;;;;;;;;:::o;2135:45::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2135:45:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2135:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3695:283::-;445:12:2;;;;;;;;:31;;;461:15;:13;:15::i;:::-;445:47;;;-1:-1:-1;481:11:2;;;;480:12;445:47;437:106;;;;-1:-1:-1;;;437:106:2;;;;;;;:::i;:::-;552:19;575:12;;;;;;574:13;594:83;;;;623:12;:19;;-1:-1:-1;;;;623:19:2;;;;;651:18;638:4;651:18;;;594:83;3836:3:0::1;:33:::0;;-1:-1:-1;;;;;3836:33:0;;::::1;-1:-1:-1::0;;;;;;3836:33:0;;::::1;;::::0;;;3884:6:::1;:37:::0;;;;::::1;::::0;;::::1;;::::0;;3937:4:::1;:33:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;695:57:2;;;;739:5;724:20;;-1:-1:-1;;724:20:2;;;695:57;3695:283:0;;;;:::o;7569:1743::-;7722:4;;:32;;-1:-1:-1;;;7722:32:0;;-1:-1:-1;;;;;7722:4:0;;;;:20;;:32;;7743:10;;7722:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7714:64;;;;-1:-1:-1;;;7714:64:0;;;;;;;:::i;:::-;7806:7;7824:333;;;;-1:-1:-1;;;;;7849:18:0;;;;;;:5;:18;;;;;;;:41;;7893:7;;7849:27;;;:41;;7877:12;;7849:41;:::i;:::-;;;;;;;;;;;;;;:51;;;;;;;7949:31;7958:7;7967:12;7949:8;:31::i;:::-;-1:-1:-1;;;;;7914:18:0;;;;;;:5;:18;;;;;:66;;;;;;;7824:333;;;-1:-1:-1;;;;;8014:18:0;;;;;;:5;:18;;;;;;;:40;;8057:7;;8014:26;;;:40;;8041:12;;8014:40;:::i;:::-;;;;;;;;;;;;;;:50;;;;;;;8114:31;8123:7;8132:12;8114:8;:31::i;:::-;-1:-1:-1;;;;;8078:18:0;;;;;;:5;:18;;;;;:32;;:67;;;;;;;7824:333;8173:12;;8167:1138;;8201:14;8218:7;:61;;8255:4;8260:12;8255:18;;;;;;:::i;:::-;;;;;;;;;;;;;8274:4;8255:24;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8255:24:0;8218:61;;;8228:4;8233:12;8228:18;;;;;;:::i;:::-;;;;;;;;;;;;;8247:4;8228:24;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8228:24:0;8218:61;8201:78;;8294:19;;:::i;:::-;-1:-1:-1;;;;;8329:15:0;;;8316:29;8329:15;;;:6;:15;;;;;;;;;;;;8316:29;;:12;:29;;;;;;8294:51;;;;;;;;;-1:-1:-1;;;;;8294:51:0;;;8329:15;8294:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8329:15;8294:51;;;;;;;;-1:-1:-1;;8294:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;8316:29;;8294:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8364:7;:30;;;;;8382:6;:12;;;8375:6;:19;8364:30;8363:69;;;;8401:7;8400:8;:31;;;;;8419:6;:12;;;8412:6;:19;8400:31;8363:93;;;-1:-1:-1;;;;;;8436:15:0;;;;;;;:6;:15;;;;;;;:20;8363:93;8360:233;;;8476:77;8486:11;8499:12;8513:10;8526:4;8531:1;8526:6;8534:1;8525:10;8537:6;8545:7;8476:9;:77::i;:::-;;8572:5;;;;8360:233;8626:10;8611:6;:13;;;:25;8608:686;;8658:13;;;:25;;;;;;;;;8710:27;;8707:129;;;-1:-1:-1;;;;;8773:15:0;;;;;;;:6;:15;;;;;;8762:54;;8773:15;;8790:12;;8811:4;8762:10;:54::i;:::-;8854:84;8865:11;8878:12;8892:10;8905:4;8910:1;8905:6;8913:1;8904:10;8916:6;:12;;;8930:7;8854:10;:84::i;:::-;8968:1;8957:12;;8608:686;;;9010:92;9020:11;9033:12;9059:6;:13;;;9047:10;:25;9075:4;9080:1;9075:6;9083:1;9074:10;9086:6;9094:7;9010:9;:92::i;:::-;;9121:84;9132:11;9145:12;9159:10;9172:4;9177:1;9172:6;9180:1;9171:10;9183:6;:12;;;9197:7;9121:10;:84::i;:::-;-1:-1:-1;;;;;9251:15:0;;;9238:29;9251:15;;;:6;:15;;;;;;;;;;;;9238:29;;:12;:29;;;:36;;;9224:50;;;;8608:686;8167:1138;;;;;7569:1743;;;;;;;:::o;22662:166::-;-1:-1:-1;;;;;22786:18:0;;22762:4;22786:18;;;:5;:18;;;;;;:34;;:26;;;;;:34;;22813:6;;22786:34;:::i;23143:147::-;-1:-1:-1;;;;;23250:18:0;;;;;;:5;:18;;;;;;;;;:32;;23243:39;;;;;;;;;;;;;;;;;23214:16;;23243:39;;;23250:32;23243:39;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23243:39:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;23243:39:0;;23143:147;-1:-1:-1;;;;;;;23143:147:0:o;20030:349::-;20108:8;20153:14;-1:-1:-1;;;;;20128:21:0;;;;;;:11;:21;;;;;;;;:39;;;;;;;;;:243;;-1:-1:-1;20370:1:0;;20128:243;;;20355:5;20343:10;20303:39;20319:4;;;;;;;;;-1:-1:-1;;;;;20319:4:0;-1:-1:-1;;;;;20319:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;20319:22:0;;;;;;;;;;;;:::i;20303:39::-;-1:-1:-1;;;;;20253:23:0;;;;;;:13;:23;;;;;;;;;:29;;;;20187:30;;;;20219;;;;20177:73;;;;;;-1:-1:-1;;20177:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20285:9;;20253:29;;20177:73;;20187:30;20177:73;20219:30;20177:73;;;20219:30;20177:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:8;:73::i;:::-;:105;:117;20295:7;20177:125;:165;:176;;;;;;:184;;;;;;20171:190;;;20128:243;;20030:349;;;;:::o;24146:146::-;24231:6;:52;;24282:1;24263:4;24268:5;24263:11;;;;;;:::i;:::-;;;;;;;;;;;;;24275:3;24263:16;;;;;;;;;;;;;;;;;;:20;;;;;-1:-1:-1;;;;;24263:20:0;;;;;-1:-1:-1;;;;;24263:20:0;;;;;24231:52;;;24259:1;24240:4;24245:5;24240:11;;;;;;:::i;:::-;;;;;;;;;;;;;24252:3;24240:16;;;;;;;;;;;;;;;;;;:20;;;;;-1:-1:-1;;;;;24240:20:0;;;;;-1:-1:-1;;;;;24240:20:0;;;;;24231:52;24146:146;;;:::o;15936:827::-;16042:4;;:32;;-1:-1:-1;;;16042:32:0;;16016:4;;-1:-1:-1;;;;;16042:4:0;;:20;;:32;;16063:10;;16042:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:116;;;;-1:-1:-1;;;;;;16116:23:0;;;;;;:13;:23;;;;;:32;;;;16085:28;;;;;16151:7;16116:42;;;16085:73;16078:3;:80;;16042:116;16033:126;;;;;;16170:8;16181:27;16197:8;16206:1;16181:15;:27::i;:::-;16219:3;;-1:-1:-1;;;;;16231:23:0;;16219:3;16231:23;;;:13;:23;;;;;;;;;:32;16273:4;;:16;;-1:-1:-1;;;16273:16:0;;;;16170:38;;-1:-1:-1;;;;;;16219:3:0;;;;:11;;16231:32;;;;16291:3;;16273:4;;;;;:14;;:16;;;;;;;;;;;:4;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16269:3;:20;16264:3;:26;:30;;;;;;16219:76;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;16306:3:0;;-1:-1:-1;;;;;16318:23:0;;16306:3;16318:23;;;:13;:23;;;;;;;;;:32;16360:4;;:16;;-1:-1:-1;;;16360:16:0;;;;-1:-1:-1;;;;;16306:3:0;;;;-1:-1:-1;16306:11:0;;-1:-1:-1;16318:32:0;;;;16378:3;;16360:4;;;:14;;:16;;;;;;;;;;:4;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16356:3;:20;16351:3;:26;:30;;;;;;16306:76;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;16396:23:0;;;;;;:13;:23;;;;;:32;;;-1:-1:-1;;16396:71:0;;;;-1:-1:-1;16441:4:0;;:26;;-1:-1:-1;;;16441:26:0;;-1:-1:-1;;;;;16441:4:0;;;;:16;;:26;;16458:8;;16441:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16440:27;16396:71;:103;;;;-1:-1:-1;16472:4:0;;:27;;-1:-1:-1;;;16472:27:0;;-1:-1:-1;;;;;16472:4:0;;;;:17;;:27;;16490:8;;16472:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16471:28;16396:103;16393:363;;;16515:4;;:33;;-1:-1:-1;;;16515:33:0;;-1:-1:-1;;;;;16515:4:0;;;;:18;;:33;;16534:8;;16515:4;;:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16563:22;16576:8;16563:12;:22::i;:::-;16393:363;;;16620:4;;-1:-1:-1;;;;;16620:4:0;:16;16637:8;16646;16655:33;16637:8;16620:4;16680:7;;16655:15;:33::i;:::-;16620:69;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16704:40;16718:8;-1:-1:-1;;;;;16704:40:0;16727:8;16736:5;16742:1;16736:7;16704:13;:40::i;:::-;15936:827;;;;;;:::o;22840:130::-;-1:-1:-1;;;;;22930:18:0;22906:4;22930:18;;;:5;:18;;;;;:32;;;;22840:130::o;22982:149::-;-1:-1:-1;;;;;23090:18:0;;;;;;:5;:18;;;;;;;;;:33;;23083:40;;;;;;;;;;;;;;;;;23054:16;;23083:40;;;23090:33;23083:40;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23083:40:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;23083:40:0;;22982:149;-1:-1:-1;;;;;;;22982:149:0:o;2187:45::-;;;;;;;;;;;;;:::o;19801:217::-;19968:3;;:28;;-1:-1:-1;;;19968:28:0;;19875:13;;-1:-1:-1;;;;;19968:3:0;;:20;;:28;;19989:6;;19968:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;19961:45:0;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19956:53;;19952:2;:57;19944:5;19919:23;19935:6;19919:15;:23::i;:::-;19912:6;:30;:38;;;;;;:98;;;;;;;19801:217;-1:-1:-1;;;19801:217:0:o;20905:374::-;21010:4;21026:12;21059:39;21075:4;;;;;;;;;-1:-1:-1;;;;;21075:4:0;-1:-1:-1;;;;;21075:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21059:39;21041:8;21051:6;21041:17;:57;;;;;21134:4;;:34;;-1:-1:-1;;;21134:34:0;;21041:57;;;;;-1:-1:-1;21109:11:0;;21185:10;;21172:3;:10;;;;-1:-1:-1;;;;;21134:4:0;;;;:20;;:34;;21155:12;;21134:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21124:7;:44;:59;21123:72;;;;;;;20905:374;-1:-1:-1;;;;;;20905:374:0:o;854:508:2:-;1271:4;1317:17;1349:7;854:508;:::o;9324:1483:0:-;9473:4;9490:15;9506:14;9521:8;9533:56;9543:7;9552:11;9565:9;9576:12;9533:9;:56::i;:::-;9489:100;;;;;;9625:379;;;;;;;;9695:11;-1:-1:-1;;;;;9625:379:0;;;;;9764:9;9625:379;;;;9829:9;9625:379;;;;9893:6;9625:379;;;;9955:12;9625:379;;;9600:12;:22;9613:8;-1:-1:-1;;;;;9600:22:0;-1:-1:-1;;;;;9600:22:0;;;;;;;;;;;;:404;;;;;;;;;;;;;-1:-1:-1;;;;;9600:404:0;;;;;-1:-1:-1;;;;;9600:404:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;10018:7;10015:699;;;-1:-1:-1;;;;;10042:21:0;;;10066:18;10042:21;;;:11;:21;;;;;;;;:42;;-1:-1:-1;;10042:42:0;;;-1:-1:-1;;;;;10099:18:0;;;;:5;:18;;;;;:32;;:47;;-1:-1:-1;10099:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10171:18;10164:6;;10066:18;10171:4;;:18;;10176:12;;10171:18;:::i;:::-;;;;;;;;;;;;;10204:1;10201;10191:9;:11;;;;;;10190:15;10171:35;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10171:35:0;;;10164:43;;;;;;;;;;;-1:-1:-1;10164:43:0;;;10161:194;;10263:8;10217:6;:43;10224:4;10229:12;10224:18;;;;;;:::i;:::-;;;;;;;;;;;;;10257:1;10254;10244:9;:11;;;;;;10243:15;10224:35;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10224:35:0;;;10217:43;;;;;;;;;;;-1:-1:-1;10217:43:0;:54;;-1:-1:-1;;10217:54:0;;;;;;;;;;;10161:194;;;10295:57;10306:8;10316:12;10330:4;;10347:1;10337:9;:11;;10295:57;10015:699;;;-1:-1:-1;;;;;10388:21:0;;;;;;:11;:21;;;;;:41;;10412:17;;10388:21;-1:-1:-1;;10388:41:0;10412:17;;10388:41;;;;-1:-1:-1;;;;;;10444:18:0;;;;;;:5;:18;;;;;;;;:33;;:48;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10444:48:0;;;;;;;;;;;;;;;;;;10519:18;10512:6;;10444:18;10519:4;;:18;;10524:12;;10519:18;:::i;:::-;;;;;;;;;;;;;10552:1;10549;10539:9;:11;;;;;;10538:15;10519:35;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10519:35:0;;;10512:43;;;;;;;;;;;-1:-1:-1;10512:43:0;;;10509:194;;10611:8;10565:6;:43;10572:4;10577:12;10572:18;;;;;;:::i;:::-;;;;;;;;;;;;;10605:1;10602;10592:9;:11;;;;;;10591:15;10572:35;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10572:35:0;;;10565:43;;;;;;;;;;;-1:-1:-1;10565:43:0;:54;;-1:-1:-1;;10565:54:0;;;;;;;;;;;10509:194;;;10643:57;10654:8;10664:12;10678:4;;10695:1;10685:9;:11;;10643:57;10748:30;10757:7;10765:12;10748:8;:30::i;:::-;-1:-1:-1;;;;;10724:23:0;;;;;;;:13;:23;;;;;:54;;;;-1:-1:-1;10796:3:0;-1:-1:-1;9324:1483:0;;;;;;;;:::o;11844:2494::-;12028:918;;;;;;;;;;12132:17;-1:-1:-1;;;;;12107:21:0;;;;;;:11;:21;;;;;;;;:42;;;;;;;;;12106:91;;-1:-1:-1;;;;;12167:22:0;;;;;;:12;:22;;;;;:30;-1:-1:-1;;;;;12167:30:0;12106:91;;;12153:11;12106:91;-1:-1:-1;;;;;12028:918:0;;;;;12281:18;-1:-1:-1;;;;;12256:21:0;;;;;;:11;:21;;;;;;;;:43;;;;;;;;;12255:92;;-1:-1:-1;;;;;12317:22:0;;;;;;:12;:22;;;;;:30;-1:-1:-1;;;;;12317:30:0;12255:92;;;12303:11;12255:92;-1:-1:-1;;;;;12028:918:0;;;;;12404:3;12028:918;;;;12473:9;12484:7;12473:19;12467:3;:25;12028:918;;;;12550:9;12028:918;;;;12615:7;12028:918;;;;12680:30;12689:7;12697:12;12680:8;:30::i;:::-;12028:918;;;;;;;;;;;;;;;;-1:-1:-1;12028:918:0;;;;;;;-1:-1:-1;;;;;12002:23:0;;;;:13;:23;;;;;:944;;;;-1:-1:-1;;;;;12002:944:0;;;-1:-1:-1;;;;;;12002:944:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;12002:944:0;;;;;;;;;;;12972:6;;12967:349;-1:-1:-1;;;;;13002:23:0;;12996:39;13002:23;;;:13;:23;;;;;;;;:32;-1:-1:-1;;;;;13002:32:0;12996:39;;:5;:39;;;;;:53;;:60;12994:62;;12967:349;;;-1:-1:-1;;;;;13087:68:0;;:39;13093:23;;;:13;:23;;;;;;;;:32;-1:-1:-1;;;;;13093:32:0;13087:39;;:5;:39;;;;;:53;;:56;;13141:1;;13087:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13087:56:0;:68;13084:91;;;-1:-1:-1;;13159:3:0;13164:8;;13084:91;-1:-1:-1;;;;;13254:23:0;;13248:39;13254:23;;;:13;:23;;;;;;;;:32;-1:-1:-1;;;;;13254:32:0;13248:39;;:5;:39;;;;;:53;;:56;;13302:1;;13248:56;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13195:23:0;;;;;:13;:23;;;;;;:32;-1:-1:-1;;;;;13195:32:0;13189:39;;:5;:39;;;;;;;:53;;:56;;13248;;;;;;;;;;;;;13189:53;13243:1;;13189:56;;;;;;;;;;;;;;;;;;;;;;;;:115;;;;;-1:-1:-1;;;;;13189:115:0;;;;;-1:-1:-1;;;;;13189:115:0;;;;;;12967:349;13059:3;;;;;13063;12967:349;;;-1:-1:-1;13331:6:0;;-1:-1:-1;13331:6:0;13326:348;-1:-1:-1;;;;;13361:23:0;;13355:39;13361:23;;;:13;:23;;;;;;;;:32;;;-1:-1:-1;;;;;13361:32:0;13355:39;;:5;:39;;;;;:54;;:61;13353:63;;13326:348;;;-1:-1:-1;;;;;13447:69:0;;:39;13453:23;;;:13;:23;;;;;;;;:32;;;-1:-1:-1;;;;;13453:32:0;13447:39;;:5;:39;;;;;:54;;:57;;13502:1;;13447:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13447:57:0;:69;13444:87;;;13520:8;;13444:87;-1:-1:-1;;;;;13611:23:0;;13605:39;13611:23;;;:13;:23;;;;;;;;:32;;;-1:-1:-1;;;;;13611:32:0;13605:39;;:5;:39;;;;;:54;;:57;;13660:1;;13605:57;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13551:23:0;;;;;:13;:23;;;;;;:32;;;-1:-1:-1;;;;;13551:32:0;13545:39;;:5;:39;;;;;;;:54;;:57;;13605;;;;;;;;;;;;;13545:54;13600:1;;13545:57;;;;;;;;;;;;;;;;;;;;;;;;:117;;;;;-1:-1:-1;;;;;13545:117:0;;;;;-1:-1:-1;;;;;13545:117:0;;;;;;13326:348;13419:3;;;;;13423;13326:348;;;-1:-1:-1;;;;;;;13691:22:0;;;;;;:12;:22;;;;;13684:29;;-1:-1:-1;;;;;;13684:29:0;;;;;;;;;;;;;;;;;;;;;13691:22;13684:29;;;;13691:22;13684:29;:::i;:::-;;;13724:58;13735:8;13745:12;13759:5;13780:1;13777;13767:9;:11;;;;13724:58;-1:-1:-1;;;;;13793:21:0;;;;;;:11;:21;;;;;:36;;-1:-1:-1;;13793:36:0;13815:14;13793:36;;;13864:30;13873:7;13881:12;13864:8;:30::i;:::-;-1:-1:-1;;;;;13840:23:0;;;;;;;:13;:23;;;;;;;;:54;;;;13911:13;:23;;;;;:32;;-1:-1:-1;;;;;13911:32:0;;;13905:39;;:5;:39;;;;;:48;;;;:63;;13911:32;13905:63;;;;;;;;;;;;;;;;;;;;;;;;;;13911:32;13905:63;;;;;;;;;;;;;;;;;;;;13985:32;;;;;;;13979:39;;;;;:48;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14053:24;13840:23;14053:14;:24::i;:::-;-1:-1:-1;;;;;14088:58:0;;14111:23;;;;:13;:23;;;;;:32;;;;;14088:58;;;-1:-1:-1;;;;;14111:32:0;;;;14088:13;:58::i;:::-;14157:3;;14177:25;;-1:-1:-1;;;14177:25:0;;-1:-1:-1;;;;;14157:3:0;;;;:19;;:3;;14177:11;;:25;;14189:12;;14177:25;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14177:25:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14213:23:0;;;;;;:13;:23;;;;;;;:32;;;14157:89;;-1:-1:-1;;;;;;14157:89:0;;;;;;;;;;14204:7;;-1:-1:-1;;;;;14213:32:0;;;;14157:89;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14257:4:0;;:72;;-1:-1:-1;;;14257:72:0;;-1:-1:-1;;;;;14257:4:0;;;;-1:-1:-1;14257:21:0;;-1:-1:-1;14257:72:0;;14279:11;;14291:9;;14301:6;;14308:7;;14316:12;;14257:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11844:2494;;;;;;:::o;17201:381::-;17286:17;17336:46;17384:8;17393;17402:5;17306:102;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;17306:102:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;17306:102:0;-1:-1:-1;;;;;;17306:102:0;;;;;;;;;;17448:6;;:16;;-1:-1:-1;;;17448:16:0;;;;17306:102;;-1:-1:-1;;;;;;;;17448:6:0;;;;:14;;:16;;;;;17306:102;17448:16;;;;;;:6;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17475:6;;17542:16;;;-1:-1:-1;;;17542:16:0;;;;17435:10;:29;;;;;-1:-1:-1;;;;;;17475:6:0;;;;:19;;17435:29;;17519:4;;17526:7;;17535:4;;17475:6;;17542:14;;:16;;;;;;;;;;;;;;;17475:6;17542:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17560:6;17569:3;17475:99;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;22065:411;22182:6;22190:4;22196;22212:14;22263:3;22246:4;;;;;;;;;-1:-1:-1;;;;;22246:4:0;-1:-1:-1;;;;;22246:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22239:6;:22;22238:28;;;;;;22229:6;:37;22212:54;;22277:8;22313:3;22296:4;;;;;;;;;-1:-1:-1;;;;;22296:4:0;-1:-1:-1;;;;;22296:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22289:6;:22;22288:28;;;;;;22277:39;;22327:15;22384:11;22396:12;22409:9;22419:3;22367:56;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;22367:56:0;;;;;;22357:67;;22367:56;22357:67;;;;;22454:9;;-1:-1:-1;22464:3:0;;-1:-1:-1;22065:411:0;;-1:-1:-1;;;;;;22065:411:0:o;16771:414::-;-1:-1:-1;;;;;16880:23:0;;16831:9;16880:23;;;:13;:23;;;;;;;:28;;;;16843:34;;;;;16939:75;;16843:65;;;16919:17;;16969:34;;16939:75;;16894:8;;16939:75;;;:::i;:::-;;;;-1:-1:-1;;16939:75:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;16939:75:0;-1:-1:-1;;;;;;16939:75:0;;;;;;;;;;17054:6;;:16;;-1:-1:-1;;;17054:16:0;;;;16939:75;;-1:-1:-1;;;;;;;;17054:6:0;;;;:14;;:16;;;;;16939:75;17054:16;;;;;;:6;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17081:6;;17145:16;;;-1:-1:-1;;;17145:16:0;;;;17041:10;:29;;;;;-1:-1:-1;;;;;;17081:6:0;;;;:19;;17041:29;;17125:4;;17132;;17138;;17081:6;;17145:14;;:16;;;;;;;;;;;;;;;17081:6;17145:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17163:6;17172:3;17081:96;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16771:414;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;1447:442;;1549:3;1542:4;1534:6;1530:17;1526:27;1516:2;;-1:-1;;1557:12;1516:2;1604:6;1591:20;1626:65;1641:49;1683:6;1641:49;:::i;:::-;1626:65;:::i;:::-;1617:74;;1711:6;1704:5;1697:21;1815:3;1747:4;1806:6;1739;1797:16;;1794:25;1791:2;;;1832:1;;1822:12;1791:2;37030:6;1747:4;1739:6;1735:17;1747:4;1773:5;1769:16;37007:30;37086:1;37068:16;;;1747:4;37068:16;37061:27;1773:5;1509:380;-1:-1;;1509:380::o;2763:132::-;2840:13;;2858:32;2840:13;2858:32;:::i;3039:241::-;;3143:2;3131:9;3122:7;3118:23;3114:32;3111:2;;;-1:-1;;3149:12;3111:2;85:6;72:20;97:33;124:5;97:33;:::i;3287:263::-;;3402:2;3390:9;3381:7;3377:23;3373:32;3370:2;;;-1:-1;;3408:12;3370:2;226:6;220:13;238:33;265:5;238:33;:::i;3557:523::-;;;;3711:2;3699:9;3690:7;3686:23;3682:32;3679:2;;;-1:-1;;3717:12;3679:2;371:6;358:20;383:41;418:5;383:41;:::i;:::-;3769:71;-1:-1;3877:2;3916:22;;72:20;97:33;72:20;97:33;:::i;:::-;3885:63;-1:-1;3985:2;4032:22;;358:20;383:41;358:20;383:41;:::i;:::-;3993:71;;;;3673:407;;;;;:::o;4087:985::-;;;;;;;4291:3;4279:9;4270:7;4266:23;4262:33;4259:2;;;-1:-1;;4298:12;4259:2;371:6;358:20;383:41;418:5;383:41;:::i;:::-;4350:71;-1:-1;4486:2;4471:18;;4458:32;-1:-1;;;;;4499:30;;4496:2;;;-1:-1;;4532:12;4496:2;4562:63;4617:7;4608:6;4597:9;4593:22;4562:63;:::i;:::-;4552:73;;;4662:2;4705:9;4701:22;2417:20;4670:63;;4770:2;4813:9;4809:22;2417:20;4778:63;;4878:3;4922:9;4918:22;2417:20;4887:63;;4987:3;5028:9;5024:22;1244:20;1269:30;1293:5;1269:30;:::i;:::-;4996:60;;;;4253:819;;;;;;;;:::o;5079:472::-;;;5210:2;5198:9;5189:7;5185:23;5181:32;5178:2;;;-1:-1;;5216:12;5178:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;5268:63;-1:-1;5396:2;5381:18;;5368:32;-1:-1;;;;;5409:30;;5406:2;;;-1:-1;;5442:12;5406:2;5472:63;5527:7;5518:6;5507:9;5503:22;5472:63;:::i;:::-;5462:73;;;5172:379;;;;;:::o;5558:717::-;;;;;5720:3;5708:9;5699:7;5695:23;5691:33;5688:2;;;-1:-1;;5727:12;5688:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;5779:63;-1:-1;5907:2;5892:18;;5879:32;-1:-1;;;;;5920:30;;5917:2;;;-1:-1;;5953:12;5917:2;5983:63;6038:7;6029:6;6018:9;6014:22;5983:63;:::i;:::-;5973:73;;;6083:2;6126:9;6122:22;2417:20;6091:63;;6191:2;6231:9;6227:22;1244:20;1269:30;1293:5;1269:30;:::i;:::-;5682:593;;;;-1:-1;5682:593;;-1:-1;;5682:593::o;6282:390::-;;6421:2;;6409:9;6400:7;6396:23;6392:32;6389:2;;;-1:-1;;6427:12;6389:2;6478:17;6472:24;-1:-1;;;;;6516:18;6508:6;6505:30;6502:2;;;-1:-1;;6538:12;6502:2;6639:6;6628:9;6624:22;;;580:3;573:4;565:6;561:17;557:27;547:2;;-1:-1;;588:12;547:2;628:6;622:13;6516:18;33216:6;33213:30;33210:2;;;-1:-1;;33246:12;33210:2;6421;33283:6;33279:17;;;650:79;6421:2;33279:17;33344:15;650:79;:::i;:::-;757:21;;;814:14;;;;789:17;;;894:27;;;;;891:36;-1:-1;888:2;;;-1:-1;;930:12;888:2;-1:-1;956:10;;950:216;975:6;972:1;969:13;950:216;;;1055:47;1098:3;1086:10;1055:47;:::i;:::-;1043:60;;997:1;990:9;;;;;1117:14;;;;1145;;950:216;;;-1:-1;6558:98;6383:289;-1:-1;;;;;;;;6383:289::o;6679:257::-;;6791:2;6779:9;6770:7;6766:23;6762:32;6759:2;;;-1:-1;;6797:12;6759:2;1392:6;1386:13;1404:30;1428:5;1404:30;:::i;6943:347::-;;7057:2;7045:9;7036:7;7032:23;7028:32;7025:2;;;-1:-1;;7063:12;7025:2;7121:17;7108:31;-1:-1;;;;;7151:6;7148:30;7145:2;;;-1:-1;;7181:12;7145:2;7211:63;7266:7;7257:6;7246:9;7242:22;7211:63;:::i;:::-;7201:73;7019:271;-1:-1;;;;7019:271::o;7297:362::-;;7422:2;7410:9;7401:7;7397:23;7393:32;7390:2;;;-1:-1;;7428:12;7390:2;7479:17;7473:24;-1:-1;;;;;7509:6;7506:30;7503:2;;;-1:-1;;7539:12;7503:2;7611:22;;2004:4;1992:17;;1988:27;-1:-1;1978:2;;-1:-1;;2019:12;1978:2;2059:6;2053:13;2081:65;2096:49;2138:6;2096:49;:::i;2081:65::-;2166:6;2159:5;2152:21;2270:3;7422:2;2261:6;2194;2252:16;;2249:25;2246:2;;;-1:-1;;2277:12;2246:2;2297:39;2329:6;7422:2;2228:5;2224:16;7422:2;2194:6;2190:17;2297:39;:::i;:::-;7559:84;7384:275;-1:-1;;;;;7384:275::o;7666:591::-;;;;7811:2;7799:9;7790:7;7786:23;7782:32;7779:2;;;-1:-1;;7817:12;7779:2;7875:17;7862:31;-1:-1;;;;;7905:6;7902:30;7899:2;;;-1:-1;;7935:12;7899:2;7965:63;8020:7;8011:6;8000:9;7996:22;7965:63;:::i;:::-;7955:73;;;8065:2;8108:9;8104:22;2417:20;8073:63;;8173:2;8213:9;8209:22;1244:20;1269:30;1293:5;1269:30;:::i;8264:263::-;;8379:2;8367:9;8358:7;8354:23;8350:32;8347:2;;;-1:-1;;8385:12;8347:2;-1:-1;2565:13;;8341:186;-1:-1;8341:186::o;8534:472::-;;;8665:2;8653:9;8644:7;8640:23;8636:32;8633:2;;;-1:-1;;8671:12;8633:2;2430:6;2417:20;8723:63;;8851:2;8840:9;8836:18;8823:32;-1:-1;;;;;8867:6;8864:30;8861:2;;;-1:-1;;8897:12;9013:239;;9116:2;9104:9;9095:7;9091:23;9087:32;9084:2;;;-1:-1;;9122:12;9084:2;2707:6;2694:20;2719:32;2745:5;2719:32;:::i;9259:261::-;;9373:2;9361:9;9352:7;9348:23;9344:32;9341:2;;;-1:-1;;9379:12;9341:2;2846:6;2840:13;2858:32;2884:5;2858:32;:::i;9527:489::-;;;;9664:2;9652:9;9643:7;9639:23;9635:32;9632:2;;;-1:-1;;9670:12;9632:2;2707:6;2694:20;2719:32;2745:5;2719:32;:::i;:::-;9722:62;-1:-1;9821:2;9860:22;;72:20;97:33;72:20;97:33;:::i;:::-;9626:390;;9829:63;;-1:-1;;;9929:2;9968:22;;;;2417:20;;9626:390::o;10023:715::-;;;;;10184:3;10172:9;10163:7;10159:23;10155:33;10152:2;;;-1:-1;;10191:12;10152:2;2707:6;2694:20;2719:32;2745:5;2719:32;:::i;:::-;10243:62;-1:-1;10370:2;10355:18;;10342:32;-1:-1;;;;;10383:30;;10380:2;;;-1:-1;;10416:12;10380:2;10446:63;10501:7;10492:6;10481:9;10477:22;10446:63;:::i;:::-;10436:73;;;10546:2;10586:9;10582:22;1244:20;1269:30;1293:5;1269:30;:::i;:::-;10146:592;;;;-1:-1;10554:60;;10651:2;10690:22;2417:20;;-1:-1;;10146:592::o;10745:364::-;;;10865:2;10853:9;10844:7;10840:23;10836:32;10833:2;;;-1:-1;;10871:12;10833:2;2707:6;2694:20;2719:32;2745:5;2719:32;:::i;:::-;10923:62;11022:2;11061:22;;;;2417:20;;-1:-1;;;10827:282::o;11116:489::-;;;;11253:2;11241:9;11232:7;11228:23;11224:32;11221:2;;;-1:-1;;11259:12;11221:2;2707:6;2694:20;2719:32;2745:5;2719:32;:::i;:::-;11311:62;-1:-1;11410:2;11449:22;;2417:20;;-1:-1;11518:2;11557:22;;72:20;97:33;72:20;97:33;:::i;11612:259::-;;11725:2;11713:9;11704:7;11700:23;11696:32;11693:2;;;-1:-1;;11731:12;11693:2;2984:6;2978:13;36032:4;38683:5;36021:16;38660:5;38657:33;38647:2;;-1:-1;;38694:12;13458:343;;13600:5;34129:12;34671:6;34666:3;34659:19;13693:52;13738:6;34708:4;34703:3;34699:14;34708:4;13719:5;13715:16;13693:52;:::i;:::-;37742:7;37726:14;-1:-1;;37722:28;13757:39;;;;34708:4;13757:39;;13548:253;-1:-1;;13548:253::o;15188:823::-;;15307:5;15301:12;15341:1;;15330:9;15326:17;15354:1;15349:248;;;;15608:1;15603:402;;;;15319:686;;15349:248;15423:1;15408:17;;15427:4;15404:28;34659:19;;-1:-1;;15536:25;;34708:4;34699:14;;15524:38;15576:14;;;;-1:-1;15349:248;;15603:402;15672:1;15661:9;15657:17;34671:6;34666:3;34659:19;15781:38;15813:5;15781:38;:::i;:::-;-1:-1;15843:130;15857:6;15854:1;15851:13;15843:130;;;15922:7;15916:14;34708:4;15912:1;34703:3;15903:11;;15896:35;15341:1;15954:7;15950:15;15939:26;;34708:4;15876:1;15872:12;15867:17;;15843:130;;;15987:11;;34708:4;15987:11;;-1:-1;;;15319:686;;;;15277:734;;;;:::o;18822:692::-;;37833:14;;35717:5;37837:2;37833:14;;12565:3;12558:58;14959:5;34129:12;15071:52;15116:6;19151:2;19146:3;19142:12;15104:4;15097:5;15093:16;15071:52;:::i;:::-;15135:16;;;19151:2;15135:16;;18390:37;;;;-1:-1;19366:12;;;18390:37;19477:12;;;;-1:-1;;19042:472::o;19521:275::-;;14959:5;34129:12;15071:52;15116:6;15111:3;15104:4;15097:5;15093:16;15071:52;:::i;:::-;15135:16;;;;;19657:139;-1:-1;;19657:139::o;19803:269::-;;-1:-1;16181:5;16175:12;16215:1;;16204:9;16200:17;16228:1;16223:268;;;;16502:1;16497:425;;;;16193:729;;16223:268;-1:-1;;16428:25;;16416:38;;16297:1;16282:17;;16301:4;16278:28;16468:16;;;-1:-1;16223:268;;16497:425;16566:1;16555:9;16551:17;33967:3;-1:-1;33957:14;33999:4;;-1:-1;33986:18;-1:-1;16755:130;16769:6;16766:1;16763:13;16755:130;;;16828:14;;16815:11;;;16808:35;16862:15;;;;16784:12;;16755:130;;;-1:-1;;;16899:16;;;-1:-1;16193:729;-1:-1;20057:10;;19936:136;-1:-1;;;;;19936:136::o;20079:222::-;-1:-1;;;;;35713:54;;;;12292:45;;20206:2;20191:18;;20177:124::o;20553:1380::-;;20984:3;4510:18;;37833:14;;;35724:42;12330:5;35713:54;12299:3;12292:45;35724:42;12330:5;35713:54;21181:2;21170:9;21166:18;12292:45;;18420:5;21264:2;21253:9;21249:18;18390:37;18420:5;21347:2;21336:9;21332:18;18390:37;18420:5;21430:3;21419:9;21415:19;18390:37;18420:5;21514:3;21503:9;21499:19;18390:37;18420:5;21598:3;21587:9;21583:19;18390:37;18420:5;21682:3;21671:9;21667:19;18390:37;20984:3;21720;21709:9;21705:19;21698:49;21761:78;20984:3;20973:9;20969:19;21825:6;21761:78;:::i;:::-;21753:86;;;18420:5;21918:3;21907:9;21903:19;18390:37;20955:978;;;;;;;;;;;;;:::o;21940:349::-;-1:-1;;;;;35713:54;;;;12135:58;;22275:2;22260:18;;18390:37;22103:2;22088:18;;22074:215::o;22296:542::-;;4510:18;;37833:14;;;35717:5;35713:54;12142:3;12135:58;18420:5;22676:2;22665:9;22661:18;18390:37;22504:2;22713;22702:9;22698:18;22691:48;22753:75;22504:2;22493:9;22489:18;22814:6;22753:75;:::i;22845:788::-;;4510:18;;37833:14;;;12330:5;35713:54;12299:3;12292:45;18420:5;23301:2;23290:9;23286:18;18390:37;18420:5;23384:2;23373:9;23369:18;18390:37;18420:5;23467:2;23456:9;23452:18;18390:37;23120:3;23504;23493:9;23489:19;23482:49;23545:78;23120:3;23109:9;23105:19;23609:6;23545:78;:::i;:::-;23537:86;23091:542;-1:-1;;;;;;;23091:542::o;24419:321::-;-1:-1;;;;;35713:54;;;;12292:45;;35494:13;35487:21;24726:2;24711:18;;13412:34;24568:2;24553:18;;24539:201::o;24747:952::-;;4510:18;;37833:14;;;12330:5;35713:54;12299:3;12292:45;36412:24;25255:2;25244:9;25240:18;14043:67;25076:3;25292:2;25281:9;25277:18;25270:48;25332:76;25076:3;25065:9;25061:19;25394:6;25332:76;:::i;:::-;25487:2;25472:18;;18390:37;;;;-1:-1;25583:3;25568:19;;14043:67;;;;25684:3;25669:19;;;14043:67;25324:84;25047:652;-1:-1;;;25047:652::o;26637:366::-;26812:2;26826:47;;;34129:12;;26797:18;;;34659:19;;;26637:366;;26812:2;33819:14;;;;34699;;;;26637:366;13060:257;13085:6;13082:1;13079:13;13060:257;;;13146:13;;-1:-1;;;;;35919:30;18657:36;;34515:14;;;;12028;;;;13107:1;13100:9;13060:257;;;-1:-1;26879:114;;26783:220;-1:-1;;;;;;26783:220::o;27010:236::-;27144:2;27129:18;;37943:1;37933:12;;37923:2;;37949:9;37923:2;13886:57;;;27115:131;:::o;27253:310::-;;27400:2;27421:17;27414:47;27475:78;27400:2;27389:9;27385:18;27539:6;27475:78;:::i;27570:421::-;;27745:2;27766:17;27759:47;27820:78;27745:2;27734:9;27730:18;27884:6;27820:78;:::i;:::-;27812:86;;18420:5;27977:2;27966:9;27962:18;18390:37;27716:275;;;;;:::o;27998:532::-;;28201:2;28222:17;28215:47;28276:78;28201:2;28190:9;28186:18;28340:6;28276:78;:::i;:::-;28433:2;28418:18;;18390:37;;;;-1:-1;;;;;;35713:54;;;;28516:2;28501:18;;;12292:45;28268:86;28172:358;-1:-1;28172:358::o;29108:304::-;;29252:2;29273:17;29266:47;29327:75;29252:2;29241:9;29237:18;29388:6;29327:75;:::i;29419:416::-;29619:2;29633:47;;;17161:2;29604:18;;;34659:19;-1:-1;;;34699:14;;;17177:44;17240:12;;;29590:245::o;29842:416::-;30042:2;30056:47;;;17491:2;30027:18;;;34659:19;17527:25;34699:14;;;17507:46;17572:12;;;30013:245::o;30265:416::-;30465:2;30479:47;;;17823:2;30450:18;;;34659:19;17859:34;34699:14;;;17839:55;-1:-1;;;17914:12;;;17907:38;17964:12;;;30436:245::o;30688:416::-;30888:2;30902:47;;;18215:2;30873:18;;;34659:19;-1:-1;;;34699:14;;;18231:43;18293:12;;;30859:245::o;31111:222::-;18390:37;;;31238:2;31223:18;;31209:124::o;31340:444::-;18390:37;;;-1:-1;;;;;35713:54;;;;31687:2;31672:18;;12292:45;31770:2;31755:18;;18390:37;31523:2;31508:18;;31494:290::o;31791:333::-;18390:37;;;32110:2;32095:18;;18390:37;31946:2;31931:18;;31917:207::o;32131:218::-;-1:-1;;;;;35919:30;;;;18657:36;;32256:2;32241:18;;32227:122::o;32356:440::-;-1:-1;;;;;35919:30;;;;18657:36;;-1:-1;;;;;35713:54;;;;32699:2;32684:18;;12292:45;32782:2;32767:18;;18390:37;32537:2;32522:18;;32508:288::o;32803:256::-;32865:2;32859:9;32891:17;;;-1:-1;;;;;32951:34;;32987:22;;;32948:62;32945:2;;;33023:1;;33013:12;32945:2;32865;33032:22;32843:216;;-1:-1;32843:216::o;33376:322::-;;-1:-1;;;;;33512:6;33509:30;33506:2;;;-1:-1;;33542:12;33506:2;-1:-1;37742:7;33596:17;-1:-1;;33592:33;33683:4;33673:15;;33443:255::o;33862:158::-;;33957:14;;;33999:4;33986:18;;;33916:104::o;37103:268::-;37168:1;37175:101;37189:6;37186:1;37183:13;37175:101;;;37256:11;;;37250:18;37237:11;;;37230:39;37211:2;37204:10;37175:101;;;37291:6;37288:1;37285:13;37282:2;;;-1:-1;;37168:1;37338:16;;37331:27;37152:219::o;37972:117::-;-1:-1;;;;;35713:54;;38031:35;;38021:2;;38080:1;;38070:12;38236:111;38317:5;35494:13;35487:21;38295:5;38292:32;38282:2;;38338:1;;38328:12;38478:115;-1:-1;;;;;38563:5;35919:30;38539:5;38536:34;38526:2;;38584:1;;38574:12
Swarm Source
ipfs://90c9783d32ccab7fc7942b4bb7127b6ac07ff8a9b2682c53f197b0ab88e54ce8
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.