ETH Price: $3,176.25 (-2.68%)

Contract

0xfE3a6567A25d74b3A7F10ED49631502806Ed1a17
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Match Market Con...112154082020-11-08 7:22:451466 days ago1604820165IN
0xfE3a6567...806Ed1a17
0 ETH0.0149854246
Match Market Con...112114292020-11-07 16:40:361466 days ago1604767236IN
0xfE3a6567...806Ed1a17
0 ETH0.15183789106
Match Market Con...112066662020-11-06 23:06:381467 days ago1604703998IN
0xfE3a6567...806Ed1a17
0 ETH0.0393882534
Match Market Con...112011152020-11-06 2:45:111468 days ago1604630711IN
0xfE3a6567...806Ed1a17
0 ETH0.0293031286
Match Market Con...112010532020-11-06 2:32:451468 days ago1604629965IN
0xfE3a6567...806Ed1a17
0 ETH0.0323341986
Match Market Con...112010022020-11-06 2:21:521468 days ago1604629312IN
0xfE3a6567...806Ed1a17
0 ETH0.1095974878
Match Market Con...112009822020-11-06 2:18:551468 days ago1604629135IN
0xfE3a6567...806Ed1a17
0 ETH0.0873736578
Match Market Con...112000302020-11-05 22:48:271468 days ago1604616507IN
0xfE3a6567...806Ed1a17
0 ETH0.0269545424
Match Market Con...111949282020-11-05 4:01:271469 days ago1604548887IN
0xfE3a6567...806Ed1a17
0 ETH0.0638628745
Match Market Con...111943012020-11-05 1:46:301469 days ago1604540790IN
0xfE3a6567...806Ed1a17
0 ETH0.0098805726
Match Market Con...111943002020-11-05 1:45:551469 days ago1604540755IN
0xfE3a6567...806Ed1a17
0 ETH0.0106614326
Match Market Con...111939982020-11-05 0:35:381469 days ago1604536538IN
0xfE3a6567...806Ed1a17
0 ETH0.0119181324.2
Match Market Con...111934032020-11-04 22:17:141469 days ago1604528234IN
0xfE3a6567...806Ed1a17
0 ETH0.0042612217
Match Market Con...111932522020-11-04 21:50:321469 days ago1604526632IN
0xfE3a6567...806Ed1a17
0 ETH0.0152111117.6
Match Market Con...111931092020-11-04 21:18:581469 days ago1604524738IN
0xfE3a6567...806Ed1a17
0 ETH0.0118803225
Match Market Con...111931092020-11-04 21:18:581469 days ago1604524738IN
0xfE3a6567...806Ed1a17
0 ETH0.0118803225
Match Market Con...111931092020-11-04 21:18:581469 days ago1604524738IN
0xfE3a6567...806Ed1a17
0 ETH0.0118797225
Match Market Con...111931092020-11-04 21:18:581469 days ago1604524738IN
0xfE3a6567...806Ed1a17
0 ETH0.0118803225
Match Market Con...111931092020-11-04 21:18:581469 days ago1604524738IN
0xfE3a6567...806Ed1a17
0 ETH0.0126303725
Match Market Con...111918322020-11-04 16:43:431469 days ago1604508223IN
0xfE3a6567...806Ed1a17
0 ETH0.2033667274
Match Market Con...111918252020-11-04 16:42:301469 days ago1604508150IN
0xfE3a6567...806Ed1a17
0 ETH0.0259939874
Match Market Con...111917732020-11-04 16:34:131469 days ago1604507653IN
0xfE3a6567...806Ed1a17
0 ETH0.0214966357
Match Market Con...111917422020-11-04 16:27:021469 days ago1604507222IN
0xfE3a6567...806Ed1a17
0 ETH0.0233640757
Match Market Con...111912152020-11-04 14:32:081469 days ago1604500328IN
0xfE3a6567...806Ed1a17
0 ETH0.0370884246
Match Market Con...111910882020-11-04 14:05:391469 days ago1604498739IN
0xfE3a6567...806Ed1a17
0 ETH0.0277707438
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MaiProtocol

Compiler Version
v0.5.2+commit.1df8f40c

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Apache-2.0 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-12-06
*/

pragma solidity ^0.5.2;
pragma experimental ABIEncoderV2;


contract EIP712 {
    string internal constant DOMAIN_NAME = "Mai Protocol";

    
    bytes32 public constant EIP712_DOMAIN_TYPEHASH = keccak256(
        abi.encodePacked("EIP712Domain(string name)")
    );

    bytes32 public DOMAIN_SEPARATOR;

    constructor () public {
        DOMAIN_SEPARATOR = keccak256(
            abi.encodePacked(
                EIP712_DOMAIN_TYPEHASH,
                keccak256(bytes(DOMAIN_NAME))
            )
        );
    }

    
    function hashEIP712Message(bytes32 eip712hash) internal view returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, eip712hash));
    }
}

contract LibSignature {

    enum SignatureMethod {
        EthSign,
        EIP712
    }

    
    struct OrderSignature {
        
        bytes32 config;
        bytes32 r;
        bytes32 s;
    }

    
    function isValidSignature(bytes32 hash, address signerAddress, OrderSignature memory signature)
        internal
        pure
        returns (bool)
    {
        uint8 method = uint8(signature.config[1]);
        address recovered;
        uint8 v = uint8(signature.config[0]);

        if (method == uint8(SignatureMethod.EthSign)) {
            recovered = ecrecover(
                keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)),
                v,
                signature.r,
                signature.s
            );
        } else if (method == uint8(SignatureMethod.EIP712)) {
            recovered = ecrecover(hash, v, signature.r, signature.s);
        } else {
            revert("INVALID_SIGN_METHOD");
        }

        return signerAddress == recovered;
    }
}

library SafeMath {
    
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        
        
        
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        

        return c;
    }

    
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

contract LibMath {
    using SafeMath for uint256;

    
    function isRoundingError(uint256 numerator, uint256 denominator, uint256 multiple)
        internal
        pure
        returns (bool)
    {
        return numerator.mul(multiple).mod(denominator).mul(1000) >= numerator.mul(multiple);
    }

    
    
    
    function getPartialAmountFloor(uint256 numerator, uint256 denominator, uint256 multiple)
        internal
        pure
        returns (uint256)
    {
        require(!isRoundingError(numerator, denominator, multiple), "ROUNDING_ERROR");
        return numerator.mul(multiple).div(denominator);
    }

    
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }
}

contract LibOrder is EIP712, LibSignature, LibMath {

    uint256 public constant REBATE_RATE_BASE = 100;

    struct Order {
        address trader;
        address relayer;
        address marketContractAddress;
        uint256 amount;
        uint256 price;
        uint256 gasTokenAmount;

        
        bytes32 data;
    }

    enum OrderStatus {
        EXPIRED,
        CANCELLED,
        FILLABLE,
        FULLY_FILLED
    }

    enum FillAction {
        INVALID,
        BUY,
        SELL,
        MINT,
        REDEEM
    }

    bytes32 public constant EIP712_ORDER_TYPE = keccak256(
        abi.encodePacked(
            "Order(address trader,address relayer,address marketContractAddress,uint256 amount,uint256 price,uint256 gasTokenAmount,bytes32 data)"
        )
    );

    
    function getOrderHash(Order memory order) internal view returns (bytes32 orderHash) {
        orderHash = hashEIP712Message(hashOrder(order));
        return orderHash;
    }

    
    function hashOrder(Order memory order) internal pure returns (bytes32 result) {
        
        bytes32 orderType = EIP712_ORDER_TYPE;

        assembly {
            let start := sub(order, 32)
            let tmp := mload(start)

            
            
            
            
            mstore(start, orderType)
            result := keccak256(start, 256)

            mstore(start, tmp)
        }

        return result;
    }

    

    function getOrderVersion(bytes32 data) internal pure returns (uint256) {
        return uint256(uint8(byte(data)));
    }

    function getExpiredAtFromOrderData(bytes32 data) internal pure returns (uint256) {
        return uint256(uint40(bytes5(data << (8*3))));
    }

    function isSell(bytes32 data) internal pure returns (bool) {
        return uint8(data[1]) == 1;
    }

    function isMarketOrder(bytes32 data) internal pure returns (bool) {
        return uint8(data[2]) == 1;
    }

    function isMakerOnly(bytes32 data) internal pure returns (bool) {
        return uint8(data[22]) == 1;
    }

    function isMarketBuy(bytes32 data) internal pure returns (bool) {
        return !isSell(data) && isMarketOrder(data);
    }

    function getAsMakerFeeRateFromOrderData(bytes32 data) internal pure returns (uint256) {
        return uint256(uint16(bytes2(data << (8*8))));
    }

    function getAsTakerFeeRateFromOrderData(bytes32 data) internal pure returns (uint256) {
        return uint256(uint16(bytes2(data << (8*10))));
    }

    function getMakerRebateRateFromOrderData(bytes32 data) internal pure returns (uint256) {
        uint256 makerRebate = uint256(uint16(bytes2(data << (8*12))));

        
        return min(makerRebate, REBATE_RATE_BASE);
    }
}

contract LibOwnable {
    address private _owner;

    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    
    constructor() internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    
    function owner() public view returns(address) {
        return _owner;
    }

    
    modifier onlyOwner() {
        require(isOwner(), "NOT_OWNER");
        _;
    }

    
    function isOwner() public view returns(bool) {
        return msg.sender == _owner;
    }

    
    
    
    
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    
    
    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "INVALID_OWNER");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

contract LibRelayer {

    
    mapping (address => mapping (address => bool)) public relayerDelegates;

    
    mapping (address => bool) hasExited;

    event RelayerApproveDelegate(address indexed relayer, address indexed delegate);
    event RelayerRevokeDelegate(address indexed relayer, address indexed delegate);

    event RelayerExit(address indexed relayer);
    event RelayerJoin(address indexed relayer);

    
    function approveDelegate(address delegate) external {
        relayerDelegates[msg.sender][delegate] = true;
        emit RelayerApproveDelegate(msg.sender, delegate);
    }

    
    function revokeDelegate(address delegate) external {
        relayerDelegates[msg.sender][delegate] = false;
        emit RelayerRevokeDelegate(msg.sender, delegate);
    }

    
    function canMatchMarketContractOrdersFrom(address relayer) public view returns(bool) {
        return msg.sender == relayer || relayerDelegates[relayer][msg.sender] == true;
    }

    
    function joinIncentiveSystem() external {
        delete hasExited[msg.sender];
        emit RelayerJoin(msg.sender);
    }

    
    function exitIncentiveSystem() external {
        hasExited[msg.sender] = true;
        emit RelayerExit(msg.sender);
    }

    
    function isParticipant(address relayer) public view returns(bool) {
        return !hasExited[relayer];
    }
}

contract LibExchangeErrors {
    string constant INVALID_TRADER = "INVALID_TRADER";
    string constant INVALID_SENDER = "INVALID_SENDER";
    
    string constant INVALID_MATCH = "INVALID_MATCH";
    string constant REDEEM_PRICE_NOT_MET = "REDEEM_PRICE_NOT_MET";
    string constant MINT_PRICE_NOT_MET = "MINT_PRICE_NOT_MET";
    string constant INVALID_SIDE = "INVALID_SIDE";
    
    string constant INVALID_ORDER_SIGNATURE = "INVALID_ORDER_SIGNATURE";
    
    string constant ORDER_IS_NOT_FILLABLE = "ORDER_IS_NOT_FILLABLE";
    string constant MAKER_ORDER_CAN_NOT_BE_MARKET_ORDER = "MAKER_ORDER_CAN_NOT_BE_MARKET_ORDER";
    string constant TRANSFER_FROM_FAILED = "TRANSFER_FROM_FAILED";
    string constant MAKER_ORDER_OVER_MATCH = "MAKER_ORDER_OVER_MATCH";
    string constant TAKER_ORDER_OVER_MATCH = "TAKER_ORDER_OVER_MATCH";
    string constant ORDER_VERSION_NOT_SUPPORTED = "ORDER_VERSION_NOT_SUPPORTED";
    string constant MAKER_ONLY_ORDER_CANNOT_BE_TAKER = "MAKER_ONLY_ORDER_CANNOT_BE_TAKER";
    string constant TRANSFER_FAILED = "TRANSFER_FAILED";
    string constant MINT_POSITION_TOKENS_FAILED = "MINT_FAILED";
    string constant REDEEM_POSITION_TOKENS_FAILED = "REDEEM_FAILED";
    string constant UNEXPECTED_MATCH = "UNEXPECTED_MATCH";
    string constant INSUFFICIENT_FEE = "INSUFFICIENT_FEE";
    string constant INVALID_MARKET_CONTRACT = "INVALID_MARKET_CONTRACT";
    string constant UNMATCHED_FILL = "UNMATCHED_FILL";
    string constant LOW_MARGIN = "LOW_MARGIN";
    string constant INVALID_AMOUNT = "LOW_MARGIN";
    string constant MAKER_CAN_NOT_BE_SAME_WITH_TAKER = "MAKER_CANNOT_BE_TAKER";
}

interface IMarketContract {
    
    function CONTRACT_NAME()
        external
        view
        returns (string memory);
    function COLLATERAL_TOKEN_ADDRESS()
        external
        view
        returns (address);
    function COLLATERAL_POOL_ADDRESS()
        external
        view
        returns (address);
    function PRICE_CAP()
        external
        view
        returns (uint);
    function PRICE_FLOOR()
        external
        view
        returns (uint);
    function PRICE_DECIMAL_PLACES()
        external
        view
        returns (uint);
    function QTY_MULTIPLIER()
        external
        view
        returns (uint);
    function COLLATERAL_PER_UNIT()
        external
        view
        returns (uint);
    function COLLATERAL_TOKEN_FEE_PER_UNIT()
        external
        view
        returns (uint);
    function MKT_TOKEN_FEE_PER_UNIT()
        external
        view
        returns (uint);
    function EXPIRATION()
        external
        view
        returns (uint);
    function SETTLEMENT_DELAY()
        external
        view
        returns (uint);
    function LONG_POSITION_TOKEN()
        external
        view
        returns (address);
    function SHORT_POSITION_TOKEN()
        external
        view
        returns (address);

    
    function lastPrice()
        external
        view
        returns (uint);
    function settlementPrice()
        external
        view
        returns (uint);
    function settlementTimeStamp()
        external
        view
        returns (uint);
    function isSettled()
        external
        view
        returns (bool);

    
    function isPostSettlementDelay()
        external
        view
        returns (bool);
}

contract IMarketContractPool {
    function mintPositionTokens(
        address marketContractAddress,
        uint qtyToMint,
        bool isAttemptToPayInMKT
    ) external;
    function redeemPositionTokens(
        address marketContractAddress,
        uint qtyToRedeem
    ) external;
    function mktToken() external view returns (address);
}

contract IMarketContractRegistry {
    function addAddressToWhiteList(address contractAddress) external;
    function isAddressWhiteListed(address contractAddress) external view returns (bool);
}

interface IERC20 {
    
    function totalSupply() external view returns (uint256);

    
    function balanceOf(address account) external view returns (uint256);

    
    function transfer(address recipient, uint256 amount) external returns (bool);

    
    function allowance(address owner, address spender) external view returns (uint256);

    
    function approve(address spender, uint256 amount) external returns (bool);

    
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    
    event Transfer(address indexed from, address indexed to, uint256 value);

    
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

library Address {
    
    function isContract(address account) internal view returns (bool) {
        
        
        

        uint256 size;
        
        assembly { size := extcodesize(account) }
        return size > 0;
    }
}

library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        
        
        
        
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    
    function callOptionalReturn(IERC20 token, bytes memory data) private {
        
        

        
        
        
        
        
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { 
            
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

contract MaiProtocol is LibMath, LibOrder, LibRelayer, LibExchangeErrors, LibOwnable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    uint256 public constant MAX_MATCHES = 3;
    uint256 public constant LONG = 0;
    uint256 public constant SHORT = 1;
    uint256 public constant FEE_RATE_BASE = 100000;

    
    uint256 public constant SUPPORTED_ORDER_VERSION = 1;

    
    address public marketRegistryAddress;

    
    address public mintingPoolAddress;

    
    mapping (bytes32 => uint256) public filled;

    
    mapping (bytes32 => bool) public cancelled;

    
    struct OrderParam {
        address trader;
        uint256 amount;
        uint256 price;
        uint256 gasTokenAmount;
        bytes32 data;
        OrderSignature signature;
    }

    
    struct OrderInfo {
        bytes32 orderHash;
        uint256 filledAmount;
        uint256[2] margins;     
        uint256[2] balances;    
    }

    struct OrderAddressSet {
        address marketContractAddress;
        address relayer;
    }

    struct OrderContext {
        IMarketContract marketContract;         
        IMarketContractPool marketContractPool; 
        IERC20 collateral;                      
        IERC20[2] positions;                    
        uint256 takerSide;                      
    }

    struct MatchResult {
        address maker;
        address taker;
        uint256 makerFee;                   
        uint256 takerFee;                   
        uint256 makerGasFee;
        uint256 takerGasFee;
        uint256 posFilledAmount;            
        uint256 ctkFilledAmount;            
        FillAction fillAction;
    }


    event Match(
        OrderAddressSet addressSet,
        MatchResult result
    );
    event Cancel(bytes32 indexed orderHash);
    event Withdraw(address indexed tokenAddress, address indexed to, uint256 amount);
    event Approval(address indexed tokenAddress, address indexed spender, uint256 amount);

    
    function setMarketRegistryAddress(address _marketRegistryAddress)
        external
        onlyOwner
    {
        marketRegistryAddress = _marketRegistryAddress;
    }


    function setMintingPool(address _mintingPoolAddress)
        external
        onlyOwner
    {
        mintingPoolAddress = _mintingPoolAddress;
    }

    function approveERC20(address token, address spender, uint256 amount)
        external
        onlyOwner
    {
        IERC20(token).safeApprove(spender, amount);
        emit Approval(token, spender, amount);
    }

    function withdrawERC20(address token, uint256 amount)
        external
        onlyOwner
    {
        require(amount > 0, INVALID_AMOUNT);
        IERC20(token).safeTransfer(msg.sender, amount);

        emit Withdraw(token, msg.sender, amount);
    }


    
    function matchMarketContractOrders(
        OrderParam memory takerOrderParam,
        OrderParam[] memory makerOrderParams,
        uint256[] memory posFilledAmounts,
        OrderAddressSet memory orderAddressSet
    )
        public
    {
        require(canMatchMarketContractOrdersFrom(orderAddressSet.relayer), INVALID_SENDER);
        require(!isMakerOnly(takerOrderParam.data), MAKER_ONLY_ORDER_CANNOT_BE_TAKER);

        validateMarketContract(orderAddressSet.marketContractAddress);
        OrderContext memory orderContext = getOrderContext(orderAddressSet, takerOrderParam);
        matchAndSettle(
            takerOrderParam,
            makerOrderParams,
            posFilledAmounts,
            orderAddressSet,
            orderContext
        );
    }

    
    function getOrderContext(
        OrderAddressSet memory orderAddressSet,
        OrderParam memory takerOrderParam
    )
        internal
        view
        returns (OrderContext memory orderContext)
    {
        orderContext.marketContract = IMarketContract(orderAddressSet.marketContractAddress);
        orderContext.marketContractPool = IMarketContractPool(
            orderContext.marketContract.COLLATERAL_POOL_ADDRESS()
        );
        orderContext.collateral = IERC20(orderContext.marketContract.COLLATERAL_TOKEN_ADDRESS());
        orderContext.positions[LONG] = IERC20(orderContext.marketContract.LONG_POSITION_TOKEN());
        orderContext.positions[SHORT] = IERC20(orderContext.marketContract.SHORT_POSITION_TOKEN());
        orderContext.takerSide = isSell(takerOrderParam.data) ? SHORT : LONG;

        return orderContext;
    }

    
    function matchAndSettle(
        OrderParam memory takerOrderParam,
        OrderParam[] memory makerOrderParams,
        uint256[] memory posFilledAmounts,
        OrderAddressSet memory orderAddressSet,
        OrderContext memory orderContext
    )
        internal
    {
        OrderInfo memory takerOrderInfo = getOrderInfo(
            takerOrderParam,
            orderAddressSet,
            orderContext
        );
        for (uint256 i = 0; i < makerOrderParams.length; i++) {
            require(!isMarketOrder(makerOrderParams[i].data), MAKER_ORDER_CAN_NOT_BE_MARKET_ORDER);
            require(isSell(takerOrderParam.data) != isSell(makerOrderParams[i].data), INVALID_SIDE);
            require(
                takerOrderParam.trader != makerOrderParams[i].trader,
                MAKER_CAN_NOT_BE_SAME_WITH_TAKER
            );
            OrderInfo memory makerOrderInfo = getOrderInfo(
                makerOrderParams[i],
                orderAddressSet,
                orderContext
            );
            validatePrice(
                takerOrderParam,
                makerOrderParams[i]
            );
            uint256 toFillAmount = posFilledAmounts[i];
            for (uint256 j = 0; j < MAX_MATCHES && toFillAmount > 0; j++) {
                MatchResult memory result;
                uint256 filledAmount;
                (result, filledAmount) = getMatchResult(
                    takerOrderParam,
                    takerOrderInfo,
                    makerOrderParams[i],
                    makerOrderInfo,
                    orderContext,
                    toFillAmount
                );
                toFillAmount = toFillAmount.sub(filledAmount);
                settleResult(result, orderAddressSet, orderContext);
            }
            
            
            require(toFillAmount == 0, UNMATCHED_FILL);
            filled[makerOrderInfo.orderHash] = makerOrderInfo.filledAmount;
        }
        filled[takerOrderInfo.orderHash] = takerOrderInfo.filledAmount;
    }

    
    function validateMarketContract(address marketContractAddress) internal view {
        if (marketRegistryAddress == address(0x0)) {
            return;
        }
        IMarketContractRegistry registry = IMarketContractRegistry(marketRegistryAddress);
        require(
            registry.isAddressWhiteListed(marketContractAddress),
            INVALID_MARKET_CONTRACT
        );
    }

    
    function calculateMiddleCollateralPerUnit(OrderContext memory orderContext)
        internal
        view
        returns (uint256)
    {
        return orderContext.marketContract.PRICE_CAP()
            .add(orderContext.marketContract.PRICE_FLOOR())
            .mul(orderContext.marketContract.QTY_MULTIPLIER())
            .div(2);
    }

    
    function calculateLongMargin(OrderContext memory orderContext, OrderParam memory orderParam)
        internal
        view
        returns (uint256)
    {
        return orderParam.price
            .sub(orderContext.marketContract.PRICE_FLOOR())
            .mul(orderContext.marketContract.QTY_MULTIPLIER());
    }

    
    function calculateShortMargin(OrderContext memory orderContext, OrderParam memory orderParam)
        internal
        view
        returns (uint256)
    {
        return orderContext.marketContract.PRICE_CAP()
            .sub(orderParam.price)
            .mul(orderContext.marketContract.QTY_MULTIPLIER());
    }

    
    function validatePrice(
        OrderParam memory takerOrderParam,
        OrderParam memory makerOrderParam
    )
        internal
        pure
    {
        if (isMarketOrder(takerOrderParam.data)) {
            return;
        }
        if (isSell(takerOrderParam.data)) {
            require(takerOrderParam.price <= makerOrderParam.price, INVALID_MATCH);
        } else {
            require(takerOrderParam.price >= makerOrderParam.price, INVALID_MATCH);
        }
    }

    
    function getMatchResult(
        OrderParam memory takerOrderParam,
        OrderInfo memory takerOrderInfo,
        OrderParam memory makerOrderParam,
        OrderInfo memory makerOrderInfo,
        OrderContext memory orderContext,
        uint256 posFilledAmount
    )
        internal
        view
        returns (MatchResult memory result, uint256 filledAmount)
    {
        require(makerOrderInfo.filledAmount <= makerOrderParam.amount, MAKER_ORDER_OVER_MATCH);
        require(takerOrderInfo.filledAmount <= takerOrderParam.amount, TAKER_ORDER_OVER_MATCH);

        
        if (takerOrderInfo.filledAmount == 0) {
            result.takerGasFee = takerOrderParam.gasTokenAmount;
        }
        if (makerOrderInfo.filledAmount == 0) {
            result.makerGasFee = makerOrderParam.gasTokenAmount;
        }

        
        filledAmount = fillMatchResult(
            result,
            takerOrderParam,
            takerOrderInfo,
            makerOrderParam,
            makerOrderInfo,
            orderContext,
            posFilledAmount
        );
        result.posFilledAmount = filledAmount;

        
        result.makerFee = filledAmount.mul(getMakerFeeBase(orderContext, makerOrderParam));
        result.takerFee = filledAmount.mul(getTakerFeeBase(orderContext, takerOrderParam));
        result.taker = takerOrderParam.trader;
        result.maker = makerOrderParam.trader;

        return (result, filledAmount);
    }

    
    function getMakerFeeBase(
        OrderContext memory orderContext,
        OrderParam memory orderParam
    )
        internal
        view
        returns (uint256)
    {
        uint256 middleCollateralPerUnit = calculateMiddleCollateralPerUnit(orderContext);
        return middleCollateralPerUnit
            .mul(getAsMakerFeeRateFromOrderData(orderParam.data))
            .div(FEE_RATE_BASE);
    }

    
    function getTakerFeeBase(
        OrderContext memory orderContext,
        OrderParam memory orderParam
    )
        internal
        view
        returns (uint256)
    {
        uint256 middleCollateralPerUnit = calculateMiddleCollateralPerUnit(orderContext);
        return middleCollateralPerUnit
            .mul(getAsTakerFeeRateFromOrderData(orderParam.data))
            .div(FEE_RATE_BASE);
    }

    
    function fillMatchResult(
        MatchResult memory result,
        OrderParam memory takerOrderParam,
        OrderInfo memory takerOrderInfo,
        OrderParam memory makerOrderParam,
        OrderInfo memory makerOrderInfo,
        OrderContext memory orderContext,
        uint256 posFilledAmount
    )
        internal
        pure
        returns (uint256 filledAmount)
    {
        uint256 side = orderContext.takerSide;
        uint256 opposite = oppositeSide(side);

        if (takerOrderInfo.balances[opposite] > 0 && makerOrderInfo.balances[side] > 0) {
            
            filledAmount = min(
                min(takerOrderInfo.balances[opposite], posFilledAmount),
                makerOrderInfo.balances[side]
            );
            
            takerOrderInfo.balances[opposite] = takerOrderInfo.balances[opposite]
                .sub(filledAmount);
            makerOrderInfo.balances[side] = makerOrderInfo.balances[side].sub(filledAmount);

            result.fillAction = FillAction.REDEEM;
            result.ctkFilledAmount = makerOrderInfo.margins[side].mul(filledAmount);

       } else if (takerOrderInfo.balances[opposite] > 0 && makerOrderInfo.balances[side] == 0) {
            
            filledAmount = min(takerOrderInfo.balances[opposite], posFilledAmount);
            takerOrderInfo.balances[opposite] = takerOrderInfo.balances[opposite]
                .sub(filledAmount);
            makerOrderInfo.balances[opposite] = makerOrderInfo.balances[opposite]
                .add(filledAmount);

            result.fillAction = FillAction.SELL;
            result.ctkFilledAmount = makerOrderInfo.margins[opposite].mul(filledAmount);

       } else if (takerOrderInfo.balances[opposite] == 0 && makerOrderInfo.balances[side] > 0) {
            
            filledAmount = min(makerOrderInfo.balances[side], posFilledAmount);
            takerOrderInfo.balances[side] = takerOrderInfo.balances[side].add(filledAmount);
            makerOrderInfo.balances[side] = makerOrderInfo.balances[side].sub(filledAmount);

            result.fillAction = FillAction.BUY;
            result.ctkFilledAmount = makerOrderInfo.margins[side].mul(filledAmount);

       } else if (takerOrderInfo.balances[opposite] == 0 && makerOrderInfo.balances[side] == 0) {
            
            filledAmount = posFilledAmount;
            
            takerOrderInfo.balances[side] = takerOrderInfo.balances[side].add(filledAmount);
            makerOrderInfo.balances[opposite] = makerOrderInfo.balances[opposite].add(filledAmount);

            result.fillAction = FillAction.MINT;
            result.ctkFilledAmount = makerOrderInfo.margins[opposite].mul(filledAmount);

        } else {
           revert(UNEXPECTED_MATCH);
        }

        
        takerOrderInfo.filledAmount = takerOrderInfo.filledAmount.add(filledAmount);
        makerOrderInfo.filledAmount = makerOrderInfo.filledAmount.add(filledAmount);

        require(takerOrderInfo.filledAmount <= takerOrderParam.amount, TAKER_ORDER_OVER_MATCH);
        require(makerOrderInfo.filledAmount <= makerOrderParam.amount, MAKER_ORDER_OVER_MATCH);

        result.posFilledAmount = filledAmount;

        return filledAmount;
    }

    
    function cancelOrder(Order memory order) public {
        require(msg.sender == order.trader || msg.sender == order.relayer, INVALID_TRADER);

        bytes32 orderHash = getOrderHash(order);
        cancelled[orderHash] = true;

        emit Cancel(orderHash);
    }

    
    function getOrderInfo(
        OrderParam memory orderParam,
        OrderAddressSet memory orderAddressSet,
        OrderContext memory orderContext
    )
        internal
        view
        returns (OrderInfo memory orderInfo)
    {
        require(
            getOrderVersion(orderParam.data) == SUPPORTED_ORDER_VERSION,
            ORDER_VERSION_NOT_SUPPORTED
        );

        Order memory order = getOrderFromOrderParam(orderParam, orderAddressSet);
        orderInfo.orderHash = getOrderHash(order);
        orderInfo.filledAmount = filled[orderInfo.orderHash];
        uint8 status = uint8(OrderStatus.FILLABLE);

        if (orderInfo.filledAmount >= order.amount) {
            status = uint8(OrderStatus.FULLY_FILLED);
        } else if (block.timestamp >= getExpiredAtFromOrderData(order.data)) {
            status = uint8(OrderStatus.EXPIRED);
        } else if (cancelled[orderInfo.orderHash]) {
            status = uint8(OrderStatus.CANCELLED);
        }

        require(status == uint8(OrderStatus.FILLABLE), ORDER_IS_NOT_FILLABLE);
        require(
            isValidSignature(orderInfo.orderHash, orderParam.trader, orderParam.signature),
            INVALID_ORDER_SIGNATURE
        );

        
        if (!isMarketOrder(orderParam.data)) {
            
            
            orderInfo.margins[LONG] = calculateLongMargin(orderContext, orderParam);
            orderInfo.margins[SHORT] = calculateShortMargin(orderContext, orderParam);
        }
        orderInfo.balances[LONG] = IERC20(orderContext.positions[LONG]).balanceOf(orderParam.trader);
        orderInfo.balances[SHORT] = IERC20(orderContext.positions[SHORT]).balanceOf(orderParam.trader);

        return orderInfo;
    }

    
    function getOrderFromOrderParam(
        OrderParam memory orderParam,
        OrderAddressSet memory orderAddressSet
    )
        internal
        pure
        returns (Order memory order)
    {
        order.trader = orderParam.trader;
        order.relayer = orderAddressSet.relayer;
        order.marketContractAddress = orderAddressSet.marketContractAddress;
        order.amount = orderParam.amount;
        order.price = orderParam.price;
        order.gasTokenAmount = orderParam.gasTokenAmount;
        order.data = orderParam.data;
    }

    
    function settleResult(
        MatchResult memory result,
        OrderAddressSet memory orderAddressSet,
        OrderContext memory orderContext
    )
        internal
    {
        if (result.fillAction == FillAction.REDEEM) {
            doRedeem(result, orderAddressSet, orderContext);
        } else if (result.fillAction == FillAction.SELL) {
            doSell(result, orderAddressSet, orderContext);
        } else if (result.fillAction == FillAction.BUY) {
            doBuy(result, orderAddressSet, orderContext);
        } else if (result.fillAction == FillAction.MINT) {
            doMint(result, orderAddressSet, orderContext);
        } else {
            revert("UNEXPECTED_FILLACTION");
        }
        emit Match(orderAddressSet, result);
    }

    function doSell(
        MatchResult memory result,
        OrderAddressSet memory orderAddressSet,
        OrderContext memory orderContext
    )
        internal
    {
        uint256 takerTotalFee = result.takerFee.add(result.takerGasFee);
        uint256 makerTotalFee = result.makerFee.add(result.makerGasFee);
        
        orderContext.positions[oppositeSide(orderContext.takerSide)]
            .safeTransferFrom(
                result.taker,
                result.maker,
                result.posFilledAmount
            );
        
        
        orderContext.collateral.safeTransferFrom(
            result.maker,
            orderAddressSet.relayer,
            result.ctkFilledAmount.add(makerTotalFee)
        );
        if (result.ctkFilledAmount > takerTotalFee) {
            
            orderContext.collateral.safeTransferFrom(
                orderAddressSet.relayer,
                result.taker,
                result.ctkFilledAmount.sub(takerTotalFee)
            );
        } else if (result.ctkFilledAmount < takerTotalFee) {
            
            orderContext.collateral.safeTransferFrom(
                result.taker,
                orderAddressSet.relayer,
                takerTotalFee.sub(result.ctkFilledAmount)
            );
        }

        
        
        
        
        
        
        
        
        
        
        
        
        
    }

    
    function doBuy(
        MatchResult memory result,
        OrderAddressSet memory orderAddressSet,
        OrderContext memory orderContext
    )
        internal
    {
        uint256 makerTotalFee = result.makerFee.add(result.makerGasFee);
        uint256 takerTotalFee = result.takerFee.add(result.takerGasFee);
        
        orderContext.positions[orderContext.takerSide]
            .safeTransferFrom(
                result.maker,
                result.taker,
                result.posFilledAmount
            );
        
        if (result.ctkFilledAmount > makerTotalFee) {
            
            orderContext.collateral.safeTransferFrom(
                result.taker,
                result.maker,
                result.ctkFilledAmount.sub(makerTotalFee)
            );
        } else if (result.ctkFilledAmount < makerTotalFee) {
            
            orderContext.collateral.safeTransferFrom(
                result.maker,
                result.taker,
                makerTotalFee.sub(result.ctkFilledAmount)
            );
        }
        
        orderContext.collateral.safeTransferFrom(
            result.taker,
            orderAddressSet.relayer,
            takerTotalFee.add(makerTotalFee)
        );

        
        
        
        
        
        
        
        
        
        
        
        
        
        
    }

    function oppositeSide(uint256 side) internal pure returns (uint256) {
        return side == LONG ? SHORT : LONG;
    }

    
    function doRedeem(
        MatchResult memory result,
        OrderAddressSet memory orderAddressSet,
        OrderContext memory orderContext
    )
        internal
    {
        uint256 makerTotalFee = result.makerFee.add(result.makerGasFee);
        uint256 takerTotalFee = result.takerFee.add(result.takerGasFee);
        uint256 collateralToTaker = orderContext.marketContract.COLLATERAL_PER_UNIT()
            .mul(result.posFilledAmount)
            .sub(result.ctkFilledAmount);

        
        
        orderContext.positions[oppositeSide(orderContext.takerSide)]
            .safeTransferFrom(
                result.taker,
                address(this),
                result.posFilledAmount
            );
        
        orderContext.positions[orderContext.takerSide]
            .safeTransferFrom(
                result.maker,
                address(this),
                result.posFilledAmount
            );
        
        redeemPositionTokens(orderContext, result.posFilledAmount);
        
        
        if (result.ctkFilledAmount > makerTotalFee) {
            
            orderContext.collateral.safeTransfer(
                result.maker,
                result.ctkFilledAmount.sub(makerTotalFee)
            );
        } else if (result.ctkFilledAmount < makerTotalFee) {
            
            orderContext.collateral.safeTransferFrom(
                result.maker,
                address(this),
                makerTotalFee.sub(result.ctkFilledAmount)
            );
        }
        
        if (collateralToTaker > takerTotalFee) {
            
            orderContext.collateral.safeTransfer(
                result.taker,
                collateralToTaker.sub(takerTotalFee)
            );
        } else if (collateralToTaker < takerTotalFee) {
            
            orderContext.collateral.safeTransferFrom(
                result.taker,
                address(this),
                takerTotalFee.sub(collateralToTaker)
            );
        }
        
        orderContext.collateral.safeTransfer(
            orderAddressSet.relayer,
            makerTotalFee.add(takerTotalFee)
        );
    }

    
    function doMint(
        MatchResult memory result,
        OrderAddressSet memory orderAddressSet,
        OrderContext memory orderContext
    )
        internal
    {
        
        uint256 neededCollateral = result.posFilledAmount
            .mul(orderContext.marketContract.COLLATERAL_PER_UNIT());
        uint256 neededCollateralTokenFee = result.posFilledAmount
            .mul(orderContext.marketContract.COLLATERAL_TOKEN_FEE_PER_UNIT());
        uint256 mintFee = result.takerFee.add(result.makerFee);
        uint256 feeToRelayer = result.takerGasFee.add(result.makerGasFee);
        
        if (neededCollateralTokenFee > mintFee) {
            orderContext.collateral.safeTransferFrom(
                orderAddressSet.relayer,
                address(this),
                neededCollateralTokenFee.sub(mintFee)
            );
        } else if (neededCollateralTokenFee < mintFee) {
            feeToRelayer = feeToRelayer.add(mintFee).sub(neededCollateralTokenFee);
        }
        
        
        orderContext.collateral.safeTransferFrom(
            result.maker,
            address(this),
            result.ctkFilledAmount
                .add(result.makerFee)
                .add(result.makerGasFee)
        );
        
        orderContext.collateral.safeTransferFrom(
            result.taker,
            address(this),
            neededCollateral
                .sub(result.ctkFilledAmount)
                .add(result.takerFee)
                .add(result.takerGasFee)
        );
        
        mintPositionTokens(orderContext, result.posFilledAmount);
        
        
        orderContext.positions[orderContext.takerSide]
            .safeTransfer(
                result.taker,
                result.posFilledAmount
            );
        
        orderContext.positions[oppositeSide(orderContext.takerSide)]
            .safeTransfer(
                result.maker,
                result.posFilledAmount
            );
        
        orderContext.collateral.safeTransfer(
            orderAddressSet.relayer,
            feeToRelayer
        );
    }

    
    
    
    function mintPositionTokens(OrderContext memory orderContext, uint256 qtyToMint)
        internal
    {
        IMarketContractPool collateralPool;
        if (mintingPoolAddress != address(0x0)) {
            collateralPool = IMarketContractPool(mintingPoolAddress);
        } else {
            collateralPool = orderContext.marketContractPool;
        }
        collateralPool.mintPositionTokens(address(orderContext.marketContract), qtyToMint, false);
    }

    
    
    
    function redeemPositionTokens(OrderContext memory orderContext, uint256 qtyToRedeem)
        internal
    {
        IMarketContractPool collateralPool;
        if (mintingPoolAddress != address(0x0)) {
            collateralPool = IMarketContractPool(mintingPoolAddress);
        } else {
            collateralPool = orderContext.marketContractPool;
        }
        collateralPool.redeemPositionTokens(address(orderContext.marketContract), qtyToRedeem);
    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"delegate","type":"address"}],"name":"approveDelegate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_MATCHES","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mintingPoolAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"relayer","type":"address"}],"name":"canMatchMarketContractOrdersFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"filled","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"cancelled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"relayerDelegates","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"exitIncentiveSystem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EIP712_ORDER_TYPE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LONG","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"components":[{"name":"trader","type":"address"},{"name":"relayer","type":"address"},{"name":"marketContractAddress","type":"address"},{"name":"amount","type":"uint256"},{"name":"price","type":"uint256"},{"name":"gasTokenAmount","type":"uint256"},{"name":"data","type":"bytes32"}],"name":"order","type":"tuple"}],"name":"cancelOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"FEE_RATE_BASE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"REBATE_RATE_BASE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_mintingPoolAddress","type":"address"}],"name":"setMintingPool","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"components":[{"name":"trader","type":"address"},{"name":"amount","type":"uint256"},{"name":"price","type":"uint256"},{"name":"gasTokenAmount","type":"uint256"},{"name":"data","type":"bytes32"},{"components":[{"name":"config","type":"bytes32"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"signature","type":"tuple"}],"name":"takerOrderParam","type":"tuple"},{"components":[{"name":"trader","type":"address"},{"name":"amount","type":"uint256"},{"name":"price","type":"uint256"},{"name":"gasTokenAmount","type":"uint256"},{"name":"data","type":"bytes32"},{"components":[{"name":"config","type":"bytes32"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"signature","type":"tuple"}],"name":"makerOrderParams","type":"tuple[]"},{"name":"posFilledAmounts","type":"uint256[]"},{"components":[{"name":"marketContractAddress","type":"address"},{"name":"relayer","type":"address"}],"name":"orderAddressSet","type":"tuple"}],"name":"matchMarketContractOrders","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"relayer","type":"address"}],"name":"isParticipant","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"}],"name":"withdrawERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SHORT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"spender","type":"address"},{"name":"amount","type":"uint256"}],"name":"approveERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_marketRegistryAddress","type":"address"}],"name":"setMarketRegistryAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"joinIncentiveSystem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SUPPORTED_ORDER_VERSION","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EIP712_DOMAIN_TYPEHASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"marketRegistryAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"delegate","type":"address"}],"name":"revokeDelegate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"components":[{"name":"marketContractAddress","type":"address"},{"name":"relayer","type":"address"}],"indexed":false,"name":"addressSet","type":"tuple"},{"components":[{"name":"maker","type":"address"},{"name":"taker","type":"address"},{"name":"makerFee","type":"uint256"},{"name":"takerFee","type":"uint256"},{"name":"makerGasFee","type":"uint256"},{"name":"takerGasFee","type":"uint256"},{"name":"posFilledAmount","type":"uint256"},{"name":"ctkFilledAmount","type":"uint256"},{"name":"fillAction","type":"uint8"}],"indexed":false,"name":"result","type":"tuple"}],"name":"Match","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderHash","type":"bytes32"}],"name":"Cancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenAddress","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenAddress","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relayer","type":"address"},{"indexed":true,"name":"delegate","type":"address"}],"name":"RelayerApproveDelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relayer","type":"address"},{"indexed":true,"name":"delegate","type":"address"}],"name":"RelayerRevokeDelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relayer","type":"address"}],"name":"RelayerExit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relayer","type":"address"}],"name":"RelayerJoin","type":"event"}]

7f454950373132446f6d61696e28737472696e67206e616d65290000000000000060a0526019608052600c60b9527f4d61692050726f746f636f6c000000000000000000000000000000000000000060d9527fb2178a58fb1eefb359ecfdd57bb19c0bdd0f4e6eed8547f46600e500ed111af3610119527fd9dd2eed8751af214e5841ee198a64943839835c8fbe48995fc2fb3d322f362861013952604060f9819052610159908190527f4bf67a92331f9543ab43d10e3a08b582abd57f9f32f07724559d64f62b2df379600090815560038054600160a060020a031916331790819055600160a060020a0316917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3613ebf806101216000396000f3fe608060405234801561001057600080fd5b50600436106101de5760003560e060020a90048063715018a611610108578063a8e5e4aa116100a6578063c7977be711610075578063c7977be714610361578063e4d00ec314610369578063f2fde38b14610371578063fa352c0014610384576101de565b8063a8e5e4aa14610333578063aadf9dcb14610346578063b875bdf114610359578063c1e31de91461032b576101de565b80638f32d59b116100e25780638f32d59b146102fd578063929066f514610305578063a1db978214610318578063a871da911461032b576101de565b8063715018a6146102da57806385fd27d0146102e25780638da5cb5b146102f5576101de565b80633560c5cd116101805780635a4e1e491161014f5780635a4e1e49146102a457806361c3efb1146102b757806363aaf8ec146102bf57806364283ad6146102c7576101de565b80633560c5cd146102845780633644e5151461028c5780635373a19114610294578063561cce0a1461029c576101de565b806320f9196f116101bc57806320f9196f1461022b578063288cdc911461024b5780632ac126221461025e57806331d4844714610271576101de565b806306df453e146101e35780630cac088b146101f8578063196eeed314610216575b600080fd5b6101f66101f13660046135a4565b610397565b005b6102006103f2565b60405161020d9190613c27565b60405180910390f35b61021e6103f7565b60405161020d9190613b85565b61023e6102393660046135a4565b610406565b60405161020d9190613c19565b6102006102593660046136b5565b61044c565b61023e61026c3660046136b5565b61045e565b61023e61027f3660046135e0565b610473565b6101f6610493565b6102006104d5565b6102006104db565b610200610507565b6101f66102b2366004613768565b61050c565b6102006105ed565b6102006105f4565b6101f66102d53660046135a4565b6105f9565b6101f6610651565b6101f66102f03660046136d3565b6106d1565b61021e6107cd565b61023e6107dc565b61023e6103133660046135a4565b6107ed565b6101f6610326366004613667565b61080c565b6102006108f7565b6101f661034136600461361a565b6108fc565b6101f66103543660046135a4565b61098f565b6101f66109e7565b610200610a26565b61021e610a70565b6101f661037f3660046135a4565b610a7f565b6101f66103923660046135a4565b610b3c565b336000818152600160208181526040808420600160a060020a0387168086529252808420805460ff191690931790925590519092917f7fa92f6e23fcdb0b7a7001ea137560a8ebee9b8302d16e3b37c64ae7116b69ad91a350565b600381565b600554600160a060020a031681565b600033600160a060020a03831614806104465750600160a060020a03821660009081526001602081815260408084203385529091529091205460ff161515145b92915050565b60066020526000908152604090205481565b60076020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b33600081815260026020526040808220805460ff19166001179055517f9bdfcd96a99ab6dad403b4ef4562bb3471fdeaab5e699160abf7c3f2cbe668059190a2565b60005481565b604051602001806084613ddf823960840190506040516020818303038152906040528051906020012081565b600081565b8051600160a060020a031633148061053957508060200151600160a060020a031633600160a060020a0316145b60408051808201909152600e81527f494e56414c49445f54524144455200000000000000000000000000000000000060208201529015156105995760405160e560020a62461bcd0281526004016105909190613c35565b60405180910390fd5b5060006105a582610b92565b600081815260076020526040808220805460ff191660011790555191925082917fe8d9861dbc9c663ed3accd261bbe2fe01e0d3d9e5f51fa38523b265c7757a93a9190a25050565b620186a081565b606481565b6106016107dc565b15156106225760405160e560020a62461bcd02815260040161059090613cb6565b6005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6106596107dc565b151561067a5760405160e560020a62461bcd02815260040161059090613cb6565b600354604051600091600160a060020a0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36003805473ffffffffffffffffffffffffffffffffffffffff19169055565b6106de8160200151610406565b60408051808201909152600e81527f494e56414c49445f53454e44455200000000000000000000000000000000000060208201529015156107355760405160e560020a62461bcd0281526004016105909190613c35565b506107438460800151610ba5565b6040805180820190915260208082527f4d414b45525f4f4e4c595f4f524445525f43414e4e4f545f42455f54414b45529082015290156107995760405160e560020a62461bcd0281526004016105909190613c35565b5080516107a590610bc6565b6107ad61316e565b6107b78286610cd4565b90506107c68585858585610f78565b5050505050565b600354600160a060020a031690565b600354600160a060020a0316331490565b600160a060020a031660009081526002602052604090205460ff161590565b6108146107dc565b15156108355760405160e560020a62461bcd02815260040161059090613cb6565b60408051808201909152600a81527f4c4f575f4d415247494e0000000000000000000000000000000000000000000060208201526000821161088d5760405160e560020a62461bcd0281526004016105909190613c35565b506108a8600160a060020a038316338363ffffffff61127f16565b33600160a060020a031682600160a060020a03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb836040516108eb9190613c27565b60405180910390a35050565b600181565b6109046107dc565b15156109255760405160e560020a62461bcd02815260040161059090613cb6565b61093f600160a060020a038416838363ffffffff61131e16565b81600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516109829190613c27565b60405180910390a3505050565b6109976107dc565b15156109b85760405160e560020a62461bcd02815260040161059090613cb6565b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b33600081815260026020526040808220805460ff19169055517fc3dd8edec722273de2ffd31b47b4f106689ae891ac1bfddf7ae6190589ab0f679190a2565b60405160200180807f454950373132446f6d61696e28737472696e67206e616d65290000000000000081525060190190506040516020818303038152906040528051906020012081565b600454600160a060020a031681565b610a876107dc565b1515610aa85760405160e560020a62461bcd02815260040161059090613cb6565b600160a060020a0381161515610ad35760405160e560020a62461bcd02815260040161059090613ca6565b600354604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b336000818152600160209081526040808320600160a060020a0386168085529252808320805460ff19169055519092917fa6568d7ca1ae4c87043ca12f90308b8ef94330ee3a047c2101e1a40812d26c9891a350565b6000610446610ba08361141b565b611464565b60008160165b1a60f860020a0260f860020a900460ff166001149050919050565b600454600160a060020a03161515610bdd57610cd1565b600480546040517fad23de63000000000000000000000000000000000000000000000000000000008152600160a060020a0390911691829163ad23de6391610c2791869101613b85565b60206040518083038186803b158015610c3f57600080fd5b505afa158015610c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c779190810190613697565b60408051808201909152601781527f494e56414c49445f4d41524b45545f434f4e54524143540000000000000000006020820152901515610cce5760405160e560020a62461bcd0281526004016105909190613c35565b50505b50565b610cdc61316e565b8251600160a060020a0316808252604080517feaafb4fa000000000000000000000000000000000000000000000000000000008152905163eaafb4fa91600480820192602092909190829003018186803b158015610d3957600080fd5b505afa158015610d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d7191908101906135c2565b8160200190600160a060020a03169081600160a060020a0316815250508060000151600160a060020a031663323bb7756040518163ffffffff1660e060020a02815260040160206040518083038186803b158015610dce57600080fd5b505afa158015610de2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e0691908101906135c2565b8160400190600160a060020a03169081600160a060020a0316815250508060000151600160a060020a03166322d1c35e6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015610e6357600080fd5b505afa158015610e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e9b91908101906135c2565b6060820151600160a060020a0391821690528151604080517f5b3f1e3f00000000000000000000000000000000000000000000000000000000815290519190921691635b3f1e3f916004808301926020929190829003018186803b158015610f0257600080fd5b505afa158015610f16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f3a91908101906135c2565b6060820151600160a060020a03919091166020909101526080820151610f5f906114bd565b610f6a576000610f6d565b60015b608082015292915050565b610f806131a4565b610f8b8684846114c7565b905060005b855181101561126057610fbd8682815181101515610faa57fe5b9060200190602002015160800151611810565b1560606040519081016040528060238152602001613e6360239139901515610ffb5760405160e560020a62461bcd0281526004016105909190613c35565b50611020868281518110151561100d57fe5b90602001906020020151608001516114bd565b151561102f88608001516114bd565b60408051808201909152600c81527f494e56414c49445f53494445000000000000000000000000000000000000000060208201529190151514156110895760405160e560020a62461bcd0281526004016105909190613c35565b50858181518110151561109857fe5b602090810290910181015151885160408051808201909152601581527f4d414b45525f43414e4e4f545f42455f54414b4552000000000000000000000093810193909352600160a060020a039081169116141561110b5760405160e560020a62461bcd0281526004016105909190613c35565b506111146131a4565b611136878381518110151561112557fe5b9060200190602002015186866114c7565b905061115988888481518110151561114a57fe5b9060200190602002015161181a565b6000868381518110151561116957fe5b60209081029091010151905060005b6003811080156111885750600082115b156111e8576111956131d5565b60006111bc8c888d898151811015156111aa57fe5b90602001906020020151888c89611909565b90925090506111d1848263ffffffff611a7616565b93506111de828a8a611aa1565b5050600101611178565b5060408051808201909152600e81527f554e4d4154434845445f46494c4c0000000000000000000000000000000000006020820152811561123f5760405160e560020a62461bcd0281526004016105909190613c35565b50506020808201519151600090815260069091526040902055600101610f90565b5060208082015191516000908152600690915260409020555050505050565b604051610cce9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906112ba9086908690602401613bd6565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611b8f565b8015806113bf57506040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a0384169063dd62ed3e9061136d9030908690600401613b93565b60206040518083038186803b15801561138557600080fd5b505afa158015611399573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113bd9190810190613786565b155b15156113e05760405160e560020a62461bcd02815260040161059090613ce6565b604051610cce9084907f095ea7b300000000000000000000000000000000000000000000000000000000906112ba9086908690602401613bd6565b6000806040516020018080613ddf6084913960408051606481840301815260849290920190528051602090910120601f1985018051918152610100812091905292505050919050565b600054604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091526022820193909352604280820194909452815180820390940184526062019052815191012090565b6000816001610bab565b6114cf6131a4565b60016114de8560800151611cd3565b60408051808201909152601b81527f4f524445525f56455253494f4e5f4e4f545f535550504f525445440000000000602082015291146115345760405160e560020a62461bcd0281526004016105909190613c35565b5061153d613239565b6115478585611ce0565b905061155281610b92565b8083526000908152600660209081526040909120549083018190526060820151600291106115845760035b90506115bb565b6115918260c00151611d3d565b421061159e57600061157d565b825160009081526007602052604090205460ff16156115bb575060015b60408051808201909152601581527f4f524445525f49535f4e4f545f46494c4c41424c450000000000000000000000602082015260ff82166002146116165760405160e560020a62461bcd0281526004016105909190613c35565b508251865160a088015161162b929190611d6e565b60408051808201909152601781527f494e56414c49445f4f524445525f5349474e415455524500000000000000000060208201529015156116825760405160e560020a62461bcd0281526004016105909190613c35565b506116908660800151611810565b15156116ba576116a08487611ef6565b6040840151526116b0848761200b565b6040840151602001525b60608401515186516040517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a03909216916370a082319161170691600401613b85565b60206040518083038186803b15801561171e57600080fd5b505afa158015611732573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117569190810190613786565b606084810151919091528401516020015186516040517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a03909216916370a08231916117ad91600401613b85565b60206040518083038186803b1580156117c557600080fd5b505afa1580156117d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117fd9190810190613786565b60608401516020015250505b9392505050565b6000816002610bab565b6118278260800151611810565b1561183157611905565b61183e82608001516114bd565b156118a757604080820151838201518251808401909352600d83527f494e56414c49445f4d4154434800000000000000000000000000000000000000602084015211156118a15760405160e560020a62461bcd0281526004016105909190613c35565b50611905565b604080820151838201518251808401909352600d83527f494e56414c49445f4d415443480000000000000000000000000000000000000060208401521015610cce5760405160e560020a62461bcd0281526004016105909190613c35565b5050565b6119116131d5565b60008560200151856020015111156040805190810160405280601681526020017f4d414b45525f4f524445525f4f5645525f4d41544348000000000000000000008152509015156119785760405160e560020a62461bcd0281526004016105909190613c35565b508760200151876020015111156040805190810160405280601681526020017f54414b45525f4f524445525f4f5645525f4d41544348000000000000000000008152509015156119de5760405160e560020a62461bcd0281526004016105909190613c35565b50602087015115156119f557606088015160a08301525b60208501511515611a0b57606086015160808301525b611a1a82898989898989612114565b60c083018190529050611a3d611a3085886125fe565b829063ffffffff61264416565b6040830152611a4f611a30858a612685565b60608301528751600160a060020a0390811660208401528651168252965096945050505050565b600082821115611a9b5760405160e560020a62461bcd02815260040161059090613c76565b50900390565b60048361010001516004811115611ab457fe5b1415611aca57611ac58383836126aa565b611b51565b60028361010001516004811115611add57fe5b1415611aee57611ac58383836128e5565b60018361010001516004811115611b0157fe5b1415611b1257611ac58383836129ea565b60038361010001516004811115611b2557fe5b1415611b3657611ac5838383612ad0565b60405160e560020a62461bcd02815260040161059090613cc6565b7f5666e33345832897d888a15af5670674266cf01e5cd1c3deef480fc606dbf4818284604051611b82929190613d06565b60405180910390a1505050565b611ba182600160a060020a0316612d9c565b1515611bc25760405160e560020a62461bcd02815260040161059090613cf6565b6000606083600160a060020a0316836040518082805190602001908083835b60208310611c005780518252601f199092019160209182019101611be1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611c62576040519150601f19603f3d011682016040523d82523d6000602084013e611c67565b606091505b5091509150811515611c8e5760405160e560020a62461bcd02815260040161059090613c56565b600081511115611ccd5780806020019051611cac9190810190613697565b1515611ccd5760405160e560020a62461bcd02815260040161059090613cd6565b50505050565b60f860020a900460ff1690565b611ce8613239565b8251600160a060020a03908116825260208084015182168184015292511660408083019190915291830151606080830191909152918301516080808301919091529183015160a082015291015160c082015290565b64ffffffffff7b01000000000000000000000000000000000000000000000000000000630100000083020416919050565b805160009060f860020a600182901a810281900491839190821a81020460ff83161515611e595760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182815260200191505060405160208183030381529060405280519060200120828760200151886040015160405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611e48573d6000803e3d6000fd5b505050602060405103519150611edd565b60ff831660011415611ec2576020808601516040808801518151600081528085018084528c905260ff861681840152606081019390935260808301525160019260a0808401939192601f1981019281900390910190855afa158015611e48573d6000803e3d6000fd5b60405160e560020a62461bcd02815260040161059090613c66565b50600160a060020a038581169116149150509392505050565b60006118098360000151600160a060020a031663ca361d676040518163ffffffff1660e060020a02815260040160206040518083038186803b158015611f3b57600080fd5b505afa158015611f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f739190810190613786565b611fff8560000151600160a060020a031663c32b1dfa6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015611fb657600080fd5b505afa158015611fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fee9190810190613786565b60408601519063ffffffff611a7616565b9063ffffffff61264416565b60006118098360000151600160a060020a031663ca361d676040518163ffffffff1660e060020a02815260040160206040518083038186803b15801561205057600080fd5b505afa158015612064573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120889190810190613786565b611fff84604001518660000151600160a060020a031663b5471dee6040518163ffffffff1660e060020a02815260040160206040518083038186803b1580156120d057600080fd5b505afa1580156120e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121089190810190613786565b9063ffffffff611a7616565b60808201516000908161212682612da4565b9050600088606001518260028110151561213c57fe5b602002015111801561216357506060860151600090836002811061215c57fe5b6020020151115b15612257576121a561218b89606001518360028110151561218057fe5b602002015186612dbb565b6060880151846002811061219b57fe5b6020020151612dbb565b92506121ce838960600151836002811015156121bd57fe5b60200201519063ffffffff611a7616565b606089015182600281106121de57fe5b602002015260608601516121f990849084600281106121bd57fe5b6060870151836002811061220957fe5b60200201526101008a0160045b9081600481111561222357fe5b905250604086015161224d908490846002811061223c57fe5b60200201519063ffffffff61264416565b60e08b01526124e9565b6060880151600090826002811061226a57fe5b602002015111801561228e57506060860151826002811061228757fe5b6020020151155b156123495760608801516122b29082600281106122a757fe5b602002015185612dbb565b92506122ca838960600151836002811015156121bd57fe5b606089015182600281106122da57fe5b6020020152606086015161230690849083600281106122f557fe5b60200201519063ffffffff612dd116565b6060870151826002811061231657fe5b60200201526101008a0160025b9081600481111561233057fe5b905250604086015161224d908490836002811061223c57fe5b6060880151816002811061235957fe5b602002015115801561238057506060860151600090836002811061237957fe5b6020020151115b156123fd5760608601516123999083600281106122a757fe5b92506123b1838960600151846002811015156122f557fe5b606089015183600281106123c157fe5b602002015260608601516123dc90849084600281106121bd57fe5b606087015183600281106123ec57fe5b60200201526101008a016001612216565b6060880151816002811061240d57fe5b602002015115801561243157506060860151826002811061242a57fe5b6020020151155b1561249b5783925061244f838960600151846002811015156122f557fe5b6060890151836002811061245f57fe5b6020020152606086015161247a90849083600281106122f557fe5b6060870151826002811061248a57fe5b60200201526101008a016003612323565b604080518082018252601081527f554e45585045435445445f4d41544348000000000000000000000000000000006020820152905160e560020a62461bcd0281526105909190600401613c35565b60208801516124fe908463ffffffff612dd116565b6020808a019190915286015161251a908463ffffffff612dd116565b602080880191909152898101518982015160408051808201909152601681527f54414b45525f4f524445525f4f5645525f4d41544348000000000000000000009381019390935211156125835760405160e560020a62461bcd0281526004016105909190613c35565b508660200151866020015111156040805190810160405280601681526020017f4d414b45525f4f524445525f4f5645525f4d41544348000000000000000000008152509015156125e95760405160e560020a62461bcd0281526004016105909190613c35565b50505060c08801819052979650505050505050565b60008061260a84612df9565b905061263c620186a06126306126238660800151612f6e565b849063ffffffff61264416565b9063ffffffff612fa416565b949350505050565b600082151561265557506000610446565b82820282848281151561266457fe5b04146118095760405160e560020a62461bcd02815260040161059090613c96565b60008061269184612df9565b905061263c620186a06126306126238660800151612fde565b60006126c784608001518560400151612dd190919063ffffffff16565b905060006126e68560a001518660600151612dd190919063ffffffff16565b905060006127728660e001516121088860c001518760000151600160a060020a031663e158e02d6040518163ffffffff1660e060020a02815260040160206040518083038186803b15801561273a57600080fd5b505afa15801561274e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fff9190810190613786565b90506127ba8660200151308860c0015187606001516127948960800151612da4565b6002811061279e57fe5b6020020151600160a060020a031692919063ffffffff61301616565b6127de8660000151308860c001518760600151886080015160028110151561279e57fe5b6127ec848760c00151613053565b828660e00151111561283457855160e087015161282f9190612814908663ffffffff611a7616565b6040870151600160a060020a0316919063ffffffff61127f16565b61287c565b828660e00151101561287c5761287c8660000151306128608960e0015187611a7690919063ffffffff16565b6040880151600160a060020a031692919063ffffffff61301616565b818111156128a257602086015161289d90612814838563ffffffff611a7616565b6128c4565b818110156128c45760208601516128c49030612860858563ffffffff611a7616565b60208501516128dd90612814858563ffffffff612dd116565b505050505050565b60006129028460a001518560600151612dd190919063ffffffff16565b9050600061292185608001518660400151612dd190919063ffffffff16565b9050612947856020015186600001518760c0015186606001516127948860800151612da4565b8451602085015160e0870151612985929190612969908563ffffffff612dd116565b6040870151600160a060020a031692919063ffffffff61301616565b818560e0015111156129ba576129b584602001518660200151612969858960e00151611a7690919063ffffffff16565b6107c6565b818560e0015110156107c6576107c6856020015185602001516129698860e0015186611a7690919063ffffffff16565b6000612a0784608001518560400151612dd190919063ffffffff16565b90506000612a268560a001518660600151612dd190919063ffffffff16565b8551602087015160c088015160608701516080880151949550612a4d946002811061279e57fe5b818560e001511115612a80576020850151855160e0870151612a7b929190612969908663ffffffff611a7616565b612ab0565b818560e001511015612ab057612ab0856000015186602001516129698860e0015186611a7690919063ffffffff16565b6107c6856020015185602001516129698585612dd190919063ffffffff16565b6000612b5e8260000151600160a060020a031663e158e02d6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612b1557600080fd5b505afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612b4d9190810190613786565b60c08601519063ffffffff61264416565b90506000612bee8360000151600160a060020a0316635c7c70596040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612ba557600080fd5b505afa158015612bb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bdd9190810190613786565b60c08701519063ffffffff61264416565b90506000612c0d86604001518760600151612dd190919063ffffffff16565b90506000612c2c87608001518860a00151612dd190919063ffffffff16565b905081831115612c71576020860151612c6c9030612c50868663ffffffff611a7616565b6040890151600160a060020a031692919063ffffffff61301616565b612c90565b81831015612c9057612c8d83612108838563ffffffff612dd116565b90505b612cc8876000015130612c508a60800151612cbc8c604001518d60e00151612dd190919063ffffffff16565b9063ffffffff612dd116565b612cf8876020015130612c508a60a00151612cbc8c60600151612cbc8e60e001518c611a7690919063ffffffff16565b612d06858860c001516130f6565b612d4487602001518860c0015187606001518860800151600281101515612d2957fe5b6020020151600160a060020a0316919063ffffffff61127f16565b612d6d87600001518860c001518760600151612d638960800151612da4565b60028110612d2957fe5b612d938660200151828760400151600160a060020a031661127f9092919063ffffffff16565b50505050505050565b6000903b1190565b60008115612db3576000610446565b506001919050565b6000818310612dca5781611809565b5090919050565b6000828201838110156118095760405160e560020a62461bcd02815260040161059090613c46565b600061044660026126308460000151600160a060020a031663ca361d676040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612e4357600080fd5b505afa158015612e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612e7b9190810190613786565b611fff8660000151600160a060020a031663c32b1dfa6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612ebe57600080fd5b505afa158015612ed2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ef69190810190613786565b8760000151600160a060020a031663b5471dee6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612f3657600080fd5b505afa158015612f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612cbc9190810190613786565b61ffff7e010000000000000000000000000000000000000000000000000000000000006801000000000000000083020416919050565b6000808211612fc85760405160e560020a62461bcd02815260040161059090613c86565b60008284811515612fd557fe5b04949350505050565b61ffff7e010000000000000000000000000000000000000000000000000000000000006a010000000000000000000083020416919050565b604051611ccd9085907f23b872dd00000000000000000000000000000000000000000000000000000000906112ba90879087908790602401613bae565b600554600090600160a060020a0316156130795750600554600160a060020a0316613080565b5060208201515b82516040517fc1b21411000000000000000000000000000000000000000000000000000000008152600160a060020a0383169163c1b21411916130c891908690600401613bd6565b600060405180830381600087803b1580156130e257600080fd5b505af1158015612d93573d6000803e3d6000fd5b600554600090600160a060020a03161561311c5750600554600160a060020a0316613123565b5060208201515b82516040517f125bb6a9000000000000000000000000000000000000000000000000000000008152600160a060020a0383169163125bb6a9916130c891908690600090600401613bf1565b6040805160c0810182526000808252602082018190529181019190915260608101613197613275565b8152602001600081525090565b6040805160c081018252600080825260208201529081016131c3613275565b81526020016131d0613275565b905290565b610120604051908101604052806000600160a060020a031681526020016000600160a060020a03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600060048111156131d057fe5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b60408051808201825290600290829080388339509192915050565b60006118098235613d6e565b60006118098251613d6e565b6000601f820183136132b957600080fd5b81356132cc6132c782613d49565b613d22565b91508181835260208401935060208101905083856101008402820111156132f257600080fd5b60005b83811015613321578161330888826133fa565b84525060209092019161010091909101906001016132f5565b5050505092915050565b6000601f8201831361333c57600080fd5b813561334a6132c782613d49565b9150818183526020840193506020810190508385602084028201111561336f57600080fd5b60005b83811015613321578161338588826133a7565b8452506020928301929190910190600101613372565b60006118098251613d79565b60006118098235613d7e565b6000604082840312156133c557600080fd5b6133cf6040613d22565b905060006133dd8484613290565b82525060206133ee84848301613290565b60208301525092915050565b6000610100828403121561340d57600080fd5b61341760c0613d22565b905060006134258484613290565b8252506020613436848483016133a7565b602083015250604061344a848285016133a7565b604083015250606061345e848285016133a7565b6060830152506080613472848285016133a7565b60808301525060a061348684828501613492565b60a08301525092915050565b6000606082840312156134a457600080fd5b6134ae6060613d22565b905060006134bc84846133a7565b82525060206134cd848483016133a7565b60208301525060406134e1848285016133a7565b60408301525092915050565b600060e082840312156134ff57600080fd5b61350960e0613d22565b905060006135178484613290565b825250602061352884848301613290565b602083015250604061353c84828501613290565b6040830152506060613550848285016133a7565b6060830152506080613564848285016133a7565b60808301525060a0613578848285016133a7565b60a08301525060c061358c848285016133a7565b60c08301525092915050565b60006118098251613d7e565b6000602082840312156135b657600080fd5b600061263c8484613290565b6000602082840312156135d457600080fd5b600061263c848461329c565b600080604083850312156135f357600080fd5b60006135ff8585613290565b925050602061361085828601613290565b9150509250929050565b60008060006060848603121561362f57600080fd5b600061363b8686613290565b935050602061364c86828701613290565b925050604061365d868287016133a7565b9150509250925092565b6000806040838503121561367a57600080fd5b60006136868585613290565b9250506020613610858286016133a7565b6000602082840312156136a957600080fd5b600061263c848461339b565b6000602082840312156136c757600080fd5b600061263c84846133a7565b60008060008061018085870312156136ea57600080fd5b60006136f687876133fa565b94505061010085013567ffffffffffffffff81111561371457600080fd5b613720878288016132a8565b93505061012085013567ffffffffffffffff81111561373e57600080fd5b61374a8782880161332b565b92505061014061375c878288016133b3565b91505092959194509250565b600060e0828403121561377a57600080fd5b600061263c84846134ed565b60006020828403121561379857600080fd5b600061263c8484613598565b6137ad81613d6e565b82525050565b6137ad81613d79565b6137ad81613d7e565b6137ad81613d9d565b60006137d982613d6a565b8084526137ed816020860160208601613da8565b6137f681613dd4565b9093016020019392505050565b601b81527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000602082015260400190565b60208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260400190565b601381527f494e56414c49445f5349474e5f4d4554484f4400000000000000000000000000602082015260400190565b601e81527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000602082015260400190565b601a81527f536166654d6174683a206469766973696f6e206279207a65726f000000000000602082015260400190565b602181527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60208201527f7700000000000000000000000000000000000000000000000000000000000000604082015260600190565b600d81527f494e56414c49445f4f574e455200000000000000000000000000000000000000602082015260400190565b600981527f4e4f545f4f574e45520000000000000000000000000000000000000000000000602082015260400190565b601581527f554e45585045435445445f46494c4c414354494f4e0000000000000000000000602082015260400190565b602a81527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60208201527f6f74207375636365656400000000000000000000000000000000000000000000604082015260600190565b603681527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60208201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000604082015260600190565b601f81527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400602082015260400190565b8051610120830190613ac784826137a4565b506020820151613ada60208501826137a4565b506040820151613aed60408501826137bc565b506060820151613b0060608501826137bc565b506080820151613b1360808501826137bc565b5060a0820151613b2660a08501826137bc565b5060c0820151613b3960c08501826137bc565b5060e0820151613b4c60e08501826137bc565b50610100820151611ccd6101008501826137c5565b80516040830190613b7284826137a4565b506020820151611ccd60208501826137a4565b6020810161044682846137a4565b60408101613ba182856137a4565b61180960208301846137a4565b60608101613bbc82866137a4565b613bc960208301856137a4565b61263c60408301846137bc565b60408101613be482856137a4565b61180960208301846137bc565b60608101613bff82866137a4565b613c0c60208301856137bc565b61263c60408301846137b3565b6020810161044682846137b3565b6020810161044682846137bc565b6020808252810161180981846137ce565b6020808252810161044681613803565b6020808252810161044681613833565b6020808252810161044681613863565b6020808252810161044681613893565b60208082528101610446816138c3565b60208082528101610446816138f3565b6020808252810161044681613949565b6020808252810161044681613979565b60208082528101610446816139a9565b60208082528101610446816139d9565b6020808252810161044681613a2f565b6020808252810161044681613a85565b6101608101613d158285613b61565b6118096040830184613ab5565b60405181810167ffffffffffffffff81118282101715613d4157600080fd5b604052919050565b600067ffffffffffffffff821115613d6057600080fd5b5060209081020190565b5190565b600061044682613d91565b151590565b90565b600060058210613d8d57fe5b5090565b600160a060020a031690565b600061044682613d81565b60005b83811015613dc3578181015183820152602001613dab565b83811115611ccd5750506000910152565b601f01601f19169056fe4f726465722861646472657373207472616465722c616464726573732072656c617965722c61646472657373206d61726b6574436f6e7472616374416464726573732c75696e7432353620616d6f756e742c75696e743235362070726963652c75696e7432353620676173546f6b656e416d6f756e742c627974657333322064617461294d414b45525f4f524445525f43414e5f4e4f545f42455f4d41524b45545f4f52444552a265627a7a72305820c604f26f79328a69aa655e95cea7af2e9177b3cbc22fe884d27c364bf1805dc26c6578706572696d656e74616cf50037

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101de5760003560e060020a90048063715018a611610108578063a8e5e4aa116100a6578063c7977be711610075578063c7977be714610361578063e4d00ec314610369578063f2fde38b14610371578063fa352c0014610384576101de565b8063a8e5e4aa14610333578063aadf9dcb14610346578063b875bdf114610359578063c1e31de91461032b576101de565b80638f32d59b116100e25780638f32d59b146102fd578063929066f514610305578063a1db978214610318578063a871da911461032b576101de565b8063715018a6146102da57806385fd27d0146102e25780638da5cb5b146102f5576101de565b80633560c5cd116101805780635a4e1e491161014f5780635a4e1e49146102a457806361c3efb1146102b757806363aaf8ec146102bf57806364283ad6146102c7576101de565b80633560c5cd146102845780633644e5151461028c5780635373a19114610294578063561cce0a1461029c576101de565b806320f9196f116101bc57806320f9196f1461022b578063288cdc911461024b5780632ac126221461025e57806331d4844714610271576101de565b806306df453e146101e35780630cac088b146101f8578063196eeed314610216575b600080fd5b6101f66101f13660046135a4565b610397565b005b6102006103f2565b60405161020d9190613c27565b60405180910390f35b61021e6103f7565b60405161020d9190613b85565b61023e6102393660046135a4565b610406565b60405161020d9190613c19565b6102006102593660046136b5565b61044c565b61023e61026c3660046136b5565b61045e565b61023e61027f3660046135e0565b610473565b6101f6610493565b6102006104d5565b6102006104db565b610200610507565b6101f66102b2366004613768565b61050c565b6102006105ed565b6102006105f4565b6101f66102d53660046135a4565b6105f9565b6101f6610651565b6101f66102f03660046136d3565b6106d1565b61021e6107cd565b61023e6107dc565b61023e6103133660046135a4565b6107ed565b6101f6610326366004613667565b61080c565b6102006108f7565b6101f661034136600461361a565b6108fc565b6101f66103543660046135a4565b61098f565b6101f66109e7565b610200610a26565b61021e610a70565b6101f661037f3660046135a4565b610a7f565b6101f66103923660046135a4565b610b3c565b336000818152600160208181526040808420600160a060020a0387168086529252808420805460ff191690931790925590519092917f7fa92f6e23fcdb0b7a7001ea137560a8ebee9b8302d16e3b37c64ae7116b69ad91a350565b600381565b600554600160a060020a031681565b600033600160a060020a03831614806104465750600160a060020a03821660009081526001602081815260408084203385529091529091205460ff161515145b92915050565b60066020526000908152604090205481565b60076020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b33600081815260026020526040808220805460ff19166001179055517f9bdfcd96a99ab6dad403b4ef4562bb3471fdeaab5e699160abf7c3f2cbe668059190a2565b60005481565b604051602001806084613ddf823960840190506040516020818303038152906040528051906020012081565b600081565b8051600160a060020a031633148061053957508060200151600160a060020a031633600160a060020a0316145b60408051808201909152600e81527f494e56414c49445f54524144455200000000000000000000000000000000000060208201529015156105995760405160e560020a62461bcd0281526004016105909190613c35565b60405180910390fd5b5060006105a582610b92565b600081815260076020526040808220805460ff191660011790555191925082917fe8d9861dbc9c663ed3accd261bbe2fe01e0d3d9e5f51fa38523b265c7757a93a9190a25050565b620186a081565b606481565b6106016107dc565b15156106225760405160e560020a62461bcd02815260040161059090613cb6565b6005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6106596107dc565b151561067a5760405160e560020a62461bcd02815260040161059090613cb6565b600354604051600091600160a060020a0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36003805473ffffffffffffffffffffffffffffffffffffffff19169055565b6106de8160200151610406565b60408051808201909152600e81527f494e56414c49445f53454e44455200000000000000000000000000000000000060208201529015156107355760405160e560020a62461bcd0281526004016105909190613c35565b506107438460800151610ba5565b6040805180820190915260208082527f4d414b45525f4f4e4c595f4f524445525f43414e4e4f545f42455f54414b45529082015290156107995760405160e560020a62461bcd0281526004016105909190613c35565b5080516107a590610bc6565b6107ad61316e565b6107b78286610cd4565b90506107c68585858585610f78565b5050505050565b600354600160a060020a031690565b600354600160a060020a0316331490565b600160a060020a031660009081526002602052604090205460ff161590565b6108146107dc565b15156108355760405160e560020a62461bcd02815260040161059090613cb6565b60408051808201909152600a81527f4c4f575f4d415247494e0000000000000000000000000000000000000000000060208201526000821161088d5760405160e560020a62461bcd0281526004016105909190613c35565b506108a8600160a060020a038316338363ffffffff61127f16565b33600160a060020a031682600160a060020a03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb836040516108eb9190613c27565b60405180910390a35050565b600181565b6109046107dc565b15156109255760405160e560020a62461bcd02815260040161059090613cb6565b61093f600160a060020a038416838363ffffffff61131e16565b81600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516109829190613c27565b60405180910390a3505050565b6109976107dc565b15156109b85760405160e560020a62461bcd02815260040161059090613cb6565b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b33600081815260026020526040808220805460ff19169055517fc3dd8edec722273de2ffd31b47b4f106689ae891ac1bfddf7ae6190589ab0f679190a2565b60405160200180807f454950373132446f6d61696e28737472696e67206e616d65290000000000000081525060190190506040516020818303038152906040528051906020012081565b600454600160a060020a031681565b610a876107dc565b1515610aa85760405160e560020a62461bcd02815260040161059090613cb6565b600160a060020a0381161515610ad35760405160e560020a62461bcd02815260040161059090613ca6565b600354604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b336000818152600160209081526040808320600160a060020a0386168085529252808320805460ff19169055519092917fa6568d7ca1ae4c87043ca12f90308b8ef94330ee3a047c2101e1a40812d26c9891a350565b6000610446610ba08361141b565b611464565b60008160165b1a60f860020a0260f860020a900460ff166001149050919050565b600454600160a060020a03161515610bdd57610cd1565b600480546040517fad23de63000000000000000000000000000000000000000000000000000000008152600160a060020a0390911691829163ad23de6391610c2791869101613b85565b60206040518083038186803b158015610c3f57600080fd5b505afa158015610c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c779190810190613697565b60408051808201909152601781527f494e56414c49445f4d41524b45545f434f4e54524143540000000000000000006020820152901515610cce5760405160e560020a62461bcd0281526004016105909190613c35565b50505b50565b610cdc61316e565b8251600160a060020a0316808252604080517feaafb4fa000000000000000000000000000000000000000000000000000000008152905163eaafb4fa91600480820192602092909190829003018186803b158015610d3957600080fd5b505afa158015610d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d7191908101906135c2565b8160200190600160a060020a03169081600160a060020a0316815250508060000151600160a060020a031663323bb7756040518163ffffffff1660e060020a02815260040160206040518083038186803b158015610dce57600080fd5b505afa158015610de2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e0691908101906135c2565b8160400190600160a060020a03169081600160a060020a0316815250508060000151600160a060020a03166322d1c35e6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015610e6357600080fd5b505afa158015610e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e9b91908101906135c2565b6060820151600160a060020a0391821690528151604080517f5b3f1e3f00000000000000000000000000000000000000000000000000000000815290519190921691635b3f1e3f916004808301926020929190829003018186803b158015610f0257600080fd5b505afa158015610f16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f3a91908101906135c2565b6060820151600160a060020a03919091166020909101526080820151610f5f906114bd565b610f6a576000610f6d565b60015b608082015292915050565b610f806131a4565b610f8b8684846114c7565b905060005b855181101561126057610fbd8682815181101515610faa57fe5b9060200190602002015160800151611810565b1560606040519081016040528060238152602001613e6360239139901515610ffb5760405160e560020a62461bcd0281526004016105909190613c35565b50611020868281518110151561100d57fe5b90602001906020020151608001516114bd565b151561102f88608001516114bd565b60408051808201909152600c81527f494e56414c49445f53494445000000000000000000000000000000000000000060208201529190151514156110895760405160e560020a62461bcd0281526004016105909190613c35565b50858181518110151561109857fe5b602090810290910181015151885160408051808201909152601581527f4d414b45525f43414e4e4f545f42455f54414b4552000000000000000000000093810193909352600160a060020a039081169116141561110b5760405160e560020a62461bcd0281526004016105909190613c35565b506111146131a4565b611136878381518110151561112557fe5b9060200190602002015186866114c7565b905061115988888481518110151561114a57fe5b9060200190602002015161181a565b6000868381518110151561116957fe5b60209081029091010151905060005b6003811080156111885750600082115b156111e8576111956131d5565b60006111bc8c888d898151811015156111aa57fe5b90602001906020020151888c89611909565b90925090506111d1848263ffffffff611a7616565b93506111de828a8a611aa1565b5050600101611178565b5060408051808201909152600e81527f554e4d4154434845445f46494c4c0000000000000000000000000000000000006020820152811561123f5760405160e560020a62461bcd0281526004016105909190613c35565b50506020808201519151600090815260069091526040902055600101610f90565b5060208082015191516000908152600690915260409020555050505050565b604051610cce9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906112ba9086908690602401613bd6565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611b8f565b8015806113bf57506040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a0384169063dd62ed3e9061136d9030908690600401613b93565b60206040518083038186803b15801561138557600080fd5b505afa158015611399573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113bd9190810190613786565b155b15156113e05760405160e560020a62461bcd02815260040161059090613ce6565b604051610cce9084907f095ea7b300000000000000000000000000000000000000000000000000000000906112ba9086908690602401613bd6565b6000806040516020018080613ddf6084913960408051606481840301815260849290920190528051602090910120601f1985018051918152610100812091905292505050919050565b600054604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091526022820193909352604280820194909452815180820390940184526062019052815191012090565b6000816001610bab565b6114cf6131a4565b60016114de8560800151611cd3565b60408051808201909152601b81527f4f524445525f56455253494f4e5f4e4f545f535550504f525445440000000000602082015291146115345760405160e560020a62461bcd0281526004016105909190613c35565b5061153d613239565b6115478585611ce0565b905061155281610b92565b8083526000908152600660209081526040909120549083018190526060820151600291106115845760035b90506115bb565b6115918260c00151611d3d565b421061159e57600061157d565b825160009081526007602052604090205460ff16156115bb575060015b60408051808201909152601581527f4f524445525f49535f4e4f545f46494c4c41424c450000000000000000000000602082015260ff82166002146116165760405160e560020a62461bcd0281526004016105909190613c35565b508251865160a088015161162b929190611d6e565b60408051808201909152601781527f494e56414c49445f4f524445525f5349474e415455524500000000000000000060208201529015156116825760405160e560020a62461bcd0281526004016105909190613c35565b506116908660800151611810565b15156116ba576116a08487611ef6565b6040840151526116b0848761200b565b6040840151602001525b60608401515186516040517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a03909216916370a082319161170691600401613b85565b60206040518083038186803b15801561171e57600080fd5b505afa158015611732573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117569190810190613786565b606084810151919091528401516020015186516040517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a03909216916370a08231916117ad91600401613b85565b60206040518083038186803b1580156117c557600080fd5b505afa1580156117d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117fd9190810190613786565b60608401516020015250505b9392505050565b6000816002610bab565b6118278260800151611810565b1561183157611905565b61183e82608001516114bd565b156118a757604080820151838201518251808401909352600d83527f494e56414c49445f4d4154434800000000000000000000000000000000000000602084015211156118a15760405160e560020a62461bcd0281526004016105909190613c35565b50611905565b604080820151838201518251808401909352600d83527f494e56414c49445f4d415443480000000000000000000000000000000000000060208401521015610cce5760405160e560020a62461bcd0281526004016105909190613c35565b5050565b6119116131d5565b60008560200151856020015111156040805190810160405280601681526020017f4d414b45525f4f524445525f4f5645525f4d41544348000000000000000000008152509015156119785760405160e560020a62461bcd0281526004016105909190613c35565b508760200151876020015111156040805190810160405280601681526020017f54414b45525f4f524445525f4f5645525f4d41544348000000000000000000008152509015156119de5760405160e560020a62461bcd0281526004016105909190613c35565b50602087015115156119f557606088015160a08301525b60208501511515611a0b57606086015160808301525b611a1a82898989898989612114565b60c083018190529050611a3d611a3085886125fe565b829063ffffffff61264416565b6040830152611a4f611a30858a612685565b60608301528751600160a060020a0390811660208401528651168252965096945050505050565b600082821115611a9b5760405160e560020a62461bcd02815260040161059090613c76565b50900390565b60048361010001516004811115611ab457fe5b1415611aca57611ac58383836126aa565b611b51565b60028361010001516004811115611add57fe5b1415611aee57611ac58383836128e5565b60018361010001516004811115611b0157fe5b1415611b1257611ac58383836129ea565b60038361010001516004811115611b2557fe5b1415611b3657611ac5838383612ad0565b60405160e560020a62461bcd02815260040161059090613cc6565b7f5666e33345832897d888a15af5670674266cf01e5cd1c3deef480fc606dbf4818284604051611b82929190613d06565b60405180910390a1505050565b611ba182600160a060020a0316612d9c565b1515611bc25760405160e560020a62461bcd02815260040161059090613cf6565b6000606083600160a060020a0316836040518082805190602001908083835b60208310611c005780518252601f199092019160209182019101611be1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611c62576040519150601f19603f3d011682016040523d82523d6000602084013e611c67565b606091505b5091509150811515611c8e5760405160e560020a62461bcd02815260040161059090613c56565b600081511115611ccd5780806020019051611cac9190810190613697565b1515611ccd5760405160e560020a62461bcd02815260040161059090613cd6565b50505050565b60f860020a900460ff1690565b611ce8613239565b8251600160a060020a03908116825260208084015182168184015292511660408083019190915291830151606080830191909152918301516080808301919091529183015160a082015291015160c082015290565b64ffffffffff7b01000000000000000000000000000000000000000000000000000000630100000083020416919050565b805160009060f860020a600182901a810281900491839190821a81020460ff83161515611e595760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182815260200191505060405160208183030381529060405280519060200120828760200151886040015160405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611e48573d6000803e3d6000fd5b505050602060405103519150611edd565b60ff831660011415611ec2576020808601516040808801518151600081528085018084528c905260ff861681840152606081019390935260808301525160019260a0808401939192601f1981019281900390910190855afa158015611e48573d6000803e3d6000fd5b60405160e560020a62461bcd02815260040161059090613c66565b50600160a060020a038581169116149150509392505050565b60006118098360000151600160a060020a031663ca361d676040518163ffffffff1660e060020a02815260040160206040518083038186803b158015611f3b57600080fd5b505afa158015611f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f739190810190613786565b611fff8560000151600160a060020a031663c32b1dfa6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015611fb657600080fd5b505afa158015611fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fee9190810190613786565b60408601519063ffffffff611a7616565b9063ffffffff61264416565b60006118098360000151600160a060020a031663ca361d676040518163ffffffff1660e060020a02815260040160206040518083038186803b15801561205057600080fd5b505afa158015612064573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120889190810190613786565b611fff84604001518660000151600160a060020a031663b5471dee6040518163ffffffff1660e060020a02815260040160206040518083038186803b1580156120d057600080fd5b505afa1580156120e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121089190810190613786565b9063ffffffff611a7616565b60808201516000908161212682612da4565b9050600088606001518260028110151561213c57fe5b602002015111801561216357506060860151600090836002811061215c57fe5b6020020151115b15612257576121a561218b89606001518360028110151561218057fe5b602002015186612dbb565b6060880151846002811061219b57fe5b6020020151612dbb565b92506121ce838960600151836002811015156121bd57fe5b60200201519063ffffffff611a7616565b606089015182600281106121de57fe5b602002015260608601516121f990849084600281106121bd57fe5b6060870151836002811061220957fe5b60200201526101008a0160045b9081600481111561222357fe5b905250604086015161224d908490846002811061223c57fe5b60200201519063ffffffff61264416565b60e08b01526124e9565b6060880151600090826002811061226a57fe5b602002015111801561228e57506060860151826002811061228757fe5b6020020151155b156123495760608801516122b29082600281106122a757fe5b602002015185612dbb565b92506122ca838960600151836002811015156121bd57fe5b606089015182600281106122da57fe5b6020020152606086015161230690849083600281106122f557fe5b60200201519063ffffffff612dd116565b6060870151826002811061231657fe5b60200201526101008a0160025b9081600481111561233057fe5b905250604086015161224d908490836002811061223c57fe5b6060880151816002811061235957fe5b602002015115801561238057506060860151600090836002811061237957fe5b6020020151115b156123fd5760608601516123999083600281106122a757fe5b92506123b1838960600151846002811015156122f557fe5b606089015183600281106123c157fe5b602002015260608601516123dc90849084600281106121bd57fe5b606087015183600281106123ec57fe5b60200201526101008a016001612216565b6060880151816002811061240d57fe5b602002015115801561243157506060860151826002811061242a57fe5b6020020151155b1561249b5783925061244f838960600151846002811015156122f557fe5b6060890151836002811061245f57fe5b6020020152606086015161247a90849083600281106122f557fe5b6060870151826002811061248a57fe5b60200201526101008a016003612323565b604080518082018252601081527f554e45585045435445445f4d41544348000000000000000000000000000000006020820152905160e560020a62461bcd0281526105909190600401613c35565b60208801516124fe908463ffffffff612dd116565b6020808a019190915286015161251a908463ffffffff612dd116565b602080880191909152898101518982015160408051808201909152601681527f54414b45525f4f524445525f4f5645525f4d41544348000000000000000000009381019390935211156125835760405160e560020a62461bcd0281526004016105909190613c35565b508660200151866020015111156040805190810160405280601681526020017f4d414b45525f4f524445525f4f5645525f4d41544348000000000000000000008152509015156125e95760405160e560020a62461bcd0281526004016105909190613c35565b50505060c08801819052979650505050505050565b60008061260a84612df9565b905061263c620186a06126306126238660800151612f6e565b849063ffffffff61264416565b9063ffffffff612fa416565b949350505050565b600082151561265557506000610446565b82820282848281151561266457fe5b04146118095760405160e560020a62461bcd02815260040161059090613c96565b60008061269184612df9565b905061263c620186a06126306126238660800151612fde565b60006126c784608001518560400151612dd190919063ffffffff16565b905060006126e68560a001518660600151612dd190919063ffffffff16565b905060006127728660e001516121088860c001518760000151600160a060020a031663e158e02d6040518163ffffffff1660e060020a02815260040160206040518083038186803b15801561273a57600080fd5b505afa15801561274e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fff9190810190613786565b90506127ba8660200151308860c0015187606001516127948960800151612da4565b6002811061279e57fe5b6020020151600160a060020a031692919063ffffffff61301616565b6127de8660000151308860c001518760600151886080015160028110151561279e57fe5b6127ec848760c00151613053565b828660e00151111561283457855160e087015161282f9190612814908663ffffffff611a7616565b6040870151600160a060020a0316919063ffffffff61127f16565b61287c565b828660e00151101561287c5761287c8660000151306128608960e0015187611a7690919063ffffffff16565b6040880151600160a060020a031692919063ffffffff61301616565b818111156128a257602086015161289d90612814838563ffffffff611a7616565b6128c4565b818110156128c45760208601516128c49030612860858563ffffffff611a7616565b60208501516128dd90612814858563ffffffff612dd116565b505050505050565b60006129028460a001518560600151612dd190919063ffffffff16565b9050600061292185608001518660400151612dd190919063ffffffff16565b9050612947856020015186600001518760c0015186606001516127948860800151612da4565b8451602085015160e0870151612985929190612969908563ffffffff612dd116565b6040870151600160a060020a031692919063ffffffff61301616565b818560e0015111156129ba576129b584602001518660200151612969858960e00151611a7690919063ffffffff16565b6107c6565b818560e0015110156107c6576107c6856020015185602001516129698860e0015186611a7690919063ffffffff16565b6000612a0784608001518560400151612dd190919063ffffffff16565b90506000612a268560a001518660600151612dd190919063ffffffff16565b8551602087015160c088015160608701516080880151949550612a4d946002811061279e57fe5b818560e001511115612a80576020850151855160e0870151612a7b929190612969908663ffffffff611a7616565b612ab0565b818560e001511015612ab057612ab0856000015186602001516129698860e0015186611a7690919063ffffffff16565b6107c6856020015185602001516129698585612dd190919063ffffffff16565b6000612b5e8260000151600160a060020a031663e158e02d6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612b1557600080fd5b505afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612b4d9190810190613786565b60c08601519063ffffffff61264416565b90506000612bee8360000151600160a060020a0316635c7c70596040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612ba557600080fd5b505afa158015612bb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bdd9190810190613786565b60c08701519063ffffffff61264416565b90506000612c0d86604001518760600151612dd190919063ffffffff16565b90506000612c2c87608001518860a00151612dd190919063ffffffff16565b905081831115612c71576020860151612c6c9030612c50868663ffffffff611a7616565b6040890151600160a060020a031692919063ffffffff61301616565b612c90565b81831015612c9057612c8d83612108838563ffffffff612dd116565b90505b612cc8876000015130612c508a60800151612cbc8c604001518d60e00151612dd190919063ffffffff16565b9063ffffffff612dd116565b612cf8876020015130612c508a60a00151612cbc8c60600151612cbc8e60e001518c611a7690919063ffffffff16565b612d06858860c001516130f6565b612d4487602001518860c0015187606001518860800151600281101515612d2957fe5b6020020151600160a060020a0316919063ffffffff61127f16565b612d6d87600001518860c001518760600151612d638960800151612da4565b60028110612d2957fe5b612d938660200151828760400151600160a060020a031661127f9092919063ffffffff16565b50505050505050565b6000903b1190565b60008115612db3576000610446565b506001919050565b6000818310612dca5781611809565b5090919050565b6000828201838110156118095760405160e560020a62461bcd02815260040161059090613c46565b600061044660026126308460000151600160a060020a031663ca361d676040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612e4357600080fd5b505afa158015612e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612e7b9190810190613786565b611fff8660000151600160a060020a031663c32b1dfa6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612ebe57600080fd5b505afa158015612ed2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ef69190810190613786565b8760000151600160a060020a031663b5471dee6040518163ffffffff1660e060020a02815260040160206040518083038186803b158015612f3657600080fd5b505afa158015612f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612cbc9190810190613786565b61ffff7e010000000000000000000000000000000000000000000000000000000000006801000000000000000083020416919050565b6000808211612fc85760405160e560020a62461bcd02815260040161059090613c86565b60008284811515612fd557fe5b04949350505050565b61ffff7e010000000000000000000000000000000000000000000000000000000000006a010000000000000000000083020416919050565b604051611ccd9085907f23b872dd00000000000000000000000000000000000000000000000000000000906112ba90879087908790602401613bae565b600554600090600160a060020a0316156130795750600554600160a060020a0316613080565b5060208201515b82516040517fc1b21411000000000000000000000000000000000000000000000000000000008152600160a060020a0383169163c1b21411916130c891908690600401613bd6565b600060405180830381600087803b1580156130e257600080fd5b505af1158015612d93573d6000803e3d6000fd5b600554600090600160a060020a03161561311c5750600554600160a060020a0316613123565b5060208201515b82516040517f125bb6a9000000000000000000000000000000000000000000000000000000008152600160a060020a0383169163125bb6a9916130c891908690600090600401613bf1565b6040805160c0810182526000808252602082018190529181019190915260608101613197613275565b8152602001600081525090565b6040805160c081018252600080825260208201529081016131c3613275565b81526020016131d0613275565b905290565b610120604051908101604052806000600160a060020a031681526020016000600160a060020a03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600060048111156131d057fe5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b60408051808201825290600290829080388339509192915050565b60006118098235613d6e565b60006118098251613d6e565b6000601f820183136132b957600080fd5b81356132cc6132c782613d49565b613d22565b91508181835260208401935060208101905083856101008402820111156132f257600080fd5b60005b83811015613321578161330888826133fa565b84525060209092019161010091909101906001016132f5565b5050505092915050565b6000601f8201831361333c57600080fd5b813561334a6132c782613d49565b9150818183526020840193506020810190508385602084028201111561336f57600080fd5b60005b83811015613321578161338588826133a7565b8452506020928301929190910190600101613372565b60006118098251613d79565b60006118098235613d7e565b6000604082840312156133c557600080fd5b6133cf6040613d22565b905060006133dd8484613290565b82525060206133ee84848301613290565b60208301525092915050565b6000610100828403121561340d57600080fd5b61341760c0613d22565b905060006134258484613290565b8252506020613436848483016133a7565b602083015250604061344a848285016133a7565b604083015250606061345e848285016133a7565b6060830152506080613472848285016133a7565b60808301525060a061348684828501613492565b60a08301525092915050565b6000606082840312156134a457600080fd5b6134ae6060613d22565b905060006134bc84846133a7565b82525060206134cd848483016133a7565b60208301525060406134e1848285016133a7565b60408301525092915050565b600060e082840312156134ff57600080fd5b61350960e0613d22565b905060006135178484613290565b825250602061352884848301613290565b602083015250604061353c84828501613290565b6040830152506060613550848285016133a7565b6060830152506080613564848285016133a7565b60808301525060a0613578848285016133a7565b60a08301525060c061358c848285016133a7565b60c08301525092915050565b60006118098251613d7e565b6000602082840312156135b657600080fd5b600061263c8484613290565b6000602082840312156135d457600080fd5b600061263c848461329c565b600080604083850312156135f357600080fd5b60006135ff8585613290565b925050602061361085828601613290565b9150509250929050565b60008060006060848603121561362f57600080fd5b600061363b8686613290565b935050602061364c86828701613290565b925050604061365d868287016133a7565b9150509250925092565b6000806040838503121561367a57600080fd5b60006136868585613290565b9250506020613610858286016133a7565b6000602082840312156136a957600080fd5b600061263c848461339b565b6000602082840312156136c757600080fd5b600061263c84846133a7565b60008060008061018085870312156136ea57600080fd5b60006136f687876133fa565b94505061010085013567ffffffffffffffff81111561371457600080fd5b613720878288016132a8565b93505061012085013567ffffffffffffffff81111561373e57600080fd5b61374a8782880161332b565b92505061014061375c878288016133b3565b91505092959194509250565b600060e0828403121561377a57600080fd5b600061263c84846134ed565b60006020828403121561379857600080fd5b600061263c8484613598565b6137ad81613d6e565b82525050565b6137ad81613d79565b6137ad81613d7e565b6137ad81613d9d565b60006137d982613d6a565b8084526137ed816020860160208601613da8565b6137f681613dd4565b9093016020019392505050565b601b81527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000602082015260400190565b60208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260400190565b601381527f494e56414c49445f5349474e5f4d4554484f4400000000000000000000000000602082015260400190565b601e81527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000602082015260400190565b601a81527f536166654d6174683a206469766973696f6e206279207a65726f000000000000602082015260400190565b602181527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60208201527f7700000000000000000000000000000000000000000000000000000000000000604082015260600190565b600d81527f494e56414c49445f4f574e455200000000000000000000000000000000000000602082015260400190565b600981527f4e4f545f4f574e45520000000000000000000000000000000000000000000000602082015260400190565b601581527f554e45585045435445445f46494c4c414354494f4e0000000000000000000000602082015260400190565b602a81527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60208201527f6f74207375636365656400000000000000000000000000000000000000000000604082015260600190565b603681527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60208201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000604082015260600190565b601f81527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400602082015260400190565b8051610120830190613ac784826137a4565b506020820151613ada60208501826137a4565b506040820151613aed60408501826137bc565b506060820151613b0060608501826137bc565b506080820151613b1360808501826137bc565b5060a0820151613b2660a08501826137bc565b5060c0820151613b3960c08501826137bc565b5060e0820151613b4c60e08501826137bc565b50610100820151611ccd6101008501826137c5565b80516040830190613b7284826137a4565b506020820151611ccd60208501826137a4565b6020810161044682846137a4565b60408101613ba182856137a4565b61180960208301846137a4565b60608101613bbc82866137a4565b613bc960208301856137a4565b61263c60408301846137bc565b60408101613be482856137a4565b61180960208301846137bc565b60608101613bff82866137a4565b613c0c60208301856137bc565b61263c60408301846137b3565b6020810161044682846137b3565b6020810161044682846137bc565b6020808252810161180981846137ce565b6020808252810161044681613803565b6020808252810161044681613833565b6020808252810161044681613863565b6020808252810161044681613893565b60208082528101610446816138c3565b60208082528101610446816138f3565b6020808252810161044681613949565b6020808252810161044681613979565b60208082528101610446816139a9565b60208082528101610446816139d9565b6020808252810161044681613a2f565b6020808252810161044681613a85565b6101608101613d158285613b61565b6118096040830184613ab5565b60405181810167ffffffffffffffff81118282101715613d4157600080fd5b604052919050565b600067ffffffffffffffff821115613d6057600080fd5b5060209081020190565b5190565b600061044682613d91565b151590565b90565b600060058210613d8d57fe5b5090565b600160a060020a031690565b600061044682613d81565b60005b83811015613dc3578181015183820152602001613dab565b83811115611ccd5750506000910152565b601f01601f19169056fe4f726465722861646472657373207472616465722c616464726573732072656c617965722c61646472657373206d61726b6574436f6e7472616374416464726573732c75696e7432353620616d6f756e742c75696e743235362070726963652c75696e7432353620676173546f6b656e416d6f756e742c627974657333322064617461294d414b45525f4f524445525f43414e5f4e4f545f42455f4d41524b45545f4f52444552a265627a7a72305820c604f26f79328a69aa655e95cea7af2e9177b3cbc22fe884d27c364bf1805dc26c6578706572696d656e74616cf50037

Deployed Bytecode Sourcemap

15941:26181:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15941:26181:0;;;;;;;;-1:-1:-1;;;15941:26181:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7919:176;;;;;;;;;:::i;:::-;;16101:39;;;:::i;:::-;;;;;;;;;;;;;;;;16404:33;;;:::i;:::-;;;;;;;;8298:181;;;;;;;;;:::i;:::-;;;;;;;;16452:42;;;;;;;;;:::i;16509:::-;;;;;;;;;:::i;7511:70::-;;;;;;;;;:::i;8633:126::-;;;:::i;285:31::-;;;:::i;4227:247::-;;;:::i;16147:32::-;;;:::i;30266:274::-;;;;;;;;;:::i;16226:46::-;;;:::i;3713:::-;;;:::i;18190:154::-;;;;;;;;;:::i;7098:140::-;;;:::i;18857:790::-;;;;;;;;;:::i;6786:78::-;;;:::i;6975:91::-;;;:::i;8773:111::-;;;;;;;;;:::i;18581:260::-;;;;;;;;;:::i;16186:33::-;;;:::i;18352:221::-;;;;;;;;;:::i;18007:173::-;;;;;;;;;:::i;8493:126::-;;;:::i;155:121::-;;;:::i;16353:36::-;;;:::i;7258:211::-;;;;;;;;;:::i;8109:175::-;;;;;;;;;:::i;7919:176::-;7999:10;7982:28;;;;8023:4;7982:28;;;;;;;;-1:-1:-1;;;;;7982:38:0;;;;;;;;;;:45;;-1:-1:-1;;7982:45:0;;;;;;;8043:44;;7982:38;;7999:10;8043:44;;;7919:176;:::o;16101:39::-;16139:1;16101:39;:::o;16404:33::-;;;-1:-1:-1;;;;;16404:33:0;;:::o;8298:181::-;8377:4;8401:10;-1:-1:-1;;;;;8401:21:0;;;;:70;;-1:-1:-1;;;;;;8426:25:0;;;;;;:16;:25;;;;;;;;8452:10;8426:37;;;;;;;;;;;:45;;;8401:70;8394:77;8298:181;-1:-1:-1;;8298:181:0:o;16452:42::-;;;;;;;;;;;;;:::o;16509:::-;;;;;;;;;;;;;;;:::o;7511:70::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;8633:126::-;8694:10;8684:21;;;;:9;:21;;;;;;:28;;-1:-1:-1;;8684:28:0;8708:4;8684:28;;;8728:23;;;8684:21;8728:23;8633:126::o;285:31::-;;;;:::o;4227:247::-;4291:176;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4291:176:0;;;4271:203;;;;;;4227:247;:::o;16147:32::-;16178:1;16147:32;:::o;30266:274::-;30347:12;;-1:-1:-1;;;;;30333:26:0;:10;:26;;:57;;;30377:5;:13;;;-1:-1:-1;;;;;30363:27:0;:10;-1:-1:-1;;;;;30363:27:0;;30333:57;30392:14;;;;;;;;;;;;;;;;;;30325:82;;;;;;-1:-1:-1;;;;;30325:82:0;;;;;;;;;;;;;;;;;;;30420:17;30440:19;30453:5;30440:12;:19::i;:::-;30470:20;;;;:9;:20;;;;;;:27;;-1:-1:-1;;30470:27:0;30493:4;30470:27;;;30515:17;30420:39;;-1:-1:-1;30420:39:0;;30515:17;;30470:20;30515:17;30266:274;;:::o;16226:46::-;16266:6;16226:46;:::o;3713:::-;3756:3;3713:46;:::o;18190:154::-;6918:9;:7;:9::i;:::-;6910:31;;;;;;-1:-1:-1;;;;;6910:31:0;;;;;;;;;18296:18;:40;;-1:-1:-1;;18296:40:0;-1:-1:-1;;;;;18296:40:0;;;;;;;;;;18190:154::o;7098:140::-;6918:9;:7;:9::i;:::-;6910:31;;;;;;-1:-1:-1;;;;;6910:31:0;;;;;;;;;7181:6;;7160:40;;7197:1;;-1:-1:-1;;;;;7181:6:0;;7160:40;;7197:1;;7160:40;7211:6;:19;;-1:-1:-1;;7211:19:0;;;7098:140::o;18857:790::-;19123:57;19156:15;:23;;;19123:32;:57::i;:::-;19182:14;;;;;;;;;;;;;;;;;;19115:82;;;;;;-1:-1:-1;;;;;19115:82:0;;;;;;;;;;;19217:33;19229:15;:20;;;19217:11;:33::i;:::-;19252:32;;;;;;;;;;;;;;;;;;;19216:34;19208:77;;;;-1:-1:-1;;;;;19208:77:0;;;;;;;;;;-1:-1:-1;19321:37:0;;19298:61;;:22;:61::i;:::-;19370:32;;:::i;:::-;19405:49;19421:15;19438;19405;:49::i;:::-;19370:84;;19465:174;19494:15;19524:16;19555;19586:15;19616:12;19465:14;:174::i;:::-;18857:790;;;;;:::o;6786:78::-;6850:6;;-1:-1:-1;;;;;6850:6:0;6786:78;:::o;6975:91::-;7052:6;;-1:-1:-1;;;;;7052:6:0;7038:10;:20;;6975:91::o;8773:111::-;-1:-1:-1;;;;;8858:18:0;8833:4;8858:18;;;:9;:18;;;;;;;;8857:19;;8773:111::o;18581:260::-;6918:9;:7;:9::i;:::-;6910:31;;;;;;-1:-1:-1;;;;;6910:31:0;;;;;;;;;18708:14;;;;;;;;;;;;;;;;;18705:1;18696:10;;18688:35;;;;-1:-1:-1;;;;;18688:35:0;;;;;;;;;;-1:-1:-1;18734:46:0;-1:-1:-1;;;;;18734:26:0;;18761:10;18773:6;18734:46;:26;:46;:::i;:::-;18814:10;-1:-1:-1;;;;;18798:35:0;18807:5;-1:-1:-1;;;;;18798:35:0;;18826:6;18798:35;;;;;;;;;;;;;;;18581:260;;:::o;16186:33::-;16218:1;16186:33;:::o;18352:221::-;6918:9;:7;:9::i;:::-;6910:31;;;;;;-1:-1:-1;;;;;6910:31:0;;;;;;;;;18475:42;-1:-1:-1;;;;;18475:25:0;;18501:7;18510:6;18475:42;:25;:42;:::i;:::-;18549:7;-1:-1:-1;;;;;18533:32:0;18542:5;-1:-1:-1;;;;;18533:32:0;;18558:6;18533:32;;;;;;;;;;;;;;;18352:221;;;:::o;18007:173::-;6918:9;:7;:9::i;:::-;6910:31;;;;;;-1:-1:-1;;;;;6910:31:0;;;;;;;;;18126:21;:46;;-1:-1:-1;;18126:46:0;-1:-1:-1;;;;;18126:46:0;;;;;;;;;;18007:173::o;8493:126::-;8561:10;8551:21;;;;:9;:21;;;;;;8544:28;;-1:-1:-1;;8544:28:0;;;8588:23;;;8551:21;8588:23;8493:126::o;155:121::-;224:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;224:45:0;;;204:72;;;;;;155:121;:::o;16353:36::-;;;-1:-1:-1;;;;;16353:36:0;;:::o;7258:211::-;6918:9;:7;:9::i;:::-;6910:31;;;;;;-1:-1:-1;;;;;6910:31:0;;;;;;;;;-1:-1:-1;;;;;7339:22:0;;;;7331:48;;;;-1:-1:-1;;;;;7331:48:0;;;;;;;;;7416:6;;7395:38;;-1:-1:-1;;;;;7395:38:0;;;;7416:6;;7395:38;;7416:6;;7395:38;7444:6;:17;;-1:-1:-1;;7444:17:0;-1:-1:-1;;;;;7444:17:0;;;;;;;;;;7258:211::o;8109:175::-;8188:10;8212:5;8171:28;;;:16;:28;;;;;;;;-1:-1:-1;;;;;8171:38:0;;;;;;;;;;:46;;-1:-1:-1;;8171:46:0;;;8233:43;8171:38;;8188:10;8233:43;;;8109:175;:::o;4489:177::-;4554:17;4596:35;4614:16;4624:5;4614:9;:16::i;:::-;4596:17;:35::i;5667:110::-;5725:4;5755;5760:2;5755:8;;-1:-1:-1;;;5755:8:0;-1:-1:-1;;;5749:15:0;;:20;;5768:1;5749:20;5742:27;;5667:110;;;:::o;22637:397::-;22729:21;;-1:-1:-1;;;;;22729:21:0;:37;22725:76;;;22783:7;;22725:76;22870:21;;;22925:52;;;;;-1:-1:-1;;;;;22870:21:0;;;;;;22925:29;;:52;;22955:21;;22925:52;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22925:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22925:52:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;22925:52:0;;;;;;;;;22992:23;;;;;;;;;;;;;;;;;;22903:123;;;;;;-1:-1:-1;;;;;22903:123:0;;;;;;;;;;;22637:397;;;:::o;19661:870::-;19836:32;;:::i;:::-;19932:37;;-1:-1:-1;;;;;19886:84:0;;;;20049:53;;;;;;;;:51;;:53;;;;;;;;;;;;;;;19886:84;20049:53;;;5:2:-1;;;;30:1;27;20:12;5:2;20049:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;20049:53:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;20049:53:0;;;;;;;;;19981:12;:31;;:132;-1:-1:-1;;;;;19981:132:0;;;-1:-1:-1;;;;;19981:132:0;;;;;20157:12;:27;;;-1:-1:-1;;;;;20157:52:0;;:54;;;;;-1:-1:-1;;;20157:54:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20157:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;20157:54:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;20157:54:0;;;;;;;;;20124:12;:23;;:88;-1:-1:-1;;;;;20124:88:0;;;-1:-1:-1;;;;;20124:88:0;;;;;20261:12;:27;;;-1:-1:-1;;;;;20261:47:0;;:49;;;;;-1:-1:-1;;;20261:49:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20261:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;20261:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;20261:49:0;;;;;;;;;20223:22;;;;-1:-1:-1;;;;;20223:88:0;;;;;20361:27;;:50;;;;;;;;:48;;;;;;;:50;;;;;20223:28;;20361:50;;;;;;;:48;:50;;;5:2:-1;;;;30:1;27;20:12;5:2;20361:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;20361:50:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;20361:50:0;;;;;;;;;20322:22;;;;-1:-1:-1;;;;;20322:90:0;;;;:29;;;;:90;20455:20;;;;20448:28;;:6;:28::i;:::-;:43;;16178:1;20448:43;;;16218:1;20448:43;20423:22;;;:68;19661:870;;;;:::o;20545:2078::-;20837:31;;:::i;:::-;20871:110;20898:15;20928;20958:12;20871;:110::i;:::-;20837:144;-1:-1:-1;20997:9:0;20992:1551;21016:16;:23;21012:1;:27;20992:1551;;;21070:39;21084:16;21101:1;21084:19;;;;;;;;;;;;;;;;;;:24;;;21070:13;:39::i;:::-;21069:40;21111:35;;;;;;;;;;;;;;;;;;21061:86;;;;;;;-1:-1:-1;;;;;21061:86:0;;;;;;;;;;;21202:32;21209:16;21226:1;21209:19;;;;;;;;;;;;;;;;;;:24;;;21202:6;:32::i;:::-;21170:64;;:28;21177:15;:20;;;21170:6;:28::i;:::-;21236:12;;;;;;;;;;;;;;;;;;21170:64;;;;;21162:87;;;;-1:-1:-1;;;;;21162:87:0;;;;;;;;;;;21316:16;21333:1;21316:19;;;;;;;;;;;;;;;;;;;;:26;21290:22;;21361:32;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;21290:52:0;;;;;;;21264:144;;;;-1:-1:-1;;;;;21264:144:0;;;;;;;;;;;21423:31;;:::i;:::-;21457:130;21488:16;21505:1;21488:19;;;;;;;;;;;;;;;;;;21526:15;21560:12;21457;:130::i;:::-;21423:164;;21602:100;21634:15;21668:16;21685:1;21668:19;;;;;;;;;;;;;;;;;;21602:13;:100::i;:::-;21717:20;21740:16;21757:1;21740:19;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21779:9:0;21774:596;16139:1;21794;:15;:35;;;;;21828:1;21813:12;:16;21794:35;21774:596;;;21855:25;;:::i;:::-;21899:20;21963:257;22000:15;22038:14;22075:16;22092:1;22075:19;;;;;;;;;;;;;;;;;;22117:14;22154:12;22189;21963:14;:257::i;:::-;21938:282;;-1:-1:-1;21938:282:0;-1:-1:-1;22254:30:0;:12;21938:282;22254:30;:16;:30;:::i;:::-;22239:45;;22303:51;22316:6;22324:15;22341:12;22303;:51::i;:::-;-1:-1:-1;;21831:3:0;;21774:596;;;-1:-1:-1;22439:14:0;;;;;;;;;;;;;;;;;22420:17;;22412:42;;;;-1:-1:-1;;;;;22412:42:0;;;;;;;;;;-1:-1:-1;;22504:27:0;;;;;22476:24;;22469:32;;;;:6;:32;;;;;;:62;21041:3;;20992:1551;;;-1:-1:-1;22588:27:0;;;;;22560:24;;22553:32;;;;:6;:32;;;;;;:62;-1:-1:-1;;;;;20545:2078:0:o;14001:176::-;14110:58;;14084:85;;14103:5;;14133:23;;14110:58;;14158:2;;14162:5;;14110:58;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;14110:58:0;;;49:4:-1;25:18;;61:17;;14110:58:0;182:15:-1;14110:58:0;;;;179:29:-1;;;;160:49;;;14084:18:0;:85::i;14397:387::-;14533:10;;;14532:62;;-1:-1:-1;14549:39:0;;;;;-1:-1:-1;;;;;14549:15:0;;;;;:39;;14573:4;;14580:7;;14549:39;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14549:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;14549:39:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;14549:39:0;;;;;;;;;:44;14532:62;14524:152;;;;;;-1:-1:-1;;;;;14524:152:0;;;;;;;;;14713:62;;14687:89;;14706:5;;14736:22;;14713:62;;14760:7;;14769:5;;14713:62;;;;4680:456;4742:14;4779:17;4291:176;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;4291:176:0;;;;;;;4271:203;;49:4:-1;4271:203:0;;;;-1:-1:-1;;4866:14:0;;4905:12;;4989:24;;;5054:3;5037:21;;5074:18;;;5037:21;-1:-1:-1;;;4680:456:0;;;:::o;554:174::-;624:7;690:16;661:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;661:58:0;;;;651:69;;;;;;554:174::o;5436:104::-;5489:4;5519;5524:1;5519:7;;30554:1760;30764:26;;:::i;:::-;16337:1;30830:32;30846:10;:15;;;30830;:32::i;:::-;30904:27;;;;;;;;;;;;;;;;;;30830:59;30808:134;;;;-1:-1:-1;;;;;30808:134:0;;;;;;;;;;;30955:18;;:::i;:::-;30976:51;30999:10;31011:15;30976:22;:51::i;:::-;30955:72;;31060:19;31073:5;31060:12;:19::i;:::-;31038:41;;;:19;31115:27;;;:6;:27;;;;;;;;;31090:22;;;:52;;;31238:12;;;;31174:20;;31212:38;31208:347;;31282:24;31276:31;31267:40;;31208:347;;;31348:37;31374:5;:10;;;31348:25;:37::i;:::-;31329:15;:56;31325:230;;31417:19;31411:26;;31325:230;31469:19;;31459:30;;;;:9;:30;;;;;;;;31455:100;;;-1:-1:-1;31521:21:0;31455:100;31614:21;;;;;;;;;;;;;;;;;31575:37;;;31591:20;31575:37;31567:69;;;;-1:-1:-1;;;;;31567:69:0;;;;;;;;;;-1:-1:-1;31686:19:0;;31707:17;;31726:20;;;;31669:78;;31686:19;31707:17;31669:16;:78::i;:::-;31762:23;;;;;;;;;;;;;;;;;;31647:149;;;;;;-1:-1:-1;;;;;31647:149:0;;;;;;;;;;;31824:30;31838:10;:15;;;31824:13;:30::i;:::-;31823:31;31819:251;;;31925:45;31945:12;31959:10;31925:19;:45::i;:::-;31899:17;;;;:71;32012:46;32033:12;32047:10;32012:20;:46::i;:::-;31985:17;;;;:24;;:73;31819:251;32114:22;;;;:28;32154:17;;32107:65;;;;;-1:-1:-1;;;;;32107:46:0;;;;;;:65;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32107:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32107:65:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;32107:65:0;;;;;;;;;32080:18;;;;;:92;;;;32218:22;;;32080:24;32218:29;;32259:17;;32211:66;;;;;-1:-1:-1;;;;;32211:47:0;;;;;;:66;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32211:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32211:66:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;32211:66:0;;;;;;;;;32183:18;;;;:25;;:94;-1:-1:-1;;30554:1760:0;;;;;;:::o;5548:111::-;5608:4;5638;5643:1;5638:7;;24088:491;24258:35;24272:15;:20;;;24258:13;:35::i;:::-;24254:74;;;24310:7;;24254:74;24342:28;24349:15;:20;;;24342:6;:28::i;:::-;24338:234;;;24420:21;;;;;24395;;;;24443:13;;;;;;;;;;;;;;;;24395:46;;24387:70;;;;-1:-1:-1;;;;;24387:70:0;;;;;;;;;;;24338:234;;;24523:21;;;;;24498;;;;24546:13;;;;;;;;;;;;;;;;24498:46;;24490:70;;;;-1:-1:-1;;;;;24490:70:0;;;;;;;;;24338:234;24088:491;;:::o;24593:1494::-;24923:25;;:::i;:::-;24950:20;25027:15;:22;;;24996:14;:27;;;:53;;25051:22;;;;;;;;;;;;;;;;;;24988:86;;;;;;;-1:-1:-1;;;;;24988:86:0;;;;;;;;;;;25124:15;:22;;;25093:14;:27;;;:53;;25148:22;;;;;;;;;;;;;;;;;;25085:86;;;;;;;-1:-1:-1;;;;;25085:86:0;;;;;;;;;;-1:-1:-1;25198:27:0;;;;:32;25194:116;;;25268:30;;;;25247:18;;;:51;25194:116;25324:27;;;;:32;25320:116;;;25394:30;;;;25373:18;;;:51;25320:116;25473:222;25503:6;25524:15;25554:14;25583:15;25613:14;25642:12;25669:15;25473;:222::i;:::-;25706:22;;;:37;;;25458:237;-1:-1:-1;25784:64:0;25801:46;25817:12;25831:15;25801;:46::i;:::-;25784:12;;:64;:16;:64;:::i;:::-;25766:15;;;:82;25877:64;25894:46;25910:12;25924:15;25894;:46::i;25877:64::-;25859:15;;;:82;25967:22;;-1:-1:-1;;;;;25952:37:0;;;:12;;;:37;26015:22;;26000:37;;;24593:1494;;;;;;;;;:::o;2017:184::-;2075:7;2103:6;;;;2095:49;;;;-1:-1:-1;;;;;2095:49:0;;;;;;;;;-1:-1:-1;2167:5:0;;;2017:184::o;32905:784::-;33121:17;33100:6;:17;;;:38;;;;;;;;;33096:540;;;33155:47;33164:6;33172:15;33189:12;33155:8;:47::i;:::-;33096:540;;;33245:15;33224:6;:17;;;:36;;;;;;;;;33220:416;;;33277:45;33284:6;33292:15;33309:12;33277:6;:45::i;33220:416::-;33365:14;33344:6;:17;;;:35;;;;;;;;;33340:296;;;33396:44;33402:6;33410:15;33427:12;33396:5;:44::i;33340:296::-;33483:15;33462:6;:17;;;:36;;;;;;;;;33458:178;;;33515:45;33522:6;33530:15;33547:12;33515:6;:45::i;33458:178::-;33593:31;;-1:-1:-1;;;;;33593:31:0;;;;;;;;33458:178;33651:30;33657:15;33674:6;33651:30;;;;;;;;;;;;;;;;32905:784;;;:::o;15384:550::-;15544:27;15552:5;-1:-1:-1;;;;;15544:25:0;;:27::i;:::-;15536:71;;;;;;-1:-1:-1;;;;;15536:71:0;;;;;;;;;15631:12;15645:23;15680:5;-1:-1:-1;;;;;15672:19:0;15692:4;15672:25;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;15672:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;15630:67:0;;;;15716:7;15708:52;;;;;;-1:-1:-1;;;;;15708:52:0;;;;;;;;;15797:1;15777:10;:17;:21;15773:154;;;15849:10;15838:30;;;;;;;;;;;;;;15830:85;;;;;;-1:-1:-1;;;;;15830:85:0;;;;;;;;;15384:550;;;;:::o;5152:123::-;-1:-1:-1;;;5249:17:0;;5241:26;;;5152:123::o;32328:563::-;32505:18;;:::i;:::-;32556:17;;-1:-1:-1;;;;;32541:32:0;;;;;32600:23;;;;;32584:39;;:13;;;:39;32664:37;;32634:67;:27;;;;:67;;;;32727:17;;;;32712:12;;;;:32;;;;32769:16;;;;32755:11;;;;:30;;;;32819:25;;;;32796:20;;;:48;32868:15;;;32855:10;;;:28;32541:5;32328:563::o;5283:145::-;5382:38;5390:29;5404:13;;;5390:29;5382:38;5283:145;;;:::o;962:823::-;1151:16;;1108:4;;-1:-1:-1;;;1168:1:0;1151:19;;;;;1145:26;;;;1108:4;;1226:19;;;;;1220:26;1263:40;;;;1259:473;;;1332:192;1423:4;1370:58;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;1370:58:0;;;1360:69;;;;;;1448:1;1468:9;:11;;;1498:9;:11;;;1332:192;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1332:192:0;;;;;;;;1320:204;;1259:473;;;1546:39;;;1562:22;1546:39;1542:190;;;1633:11;;;;;1646;;;;;1614:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1633:11;;-1:-1:-1;;1614:44:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;1542:190:0;1691:29;;-1:-1:-1;;;;;1691:29:0;;;;;;;;1542:190;-1:-1:-1;;;;;;1751:26:0;;;;;;;-1:-1:-1;;962:823:0;;;;;:::o;23413:324::-;23556:7;23588:141;23684:12;:27;;;-1:-1:-1;;;;;23684:42:0;;:44;;;;;-1:-1:-1;;;23684:44:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23684:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23684:44:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;23684:44:0;;;;;;;;;23588:77;23623:12;:27;;;-1:-1:-1;;;;;23623:39:0;;:41;;;;;-1:-1:-1;;;23623:41:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23623:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23623:41:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;23623:41:0;;;;;;;;;23588:16;;;;;:77;:34;:77;:::i;:::-;:95;:141;:95;:141;:::i;23751:323::-;23895:7;23927:139;24021:12;:27;;;-1:-1:-1;;;;;24021:42:0;;:44;;;;;-1:-1:-1;;;24021:44:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24021:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24021:44:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;24021:44:0;;;;;;;;;23927:75;23985:10;:16;;;23927:12;:27;;;-1:-1:-1;;;;;23927:37:0;;:39;;;;;-1:-1:-1;;;23927:39:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23927:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23927:39:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;23927:39:0;;;;;;;;;:57;:75;:57;:75;:::i;26965:3287::-;27385:22;;;;27332:20;;;27437:18;27385:22;27437:12;:18::i;:::-;27418:37;;27508:1;27472:14;:23;;;27496:8;27472:33;;;;;;;;;;;;;:37;:74;;;;-1:-1:-1;27513:23:0;;;;27545:1;;27537:4;27513:29;;;;;;;;;;;:33;27472:74;27468:2315;;;27592:140;27614:55;27618:14;:23;;;27642:8;27618:33;;;;;;;;;;;;;27653:15;27614:3;:55::i;:::-;27688:23;;;;27712:4;27688:29;;;;;;;;;;;27592:3;:140::i;:::-;27577:155;;27797:69;27853:12;27797:14;:23;;;27821:8;27797:33;;;;;;;;;;;;;;:69;:55;:69;:::i;:::-;27761:23;;;;27785:8;27761:33;;;;;;;;;;:105;27913:23;;;;:47;;27947:12;;27937:4;27913:29;;;;;;:47;27881:23;;;;27905:4;27881:29;;;;;;;;;;:79;27977:17;;;27997;27977:37;;;;;;;;;;;;;-1:-1:-1;28054:22:0;;;;:46;;28087:12;;28077:4;28054:28;;;;;;;;;;;;:46;:32;:46;:::i;:::-;28029:22;;;:71;27468:2315;;;28123:23;;;;28159:1;;28147:8;28123:33;;;;;;;;;;;:37;:75;;;;-1:-1:-1;28164:23:0;;;;28188:4;28164:29;;;;;;;;;;;:34;28123:75;28119:1664;;;28248:23;;;;28244:55;;28272:8;28248:33;;;;;;;;;;;28283:15;28244:3;:55::i;:::-;28229:70;;28350:69;28406:12;28350:14;:23;;;28374:8;28350:33;;;;;;;;:69;28314:23;;;;28338:8;28314:33;;;;;;;;;;:105;28470:23;;;;:69;;28526:12;;28494:8;28470:33;;;;;;;;;;;;:69;:55;:69;:::i;:::-;28434:23;;;;28458:8;28434:33;;;;;;;;;;:105;28556:17;;;28576:15;28556:35;;;;;;;;;;;;;-1:-1:-1;28631:22:0;;;;:50;;28668:12;;28654:8;28631:32;;;;;;28119:1664;28704:23;;;;28728:8;28704:33;;;;;;;;;;;:38;:75;;;;-1:-1:-1;28746:23:0;;;;28778:1;;28770:4;28746:29;;;;;;;;;;;:33;28704:75;28700:1083;;;28829:23;;;;28825:51;;28853:4;28829:29;;;;;;28825:51;28810:66;;28923:47;28957:12;28923:14;:23;;;28947:4;28923:29;;;;;;;;:47;28891:23;;;;28915:4;28891:29;;;;;;;;;;:79;29017:23;;;;:47;;29051:12;;29041:4;29017:29;;;;;;:47;28985:23;;;;29009:4;28985:29;;;;;;;;;;:79;29081:17;;;29101:14;29081:34;;28700:1083;29224:23;;;;29248:8;29224:33;;;;;;;;;;;:38;:76;;;;-1:-1:-1;29266:23:0;;;;29290:4;29266:29;;;;;;;;;;;:34;29224:76;29220:563;;;29346:15;29331:30;;29422:47;29456:12;29422:14;:23;;;29446:4;29422:29;;;;;;;;:47;29390:23;;;;29414:4;29390:29;;;;;;;;;;:79;29520:23;;;;:51;;29558:12;;29544:8;29520:33;;;;;;:51;29484:23;;;;29508:8;29484:33;;;;;;;;;;:87;29588:17;;;29608:15;29588:35;;29220:563;29754:16;;;;;;;;;;;;;;;;29747:24;;-1:-1:-1;;;;;29747:24:0;;;;29754:16;29747:24;;;;29220:563;29835:27;;;;:45;;29867:12;29835:45;:31;:45;:::i;:::-;29805:27;;;;:75;;;;29921:27;;;:45;;29953:12;29921:45;:31;:45;:::i;:::-;29891:27;;;;:75;;;;30018:22;;;;29987:27;;;;30042:22;;;;;;;;;;;;;;;;;;;;29987:53;;29979:86;;;;-1:-1:-1;;;;;29979:86:0;;;;;;;;;;;30115:15;:22;;;30084:14;:27;;;:53;;30139:22;;;;;;;;;;;;;;;;;;30076:86;;;;;;;-1:-1:-1;;;;;30076:86:0;;;;;;;;;;-1:-1:-1;;;30175:22:0;;;:37;;;26965:3287;;;;;;;;;:::o;26101:418::-;26265:7;26290:31;26324:46;26357:12;26324:32;:46::i;:::-;26290:80;;26388:123;16266:6;26388:90;26430:47;26461:10;:15;;;26430:30;:47::i;:::-;26388:23;;:90;:41;:90;:::i;:::-;:108;:123;:108;:123;:::i;:::-;26381:130;26101:418;-1:-1:-1;;;;26101:418:0:o;2215:280::-;2273:7;2327:6;;2323:47;;;-1:-1:-1;2357:1:0;2350:8;;2323:47;2394:5;;;2398:1;2394;:5;2418;;;;;;;;:10;2410:56;;;;-1:-1:-1;;;;;2410:56:0;;;;;;;;26533:418;26697:7;26722:31;26756:46;26789:12;26756:32;:46::i;:::-;26722:80;;26820:123;16266:6;26820:90;26862:47;26893:10;:15;;;26862:30;:47::i;36732:2218::-;36919:21;36943:39;36963:6;:18;;;36943:6;:15;;;:19;;:39;;;;:::i;:::-;36919:63;;36993:21;37017:39;37037:6;:18;;;37017:6;:15;;;:19;;:39;;;;:::i;:::-;36993:63;;37067:25;37095:133;37205:6;:22;;;37095:91;37163:6;:22;;;37095:12;:27;;;-1:-1:-1;;;;;37095:47:0;;:49;;;;;-1:-1:-1;;;37095:49:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37095:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;37095:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;37095:49:0;;;;;;;;:133;37067:161;;37261:210;37371:6;:12;;;37410:4;37434:6;:22;;;37261:12;:22;;;37284:36;37297:12;:22;;;37284:12;:36::i;:::-;37261:60;;;;;;;;;;;-1:-1:-1;;;;;37261:91:0;;:210;;;:91;:210;:::i;:::-;37492:196;37588:6;:12;;;37627:4;37651:6;:22;;;37492:12;:22;;;37515:12;:22;;;37492:46;;;;;;;;:196;37709:58;37730:12;37744:6;:22;;;37709:20;:58::i;:::-;37827:13;37802:6;:22;;;:38;37798:496;;;37926:12;;37957:22;;;;37871:142;;37926:12;37957:41;;37984:13;37957:41;:26;:41;:::i;:::-;37871:23;;;;-1:-1:-1;;;;;37871:36:0;;:142;;:36;:142;:::i;:::-;37798:496;;;38060:13;38035:6;:22;;;:38;38031:263;;;38104:178;38163:6;:12;;;38202:4;38226:41;38244:6;:22;;;38226:13;:17;;:41;;;;:::i;:::-;38104:23;;;;-1:-1:-1;;;;;38104:40:0;;:178;;;:40;:178;:::i;:::-;38338:13;38318:17;:33;38314:476;;;38437:12;;;;38382:137;;38468:36;:17;38490:13;38468:36;:21;:36;:::i;38382:137::-;38314:476;;;38561:13;38541:17;:33;38537:253;;;38664:12;;;;38605:173;;38703:4;38727:36;:13;38745:17;38727:36;:17;:36;:::i;38605:173::-;38861:23;;;;38810:132;;38899:32;:13;38917;38899:32;:17;:32;:::i;38810:132::-;36732:2218;;;;;;:::o;33697:1457::-;33882:21;33906:39;33926:6;:18;;;33906:6;:15;;;:19;;:39;;;;:::i;:::-;33882:63;;33956:21;33980:39;34000:6;:18;;;33980:6;:15;;;:19;;:39;;;;:::i;:::-;33956:63;;34040:209;34150:6;:12;;;34181:6;:12;;;34212:6;:22;;;34040:12;:22;;;34063:36;34076:12;:22;;;34063:12;:36::i;34040:209::-;34335:12;;34362:23;;;;34400:22;;;;34280:172;;34335:12;34362:23;34400:41;;34427:13;34400:41;:26;:41;:::i;:::-;34280:23;;;;-1:-1:-1;;;;;34280:40:0;;:172;;;:40;:172;:::i;:::-;34492:13;34467:6;:22;;;:38;34463:552;;;34536:188;34595:15;:23;;;34637:6;:12;;;34668:41;34695:13;34668:6;:22;;;:26;;:41;;;;:::i;34536:188::-;34463:552;;;34771:13;34746:6;:22;;;:38;34742:273;;;34815:188;34874:6;:12;;;34905:15;:23;;;34947:41;34965:6;:22;;;34947:13;:17;;:41;;;;:::i;35168:1421::-;35352:21;35376:39;35396:6;:18;;;35376:6;:15;;;:19;;:39;;;;:::i;:::-;35352:63;;35426:21;35450:39;35470:6;:18;;;35450:6;:15;;;:19;;:39;;;;:::i;:::-;35606:12;;35637;;;;35668:22;;;;35510;;;;35533;;;;35426:63;;-1:-1:-1;35510:195:0;;:46;;;;;;:195;35755:13;35730:6;:22;;;:38;35726:530;;;35858:12;;;;35889;;35920:22;;;;35799:177;;35858:12;35889;35920:41;;35947:13;35920:41;:26;:41;:::i;35799:177::-;35726:530;;;36023:13;35998:6;:22;;;:38;35994:262;;;36067:177;36126:6;:12;;;36157:6;:12;;;36188:41;36206:6;:22;;;36188:13;:17;;:41;;;;:::i;36067:177::-;36276:163;36331:6;:12;;;36358:15;:23;;;36396:32;36414:13;36396;:17;;:32;;;;:::i;38964:2160::-;39159:24;39186:91;39227:12;:27;;;-1:-1:-1;;;;;39227:47:0;;:49;;;;;-1:-1:-1;;;39227:49:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39227:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;39227:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;39227:49:0;;;;;;;;;39186:22;;;;;:91;:40;:91;:::i;:::-;39159:118;;39288:32;39323:101;39364:12;:27;;;-1:-1:-1;;;;;39364:57:0;;:59;;;;;-1:-1:-1;;;39364:59:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39364:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;39364:59:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;39364:59:0;;;;;;;;;39323:22;;;;;:101;:40;:101;:::i;:::-;39288:136;;39435:15;39453:36;39473:6;:15;;;39453:6;:15;;;:19;;:36;;;;:::i;:::-;39435:54;;39500:20;39523:42;39546:6;:18;;;39523:6;:18;;;:22;;:42;;;;:::i;:::-;39500:65;;39617:7;39590:24;:34;39586:395;;;39700:23;;;;39641:185;;39750:4;39774:37;:24;39803:7;39774:37;:28;:37;:::i;:::-;39641:23;;;;-1:-1:-1;;;;;39641:40:0;;:185;;;:40;:185;:::i;:::-;39586:395;;;39875:7;39848:24;:34;39844:137;;;39914:55;39944:24;39914:25;:12;39931:7;39914:25;:16;:25;:::i;:55::-;39899:70;;39844:137;40011:224;40066:6;:12;;;40101:4;40121:103;40205:6;:18;;;40121:61;40166:6;:15;;;40121:6;:22;;;:44;;:61;;;;:::i;:::-;:83;:103;:83;:103;:::i;40011:224::-;40256:264;40311:6;:12;;;40346:4;40366:143;40490:6;:18;;;40366:101;40451:6;:15;;;40366:62;40405:6;:22;;;40366:16;:38;;:62;;;;:::i;40256:264::-;40541:56;40560:12;40574:6;:22;;;40541:18;:56::i;:::-;40628:160;40720:6;:12;;;40751:6;:22;;;40628:12;:22;;;40651:12;:22;;;40628:46;;;;;;;;;;;;;-1:-1:-1;;;;;40628:73:0;;:160;;:73;:160;:::i;:::-;40809:174;40915:6;:12;;;40946:6;:22;;;40809:12;:22;;;40832:36;40845:12;:22;;;40832:12;:36::i;:::-;40809:60;;;;;;:174;41004:112;41055:15;:23;;;41093:12;41004;:23;;;-1:-1:-1;;;;;41004:36:0;;;:112;;;;;:::i;:::-;38964:2160;;;;;;;:::o;13686:216::-;13746:4;13847:20;;13886:8;;13686:216::o;36597:121::-;36656:7;36683:12;;:27;;16178:1;36683:27;;;-1:-1:-1;16218:1:0;;36597:121;-1:-1:-1;36597:121:0:o;3540:106::-;3598:7;3629:1;3625;:5;:13;;3637:1;3625:13;;;-1:-1:-1;3633:1:0;;3540:106;-1:-1:-1;3540:106:0:o;1822:181::-;1880:7;1912:5;;;1936:6;;;;1928:46;;;;-1:-1:-1;;;;;1928:46:0;;;;;;;;23048:351;23174:7;23206:185;23389:1;23206:164;23325:12;:27;;;-1:-1:-1;;;;;23325:42:0;;:44;;;;;-1:-1:-1;;;23325:44:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23325:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23325:44:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;23325:44:0;;;;;;;;;23206:100;23264:12;:27;;;-1:-1:-1;;;;;23264:39:0;;:41;;;;;-1:-1:-1;;;23264:41:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23264:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23264:41:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;23264:41:0;;;;;;;;;23206:12;:27;;;-1:-1:-1;;;;;23206:37:0;;:39;;;;;-1:-1:-1;;;23206:39:0;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23206:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23206:39:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;23206:39:0;;;;;;;;5919:150;6023:38;6031:29;6045:13;;;6031:29;6023:38;5919:150;;;:::o;2509:199::-;2567:7;2605:5;;;2597:44;;;;-1:-1:-1;;;;;2597:44:0;;;;;;;;;2652:9;2668:1;2664;:5;;;;;;;;;2509:199;-1:-1:-1;;;;2509:199:0:o;6077:151::-;6181:39;6189:30;6203:14;;;6189:30;6181:39;6077:151;;;:::o;14185:204::-;14312:68;;14286:95;;14305:5;;14335:27;;14312:68;;14364:4;;14370:2;;14374:5;;14312:68;;;;41647:472;41815:18;;41766:34;;-1:-1:-1;;;;;41815:18:0;:34;41811:204;;-1:-1:-1;41903:18:0;;-1:-1:-1;;;;;41903:18:0;41811:204;;;-1:-1:-1;41972:31:0;;;;41811:204;42069:27;;42025:86;;;;;-1:-1:-1;;;;;42025:35:0;;;;;:86;;42069:27;42099:11;;42025:86;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42025:86:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;41150:471:0;41314:18;;41265:34;;-1:-1:-1;;;;;41314:18:0;:34;41310:204;;-1:-1:-1;41402:18:0;;-1:-1:-1;;;;;41402:18:0;41310:204;;;-1:-1:-1;41471:31:0;;;;41310:204;41566:27;;41524:89;;;;;-1:-1:-1;;;;;41524:33:0;;;;;:89;;41566:27;41596:9;;41566:27;;41524:89;;;;15941:26181;;;;;;;;;-1:-1:-1;15941:26181:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;15941:26181:0;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;;;;;15941:26181:0;;;;;;-1:-1:-1;;;;;15941:26181:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15941:26181:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;105:10:-1;15941:26181:0;88:34:-1;-1:-1;15941:26181:0;;;-1:-1:-1;;15941:26181:0:o;5:118:-1:-;;72:46;110:6;97:20;72:46;;130:122;;208:39;239:6;233:13;208:39;;299:781;;433:4;421:17;;417:27;-1:-1;407:2;;458:1;455;448:12;407:2;495:6;482:20;517:104;532:88;613:6;532:88;;;517:104;;;508:113;;638:5;663:6;656:5;649:21;693:4;685:6;681:17;671:27;;715:4;710:3;706:14;699:21;;768:6;816:3;807:5;799:6;795:18;790:3;786:28;783:37;780:2;;;833:1;830;823:12;780:2;858:1;843:231;868:6;865:1;862:13;843:231;;;926:3;948:61;1005:3;993:10;948:61;;;936:74;;-1:-1;1033:4;1024:14;;;;1061:5;1052:15;;;;;890:1;883:9;843:231;;;847:14;400:680;;;;;;;;1106:707;;1216:4;1204:17;;1200:27;-1:-1;1190:2;;1241:1;1238;1231:12;1190:2;1278:6;1265:20;1300:80;1315:64;1372:6;1315:64;;1300:80;1291:89;;1397:5;1422:6;1415:5;1408:21;1452:4;1444:6;1440:17;1430:27;;1474:4;1469:3;1465:14;1458:21;;1527:6;1574:3;1566:4;1558:6;1554:17;1549:3;1545:27;1542:36;1539:2;;;1591:1;1588;1581:12;1539:2;1616:1;1601:206;1626:6;1623:1;1620:13;1601:206;;;1684:3;1706:37;1739:3;1727:10;1706:37;;;1694:50;;-1:-1;1767:4;1758:14;;;;1786;;;;;1648:1;1641:9;1601:206;;1821:116;;1896:36;1924:6;1918:13;1896:36;;1944:118;;2011:46;2049:6;2036:20;2011:46;;2110:494;;2232:4;2220:9;2215:3;2211:19;2207:30;2204:2;;;2250:1;2247;2240:12;2204:2;2268:20;2283:4;2268:20;;;2259:29;-1:-1;2355:1;2386:49;2431:3;2411:9;2386:49;;;2362:74;;-1:-1;2500:2;2533:49;2578:3;2554:22;;;2533:49;;;2526:4;2519:5;2515:16;2508:75;2457:137;2198:406;;;;;2647:1090;;2760:5;2748:9;2743:3;2739:19;2735:31;2732:2;;;2779:1;2776;2769:12;2732:2;2797:20;2812:4;2797:20;;;2788:29;-1:-1;2869:1;2900:49;2945:3;2925:9;2900:49;;;2876:74;;-1:-1;3013:2;3046:49;3091:3;3067:22;;;3046:49;;;3039:4;3032:5;3028:16;3021:75;2971:136;3158:2;3191:49;3236:3;3227:6;3216:9;3212:22;3191:49;;;3184:4;3177:5;3173:16;3166:75;3117:135;3312:2;3345:49;3390:3;3381:6;3370:9;3366:22;3345:49;;;3338:4;3331:5;3327:16;3320:75;3262:144;3456:3;3490:49;3535:3;3526:6;3515:9;3511:22;3490:49;;;3483:4;3476:5;3472:16;3465:75;3416:135;3606:3;3640:75;3711:3;3702:6;3691:9;3687:22;3640:75;;;3633:4;3626:5;3622:16;3615:101;3561:166;2726:1011;;;;;4922:607;;5037:4;5025:9;5020:3;5016:19;5012:30;5009:2;;;5055:1;5052;5045:12;5009:2;5073:20;5088:4;5073:20;;;5064:29;-1:-1;5145:1;5176:49;5221:3;5201:9;5176:49;;;5152:74;;-1:-1;5284:2;5317:49;5362:3;5338:22;;;5317:49;;;5310:4;5303:5;5299:16;5292:75;5247:131;5425:2;5458:49;5503:3;5494:6;5483:9;5479:22;5458:49;;;5451:4;5444:5;5440:16;5433:75;5388:131;5003:526;;;;;5564:1221;;5675:4;5663:9;5658:3;5654:19;5650:30;5647:2;;;5693:1;5690;5683:12;5647:2;5711:20;5726:4;5711:20;;;5702:29;-1:-1;5783:1;5814:49;5859:3;5839:9;5814:49;;;5790:74;;-1:-1;5928:2;5961:49;6006:3;5982:22;;;5961:49;;;5954:4;5947:5;5943:16;5936:75;5885:137;6089:2;6122:49;6167:3;6158:6;6147:9;6143:22;6122:49;;;6115:4;6108:5;6104:16;6097:75;6032:151;6235:2;6268:49;6313:3;6304:6;6293:9;6289:22;6268:49;;;6261:4;6254:5;6250:16;6243:75;6193:136;6380:3;6414:49;6459:3;6450:6;6439:9;6435:22;6414:49;;;6407:4;6400:5;6396:16;6389:75;6339:136;6535:3;6569:49;6614:3;6605:6;6594:9;6590:22;6569:49;;;6562:4;6555:5;6551:16;6544:75;6485:145;6680:3;6714:49;6759:3;6750:6;6739:9;6735:22;6714:49;;;6707:4;6700:5;6696:16;6689:75;6640:135;5641:1144;;;;;6917:122;;6995:39;7026:6;7020:13;6995:39;;7046:241;;7150:2;7138:9;7129:7;7125:23;7121:32;7118:2;;;7166:1;7163;7156:12;7118:2;7201:1;7218:53;7263:7;7243:9;7218:53;;7294:263;;7409:2;7397:9;7388:7;7384:23;7380:32;7377:2;;;7425:1;7422;7415:12;7377:2;7460:1;7477:64;7533:7;7513:9;7477:64;;7564:366;;;7685:2;7673:9;7664:7;7660:23;7656:32;7653:2;;;7701:1;7698;7691:12;7653:2;7736:1;7753:53;7798:7;7778:9;7753:53;;;7743:63;;7715:97;7843:2;7861:53;7906:7;7897:6;7886:9;7882:22;7861:53;;;7851:63;;7822:98;7647:283;;;;;;7937:491;;;;8075:2;8063:9;8054:7;8050:23;8046:32;8043:2;;;8091:1;8088;8081:12;8043:2;8126:1;8143:53;8188:7;8168:9;8143:53;;;8133:63;;8105:97;8233:2;8251:53;8296:7;8287:6;8276:9;8272:22;8251:53;;;8241:63;;8212:98;8341:2;8359:53;8404:7;8395:6;8384:9;8380:22;8359:53;;;8349:63;;8320:98;8037:391;;;;;;8435:366;;;8556:2;8544:9;8535:7;8531:23;8527:32;8524:2;;;8572:1;8569;8562:12;8524:2;8607:1;8624:53;8669:7;8649:9;8624:53;;;8614:63;;8586:97;8714:2;8732:53;8777:7;8768:6;8757:9;8753:22;8732:53;;8808:257;;8920:2;8908:9;8899:7;8895:23;8891:32;8888:2;;;8936:1;8933;8926:12;8888:2;8971:1;8988:61;9041:7;9021:9;8988:61;;9072:241;;9176:2;9164:9;9155:7;9151:23;9147:32;9144:2;;;9192:1;9189;9182:12;9144:2;9227:1;9244:53;9289:7;9269:9;9244:53;;9320:1062;;;;;9610:3;9598:9;9589:7;9585:23;9581:33;9578:2;;;9627:1;9624;9617:12;9578:2;9662:1;9679:81;9752:7;9732:9;9679:81;;;9669:91;;9641:125;9825:3;9814:9;9810:19;9797:33;9850:18;9842:6;9839:30;9836:2;;;9882:1;9879;9872:12;9836:2;9902:102;9996:7;9987:6;9976:9;9972:22;9902:102;;;9892:112;;9776:234;10069:3;10058:9;10054:19;10041:33;10094:18;10086:6;10083:30;10080:2;;;10126:1;10123;10116:12;10080:2;10146:78;10216:7;10207:6;10196:9;10192:22;10146:78;;;10136:88;;10020:210;10261:3;10280:86;10358:7;10349:6;10338:9;10334:22;10280:86;;;10270:96;;10240:132;9572:810;;;;;;;;10389:286;;10515:3;10503:9;10494:7;10490:23;10486:33;10483:2;;;10532:1;10529;10522:12;10483:2;10567:1;10584:75;10651:7;10631:9;10584:75;;10682:263;;10797:2;10785:9;10776:7;10772:23;10768:32;10765:2;;;10813:1;10810;10803:12;10765:2;10848:1;10865:64;10921:7;10901:9;10865:64;;10952:110;11025:31;11050:5;11025:31;;;11020:3;11013:44;11007:55;;;11069:101;11136:28;11158:5;11136:28;;11177:110;11250:31;11275:5;11250:31;;11294:140;11379:49;11422:5;11379:49;;11441:292;;11539:35;11568:5;11539:35;;;11591:6;11586:3;11579:19;11603:63;11659:6;11652:4;11647:3;11643:14;11636:4;11629:5;11625:16;11603:63;;;11698:29;11720:6;11698:29;;;11678:50;;;11691:4;11678:50;;11519:214;-1:-1;;;11519:214;11741:296;11896:2;11884:15;;11933:66;11928:2;11919:12;;11912:88;12028:2;12019:12;;11877:160;12046:296;12201:2;12189:15;;;12238:66;12224:12;;;12217:88;12333:2;12324:12;;12182:160;12351:296;12506:2;12494:15;;12543:66;12538:2;12529:12;;12522:88;12638:2;12629:12;;12487:160;12656:296;12811:2;12799:15;;12848:66;12843:2;12834:12;;12827:88;12943:2;12934:12;;12792:160;12961:296;13116:2;13104:15;;13153:66;13148:2;13139:12;;13132:88;13248:2;13239:12;;13097:160;13266:397;13421:2;13409:15;;13458:66;13453:2;13444:12;;13437:88;13559:66;13554:2;13545:12;;13538:88;13654:2;13645:12;;13402:261;13672:296;13827:2;13815:15;;13864:66;13859:2;13850:12;;13843:88;13959:2;13950:12;;13808:160;13977:295;14132:1;14120:14;;14168:66;14163:2;14154:12;;14147:88;14263:2;14254:12;;14113:159;14281:296;14436:2;14424:15;;14473:66;14468:2;14459:12;;14452:88;14568:2;14559:12;;14417:160;14586:397;14741:2;14729:15;;14778:66;14773:2;14764:12;;14757:88;14879:66;14874:2;14865:12;;14858:88;14974:2;14965:12;;14722:261;14992:397;15147:2;15135:15;;15184:66;15179:2;15170:12;;15163:88;15285:66;15280:2;15271:12;;15264:88;15380:2;15371:12;;15128:261;15398:296;15553:2;15541:15;;15590:66;15585:2;15576:12;;15569:88;15685:2;15676:12;;15534:160;15773:1743;15985:22;;15914:5;15905:15;;;16019:61;15909:3;15985:22;16019:61;;;15935:157;16169:4;16162:5;16158:16;16152:23;16187:62;16243:4;16238:3;16234:14;16221:11;16187:62;;;16102:159;16341:4;16334:5;16330:16;16324:23;16359:62;16415:4;16410:3;16406:14;16393:11;16359:62;;;16271:162;16513:4;16506:5;16502:16;16496:23;16531:62;16587:4;16582:3;16578:14;16565:11;16531:62;;;16443:162;16688:4;16681:5;16677:16;16671:23;16706:62;16762:4;16757:3;16753:14;16740:11;16706:62;;;16615:165;16863:4;16856:5;16852:16;16846:23;16881:62;16937:4;16932:3;16928:14;16915:11;16881:62;;;16790:165;17042:4;17035:5;17031:16;17025:23;17060:62;17116:4;17111:3;17107:14;17094:11;17060:62;;;16965:169;17221:4;17214:5;17210:16;17204:23;17239:62;17295:4;17290:3;17286:14;17273:11;17239:62;;;17144:169;17395:5;17388;17384:17;17378:24;17414:75;17482:5;17477:3;17473:15;17460:11;17414:75;;17602:528;17837:22;;17751:4;17742:14;;;17871:61;17746:3;17837:22;17871:61;;;17771:173;18023:4;18016:5;18012:16;18006:23;18041:62;18097:4;18092:3;18088:14;18075:11;18041:62;;18254:193;18362:2;18347:18;;18376:61;18351:9;18410:6;18376:61;;18454:294;18590:2;18575:18;;18604:61;18579:9;18638:6;18604:61;;;18676:62;18734:2;18723:9;18719:18;18710:6;18676:62;;18755:395;18919:2;18904:18;;18933:61;18908:9;18967:6;18933:61;;;19005:62;19063:2;19052:9;19048:18;19039:6;19005:62;;;19078;19136:2;19125:9;19121:18;19112:6;19078:62;;19157:294;19293:2;19278:18;;19307:61;19282:9;19341:6;19307:61;;;19379:62;19437:2;19426:9;19422:18;19413:6;19379:62;;19458:383;19616:2;19601:18;;19630:61;19605:9;19664:6;19630:61;;;19702:62;19760:2;19749:9;19745:18;19736:6;19702:62;;;19775:56;19827:2;19816:9;19812:18;19803:6;19775:56;;19848:181;19950:2;19935:18;;19964:55;19939:9;19992:6;19964:55;;20036:193;20144:2;20129:18;;20158:61;20133:9;20192:6;20158:61;;20236:273;20360:2;20374:47;;;20345:18;;20435:64;20345:18;20485:6;20435:64;;20516:387;20697:2;20711:47;;;20682:18;;20772:121;20682:18;20772:121;;20910:387;21091:2;21105:47;;;21076:18;;21166:121;21076:18;21166:121;;21304:387;21485:2;21499:47;;;21470:18;;21560:121;21470:18;21560:121;;21698:387;21879:2;21893:47;;;21864:18;;21954:121;21864:18;21954:121;;22092:387;22273:2;22287:47;;;22258:18;;22348:121;22258:18;22348:121;;22486:387;22667:2;22681:47;;;22652:18;;22742:121;22652:18;22742:121;;22880:387;23061:2;23075:47;;;23046:18;;23136:121;23046:18;23136:121;;23274:387;23455:2;23469:47;;;23440:18;;23530:121;23440:18;23530:121;;23668:387;23849:2;23863:47;;;23834:18;;23924:121;23834:18;23924:121;;24062:387;24243:2;24257:47;;;24228:18;;24318:121;24228:18;24318:121;;24456:387;24637:2;24651:47;;;24622:18;;24712:121;24622:18;24712:121;;24850:387;25031:2;25045:47;;;25016:18;;25106:121;25016:18;25106:121;;25244:543;25504:3;25489:19;;25519:127;25493:9;25619:6;25519:127;;;25657:120;25773:2;25762:9;25758:18;25749:6;25657:120;;25994:256;26056:2;26050:9;26082:17;;;26157:18;26142:34;;26178:22;;;26139:62;26136:2;;;26214:1;26211;26204:12;26136:2;26230;26223:22;26034:216;;-1:-1;26034:216;26257:282;;26440:18;26432:6;26429:30;26426:2;;;26472:1;26469;26462:12;26426:2;-1:-1;26501:4;26489:17;;;26519:15;;26363:176;26811:88;26882:12;;26866:33;26906:105;;26975:31;27000:5;26975:31;;27018:92;27091:13;27084:21;;27067:43;27117:79;27186:5;27169:27;27203:131;;27295:1;27285:12;;27275:2;;27301:9;27275:2;-1:-1;27324:5;27269:65;27341:128;-1:-1;;;;;27410:54;;27393:76;27945:141;;28036:45;28075:5;28036:45;;28094:268;28159:1;28166:101;28180:6;28177:1;28174:13;28166:101;;;28247:11;;;28241:18;28228:11;;;28221:39;28202:2;28195:10;28166:101;;;28282:6;28279:1;28276:13;28273:2;;;-1:-1;;28347:1;28329:16;;28322:27;28143:219;28370:97;28458:2;28438:14;-1:-1;;28434:28;;28418:49

Swarm Source

bzzr://c604f26f79328a69aa655e95cea7af2e9177b3cbc22fe884d27c364bf1805dc2

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.