Contract 0xd216153c06e857cd7f72665e0af1d7d82172f494 6

 
Ad
Ad
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x11b6f1a222d4a088359bf870937de50c1ea80429282315296c21a9dfd8aaf1e4Relay Call(pending)2021-11-28 11:56:033 secs ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN 0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC(Pending)
0xcc06db8ee8e6a2cbe9188a0fced0c28a2545712ee6aa8b094342124dca1c47c7Relay Call218972002021-11-28 11:29:5226 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.060879346
0x2fa99afd6dfb51e6ab47e03c49a7cfe781540ee232a7e30fc6510885447ef236Relay Call218971572021-11-28 11:28:2627 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.062683335
0x9a2785c2f614a0e5924ee71396b44774bc8cb223886948704a1b3caa63619741Relay Call218970882021-11-28 11:23:5832 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.104911103715
0x41f71c56f250048df5f4c34721883f71b412989fabe1e8235498ce35cc649a0cRelay Call218969162021-11-28 11:15:5240 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.08261643
0x06d70ffa3863bed3374bde2302e0c18680bd477b89a035ad8580dcc201d97a9eRelay Call218968862021-11-28 11:14:4841 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.038987088
0x949a9bf1b2c2a03490a747b6266e8f5a038e1b934b52c99db1df024429ecee5fRelay Call218968672021-11-28 11:14:1041 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.061199712
0x9d53767ab145d12bf43f2c83a5fadd2b3569f312eee9704fcfe49e944106bf00Relay Call218968322021-11-28 11:13:0043 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.1485799796
0xb0cc8673f88926adf4867c875b34d4d220e91d6b7de6db630d7047092eda8ceeRelay Call218967962021-11-28 11:11:4444 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.038987088
0x4e56b51bed0e0210d404ec9f5b6241a115888ac00812aca1e7c413a5729f9368Relay Call218967802021-11-28 11:11:1244 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.0673219008
0xb10bf96342c26a8c97ab305645d751e279d0a55042ae56a6f4ae224220b5ed97Relay Call218967672021-11-28 11:10:4245 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.078260952
0x63a606c1e9fc3f7c849d1c50324026278cc34c83e1faae1e8e6f9548da71cefeRelay Call218967112021-11-28 11:08:5047 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.05508102
0x0b0c95a194869290f086312a68fddc204756fab8e29cd40ea511fd4e95157794Relay Call218966742021-11-28 11:07:3248 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.068684184
0x4a6d8838c37629de1e4190c77128209d721f5ba3c6e8f10532fff1fe2aed46e8Relay Call218966382021-11-28 11:06:1549 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.065445172
0x60a81d0309b2dfb6c302355939878d23edd9cc431e8facc62d871d5e624264f8Relay Call218965992021-11-28 11:04:5751 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.0576916076
0x7542872c2575c8856c0f65eb9ca8dbf6ed694d2909cdc55b47cac6a7598ddf20Relay Call218965882021-11-28 11:04:3551 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.080391656
0xdd6a8884992b4da25d53b78101df484744396a484eb8b3ee34a4e75cfafb8046Relay Call218965872021-11-28 11:04:3351 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.093615848
0x9e233985d4576453e9d9bcd08b8bd1f7109315795610bbaabdc81a5929d0c11dRelay Call218963692021-11-28 10:54:431 hr 1 min ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.05564808
0x2ddc9744db57dadcaee321049843b6a430c9d9aaa07857bf4a7ebb74bca77ba3Relay Call218961372021-11-28 10:46:471 hr 9 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.033260976
0xd3c7e6ff485700bf7f7c081e8ca3f7a3bf5154b82551a6985692734358155d44Relay Call218961252021-11-28 10:46:191 hr 9 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.037187976
0xe9e1b228bc2ce870ff11728800c66e0a2022f407ada1d749e4ebe1f444834a85Relay Call218959562021-11-28 10:38:251 hr 17 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.06800442
0x6c86f291fc9fb0b053ad9ab3d1456aab396343bb431ddb4c2a8ea0dcee780c21Relay Call218959072021-11-28 10:36:431 hr 19 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.04162653
0x3292fbf16c65829575eae8b6ceb7be7c3deca59f31878d4a53942d21e4c2a99bRelay Call218958882021-11-28 10:36:051 hr 20 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.043512084
0x0c3b9d422bc3dad8634a70ae089b3e7f8e642be69b52693790c85babe127d0c0Relay Call218958682021-11-28 10:35:211 hr 20 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.039730635
0xcbfc6d860866705b8bf3b34e8d5340e3dd9b34523951032a117d2430f6fbdd0cRelay Call218958442021-11-28 10:34:331 hr 21 mins ago0x3a9a17241db35c6722b63db2e66186cfe2d3ca65 IN  0xd216153c06e857cd7f72665e0af1d7d82172f4940 MATIC0.04822194
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RelayHub

Compiler Version
v0.5.10+commit.5a6ea5b1

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2021-06-22
*/

// File: contracts/IRelayHub.sol

pragma solidity ^0.5.5;

contract IRelayHub {
    // Relay management

    // Add stake to a relay and sets its unstakeDelay.
    // If the relay does not exist, it is created, and the caller
    // of this function becomes its owner. If the relay already exists, only the owner can call this function. A relay
    // cannot be its own owner.
    // All Ether in this function call will be added to the relay's stake.
    // Its unstake delay will be assigned to unstakeDelay, but the new value must be greater or equal to the current one.
    // Emits a Staked event.
    function stake(address relayaddr, uint256 unstakeDelay) external payable;

    // Emited when a relay's stake or unstakeDelay are increased
    event Staked(address indexed relay, uint256 stake, uint256 unstakeDelay);

    // Registers the caller as a relay.
    // The relay must be staked for, and not be a contract (i.e. this function must be called directly from an EOA).
    // Emits a RelayAdded event.
    // This function can be called multiple times, emitting new RelayAdded events. Note that the received transactionFee
    // is not enforced by relayCall.
    function registerRelay(uint256 transactionFee, string memory url) public;

    // Emitted when a relay is registered or re-registerd. Looking at these events (and filtering out RelayRemoved
    // events) lets a client discover the list of available relays.
    event RelayAdded(address indexed relay, address indexed owner, uint256 transactionFee, uint256 stake, uint256 unstakeDelay, string url);

    // Removes (deregisters) a relay. Unregistered (but staked for) relays can also be removed. Can only be called by
    // the owner of the relay. After the relay's unstakeDelay has elapsed, unstake will be callable.
    // Emits a RelayRemoved event.
    function removeRelayByOwner(address relay) public;

    // Emitted when a relay is removed (deregistered). unstakeTime is the time when unstake will be callable.
    event RelayRemoved(address indexed relay, uint256 unstakeTime);

    // Deletes the relay from the system, and gives back its stake to the owner. Can only be called by the relay owner,
    // after unstakeDelay has elapsed since removeRelayByOwner was called.
    // Emits an Unstaked event.
    function unstake(address relay) public;

    // Emitted when a relay is unstaked for, including the returned stake.
    event Unstaked(address indexed relay, uint256 stake);

    // States a relay can be in
    enum RelayState {
        Unknown, // The relay is unknown to the system: it has never been staked for
        Staked, // The relay has been staked for, but it is not yet active
        Registered, // The relay has registered itself, and is active (can relay calls)
        Removed    // The relay has been removed by its owner and can no longer relay calls. It must wait for its unstakeDelay to elapse before it can unstake
    }

    // Returns a relay's status. Note that relays can be deleted when unstaked or penalized.
    function getRelay(address relay) external view returns (uint256 totalStake, uint256 unstakeDelay, uint256 unstakeTime, address payable owner, RelayState state);

    // Balance management

    // Deposits ether for a contract, so that it can receive (and pay for) relayed transactions. Unused balance can only
    // be withdrawn by the contract itself, by callingn withdraw.
    // Emits a Deposited event.
    function depositFor(address target) public payable;

    // Emitted when depositFor is called, including the amount and account that was funded.
    event Deposited(address indexed recipient, address indexed from, uint256 amount);

    // Returns an account's deposits. These can be either a contnract's funds, or a relay owner's revenue.
    function balanceOf(address target) external view returns (uint256);

    // Withdraws from an account's balance, sending it back to it. Relay owners call this to retrieve their revenue, and
    // contracts can also use it to reduce their funding.
    // Emits a Withdrawn event.
    function withdraw(uint256 amount, address payable dest) public;

    // Emitted when an account withdraws funds from RelayHub.
    event Withdrawn(address indexed account, address indexed dest, uint256 amount);

    // Relaying

    // Check if the RelayHub will accept a relayed operation. Multiple things must be true for this to happen:
    //  - all arguments must be signed for by the sender (from)
    //  - the sender's nonce must be the current one
    //  - the recipient must accept this transaction (via acceptRelayedCall)
    // Returns a PreconditionCheck value (OK when the transaction can be relayed), or a recipient-specific error code if
    // it returns one in acceptRelayedCall.
    function canRelay(
        address relay,
        address from,
        address to,
        bytes memory encodedFunction,
        uint256 transactionFee,
        uint256 gasPrice,
        uint256 gasLimit,
        uint256 nonce,
        bytes memory signature,
        bytes memory approvalData
    ) public view returns (uint256 status, bytes memory recipientContext);

    // Preconditions for relaying, checked by canRelay and returned as the corresponding numeric values.
    enum PreconditionCheck {
        OK,                         // All checks passed, the call can be relayed
        WrongSignature,             // The transaction to relay is not signed by requested sender
        WrongNonce,                 // The provided nonce has already been used by the sender
        AcceptRelayedCallReverted,  // The recipient rejected this call via acceptRelayedCall
        InvalidRecipientStatusCode  // The recipient returned an invalid (reserved) status code
    }

    // Relays a transaction. For this to suceed, multiple conditions must be met:
    //  - canRelay must return PreconditionCheck.OK
    //  - the sender must be a registered relay
    //  - the transaction's gas price must be larger or equal to the one that was requested by the sender
    //  - the transaction must have enough gas to not run out of gas if all internal transactions (calls to the
    // recipient) use all gas available to them
    //  - the recipient must have enough balance to pay the relay for the worst-case scenario (i.e. when all gas is
    // spent)
    //
    // If all conditions are met, the call will be relayed and the recipient charged. preRelayedCall, the encoded
    // function and postRelayedCall will be called in order.
    //
    // Arguments:
    //  - from: the client originating the request
    //  - recipient: the target IRelayRecipient contract
    //  - encodedFunction: the function call to relay, including data
    //  - transactionFee: fee (%) the relay takes over actual gas cost
    //  - gasPrice: gas price the client is willing to pay
    //  - gasLimit: gas to forward when calling the encoded function
    //  - nonce: client's nonce
    //  - signature: client's signature over all previous params, plus the relay and RelayHub addresses
    //  - approvalData: dapp-specific data forwared to acceptRelayedCall. This value is *not* verified by the Hub, but
    //    it still can be used for e.g. a signature.
    //
    // Emits a TransactionRelayed event.
    function relayCall(
        address from,
        address to,
        bytes memory encodedFunction,
        uint256 transactionFee,
        uint256 gasPrice,
        uint256 gasLimit,
        uint256 nonce,
        bytes memory signature,
        bytes memory approvalData
    ) public;

    // Emitted when an attempt to relay a call failed. This can happen due to incorrect relayCall arguments, or the
    // recipient not accepting the relayed call. The actual relayed call was not executed, and the recipient not charged.
    // The reason field contains an error code: values 1-10 correspond to PreconditionCheck entries, and values over 10
    // are custom recipient error codes returned from acceptRelayedCall.
    event CanRelayFailed(address indexed relay, address indexed from, address indexed to, bytes4 selector, uint256 reason);

    // Emitted when a transaction is relayed. Note that the actual encoded function might be reverted: this will be
    // indicated in the status field.
    // Useful when monitoring a relay's operation and relayed calls to a contract.
    // Charge is the ether value deducted from the recipient's balance, paid to the relay's owner.
    event TransactionRelayed(address indexed relay, address indexed from, address indexed to, bytes4 selector, RelayCallStatus status, uint256 charge);

    // Reason error codes for the TransactionRelayed event
    enum RelayCallStatus {
        OK,                      // The transaction was successfully relayed and execution successful - never included in the event
        RelayedCallFailed,       // The transaction was relayed, but the relayed call failed
        PreRelayedFailed,        // The transaction was not relayed due to preRelatedCall reverting
        PostRelayedFailed,       // The transaction was relayed and reverted due to postRelatedCall reverting
        RecipientBalanceChanged  // The transaction was relayed and reverted due to the recipient's balance changing
    }

    // Returns how much gas should be forwarded to a call to relayCall, in order to relay a transaction that will spend
    // up to relayedCallStipend gas.
    function requiredGas(uint256 relayedCallStipend) public view returns (uint256);

    // Returns the maximum recipient charge, given the amount of gas forwarded, gas price and relay fee.
    function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) public view returns (uint256);

    // Relay penalization. Any account can penalize relays, removing them from the system immediately, and rewarding the
    // reporter with half of the relay's stake. The other half is burned so that, even if the relay penalizes itself, it
    // still loses half of its stake.

    // Penalize a relay that signed two transactions using the same nonce (making only the first one valid) and
    // different data (gas price, gas limit, etc. may be different). The (unsigned) transaction data and signature for
    // both transactions must be provided.
    function penalizeRepeatedNonce(bytes memory unsignedTx1, bytes memory signature1, bytes memory unsignedTx2, bytes memory signature2) public;

    // Penalize a relay that sent a transaction that didn't target RelayHub's registerRelay or relayCall.
    function penalizeIllegalTransaction(bytes memory unsignedTx, bytes memory signature) public;

    event Penalized(address indexed relay, address sender, uint256 amount);

    function getNonce(address from) view external returns (uint256);
}

// File: contracts/IRelayRecipient.sol

pragma solidity ^0.5.5;

contract IRelayRecipient {

    /**
     * return the relayHub of this contract.
     */
    function getHubAddr() public view returns (address);

    /**
     * return the contract's balance on the RelayHub.
     * can be used to determine if the contract can pay for incoming calls,
     * before making any.
     */
    function getRecipientBalance() public view returns (uint);

    /*
     * Called by Relay (and RelayHub), to validate if this recipient accepts this call.
     * Note: Accepting this call means paying for the tx whether the relayed call reverted or not.
     *
     *  @return "0" if the the contract is willing to accept the charges from this sender, for this function call.
     *      any other value is a failure. actual value is for diagnostics only.
     *      ** Note: values below 10 are reserved by canRelay

     *  @param relay the relay that attempts to relay this function call.
     *          the contract may restrict some encoded functions to specific known relays.
     *  @param from the sender (signer) of this function call.
     *  @param encodedFunction the encoded function call (without any ethereum signature).
     *          the contract may check the method-id for valid methods
     *  @param gasPrice - the gas price for this transaction
     *  @param transactionFee - the relay compensation (in %) for this transaction
     *  @param signature - sender's signature over all parameters except approvalData
     *  @param approvalData - extra dapp-specific data (e.g. signature from trusted party)
     */
     function acceptRelayedCall(
        address relay,
        address from,
        bytes calldata encodedFunction,
        uint256 transactionFee,
        uint256 gasPrice,
        uint256 gasLimit,
        uint256 nonce,
        bytes calldata approvalData,
        uint256 maxPossibleCharge
    )
    external
    view
    returns (uint256, bytes memory);

    /*
     * modifier to be used by recipients as access control protection for preRelayedCall & postRelayedCall
     */
    modifier relayHubOnly() {
        require(msg.sender == getHubAddr(),"Function can only be called by RelayHub");
        _;
    }

    /** this method is called before the actual relayed function call.
     * It may be used to charge the caller before (in conjuction with refunding him later in postRelayedCall for example).
     * the method is given all parameters of acceptRelayedCall and actual used gas.
     *
     *
     *** NOTICE: if this method modifies the contract's state, it must be protected with access control i.e. require msg.sender == getHubAddr()
     *
     *
     * Revert in this functions causes a revert of the client's relayed call but not in the entire transaction
     * (that is, the relay will still get compensated)
     */
    function preRelayedCall(bytes calldata context) external returns (bytes32);

    /** this method is called after the actual relayed function call.
     * It may be used to record the transaction (e.g. charge the caller by some contract logic) for this call.
     * the method is given all parameters of acceptRelayedCall, and also the success/failure status and actual used gas.
     *
     *
     *** NOTICE: if this method modifies the contract's state, it must be protected with access control i.e. require msg.sender == getHubAddr()
     *
     *
     * @param success - true if the relayed call succeeded, false if it reverted
     * @param actualCharge - estimation of how much the recipient will be charged. This information may be used to perform local booking and
     *   charge the sender for this call (e.g. in tokens).
     * @param preRetVal - preRelayedCall() return value passed back to the recipient
     *
     * Revert in this functions causes a revert of the client's relayed call but not in the entire transaction
     * (that is, the relay will still get compensated)
     */
    function postRelayedCall(bytes calldata context, bool success, uint actualCharge, bytes32 preRetVal) external;

}

// File: @0x/contracts-utils/contracts/src/LibBytes.sol

/*

  Copyright 2018 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

pragma solidity ^0.5.5;


library LibBytes {

    using LibBytes for bytes;

    /// @dev Gets the memory address for a byte array.
    /// @param input Byte array to lookup.
    /// @return memoryAddress Memory address of byte array. This
    ///         points to the header of the byte array which contains
    ///         the length.
    function rawAddress(bytes memory input)
        internal
        pure
        returns (uint256 memoryAddress)
    {
        assembly {
            memoryAddress := input
        }
        return memoryAddress;
    }
    
    /// @dev Gets the memory address for the contents of a byte array.
    /// @param input Byte array to lookup.
    /// @return memoryAddress Memory address of the contents of the byte array.
    function contentAddress(bytes memory input)
        internal
        pure
        returns (uint256 memoryAddress)
    {
        assembly {
            memoryAddress := add(input, 32)
        }
        return memoryAddress;
    }

    /// @dev Copies `length` bytes from memory location `source` to `dest`.
    /// @param dest memory address to copy bytes to.
    /// @param source memory address to copy bytes from.
    /// @param length number of bytes to copy.
    function memCopy(
        uint256 dest,
        uint256 source,
        uint256 length
    )
        internal
        pure
    {
        if (length < 32) {
            // Handle a partial word by reading destination and masking
            // off the bits we are interested in.
            // This correctly handles overlap, zero lengths and source == dest
            assembly {
                let mask := sub(exp(256, sub(32, length)), 1)
                let s := and(mload(source), not(mask))
                let d := and(mload(dest), mask)
                mstore(dest, or(s, d))
            }
        } else {
            // Skip the O(length) loop when source == dest.
            if (source == dest) {
                return;
            }

            // For large copies we copy whole words at a time. The final
            // word is aligned to the end of the range (instead of after the
            // previous) to handle partial words. So a copy will look like this:
            //
            //  ####
            //      ####
            //          ####
            //            ####
            //
            // We handle overlap in the source and destination range by
            // changing the copying direction. This prevents us from
            // overwriting parts of source that we still need to copy.
            //
            // This correctly handles source == dest
            //
            if (source > dest) {
                assembly {
                    // We subtract 32 from `sEnd` and `dEnd` because it
                    // is easier to compare with in the loop, and these
                    // are also the addresses we need for copying the
                    // last bytes.
                    length := sub(length, 32)
                    let sEnd := add(source, length)
                    let dEnd := add(dest, length)

                    // Remember the last 32 bytes of source
                    // This needs to be done here and not after the loop
                    // because we may have overwritten the last bytes in
                    // source already due to overlap.
                    let last := mload(sEnd)

                    // Copy whole words front to back
                    // Note: the first check is always true,
                    // this could have been a do-while loop.
                    // solhint-disable-next-line no-empty-blocks
                    for {} lt(source, sEnd) {} {
                        mstore(dest, mload(source))
                        source := add(source, 32)
                        dest := add(dest, 32)
                    }
                    
                    // Write the last 32 bytes
                    mstore(dEnd, last)
                }
            } else {
                assembly {
                    // We subtract 32 from `sEnd` and `dEnd` because those
                    // are the starting points when copying a word at the end.
                    length := sub(length, 32)
                    let sEnd := add(source, length)
                    let dEnd := add(dest, length)

                    // Remember the first 32 bytes of source
                    // This needs to be done here and not after the loop
                    // because we may have overwritten the first bytes in
                    // source already due to overlap.
                    let first := mload(source)

                    // Copy whole words back to front
                    // We use a signed comparisson here to allow dEnd to become
                    // negative (happens when source and dest < 32). Valid
                    // addresses in local memory will never be larger than
                    // 2**255, so they can be safely re-interpreted as signed.
                    // Note: the first check is always true,
                    // this could have been a do-while loop.
                    // solhint-disable-next-line no-empty-blocks
                    for {} slt(dest, dEnd) {} {
                        mstore(dEnd, mload(sEnd))
                        sEnd := sub(sEnd, 32)
                        dEnd := sub(dEnd, 32)
                    }
                    
                    // Write the first 32 bytes
                    mstore(dest, first)
                }
            }
        }
    }

    /// @dev Returns a slices from a byte array.
    /// @param b The byte array to take a slice from.
    /// @param from The starting index for the slice (inclusive).
    /// @param to The final index for the slice (exclusive).
    /// @return result The slice containing bytes at indices [from, to)
    function slice(
        bytes memory b,
        uint256 from,
        uint256 to
    )
        internal
        pure
        returns (bytes memory result)
    {
        require(
            from <= to,
            "FROM_LESS_THAN_TO_REQUIRED"
        );
        require(
            to <= b.length,
            "TO_LESS_THAN_LENGTH_REQUIRED"
        );
        
        // Create a new bytes structure and copy contents
        result = new bytes(to - from);
        memCopy(
            result.contentAddress(),
            b.contentAddress() + from,
            result.length
        );
        return result;
    }
    
    /// @dev Returns a slice from a byte array without preserving the input.
    /// @param b The byte array to take a slice from. Will be destroyed in the process.
    /// @param from The starting index for the slice (inclusive).
    /// @param to The final index for the slice (exclusive).
    /// @return result The slice containing bytes at indices [from, to)
    /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted.
    function sliceDestructive(
        bytes memory b,
        uint256 from,
        uint256 to
    )
        internal
        pure
        returns (bytes memory result)
    {
        require(
            from <= to,
            "FROM_LESS_THAN_TO_REQUIRED"
        );
        require(
            to <= b.length,
            "TO_LESS_THAN_LENGTH_REQUIRED"
        );
        
        // Create a new bytes structure around [from, to) in-place.
        assembly {
            result := add(b, from)
            mstore(result, sub(to, from))
        }
        return result;
    }

    /// @dev Pops the last byte off of a byte array by modifying its length.
    /// @param b Byte array that will be modified.
    /// @return The byte that was popped off.
    function popLastByte(bytes memory b)
        internal
        pure
        returns (bytes1 result)
    {
        require(
            b.length > 0,
            "GREATER_THAN_ZERO_LENGTH_REQUIRED"
        );

        // Store last byte.
        result = b[b.length - 1];

        assembly {
            // Decrement length of byte array.
            let newLen := sub(mload(b), 1)
            mstore(b, newLen)
        }
        return result;
    }

    /// @dev Pops the last 20 bytes off of a byte array by modifying its length.
    /// @param b Byte array that will be modified.
    /// @return The 20 byte address that was popped off.
    function popLast20Bytes(bytes memory b)
        internal
        pure
        returns (address result)
    {
        require(
            b.length >= 20,
            "GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED"
        );

        // Store last 20 bytes.
        result = readAddress(b, b.length - 20);

        assembly {
            // Subtract 20 from byte array length.
            let newLen := sub(mload(b), 20)
            mstore(b, newLen)
        }
        return result;
    }

    /// @dev Tests equality of two byte arrays.
    /// @param lhs First byte array to compare.
    /// @param rhs Second byte array to compare.
    /// @return True if arrays are the same. False otherwise.
    function equals(
        bytes memory lhs,
        bytes memory rhs
    )
        internal
        pure
        returns (bool equal)
    {
        // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.
        // We early exit on unequal lengths, but keccak would also correctly
        // handle this.
        return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);
    }

    /// @dev Reads an address from a position in a byte array.
    /// @param b Byte array containing an address.
    /// @param index Index in byte array of address.
    /// @return address from byte array.
    function readAddress(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (address result)
    {
        require(
            b.length >= index + 20,  // 20 is length of address
            "GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED"
        );

        // Add offset to index:
        // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
        // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)
        index += 20;

        // Read address from array memory
        assembly {
            // 1. Add index to address of bytes array
            // 2. Load 32-byte word from memory
            // 3. Apply 20-byte mask to obtain address
            result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)
        }
        return result;
    }

    /// @dev Writes an address into a specific position in a byte array.
    /// @param b Byte array to insert address into.
    /// @param index Index in byte array of address.
    /// @param input Address to put into byte array.
    function writeAddress(
        bytes memory b,
        uint256 index,
        address input
    )
        internal
        pure
    {
        require(
            b.length >= index + 20,  // 20 is length of address
            "GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED"
        );

        // Add offset to index:
        // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
        // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)
        index += 20;

        // Store address into array memory
        assembly {
            // The address occupies 20 bytes and mstore stores 32 bytes.
            // First fetch the 32-byte word where we'll be storing the address, then
            // apply a mask so we have only the bytes in the word that the address will not occupy.
            // Then combine these bytes with the address and store the 32 bytes back to memory with mstore.

            // 1. Add index to address of bytes array
            // 2. Load 32-byte word from memory
            // 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address
            let neighbors := and(
                mload(add(b, index)),
                0xffffffffffffffffffffffff0000000000000000000000000000000000000000
            )
            
            // Make sure input address is clean.
            // (Solidity does not guarantee this)
            input := and(input, 0xffffffffffffffffffffffffffffffffffffffff)

            // Store the neighbors and address into memory
            mstore(add(b, index), xor(input, neighbors))
        }
    }

    /// @dev Reads a bytes32 value from a position in a byte array.
    /// @param b Byte array containing a bytes32 value.
    /// @param index Index in byte array of bytes32 value.
    /// @return bytes32 value from byte array.
    function readBytes32(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (bytes32 result)
    {
        require(
            b.length >= index + 32,
            "GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED"
        );

        // Arrays are prefixed by a 256 bit length parameter
        index += 32;

        // Read the bytes32 from array memory
        assembly {
            result := mload(add(b, index))
        }
        return result;
    }

    /// @dev Writes a bytes32 into a specific position in a byte array.
    /// @param b Byte array to insert <input> into.
    /// @param index Index in byte array of <input>.
    /// @param input bytes32 to put into byte array.
    function writeBytes32(
        bytes memory b,
        uint256 index,
        bytes32 input
    )
        internal
        pure
    {
        require(
            b.length >= index + 32,
            "GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED"
        );

        // Arrays are prefixed by a 256 bit length parameter
        index += 32;

        // Read the bytes32 from array memory
        assembly {
            mstore(add(b, index), input)
        }
    }

    /// @dev Reads a uint256 value from a position in a byte array.
    /// @param b Byte array containing a uint256 value.
    /// @param index Index in byte array of uint256 value.
    /// @return uint256 value from byte array.
    function readUint256(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (uint256 result)
    {
        result = uint256(readBytes32(b, index));
        return result;
    }

    /// @dev Writes a uint256 into a specific position in a byte array.
    /// @param b Byte array to insert <input> into.
    /// @param index Index in byte array of <input>.
    /// @param input uint256 to put into byte array.
    function writeUint256(
        bytes memory b,
        uint256 index,
        uint256 input
    )
        internal
        pure
    {
        writeBytes32(b, index, bytes32(input));
    }

    /// @dev Reads an unpadded bytes4 value from a position in a byte array.
    /// @param b Byte array containing a bytes4 value.
    /// @param index Index in byte array of bytes4 value.
    /// @return bytes4 value from byte array.
    function readBytes4(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (bytes4 result)
    {
        require(
            b.length >= index + 4,
            "GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED"
        );

        // Arrays are prefixed by a 32 byte length field
        index += 32;

        // Read the bytes4 from array memory
        assembly {
            result := mload(add(b, index))
            // Solidity does not require us to clean the trailing bytes.
            // We do it anyway
            result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
        }
        return result;
    }

    /// @dev Reads nested bytes from a specific position.
    /// @dev NOTE: the returned value overlaps with the input value.
    ///            Both should be treated as immutable.
    /// @param b Byte array containing nested bytes.
    /// @param index Index of nested bytes.
    /// @return result Nested bytes.
    function readBytesWithLength(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (bytes memory result)
    {
        // Read length of nested bytes
        uint256 nestedBytesLength = readUint256(b, index);
        index += 32;

        // Assert length of <b> is valid, given
        // length of nested bytes
        require(
            b.length >= index + nestedBytesLength,
            "GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED"
        );
        
        // Return a pointer to the byte array as it exists inside `b`
        assembly {
            result := add(b, index)
        }
        return result;
    }

    /// @dev Inserts bytes at a specific position in a byte array.
    /// @param b Byte array to insert <input> into.
    /// @param index Index in byte array of <input>.
    /// @param input bytes to insert.
    function writeBytesWithLength(
        bytes memory b,
        uint256 index,
        bytes memory input
    )
        internal
        pure
    {
        // Assert length of <b> is valid, given
        // length of input
        require(
            b.length >= index + 32 + input.length,  // 32 bytes to store length
            "GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED"
        );

        // Copy <input> into <b>
        memCopy(
            b.contentAddress() + index,
            input.rawAddress(), // includes length of <input>
            input.length + 32   // +32 bytes to store <input> length
        );
    }

    /// @dev Performs a deep copy of a byte array onto another byte array of greater than or equal length.
    /// @param dest Byte array that will be overwritten with source bytes.
    /// @param source Byte array to copy onto dest bytes.
    function deepCopyBytes(
        bytes memory dest,
        bytes memory source
    )
        internal
        pure
    {
        uint256 sourceLen = source.length;
        // Dest length must be >= source length, or some bytes would not be copied.
        require(
            dest.length >= sourceLen,
            "GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED"
        );
        memCopy(
            dest.contentAddress(),
            source.contentAddress(),
            sourceLen
        );
    }
}

// File: contracts/GsnUtils.sol

pragma solidity ^0.5.5;


library GsnUtils {

    /**
     * extract method sig from encoded function call
     */
    function getMethodSig(bytes memory msgData) internal pure returns (bytes4) {
        return bytes4(bytes32(LibBytes.readUint256(msgData, 0)));
    }

    /**
     * extract parameter from encoded-function block.
     * see: https://solidity.readthedocs.io/en/develop/abi-spec.html#formal-specification-of-the-encoding
     * note that the type of the parameter must be static.
     * the return value should be casted to the right type.
     */
    function getParam(bytes memory msgData, uint index) internal pure returns (uint) {
        return LibBytes.readUint256(msgData, 4 + index * 32);
    }

    /**
     * extract dynamic-sized (string/bytes) parameter.
     * we assume that there ARE dynamic parameters, hence getParam(0) is the offset to the first
     * dynamic param
     * https://solidity.readthedocs.io/en/develop/abi-spec.html#use-of-dynamic-types
     */
    function getBytesParam(bytes memory msgData, uint index) internal pure returns (bytes memory ret)  {
        uint ofs = getParam(msgData,index)+4;
        uint len = LibBytes.readUint256(msgData, ofs);
        ret = LibBytes.slice(msgData, ofs+32, ofs+32+len);
    }

    function getStringParam(bytes memory msgData, uint index) internal pure returns (string memory) {
        return string(getBytesParam(msgData,index));
    }

    function checkSig(address signer, bytes32 hash, bytes memory sig) pure internal returns (bool) {
        // Check if @v,@r,@s are a valid signature of @signer for @hash
        uint8 v = uint8(sig[0]);
        bytes32 r = LibBytes.readBytes32(sig,1);
        bytes32 s = LibBytes.readBytes32(sig,33);
        return signer == ecrecover(hash, v, r, s);
    }
}

// File: contracts/RLPReader.sol

/*
* Taken from https://github.com/hamdiallam/Solidity-RLP
*/

pragma solidity ^0.5.5;

library RLPReader {

    uint8 constant STRING_SHORT_START = 0x80;
    uint8 constant STRING_LONG_START = 0xb8;
    uint8 constant LIST_SHORT_START = 0xc0;
    uint8 constant LIST_LONG_START = 0xf8;
    uint8 constant WORD_SIZE = 32;

    struct RLPItem {
        uint len;
        uint memPtr;
    }

    using RLPReader for bytes;
    using RLPReader for uint;
    using RLPReader for RLPReader.RLPItem;

    // helper function to decode rlp encoded  ethereum transaction
    /*
    * @param rawTransaction RLP encoded ethereum transaction
    * @return tuple (nonce,gasPrice,gasLimit,to,value,data)
    */

    function decodeTransaction(bytes memory rawTransaction) internal pure returns (uint, uint, uint, address, uint, bytes memory){
        RLPReader.RLPItem[] memory values = rawTransaction.toRlpItem().toList(); // must convert to an rlpItem first!
        return (values[0].toUint(), values[1].toUint(), values[2].toUint(), values[3].toAddress(), values[4].toUint(), values[5].toBytes());
    }

    /*
    * @param item RLP encoded bytes
    */
    function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {
        if (item.length == 0)
            return RLPItem(0, 0);
        uint memPtr;
        assembly {
            memPtr := add(item, 0x20)
        }
        return RLPItem(item.length, memPtr);
    }
    /*
    * @param item RLP encoded list in bytes
    */
    function toList(RLPItem memory item) internal pure returns (RLPItem[] memory result) {
        require(isList(item), "isList failed");
        uint items = numItems(item);
        result = new RLPItem[](items);
        uint memPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint dataLen;
        for (uint i = 0; i < items; i++) {
            dataLen = _itemLength(memPtr);
            result[i] = RLPItem(dataLen, memPtr);
            memPtr = memPtr + dataLen;
        }
    }
    /*
    * Helpers
    */
    // @return indicator whether encoded payload is a list. negate this function call for isData.
    function isList(RLPItem memory item) internal pure returns (bool) {
        uint8 byte0;
        uint memPtr = item.memPtr;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }
        if (byte0 < LIST_SHORT_START)
            return false;
        return true;
    }
    // @return number of payload items inside an encoded list.
    function numItems(RLPItem memory item) internal pure returns (uint) {
        uint count = 0;
        uint currPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint endPtr = item.memPtr + item.len;
        while (currPtr < endPtr) {
            currPtr = currPtr + _itemLength(currPtr);
            // skip over an item
            count++;
        }
        return count;
    }
    // @return entire rlp item byte length
    function _itemLength(uint memPtr) internal pure returns (uint len) {
        uint byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }
        if (byte0 < STRING_SHORT_START)
            return 1;
        else if (byte0 < STRING_LONG_START)
            return byte0 - STRING_SHORT_START + 1;
        else if (byte0 < LIST_SHORT_START) {
            assembly {
                let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is
                memPtr := add(memPtr, 1) // skip over the first byte
            /* 32 byte word size */
                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len
                len := add(dataLen, add(byteLen, 1))
            }
        }
        else if (byte0 < LIST_LONG_START) {
            return byte0 - LIST_SHORT_START + 1;
        }
        else {
            assembly {
                let byteLen := sub(byte0, 0xf7)
                memPtr := add(memPtr, 1)
                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length
                len := add(dataLen, add(byteLen, 1))
            }
        }
    }
    // @return number of bytes until the data
    function _payloadOffset(uint memPtr) internal pure returns (uint) {
        uint byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }
        if (byte0 < STRING_SHORT_START)
            return 0;
        else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))
            return 1;
        else if (byte0 < LIST_SHORT_START)  // being explicit
            return byte0 - (STRING_LONG_START - 1) + 1;
        else
            return byte0 - (LIST_LONG_START - 1) + 1;
    }
    /** RLPItem conversions into data types **/
    // @returns raw rlp encoding in bytes
    function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
        bytes memory result = new bytes(item.len);
        uint ptr;
        assembly {
            ptr := add(0x20, result)
        }
        copy(item.memPtr, ptr, item.len);
        return result;
    }

    function toBoolean(RLPItem memory item) internal pure returns (bool) {
        require(item.len == 1, "Invalid RLPItem. Booleans are encoded in 1 byte");
        uint result;
        uint memPtr = item.memPtr;
        assembly {
            result := byte(0, mload(memPtr))
        }
        return result == 0 ? false : true;
    }

    function toAddress(RLPItem memory item) internal pure returns (address) {
        // 1 byte for the length prefix according to RLP spec
        require(item.len <= 21, "Invalid RLPItem. Addresses are encoded in 20 bytes or less");
        return address(toUint(item));
    }

    function toUint(RLPItem memory item) internal pure returns (uint) {
        uint offset = _payloadOffset(item.memPtr);
        uint len = item.len - offset;
        uint memPtr = item.memPtr + offset;
        uint result;
        assembly {
            result := div(mload(memPtr), exp(256, sub(32, len))) // shift to the correct location
        }
        return result;
    }

    function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
        uint offset = _payloadOffset(item.memPtr);
        uint len = item.len - offset;
        // data length
        bytes memory result = new bytes(len);
        uint destPtr;
        assembly {
            destPtr := add(0x20, result)
        }
        copy(item.memPtr + offset, destPtr, len);
        return result;
    }
    /*
    * @param src Pointer to source
    * @param dest Pointer to destination
    * @param len Amount of memory to copy from the source
    */
    function copy(uint src, uint dest, uint len) internal pure {
        // copy as many word sizes as possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }
            src += WORD_SIZE;
            dest += WORD_SIZE;
        }
        // left over bytes. Mask is used to remove unwanted bytes from the word
        uint mask = 256 ** (WORD_SIZE - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask)) // zero out src
            let destpart := and(mload(dest), mask) // retrieve the bytes
            mstore(dest, or(destpart, srcpart))
        }
    }
}

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

pragma solidity ^0.5.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

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

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

// File: openzeppelin-solidity/contracts/cryptography/ECDSA.sol

pragma solidity ^0.5.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * (.note) This call _does not revert_ if the signature is invalid, or
     * if the signer is otherwise unable to be retrieved. In those scenarios,
     * the zero address is returned.
     *
     * (.warning) `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise)
     * be too long), and then calling `toEthSignedMessageHash` on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Check the signature length
        if (signature.length != 65) {
            return (address(0));
        }

        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            r := mload(add(signature, 0x20))
            s := mload(add(signature, 0x40))
            v := byte(0, mload(add(signature, 0x60)))
        }

        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return address(0);
        }

        if (v != 27 && v != 28) {
            return address(0);
        }

        // If the signature is valid (and not malleable), return the signer address
        return ecrecover(hash, v, r, s);
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * replicates the behavior of the
     * [`eth_sign`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign)
     * JSON-RPC method.
     *
     * See `recover`.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }
}

// File: contracts/RelayHub.sol

pragma solidity ^0.5.5;








contract RelayHub is IRelayHub {

    string constant commitId = "$Id: 5a82a94cecb1c32344dd239889272d1845035ef0 $";

    using ECDSA for bytes32;

    // Minimum stake a relay can have. An attack to the network will never cost less than half this value.
    uint256 constant private minimumStake = 1 ether;

    // Minimum unstake delay. A relay needs to wait for this time to elapse after deregistering to retrieve its stake.
    uint256 constant private minimumUnstakeDelay = 1 weeks;
    // Maximum unstake delay. Prevents relays from locking their funds into the RelayHub for too long.
    uint256 constant private maximumUnstakeDelay = 12 weeks;

    // Minimum balance required for a relay to register or re-register. Prevents user error in registering a relay that
    // will not be able to immediatly start serving requests.
    uint256 constant private minimumRelayBalance = 0.1 ether;

    // Maximum funds that can be deposited at once. Prevents user error by disallowing large deposits.
    uint256 constant private maximumRecipientDeposit = 2 ether;

    /**
    * the total gas overhead of relayCall(), before the first gasleft() and after the last gasleft().
    * Assume that relay has non-zero balance (costs 15'000 more otherwise).
    */

    // Gas cost of all relayCall() instructions before first gasleft() and after last gasleft()
    uint256 constant private gasOverhead = 48204;

    // Gas cost of all relayCall() instructions after first gasleft() and before last gasleft()
    uint256 constant private gasReserve = 100000;

    // Approximation of how much calling recipientCallsAtomic costs
    uint256 constant private recipientCallsAtomicOverhead = 5000;

    // Gas stipends for acceptRelayedCall, preRelayedCall and postRelayedCall
    uint256 constant private acceptRelayedCallMaxGas = 50000;
    uint256 constant private preRelayedCallMaxGas = 100000;
    uint256 constant private postRelayedCallMaxGas = 100000;

    // Nonces of senders, used to prevent replay attacks
    mapping(address => uint256) private nonces;

    enum AtomicRecipientCallsStatus {OK, CanRelayFailed, RelayedCallFailed, PreRelayedFailed, PostRelayedFailed}

    struct Relay {
        uint256 stake;          // Ether staked for this relay
        uint256 unstakeDelay;   // Time that must elapse before the owner can retrieve the stake after calling remove
        uint256 unstakeTime;    // Time when unstake will be callable. A value of zero indicates the relay has not been removed.
        address payable owner;  // Relay's owner, will receive revenue and manage it (call stake, remove and unstake).
        RelayState state;
    }

    mapping(address => Relay) private relays;
    mapping(address => uint256) private balances;

    string public version = "1.0.0";

    function stake(address relay, uint256 unstakeDelay) external payable {
        if (relays[relay].state == RelayState.Unknown) {
            require(msg.sender != relay, "relay cannot stake for itself");
            relays[relay].owner = msg.sender;
            relays[relay].state = RelayState.Staked;

        } else if ((relays[relay].state == RelayState.Staked) || (relays[relay].state == RelayState.Registered)) {
            require(relays[relay].owner == msg.sender, "not owner");

        } else {
            revert('wrong state for stake');
        }

        // Increase the stake

        uint256 addedStake = msg.value;
        relays[relay].stake += addedStake;

        // The added stake may be e.g. zero when only the unstake delay is being updated
        require(relays[relay].stake >= minimumStake, "stake lower than minimum");

        // Increase the unstake delay

        require(unstakeDelay >= minimumUnstakeDelay, "delay lower than minimum");
        require(unstakeDelay <= maximumUnstakeDelay, "delay higher than maximum");

        require(unstakeDelay >= relays[relay].unstakeDelay, "unstakeDelay cannot be decreased");
        relays[relay].unstakeDelay = unstakeDelay;

        emit Staked(relay, relays[relay].stake, relays[relay].unstakeDelay);
    }

    function registerRelay(uint256 transactionFee, string memory url) public {
        address relay = msg.sender;

        require(relay == tx.origin, "Contracts cannot register as relays");
        require(relays[relay].state == RelayState.Staked || relays[relay].state == RelayState.Registered, "wrong state for stake");
        require(relay.balance >= minimumRelayBalance, "balance lower than minimum");

        if (relays[relay].state != RelayState.Registered) {
            relays[relay].state = RelayState.Registered;
        }

        emit RelayAdded(relay, relays[relay].owner, transactionFee, relays[relay].stake, relays[relay].unstakeDelay, url);
    }

    function removeRelayByOwner(address relay) public {
        require(relays[relay].owner == msg.sender, "not owner");
        require((relays[relay].state == RelayState.Staked) || (relays[relay].state == RelayState.Registered), "already removed");

        // Start the unstake counter
        relays[relay].unstakeTime = relays[relay].unstakeDelay + now;
        relays[relay].state = RelayState.Removed;

        emit RelayRemoved(relay, relays[relay].unstakeTime);
    }

    function unstake(address relay) public {
        require(canUnstake(relay), "canUnstake failed");
        require(relays[relay].owner == msg.sender, "not owner");

        address payable owner = msg.sender;
        uint256 amount = relays[relay].stake;

        delete relays[relay];

        owner.transfer(amount);
        emit Unstaked(relay, amount);
    }

    function getRelay(address relay) external view returns (uint256 totalStake, uint256 unstakeDelay, uint256 unstakeTime, address payable owner, RelayState state) {
        totalStake = relays[relay].stake;
        unstakeDelay = relays[relay].unstakeDelay;
        unstakeTime = relays[relay].unstakeTime;
        owner = relays[relay].owner;
        state = relays[relay].state;
    }

    /**
     * deposit ether for a contract.
     * This ether will be used to repay relay calls into this contract.
     * Contract owner should monitor the balance of his contract, and make sure
     * to deposit more, otherwise the contract won't be able to receive relayed calls.
     * Unused deposited can be withdrawn with `withdraw()`
     */
    function depositFor(address target) public payable {
        uint256 amount = msg.value;
        require(amount <= maximumRecipientDeposit, "deposit too big");

        balances[target] = SafeMath.add(balances[target], amount);

        emit Deposited(target, msg.sender, amount);
    }

    //check the deposit balance of a contract.
    function balanceOf(address target) external view returns (uint256) {
        return balances[target];
    }

    /**
     * withdraw funds.
     * caller is either a relay owner, withdrawing collected transaction fees.
     * or a IRelayRecipient contract, withdrawing its deposit.
     * note that while everyone can `depositFor()` a contract, only
     * the contract itself can withdraw its funds.
     */
    function withdraw(uint256 amount, address payable dest) public {
        address payable account = msg.sender;
        require(balances[account] >= amount, "insufficient funds");

        balances[account] -= amount;
        dest.transfer(amount);

        emit Withdrawn(account, dest, amount);
    }

    function getNonce(address from) view external returns (uint256) {
        return nonces[from];
    }

    function canUnstake(address relay) public view returns (bool) {
        return relays[relay].unstakeTime > 0 && relays[relay].unstakeTime <= now;
        // Finished the unstaking delay period?
    }

    function canRelay(
        address relay,
        address from,
        address to,
        bytes memory encodedFunction,
        uint256 transactionFee,
        uint256 gasPrice,
        uint256 gasLimit,
        uint256 nonce,
        bytes memory signature,
        bytes memory approvalData
    )
    public view returns (uint256 status, bytes memory recipientContext)
    {
        // Verify the sender's signature on the transaction - note that approvalData is *not* signed
        {
            bytes memory packed = abi.encodePacked("rlx:", from, to, encodedFunction, transactionFee, gasPrice, gasLimit, nonce, address(this));
            bytes32 hashedMessage = keccak256(abi.encodePacked(packed, relay));

            if (hashedMessage.toEthSignedMessageHash().recover(signature) != from) {
                return (uint256(PreconditionCheck.WrongSignature), "");
            }
        }

        // Verify the transaction is not being replayed
        if (nonces[from] != nonce) {
            return (uint256(PreconditionCheck.WrongNonce), "");
        }

        uint256 maxCharge = maxPossibleCharge(gasLimit, gasPrice, transactionFee);
        bytes memory encodedTx = abi.encodeWithSelector(IRelayRecipient(to).acceptRelayedCall.selector,
            relay, from, encodedFunction, transactionFee, gasPrice, gasLimit, nonce, approvalData, maxCharge
        );

        (bool success, bytes memory returndata) = to.staticcall.gas(acceptRelayedCallMaxGas)(encodedTx);

        if (!success) {
            return (uint256(PreconditionCheck.AcceptRelayedCallReverted), "");
        } else {
            (status, recipientContext) = abi.decode(returndata, (uint256, bytes));

            // This can be either PreconditionCheck.OK or a custom error code
            if ((status == 0) || (status > 10)) {
                return (status, recipientContext);
            } else {
                // Error codes [1-10] are reserved to RelayHub
                return (uint256(PreconditionCheck.InvalidRecipientStatusCode), "");
            }
        }
    }

    /**
     * @notice Relay a transaction.
     *
     * @param from the client originating the request.
     * @param recipient the target IRelayRecipient contract.
     * @param encodedFunction the function call to relay.
     * @param transactionFee fee (%) the relay takes over actual gas cost.
     * @param gasPrice gas price the client is willing to pay
     * @param gasLimit limit the client want to put on its transaction
     * @param transactionFee fee (%) the relay takes over actual gas cost.
     * @param nonce sender's nonce (in nonces[])
     * @param signature client's signature over all params except approvalData
     * @param approvalData dapp-specific data
     */
    function relayCall(
        address from,
        address recipient,
        bytes memory encodedFunction,
        uint256 transactionFee,
        uint256 gasPrice,
        uint256 gasLimit,
        uint256 nonce,
        bytes memory signature,
        bytes memory approvalData
    )
    public
    {
        uint256 initialGas = gasleft();

        // Initial soundness checks - the relay must make sure these pass, or it will pay for a reverted transaction.

        // The relay must be registered
        require(relays[msg.sender].state == RelayState.Registered, "Unknown relay");

        // A relay may use a higher gas price than the one requested by the signer (to e.g. get the transaction in a
        // block faster), but it must not be lower. The recipient will be charged for the requested gas price, not the
        // one used in the transaction.
        require(gasPrice <= tx.gasprice, "Invalid gas price");

        // This transaction must have enough gas to forward the call to the recipient with the requested amount, and not
        // run out of gas later in this function.
        require(initialGas >= SafeMath.sub(requiredGas(gasLimit), gasOverhead), "Not enough gasleft()");

        // We don't yet know how much gas will be used by the recipient, so we make sure there are enough funds to pay
        // for the maximum possible charge.
        require(maxPossibleCharge(gasLimit, gasPrice, transactionFee) <= balances[recipient], "Recipient balance too low");

        bytes4 functionSelector = LibBytes.readBytes4(encodedFunction, 0);

        bytes memory recipientContext;
        {
            // We now verify the legitimacy of the transaction (it must be signed by the sender, and not be replayed),
            // and that the recpient will accept to be charged by it.
            uint256 preconditionCheck;
            (preconditionCheck, recipientContext) = canRelay(msg.sender, from, recipient, encodedFunction, transactionFee, gasPrice, gasLimit, nonce, signature, approvalData);

            if (preconditionCheck != uint256(PreconditionCheck.OK)) {
                emit CanRelayFailed(msg.sender, from, recipient, functionSelector, preconditionCheck);
                return;
            }
        }

        // From this point on, this transaction will not revert nor run out of gas, and the recipient will be charged
        // for the gas spent.

        // The sender's nonce is advanced to prevent transaction replays.
        nonces[from]++;

        // Calls to the recipient are performed atomically inside an inner transaction which may revert in case of
        // errors in the recipient. In either case (revert or regular execution) the return data encodes the
        // RelayCallStatus value.
        RelayCallStatus status;
        {
            uint256 preChecksGas = initialGas - gasleft();
            bytes memory encodedFunctionWithFrom = abi.encodePacked(encodedFunction, from);
            bytes memory data = abi.encodeWithSelector(this.recipientCallsAtomic.selector, recipient, encodedFunctionWithFrom, transactionFee, gasPrice, gasLimit, preChecksGas, recipientContext);
            (, bytes memory relayCallStatus) = address(this).call(data);
            status = abi.decode(relayCallStatus, (RelayCallStatus));
        }

        // We now perform the actual charge calculation, based on the measured gas used
        uint256 charge = calculateCharge(
            getChargeableGas(initialGas - gasleft(), false),
            gasPrice,
            transactionFee
        );

        // We've already checked that the recipient has enough balance to pay for the relayed transaction, this is only
        // a sanity check to prevent overflows in case of bugs.
        require(balances[recipient] >= charge, "Should not get here");
        balances[recipient] -= charge;
        balances[relays[msg.sender].owner] += charge;

        emit TransactionRelayed(msg.sender, from, recipient, functionSelector, status, charge);
    }

    struct AtomicData {
        uint256 atomicInitialGas;
        uint256 balanceBefore;
        bytes32 preReturnValue;
        bool relayedCallSuccess;
    }

    function recipientCallsAtomic(
        address recipient,
        bytes calldata encodedFunctionWithFrom,
        uint256 transactionFee,
        uint256 gasPrice,
        uint256 gasLimit,
        uint256 preChecksGas,
        bytes calldata recipientContext
    )
    external
    returns (RelayCallStatus)
    {
        AtomicData memory atomicData;
        atomicData.atomicInitialGas = gasleft(); // A new gas measurement is performed inside recipientCallsAtomic, since
        // due to EIP150 available gas amounts cannot be directly compared across external calls

        // This external function can only be called by RelayHub itself, creating an internal transaction. Calls to the
        // recipient (preRelayedCall, the relayedCall, and postRelayedCall) are called from inside this transaction.
        require(msg.sender == address(this), "Only RelayHub should call this function");

        // If either pre or post reverts, the whole internal transaction will be reverted, reverting all side effects on
        // the recipient. The recipient will still be charged for the used gas by the relay.

        // The recipient is no allowed to withdraw balance from RelayHub during a relayed transaction. We check pre and
        // post state to ensure this doesn't happen.
        atomicData.balanceBefore = balances[recipient];

        // First preRelayedCall is executed.
        {
            // Note: we open a new block to avoid growing the stack too much.
            bytes memory data = abi.encodeWithSelector(
                IRelayRecipient(recipient).preRelayedCall.selector, recipientContext
            );

            // preRelayedCall may revert, but the recipient will still be charged: it should ensure in
            // acceptRelayedCall that this will not happen.
            (bool success, bytes memory retData) = recipient.call.gas(preRelayedCallMaxGas)(data);

            if (!success) {
                revertWithStatus(RelayCallStatus.PreRelayedFailed);
            }

            atomicData.preReturnValue = abi.decode(retData, (bytes32));
        }

        // The actual relayed call is now executed. The sender's address is appended at the end of the transaction data
        (atomicData.relayedCallSuccess,) = recipient.call.gas(gasLimit)(encodedFunctionWithFrom);

        // Finally, postRelayedCall is executed, with the relayedCall execution's status and a charge estimate
        {
            bytes memory data;
            {
                // We now determine how much the recipient will be charged, to pass this value to postRelayedCall for accurate
                // accounting.
                uint256 estimatedCharge = calculateCharge(
                    getChargeableGas(preChecksGas + atomicData.atomicInitialGas - gasleft(), true), // postRelayedCall is included in the charge
                    gasPrice,
                    transactionFee
                );

                data = abi.encodeWithSelector(
                    IRelayRecipient(recipient).postRelayedCall.selector,
                    recipientContext, atomicData.relayedCallSuccess, estimatedCharge, atomicData.preReturnValue
                );
            }

            (bool successPost,) = recipient.call.gas(postRelayedCallMaxGas)(data);

            if (!successPost) {
                revertWithStatus(RelayCallStatus.PostRelayedFailed);
            }
        }

        if (balances[recipient] < atomicData.balanceBefore) {
            revertWithStatus(RelayCallStatus.RecipientBalanceChanged);
        }

        return atomicData.relayedCallSuccess ? RelayCallStatus.OK : RelayCallStatus.RelayedCallFailed;
    }

    /**
     * @dev Reverts the transaction with returndata set to the ABI encoding of the status argument.
     */
    function revertWithStatus(RelayCallStatus status) private pure {
        bytes memory data = abi.encode(status);

        assembly {
            let dataSize := mload(data)
            let dataPtr := add(data, 32)

            revert(dataPtr, dataSize)
        }
    }

    function requiredGas(uint256 relayedCallStipend) public view returns (uint256) {
        return gasOverhead + gasReserve + acceptRelayedCallMaxGas + preRelayedCallMaxGas + postRelayedCallMaxGas + relayedCallStipend;
    }

    function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) public view returns (uint256) {
        return calculateCharge(requiredGas(relayedCallStipend), gasPrice, transactionFee);
    }

    function calculateCharge(uint256 gas, uint256 gasPrice, uint256 fee) private pure returns (uint256) {
        // The fee is expressed as a percentage. E.g. a value of 40 stands for a 40% fee, so the recipient will be
        // charged for 1.4 times the spent amount.
        return (gas * gasPrice * (100 + fee)) / 100;
    }

    function getChargeableGas(uint256 gasUsed, bool postRelayedCallEstimation) private pure returns (uint256) {
        return gasOverhead + gasUsed + (postRelayedCallEstimation ? (postRelayedCallMaxGas + recipientCallsAtomicOverhead) : 0);
    }

    struct Transaction {
        uint256 nonce;
        uint256 gasPrice;
        uint256 gasLimit;
        address to;
        uint256 value;
        bytes data;
    }

    function decodeTransaction(bytes memory rawTransaction) private pure returns (Transaction memory transaction) {
        (transaction.nonce, transaction.gasPrice, transaction.gasLimit, transaction.to, transaction.value, transaction.data) = RLPReader.decodeTransaction(rawTransaction);
        return transaction;

    }

    function penalizeRepeatedNonce(bytes memory unsignedTx1, bytes memory signature1, bytes memory unsignedTx2, bytes memory signature2) public {
        // Can be called by anyone.
        // If a relay attacked the system by signing multiple transactions with the same nonce (so only one is accepted), anyone can grab both transactions from the blockchain and submit them here.
        // Check whether unsignedTx1 != unsignedTx2, that both are signed by the same address, and that unsignedTx1.nonce == unsignedTx2.nonce.  If all conditions are met, relay is considered an "offending relay".
        // The offending relay will be unregistered immediately, its stake will be forfeited and given to the address who reported it (msg.sender), thus incentivizing anyone to report offending relays.
        // If reported via a relay, the forfeited stake is split between msg.sender (the relay used for reporting) and the address that reported it.

        address addr1 = keccak256(abi.encodePacked(unsignedTx1)).recover(signature1);
        address addr2 = keccak256(abi.encodePacked(unsignedTx2)).recover(signature2);

        require(addr1 == addr2, "Different signer");

        Transaction memory decodedTx1 = decodeTransaction(unsignedTx1);
        Transaction memory decodedTx2 = decodeTransaction(unsignedTx2);

        //checking that the same nonce is used in both transaction, with both signed by the same address and the actual data is different
        // note: we compare the hash of the tx to save gas over iterating both byte arrays
        require(decodedTx1.nonce == decodedTx2.nonce, "Different nonce");

        bytes memory dataToCheck1 = abi.encodePacked(decodedTx1.data, decodedTx1.gasLimit, decodedTx1.to, decodedTx1.value);
        bytes memory dataToCheck2 = abi.encodePacked(decodedTx2.data, decodedTx2.gasLimit, decodedTx2.to, decodedTx2.value);
        require(keccak256(dataToCheck1) != keccak256(dataToCheck2), "tx is equal");

        penalize(addr1);
    }

    function penalizeIllegalTransaction(bytes memory unsignedTx, bytes memory signature) public {
        Transaction memory decodedTx = decodeTransaction(unsignedTx);
        if (decodedTx.to == address(this)) {
            bytes4 selector = GsnUtils.getMethodSig(decodedTx.data);
            // Note: If RelayHub's relay API is extended, the selectors must be added to the ones listed here
            require(selector != this.relayCall.selector && selector != this.registerRelay.selector, "Legal relay transaction");
        }

        address relay = keccak256(abi.encodePacked(unsignedTx)).recover(signature);

        penalize(relay);
    }

    function penalize(address relay) private {
        require((relays[relay].state == RelayState.Staked) ||
        (relays[relay].state == RelayState.Registered) ||
            (relays[relay].state == RelayState.Removed), "Unstaked relay");

        // Half of the stake will be burned (sent to address 0)
        uint256 totalStake = relays[relay].stake;
        uint256 toBurn = SafeMath.div(totalStake, 2);
        uint256 reward = SafeMath.sub(totalStake, toBurn);

        if (relays[relay].state == RelayState.Registered) {
            emit RelayRemoved(relay, now);
        }

        // The relay is deleted
        delete relays[relay];

        // Ether is burned and transferred
        address(0).transfer(toBurn);
        address payable reporter = msg.sender;
        reporter.transfer(reward);

        emit Penalized(relay, reporter, reward);
    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"amount","type":"uint256"},{"name":"dest","type":"address"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"transactionFee","type":"uint256"},{"name":"url","type":"string"}],"name":"registerRelay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"relay","type":"address"},{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"encodedFunction","type":"bytes"},{"name":"transactionFee","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"gasLimit","type":"uint256"},{"name":"nonce","type":"uint256"},{"name":"signature","type":"bytes"},{"name":"approvalData","type":"bytes"}],"name":"canRelay","outputs":[{"name":"status","type":"uint256"},{"name":"recipientContext","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"encodedFunctionWithFrom","type":"bytes"},{"name":"transactionFee","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"gasLimit","type":"uint256"},{"name":"preChecksGas","type":"uint256"},{"name":"recipientContext","type":"bytes"}],"name":"recipientCallsAtomic","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"from","type":"address"}],"name":"getNonce","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"unsignedTx","type":"bytes"},{"name":"signature","type":"bytes"}],"name":"penalizeIllegalTransaction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"recipient","type":"address"},{"name":"encodedFunction","type":"bytes"},{"name":"transactionFee","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"gasLimit","type":"uint256"},{"name":"nonce","type":"uint256"},{"name":"signature","type":"bytes"},{"name":"approvalData","type":"bytes"}],"name":"relayCall","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"relayedCallStipend","type":"uint256"}],"name":"requiredGas","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"target","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"relay","type":"address"}],"name":"canUnstake","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"relay","type":"address"}],"name":"getRelay","outputs":[{"name":"totalStake","type":"uint256"},{"name":"unstakeDelay","type":"uint256"},{"name":"unstakeTime","type":"uint256"},{"name":"owner","type":"address"},{"name":"state","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"relayedCallStipend","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"transactionFee","type":"uint256"}],"name":"maxPossibleCharge","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"unsignedTx1","type":"bytes"},{"name":"signature1","type":"bytes"},{"name":"unsignedTx2","type":"bytes"},{"name":"signature2","type":"bytes"}],"name":"penalizeRepeatedNonce","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"target","type":"address"}],"name":"depositFor","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"relay","type":"address"},{"name":"unstakeDelay","type":"uint256"}],"name":"stake","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"relay","type":"address"}],"name":"removeRelayByOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"relay","type":"address"}],"name":"unstake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relay","type":"address"},{"indexed":false,"name":"stake","type":"uint256"},{"indexed":false,"name":"unstakeDelay","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relay","type":"address"},{"indexed":true,"name":"owner","type":"address"},{"indexed":false,"name":"transactionFee","type":"uint256"},{"indexed":false,"name":"stake","type":"uint256"},{"indexed":false,"name":"unstakeDelay","type":"uint256"},{"indexed":false,"name":"url","type":"string"}],"name":"RelayAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relay","type":"address"},{"indexed":false,"name":"unstakeTime","type":"uint256"}],"name":"RelayRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relay","type":"address"},{"indexed":false,"name":"stake","type":"uint256"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":true,"name":"from","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":true,"name":"dest","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relay","type":"address"},{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"selector","type":"bytes4"},{"indexed":false,"name":"reason","type":"uint256"}],"name":"CanRelayFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relay","type":"address"},{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"selector","type":"bytes4"},{"indexed":false,"name":"status","type":"uint8"},{"indexed":false,"name":"charge","type":"uint256"}],"name":"TransactionRelayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"relay","type":"address"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Penalized","type":"event"}]

60c0604052600560808190527f312e302e3000000000000000000000000000000000000000000000000000000060a090815262000040916003919062000055565b503480156200004e57600080fd5b50620000fa565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200009857805160ff1916838001178555620000c8565b82800160010185558215620000c8579182015b82811115620000c8578251825591602001919060010190620000ab565b50620000d6929150620000da565b5090565b620000f791905b80821115620000d65760008155600101620000e1565b90565b613b1c806200010a6000396000f3fe6080604052600436106101085760003560e01c806370a0823111610095578063a8cd957211610064578063a8cd957214610ada578063aa67c91914610d1a578063adc9772e14610d40578063c3e712f214610d6c578063f2888dbb14610d9f57610108565b806370a08231146109a557806385f4498b146109d85780638d85146014610a1f578063a863f8f914610aa457610108565b80632d0335ab116100dc5780632d0335ab1461058957806339002432146105ce578063405cec671461070457806354fd4d50146108f15780636a7d84a41461097b57610108565b8062f714ce1461010d5780631166073a146101485780632b601747146102005780632ca70eba14610474575b600080fd5b34801561011957600080fd5b506101466004803603604081101561013057600080fd5b50803590602001356001600160a01b0316610dd2565b005b34801561015457600080fd5b506101466004803603604081101561016b57600080fd5b81359190810190604081016020820135600160201b81111561018c57600080fd5b82018360208201111561019e57600080fd5b803590602001918460018302840111600160201b831117156101bf57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610ec9945050505050565b34801561020c57600080fd5b506103f5600480360361014081101561022457600080fd5b6001600160a01b0382358116926020810135821692604082013590921691810190608081016060820135600160201b81111561025f57600080fd5b82018360208201111561027157600080fd5b803590602001918460018302840111600160201b8311171561029257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929584359560208601359560408101359550606081013594509192509060a081019060800135600160201b8111156102fc57600080fd5b82018360208201111561030e57600080fd5b803590602001918460018302840111600160201b8311171561032f57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561038157600080fd5b82018360208201111561039357600080fd5b803590602001918460018302840111600160201b831117156103b457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611178945050505050565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610438578181015183820152602001610420565b50505050905090810190601f1680156104655780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561048057600080fd5b50610565600480360360e081101561049757600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104c157600080fd5b8201836020820111156104d357600080fd5b803590602001918460018302840111600160201b831117156104f457600080fd5b9193909282359260208101359260408201359260608301359260a081019060800135600160201b81111561052757600080fd5b82018360208201111561053957600080fd5b803590602001918460018302840111600160201b8311171561055a57600080fd5b509092509050611684565b6040518082600481111561057557fe5b60ff16815260200191505060405180910390f35b34801561059557600080fd5b506105bc600480360360208110156105ac57600080fd5b50356001600160a01b0316611a97565b60408051918252519081900360200190f35b3480156105da57600080fd5b50610146600480360360408110156105f157600080fd5b810190602081018135600160201b81111561060b57600080fd5b82018360208201111561061d57600080fd5b803590602001918460018302840111600160201b8311171561063e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561069057600080fd5b8201836020820111156106a257600080fd5b803590602001918460018302840111600160201b831117156106c357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611ab6945050505050565b34801561071057600080fd5b50610146600480360361012081101561072857600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561075b57600080fd5b82018360208201111561076d57600080fd5b803590602001918460018302840111600160201b8311171561078e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929584359560208601359560408101359550606081013594509192509060a081019060800135600160201b8111156107f857600080fd5b82018360208201111561080a57600080fd5b803590602001918460018302840111600160201b8311171561082b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561087d57600080fd5b82018360208201111561088f57600080fd5b803590602001918460018302840111600160201b831117156108b057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611c08945050505050565b3480156108fd57600080fd5b506109066122c2565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610940578181015183820152602001610928565b50505050905090810190601f16801561096d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561098757600080fd5b506105bc6004803603602081101561099e57600080fd5b5035612350565b3480156109b157600080fd5b506105bc600480360360208110156109c857600080fd5b50356001600160a01b0316612358565b3480156109e457600080fd5b50610a0b600480360360208110156109fb57600080fd5b50356001600160a01b0316612373565b604080519115158252519081900360200190f35b348015610a2b57600080fd5b50610a5260048036036020811015610a4257600080fd5b50356001600160a01b03166123be565b60405180868152602001858152602001848152602001836001600160a01b03166001600160a01b03168152602001826003811115610a8c57fe5b60ff1681526020019550505050505060405180910390f35b348015610ab057600080fd5b506105bc60048036036060811015610ac757600080fd5b5080359060208101359060400135612402565b348015610ae657600080fd5b5061014660048036036080811015610afd57600080fd5b810190602081018135600160201b811115610b1757600080fd5b820183602082011115610b2957600080fd5b803590602001918460018302840111600160201b83111715610b4a57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610b9c57600080fd5b820183602082011115610bae57600080fd5b803590602001918460018302840111600160201b83111715610bcf57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610c2157600080fd5b820183602082011115610c3357600080fd5b803590602001918460018302840111600160201b83111715610c5457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610ca657600080fd5b820183602082011115610cb857600080fd5b803590602001918460018302840111600160201b83111715610cd957600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061241f945050505050565b61014660048036036020811015610d3057600080fd5b50356001600160a01b0316612711565b61014660048036036040811015610d5657600080fd5b506001600160a01b0381351690602001356127d9565b348015610d7857600080fd5b5061014660048036036020811015610d8f57600080fd5b50356001600160a01b0316612bcc565b348015610dab57600080fd5b5061014660048036036020811015610dc257600080fd5b50356001600160a01b0316612d51565b33600081815260026020526040902054831115610e2b576040805162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b604482015290519081900360640190fd5b6001600160a01b0380821660009081526002602052604080822080548790039055519184169185156108fc0291869190818181858888f19350505050158015610e78573d6000803e3d6000fd5b50816001600160a01b0316816001600160a01b03167fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb856040518082815260200191505060405180910390a3505050565b33328114610f085760405162461bcd60e51b8152600401808060200182810382526023815260200180613ac56023913960400191505060405180910390fd5b60016001600160a01b0382166000908152600160205260409020600390810154600160a01b900460ff1690811115610f3c57fe5b1480610f79575060026001600160a01b0382166000908152600160205260409020600390810154600160a01b900460ff1690811115610f7757fe5b145b610fc2576040805162461bcd60e51b815260206004820152601560248201527477726f6e6720737461746520666f72207374616b6560581b604482015290519081900360640190fd5b67016345785d8a0000816001600160a01b0316311015611029576040805162461bcd60e51b815260206004820152601a60248201527f62616c616e6365206c6f776572207468616e206d696e696d756d000000000000604482015290519081900360640190fd5b60026001600160a01b0382166000908152600160205260409020600390810154600160a01b900460ff169081111561105d57fe5b1461108f576001600160a01b0381166000908152600160205260409020600301805460ff60a01b1916600160a11b1790555b6001600160a01b03808216600081815260016020818152604080842060038101548154919094015482518b81528085018390529283018190526080606084018181528b51918501919091528a5195909816977f85b3ae3aae9d3fcb31142fbd8c3b4722d57825b8edd6e1366e69204afa5a0dfa968c96939592948c94909360a085019290860191908190849084905b8381101561113657818101518382015260200161111e565b50505050905090810190601f1680156111635780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a3505050565b60006060808b8b8b8b8b8b8b3060405160200180806339363c1d60e11b815250600401896001600160a01b03166001600160a01b031660601b8152601401886001600160a01b03166001600160a01b031660601b815260140187805190602001908083835b602083106111fc5780518252601f1990920191602091820191016111dd565b6001836020036101000a038019825116818451168082178552505050505050905001868152602001858152602001848152602001838152602001826001600160a01b03166001600160a01b031660601b81526014019850505050505050505060405160208183030381529060405290506000818e6040516020018083805190602001908083835b602083106112a25780518252601f199092019160209182019101611283565b6001836020036101000a038019825116818451168082178552505050505050905001826001600160a01b03166001600160a01b031660601b8152601401925050506040516020818303038152906040528051906020012090508c6001600160a01b031661131e8761131284612eab565b9063ffffffff612efc16565b6001600160a01b03161461134957600160405180602001604052806000815250935093505050611675565b50506001600160a01b038b166000908152602081905260409020548514611383575050604080516020810190915260008152600290611675565b600061139087898b612402565b905060608b6001600160a01b03166383947ea0905060e01b8e8e8d8d8d8d8d8c8a604051602401808a6001600160a01b03166001600160a01b03168152602001896001600160a01b03166001600160a01b03168152602001806020018881526020018781526020018681526020018581526020018060200184815260200183810383528a818151815260200191508051906020019080838360005b8381101561144357818101518382015260200161142b565b50505050905090810190601f1680156114705780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b838110156114a357818101518382015260200161148b565b50505050905090810190601f1680156114d05780820380516001836020036101000a031916815260200191505b509b505050505050505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050509050600060608d6001600160a01b031661c350846040518082805190602001908083835b602083106115545780518252601f199092019160209182019101611535565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303818686fa925050503d80600081146115b5576040519150601f19603f3d011682016040523d82523d6000602084013e6115ba565b606091505b5091509150816115e45760035b604051806020016040528060008152509550955050505050611675565b8080602001905160408110156115f957600080fd5b815160208301805191939283019291600160201b81111561161957600080fd5b8201602081018481111561162c57600080fd5b8151600160201b81118282018710171561164557600080fd5b50949a509850508815925082915061165f90505750600a86115b1561166e575061167592505050565b60046115c7565b9a509a98505050505050505050565b600061168e613998565b5a81523330146116cf5760405162461bcd60e51b8152600401808060200182810382526027815260200180613a196027913960400191505060405180910390fd5b6001600160a01b038b166000908152600260209081526040918290205483820152905160248101918252604481018590526060916380274db760e01b91879187918190606401848480828437600081840152601f19601f8201169050808301925050509350505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050509050600060608d6001600160a01b0316620186a0846040518082805190602001908083835b602083106117ae5780518252601f19909201916020918201910161178f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d8060008114611811576040519150601f19603f3d011682016040523d82523d6000602084013e611816565b606091505b50915091508161182a5761182a6002612fea565b80806020019051602081101561183f57600080fd5b5051604080860191909152516001600160a01b038f1693508992508d91508c908083838082843760405192019450600093509091505080830381838787f1925050503d80600081146118ad576040519150601f19603f3d011682016040523d82523d6000602084013e6118b2565b606091505b5050151560608083019190915260006118db6118d45a85518a01036001613026565b8a8c613046565b90508c6001600160a01b031663e06e0e22905060e01b868685606001518487604001516040516024018080602001851515151581526020018481526020018381526020018281038252878782818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505091505060008c6001600160a01b0316620186a0836040518082805190602001908083835b602083106119c85780518252601f1990920191602091820191016119a9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d8060008114611a2b576040519150601f19603f3d011682016040523d82523d6000602084013e611a30565b606091505b5050905080611a4357611a436003612fea565b50506020808201516001600160a01b038d16600090815260029092526040909120541015611a7557611a756004612fea565b8060600151611a85576001611a88565b60005b9b9a5050505050505050505050565b6001600160a01b0381166000908152602081905260409020545b919050565b611abe6139bf565b611ac783613054565b60608101519091506001600160a01b0316301415611b75576000611aee8260a0015161308e565b90506001600160e01b0319811663405cec6760e01b14801590611b2257506001600160e01b031981166308b3039d60e11b14155b611b73576040805162461bcd60e51b815260206004820152601760248201527f4c6567616c2072656c6179207472616e73616374696f6e000000000000000000604482015290519081900360640190fd5b505b6000611bf783856040516020018082805190602001908083835b60208310611bae5780518252601f199092019160209182019101611b8f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120612efc90919063ffffffff16565b9050611c028161309b565b50505050565b60005a90506002336000908152600160205260409020600390810154600160a01b900460ff1690811115611c3857fe5b14611c7a576040805162461bcd60e51b815260206004820152600d60248201526c556e6b6e6f776e2072656c617960981b604482015290519081900360640190fd5b3a861115611cc3576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642067617320707269636560781b604482015290519081900360640190fd5b611cd7611ccf86612350565b61bc4c61331d565b811015611d22576040805162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768206761736c656674282960601b604482015290519081900360640190fd5b6001600160a01b038916600090815260026020526040902054611d4686888a612402565b1115611d99576040805162461bcd60e51b815260206004820152601960248201527f526563697069656e742062616c616e636520746f6f206c6f7700000000000000604482015290519081900360640190fd5b6000611da689600061337a565b905060606000611dbe338e8e8e8e8e8e8e8e8e611178565b925090508015611e42578b6001600160a01b03168d6001600160a01b0316336001600160a01b03167fafb5afd6d1c2e8ffbfb480e674a169f493ece0b22658d4f4484e7334f0241e22868560405180836001600160e01b0319166001600160e01b03191681526020018281526020019250505060405180910390a4505050506122b7565b506001600160a01b038c16600090815260208190526040812080546001019055805a8503905060608c8f6040516020018083805190602001908083835b60208310611e9e5780518252601f199092019160209182019101611e7f565b6001836020036101000a038019825116818451168082178552505050505050905001826001600160a01b03166001600160a01b031660601b81526014019250505060405160208183030381529060405290506060632ca70eba60e01b8f838f8f8f888b60405160240180886001600160a01b03166001600160a01b031681526020018060200187815260200186815260200185815260200184815260200180602001838103835289818151815260200191508051906020019080838360005b83811015611f75578181015183820152602001611f5d565b50505050905090810190601f168015611fa25780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015611fd5578181015183820152602001611fbd565b50505050905090810190601f1680156120025780820380516001836020036101000a031916815260200191505b509950505050505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505090506060306001600160a01b0316826040518082805190602001908083835b6020831061207f5780518252601f199092019160209182019101612060565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146120e1576040519150601f19603f3d011682016040523d82523d6000602084013e6120e6565b606091505b509150508080602001905160208110156120ff57600080fd5b5051945060009350612123925061211c9150505a87036000613026565b8b8d613046565b6001600160a01b038e16600090815260026020526040902054909150811115612189576040805162461bcd60e51b815260206004820152601360248201527253686f756c64206e6f7420676574206865726560681b604482015290519081900360640190fd5b80600260008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008282540392505081905550806002600060016000336001600160a01b03166001600160a01b0316815260200190815260200160002060030160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020600082825401925050819055508c6001600160a01b03168e6001600160a01b0316336001600160a01b03167fab74390d395916d9e0006298d47938a5def5d367054dcca78fa6ec84381f3f2287868660405180846001600160e01b0319166001600160e01b031916815260200183600481111561229657fe5b60ff168152602001828152602001935050505060405180910390a450505050505b505050505050505050565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156123485780601f1061231d57610100808354040283529160200191612348565b820191906000526020600020905b81548152906001019060200180831161232b57829003601f168201915b505050505081565b6206137c0190565b6001600160a01b031660009081526002602052604090205490565b6001600160a01b038116600090815260016020526040812060020154158015906123b857506001600160a01b0382166000908152600160205260409020600201544210155b92915050565b6001600160a01b039081166000908152600160208190526040909120805491810154600282015460039092015492949093919291821691600160a01b900460ff1690565b600061241761241085612350565b8484613046565b949350505050565b6000612457848660405160200180828051906020019080838360208310611bae5780518252601f199092019160209182019101611b8f565b90506000612491838560405160200180828051906020019080838360208310611bae5780518252601f199092019160209182019101611b8f565b9050806001600160a01b0316826001600160a01b0316146124ec576040805162461bcd60e51b815260206004820152601060248201526f2234b33332b932b73a1039b4b3b732b960811b604482015290519081900360640190fd5b6124f46139bf565b6124fd87613054565b90506125076139bf565b61251086613054565b805183519192501461255b576040805162461bcd60e51b815260206004820152600f60248201526e446966666572656e74206e6f6e636560881b604482015290519081900360640190fd5b60608260a001518360400151846060015185608001516040516020018085805190602001908083835b602083106125a35780518252601f199092019160209182019101612584565b6001836020036101000a038019825116818451168082178552505050505050905001848152602001836001600160a01b03166001600160a01b031660601b8152601401828152602001945050505050604051602081830303815290604052905060608260a001518360400151846060015185608001516040516020018085805190602001908083835b6020831061264b5780518252601f19909201916020918201910161262c565b6001836020036101000a038019825116818451168082178552505050505050905001848152602001836001600160a01b03166001600160a01b031660601b815260140182815260200194505050505060405160208183030381529060405290508080519060200120828051906020012014156126fc576040805162461bcd60e51b815260206004820152600b60248201526a1d1e081a5cc8195c5d585b60aa1b604482015290519081900360640190fd5b6127058661309b565b50505050505050505050565b34671bc16d674ec80000811115612761576040805162461bcd60e51b815260206004820152600f60248201526e6465706f73697420746f6f2062696760881b604482015290519081900360640190fd5b6001600160a01b03821660009081526002602052604090205461278490826133d2565b6001600160a01b038316600081815260026020908152604091829020939093558051848152905133937f8752a472e571a816aea92eec8dae9baf628e840f4929fbcc2d155e6233ff68a7928290030190a35050565b60006001600160a01b0383166000908152600160205260409020600390810154600160a01b900460ff169081111561280d57fe5b14156128ae57336001600160a01b0383161415612871576040805162461bcd60e51b815260206004820152601d60248201527f72656c61792063616e6e6f74207374616b6520666f7220697473656c66000000604482015290519081900360640190fd5b6001600160a01b038216600090815260016020526040902060030180546001600160a01b031916331760ff60a01b1916600160a01b1790556129cb565b60016001600160a01b0383166000908152600160205260409020600390810154600160a01b900460ff16908111156128e257fe5b148061291f575060026001600160a01b0383166000908152600160205260409020600390810154600160a01b900460ff169081111561291d57fe5b145b15612986576001600160a01b03828116600090815260016020526040902060030154163314612981576040805162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b604482015290519081900360640190fd5b6129cb565b6040805162461bcd60e51b815260206004820152601560248201527477726f6e6720737461746520666f72207374616b6560581b604482015290519081900360640190fd5b6001600160a01b03821660009081526001602052604090208054349081019182905590670de0b6b3a76400001115612a4a576040805162461bcd60e51b815260206004820152601860248201527f7374616b65206c6f776572207468616e206d696e696d756d0000000000000000604482015290519081900360640190fd5b62093a80821015612aa2576040805162461bcd60e51b815260206004820152601860248201527f64656c6179206c6f776572207468616e206d696e696d756d0000000000000000604482015290519081900360640190fd5b626ebe00821115612afa576040805162461bcd60e51b815260206004820152601960248201527f64656c617920686967686572207468616e206d6178696d756d00000000000000604482015290519081900360640190fd5b6001600160a01b03831660009081526001602081905260409091200154821015612b6b576040805162461bcd60e51b815260206004820181905260248201527f756e7374616b6544656c61792063616e6e6f7420626520646563726561736564604482015290519081900360640190fd5b6001600160a01b0383166000818152600160208181526040928390209182018690559054825190815290810185905281517f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90929181900390910190a2505050565b6001600160a01b03818116600090815260016020526040902060030154163314612c29576040805162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b604482015290519081900360640190fd5b60016001600160a01b0382166000908152600160205260409020600390810154600160a01b900460ff1690811115612c5d57fe5b1480612c9a575060026001600160a01b0382166000908152600160205260409020600390810154600160a01b900460ff1690811115612c9857fe5b145b612cdd576040805162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e481c995b5bdd9959608a1b604482015290519081900360640190fd5b6001600160a01b038116600081815260016020818152604092839020918201544201600283018190556003909201805460ff60a01b1916600360a01b179055825191825291517f5490afc1d818789c8b3d5d63bce3d2a3327d0bba4efb5a7751f783dc977d7d11929181900390910190a250565b612d5a81612373565b612d9f576040805162461bcd60e51b815260206004820152601160248201527018d85b955b9cdd185ad94819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b03818116600090815260016020526040902060030154163314612dfc576040805162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b604482015290519081900360640190fd5b6001600160a01b038116600090815260016020819052604080832080548482559281018490556002810184905560030180546001600160a81b0319169055513392839183156108fc0291849190818181858888f19350505050158015612e66573d6000803e3d6000fd5b506040805182815290516001600160a01b038516917f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75919081900360200190a2505050565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b60008151604114612f0f575060006123b8565b60208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115612f5557600093505050506123b8565b8060ff16601b14158015612f6d57508060ff16601c14155b15612f7e57600093505050506123b8565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015612fd5573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6060816040516020018082600481111561300057fe5b60ff16815260200191505060405160208183030381529060405290508051602082018181fd5b600081613034576000613039565b62019a285b90920161bc4c0192915050565b606490810191909202020490565b61305c6139bf565b61306582613433565b60a087015260808601526001600160a01b03166060850152604084015260208301528152919050565b60006123b88260006134ed565b60016001600160a01b0382166000908152600160205260409020600390810154600160a01b900460ff16908111156130cf57fe5b148061310c575060026001600160a01b0382166000908152600160205260409020600390810154600160a01b900460ff169081111561310a57fe5b145b80613148575060036001600160a01b0382166000908152600160205260409020600390810154600160a01b900460ff169081111561314657fe5b145b61318a576040805162461bcd60e51b815260206004820152600e60248201526d556e7374616b65642072656c617960901b604482015290519081900360640190fd5b6001600160a01b038116600090815260016020526040812054906131af8260026134f9565b905060006131bd838361331d565b905060026001600160a01b0385166000908152600160205260409020600390810154600160a01b900460ff16908111156131f357fe5b1415613239576040805142815290516001600160a01b038616917f5490afc1d818789c8b3d5d63bce3d2a3327d0bba4efb5a7751f783dc977d7d11919081900360200190a25b6001600160a01b038416600090815260016020819052604080832083815591820183905560028201839055600390910180546001600160a81b03191690555183156108fc0290849083818181858288f1935050505015801561329f573d6000803e3d6000fd5b506040513390819083156108fc029084906000818181858888f193505050501580156132cf573d6000803e3d6000fd5b50604080516001600160a01b038381168252602082018590528251908816927fb0595266ccec357806b2691f348b128209f1060a0bda4f5c95f7090730351ff8928290030190a25050505050565b600082821115613374576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600081600401835110156133bf5760405162461bcd60e51b8152600401808060200182810382526025815260200180613aa06025913960400191505060405180910390fd5b5001602001516001600160e01b03191690565b60008282018381101561342c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600080600080600060608061344f61344a89613563565b6135a8565b905061346e8160008151811061346157fe5b60200260200101516136ad565b61347e8260018151811061346157fe5b61348e8360028151811061346157fe5b6134ab8460038151811061349e57fe5b60200260200101516136db565b6134bb8560048151811061346157fe5b6134d8866005815181106134cb57fe5b602002602001015161372a565b949d939c50919a509850965090945092505050565b600061342c8383613797565b600080821161354f576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161355a57fe5b04949350505050565b61356b6139fe565b815161358b57506040805180820190915260008082526020820152611ab1565b506040805180820190915281518152602082810190820152919050565b60606135b3826137e5565b6135f4576040805162461bcd60e51b815260206004820152600d60248201526c1a5cd31a5cdd0819985a5b1959609a1b604482015290519081900360640190fd5b60006135ff83613811565b90508060405190808252806020026020018201604052801561363b57816020015b6136286139fe565b8152602001906001900390816136205790505b509150600061364d846020015161385e565b60208501510190506000805b838110156136a45761366a836138c7565b915060405180604001604052808381526020018481525085828151811061368d57fe5b602090810291909101015291810191600101613659565b50505050919050565b6000806136bd836020015161385e565b83516020948501518201519190039093036101000a90920492915050565b60006015826000015111156137215760405162461bcd60e51b815260040180806020018281038252603a815260200180613a40603a913960400191505060405180910390fd5b6123b8826136ad565b6060600061373b836020015161385e565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015613772576020820181803883390190505b509050600081602001905061378e848760200151018285613957565b50949350505050565b600081602001835110156137dc5760405162461bcd60e51b8152600401808060200182810382526026815260200180613a7a6026913960400191505060405180910390fd5b50016020015190565b6020810151805160009190821a9060c082101561380757600092505050611ab1565b5060019392505050565b600080600090506000613827846020015161385e565b602085015185519181019250015b8082101561385557613846826138c7565b60019093019290910190613835565b50909392505050565b8051600090811a6080811015613878576000915050611ab1565b60b8811080613893575060c08110801590613893575060f881105b156138a2576001915050611ab1565b60c08110156138b65760b519019050611ab1565b60f519019050611ab1565b50919050565b8051600090811a60808110156138e1576001915050611ab1565b60b88110156138f557607e19019050611ab1565b60c08110156139225760b78103600184019350806020036101000a845104600182018101935050506138c1565b60f88110156139365760be19019050611ab1565b60019290920151602083900360f7016101000a900490910160f51901919050565b5b60208110613977578251825260209283019290910190601f1901613958565b915181516020939093036101000a6000190180199091169216919091179052565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040518060c0016040528060008152602001600081526020016000815260200160006001600160a01b0316815260200160008152602001606081525090565b60405180604001604052806000815260200160008152509056fe4f6e6c792052656c61794875622073686f756c642063616c6c20746869732066756e6374696f6e496e76616c696420524c504974656d2e204164647265737365732061726520656e636f64656420696e203230206279746573206f72206c657373475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f5245515549524544475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f5245515549524544436f6e7472616374732063616e6e6f742072656769737465722061732072656c617973a265627a7a72305820ac2aa0393ce6b8813055ebaead9b1b776f47b7e48a65bcca3c6bd72394ef5d6464736f6c634300050a0032

Deployed ByteCode Sourcemap

51662:24230:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58911:309;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58911:309:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58911:309:0;;;;;;-1:-1:-1;;;;;58911:309:0;;:::i;:::-;;55832:674;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55832:674:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;55832:674:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;55832:674:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;55832:674:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;55832:674:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;55832:674:0;;-1:-1:-1;55832:674:0;;-1:-1:-1;;;;;55832:674:0:i;59548:2109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59548:2109:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;59548:2109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;59548:2109:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;59548:2109:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;59548:2109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;59548:2109:0;;;;;;;;;;;;;;;-1:-1:-1;59548:2109:0;;;;;-1:-1:-1;59548:2109:0;;-1:-1:-1;59548:2109:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;59548:2109:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;59548:2109:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;59548:2109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;59548:2109:0;;;;;;;;-1:-1:-1;59548:2109:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;59548:2109:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;59548:2109:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;59548:2109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;59548:2109:0;;-1:-1:-1;59548:2109:0;;-1:-1:-1;;;;;59548:2109:0:i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;59548:2109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66621:3730;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66621:3730:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;66621:3730:0;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;66621:3730:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;66621:3730:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;66621:3730:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;66621:3730:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;66621:3730:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;66621:3730:0;;-1:-1:-1;66621:3730:0;-1:-1:-1;66621:3730:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59228:102;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59228:102:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59228:102:0;-1:-1:-1;;;;;59228:102:0;;:::i;:::-;;;;;;;;;;;;;;;;74343:653;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74343:653:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;74343:653:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;74343:653:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;74343:653:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;74343:653:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;74343:653:0;;;;;;;;-1:-1:-1;74343:653:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;74343:653:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;74343:653:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;74343:653:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;74343:653:0;;-1:-1:-1;74343:653:0;;-1:-1:-1;;;;;74343:653:0:i;62369:4076::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62369:4076:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;62369:4076:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;62369:4076:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;62369:4076:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;62369:4076:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;62369:4076:0;;;;;;;;;;;;;;;-1:-1:-1;62369:4076:0;;;;;-1:-1:-1;62369:4076:0;;-1:-1:-1;62369:4076:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;62369:4076:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;62369:4076:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;62369:4076:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;62369:4076:0;;;;;;;;-1:-1:-1;62369:4076:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;62369:4076:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;62369:4076:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;62369:4076:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;62369:4076:0;;-1:-1:-1;62369:4076:0;;-1:-1:-1;;;;;62369:4076:0:i;54470:31::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54470:31:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;54470:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70763:223;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70763:223:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70763:223:0;;:::i;58487:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58487:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58487:109:0;-1:-1:-1;;;;;58487:109:0;;:::i;59338:202::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59338:202:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59338:202:0;-1:-1:-1;;;;;59338:202:0;;:::i;:::-;;;;;;;;;;;;;;;;;;57383:389;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57383:389:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57383:389:0;-1:-1:-1;;;;;57383:389:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57383:389:0;-1:-1:-1;;;;;57383:389:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70994:227;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70994:227:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70994:227:0;;;;;;;;;;;;:::i;72328:2007::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72328:2007:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;72328:2007:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;72328:2007:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72328:2007:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;72328:2007:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;72328:2007:0;;;;;;;;-1:-1:-1;72328:2007:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;72328:2007:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72328:2007:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;72328:2007:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;72328:2007:0;;;;;;;;-1:-1:-1;72328:2007:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;72328:2007:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72328:2007:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;72328:2007:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;72328:2007:0;;;;;;;;-1:-1:-1;72328:2007:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;72328:2007:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72328:2007:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;72328:2007:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;72328:2007:0;;-1:-1:-1;72328:2007:0;;-1:-1:-1;;;;;72328:2007:0:i;58138:293::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58138:293:0;-1:-1:-1;;;;;58138:293:0;;:::i;54510:1314::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;54510:1314:0;;;;;;;;:::i;56514:481::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56514:481:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56514:481:0;-1:-1:-1;;;;;56514:481:0;;:::i;57003:372::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57003:372:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57003:372:0;-1:-1:-1;;;;;57003:372:0;;:::i;58911:309::-;59011:10;58985:23;59040:17;;;:8;:17;;;;;;:27;-1:-1:-1;59040:27:0;59032:58;;;;;-1:-1:-1;;;59032:58:0;;;;;;;;;;;;-1:-1:-1;;;59032:58:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;59103:17:0;;;;;;;:8;:17;;;;;;:27;;;;;;;59141:21;:13;;;;:21;;;;;59124:6;;59141:21;;59103:17;59141:21;59124:6;59141:13;:21;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59141:21:0;59199:4;-1:-1:-1;;;;;59180:32:0;59190:7;-1:-1:-1;;;;;59180:32:0;;59205:6;59180:32;;;;;;;;;;;;;;;;;;58911:309;;;:::o;55832:674::-;55932:10;55972:9;55963:18;;55955:66;;;;-1:-1:-1;;;55955:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56063:17;-1:-1:-1;;;;;56040:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;56040:19:0;;;;;:40;;;;;;;;:88;;;-1:-1:-1;56107:21:0;-1:-1:-1;;;;;56084:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;56084:19:0;;;;;:44;;;;;;;;56040:88;56032:122;;;;;-1:-1:-1;;;56032:122:0;;;;;;;;;;;;-1:-1:-1;;;56032:122:0;;;;;;;;;;;;;;;52563:9;56173:5;-1:-1:-1;;;;;56173:13:0;;:36;;56165:75;;;;;-1:-1:-1;;;56165:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56280:21;-1:-1:-1;;;;;56257:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;56257:19:0;;;;;:44;;;;;;;;56253:120;;-1:-1:-1;;;;;56318:13:0;;;;;;:6;:13;;;;;:19;;:43;;-1:-1:-1;;;;56318:43:0;-1:-1:-1;;;56318:43:0;;;56253:120;-1:-1:-1;;;;;56408:13:0;;;;;;;:6;:13;;;;;;;;:19;;;;56445;;56466:26;;;;;56390:108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56408:19;;;;;56390:108;;56429:14;;56445:19;;56466:26;;56494:3;;56390:108;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;56390:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55832:674;;;:::o;59548:2109::-;59886:14;59902:29;60066:19;60113:4;60119:2;60123:15;60140:14;60156:8;60166;60176:5;60191:4;60088:109;;;;;;-1:-1:-1;;;60088:109:0;;;;;;-1:-1:-1;;;;;60088:109:0;-1:-1:-1;;;;;60088:109:0;;;;;;;;-1:-1:-1;;;;;60088:109:0;-1:-1:-1;;;;;60088:109:0;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;60088:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60088:109:0;-1:-1:-1;;;;;60088:109:0;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;60088:109:0;;;60066:131;;60212:21;60263:6;60271:5;60246:31;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;60246:31:0;;;;;;;-1:-1:-1;;;;;60246:31:0;-1:-1:-1;;;;;60246:31:0;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;60246:31:0;;;60236:42;;;;;;60212:66;;60360:4;-1:-1:-1;;;;;60299:65:0;:57;60346:9;60299:38;:13;:36;:38::i;:::-;:46;:57;:46;:57;:::i;:::-;-1:-1:-1;;;;;60299:65:0;;60295:160;;60401:32;60385:54;;;;;;;;;;;;;;;;;;;;60295:160;-1:-1:-1;;;;;;;60539:12:0;;:6;:12;;;;;;;;;;;:21;;60535:104;;-1:-1:-1;;60577:50:0;;;;;;;;;-1:-1:-1;60577:50:0;;60593:28;;60577:50;;60535:104;60651:17;60671:53;60689:8;60699;60709:14;60671:17;:53::i;:::-;60651:73;;60735:22;60799:2;-1:-1:-1;;;;;60783:37:0;;:46;;;;60844:5;60851:4;60857:15;60874:14;60890:8;60900;60910:5;60917:12;60931:9;60760:191;;;;;;-1:-1:-1;;;;;60760:191:0;-1:-1:-1;;;;;60760:191:0;;;;;;-1:-1:-1;;;;;60760:191:0;-1:-1:-1;;;;;60760:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;60760:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60760:191:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;60760:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;60760:191:0;;;;-1:-1:-1;;;;;60760:191:0;;38:4:-1;29:7;25:18;67:10;61:17;-1:-1;;;;;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;60760:191:0;60735:216;;60965:12;60979:23;61006:2;-1:-1:-1;;;;;61006:13:0;53519:5;61049:9;61006:53;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;61006:53: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;;60964:95:0;;;;61077:7;61072:578;;61117:43;61109:52;61101:65;;;;;;;;;;;;;;;;;;;;;;61072:578;61239:10;61228:40;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;61228:40:0;;;;;;;;;;;;;;-1:-1:-1;;;11:20;;8:2;;;44:1;41;34:12;8:2;62:21;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;;;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;-1:-1;61199:69:0;;-1:-1:-1;61228:40:0;-1:-1:-1;;61369:11:0;;;-1:-1:-1;61369:11:0;;-1:-1:-1;61368:30:0;;-1:-1:-1;61368:30:0;;61395:2;61386:6;:11;61368:30;61364:275;;;-1:-1:-1;61419:33:0;;-1:-1:-1;;;61419:33:0;61364:275;61573:44;61565:53;;59548:2109;;;;;;;;;;;;;;:::o;66621:3730::-;66923:15;66956:28;;:::i;:::-;67025:9;66995:39;;67465:10;67487:4;67465:27;67457:79;;;;-1:-1:-1;;;67457:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67969:19:0;;;;;;:8;:19;;;;;;;;;;67942:24;;;:46;68161:124;;;;;;;;;;;;;;68141:17;;-1:-1:-1;;;68202:50:0;68254:16;;;;68161:124;;;;68254:16;;;;68161:124;1:33:-1;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;68161:124:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;68161:124:0;;;;-1:-1:-1;;;;;68161:124:0;;38:4:-1;29:7;25:18;67:10;61:17;-1:-1;;;;;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;68161:124:0;68141:144;;68468:12;68482:20;68506:9;-1:-1:-1;;;;;68506:14:0;53579:6;68547:4;68506:46;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;68506:46: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;;68467:85:0;;;;68574:7;68569:99;;68602:50;68619:32;68602:16;:50::i;:::-;68723:7;68712:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68712:30:0;68684:25;;;;:58;;;;68922:53;-1:-1:-1;;;;;68922:14:0;;;-1:-1:-1;68941:8:0;;-1:-1:-1;68951:23:0;;-1:-1:-1;68951:23:0;;68922:53;68951:23;;;;68922:53;1:33:-1;68922:53:0;;45:16:-1;;;-1:-1;68922:53:0;;-1:-1:-1;68922:53:0;;-1:-1:-1;;68922:53: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;-1:-1;;68887:88:0;;68888:29;;;;68887:88;;;;69326:23;69352:248;69390:78;69452:9;69422:27;;69407:42;;:54;69463:4;69390:16;:78::i;:::-;69536:8;69567:14;69352:15;:248::i;:::-;69326:274;;69689:9;-1:-1:-1;;;;;69673:42:0;;:51;;;;69747:16;;69765:10;:29;;;69796:15;69813:10;:25;;;69628:229;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;69628:229:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;69628:229:0;;;;-1:-1:-1;;;;;69628:229:0;;38:4:-1;29:7;25:18;67:10;61:17;-1:-1;;;;;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;69628:229:0;69621:236;;66621:3730;69890:16;69911:9;-1:-1:-1;;;;;69911:14:0;53641:6;69953:4;69911:47;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;69911:47: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;;69889:69:0;;;69980:11;69975:104;;70012:51;70029:33;70012:16;:51::i;:::-;-1:-1:-1;;70128:24:0;;;;;-1:-1:-1;;;;;70106:19:0;;;;;;:8;:19;;;;;;;;:46;70102:136;;;70169:57;70186:39;70169:16;:57::i;:::-;70257:10;:29;;;:86;;70310:33;70257:86;;;70289:18;70257:86;70250:93;66621:3730;-1:-1:-1;;;;;;;;;;;66621:3730:0:o;59228:102::-;-1:-1:-1;;;;;59310:12:0;;59283:7;59310:12;;;;;;;;;;;59228:102;;;;:::o;74343:653::-;74446:28;;:::i;:::-;74477:29;74495:10;74477:17;:29::i;:::-;74521:12;;;;74446:60;;-1:-1:-1;;;;;;74521:29:0;74545:4;74521:29;74517:357;;;74567:15;74585:37;74607:9;:14;;;74585:21;:37::i;:::-;74567:55;-1:-1:-1;;;;;;;74756:35:0;;-1:-1:-1;;;74756:35:0;;;;:78;;-1:-1:-1;;;;;;;74795:39:0;;-1:-1:-1;;;74795:39:0;;74756:78;74748:114;;;;;-1:-1:-1;;;74748:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;74517:357;;74886:13;74902:58;74950:9;74929:10;74912:28;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;74912:28:0;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;74912:28:0;;;74902:39;;;;;;:47;;:58;;;;:::i;:::-;74886:74;;74973:15;74982:5;74973:8;:15::i;:::-;74343:653;;;;:::o;62369:4076::-;62693:18;62714:9;62693:30;-1:-1:-1;62934:21:0;62913:10;62906:18;;;;:6;:18;;;;;:24;;;;;-1:-1:-1;;;62906:24:0;;;;;:49;;;;;;;;62898:75;;;;;-1:-1:-1;;;62898:75:0;;;;;;;;;;;;-1:-1:-1;;;62898:75:0;;;;;;;;;;;;;;;63285:11;63273:8;:23;;63265:53;;;;;-1:-1:-1;;;63265:53:0;;;;;;;;;;;;-1:-1:-1;;;63265:53:0;;;;;;;;;;;;;;;63526:48;63539:21;63551:8;63539:11;:21::i;:::-;53087:5;63526:12;:48::i;:::-;63512:10;:62;;63504:95;;;;;-1:-1:-1;;;63504:95:0;;;;;;;;;;;;-1:-1:-1;;;63504:95:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;63842:19:0;;;;;;:8;:19;;;;;;63785:53;63803:8;63813;63823:14;63785:17;:53::i;:::-;:76;;63777:114;;;;;-1:-1:-1;;;63777:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;63904:23;63930:39;63950:15;63967:1;63930:19;:39::i;:::-;63904:65;;63982:29;64228:25;64308:122;64317:10;64329:4;64335:9;64346:15;64363:14;64379:8;64389;64399:5;64406:9;64417:12;64308:8;:122::i;:::-;64268:162;-1:-1:-1;64268:162:0;-1:-1:-1;64451:50:0;;64447:201;;64560:9;-1:-1:-1;;;;;64527:80:0;64554:4;-1:-1:-1;;;;;64527:80:0;64542:10;-1:-1:-1;;;;;64527:80:0;;64571:16;64589:17;64527:80;;;;-1:-1:-1;;;;;64527:80:0;;-1:-1:-1;;;;;64527:80:0;;;;;;;;;;;;;;;;;;;;;;64626:7;;;;;;64447:201;-1:-1:-1;;;;;;64898:12:0;;:6;:12;;;;;;;;;;:14;;;;;;:6;65270:9;65257:10;:22;65234:45;;65294:36;65350:15;65367:4;65333:39;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;65333:39:0;;;;;;;-1:-1:-1;;;;;65333:39:0;-1:-1:-1;;;;;65333:39:0;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;65333:39:0;;;65294:78;;65387:17;65430:34;;;65466:9;65477:23;65502:14;65518:8;65528;65538:12;65552:16;65407:162;;;;;;-1:-1:-1;;;;;65407:162:0;-1:-1:-1;;;;;65407:162:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;65407:162:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65407:162:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;65407:162:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;65407:162:0;;;;-1:-1:-1;;;;;65407:162:0;;38:4:-1;29:7;25:18;67:10;61:17;-1:-1;;;;;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;65407:162:0;65387:182;;65587:28;65627:4;-1:-1:-1;;;;;65619:18:0;65638:4;65619:24;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;65619:24: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;;65584:59:0;;;65678:15;65667:46;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65667:46:0;;-1:-1:-1;65826:14:0;;-1:-1:-1;65843:140:0;;-1:-1:-1;65873:47:0;;-1:-1:-1;;65903:9:0;65890:10;:22;65914:5;65873:16;:47::i;:::-;65935:8;65958:14;65843:15;:140::i;:::-;-1:-1:-1;;;;;66190:19:0;;;;;;:8;:19;;;;;;65826:157;;-1:-1:-1;66190:29:0;-1:-1:-1;66190:29:0;66182:61;;;;;-1:-1:-1;;;66182:61:0;;;;;;;;;;;;-1:-1:-1;;;66182:61:0;;;;;;;;;;;;;;;66277:6;66254:8;:19;66263:9;-1:-1:-1;;;;;66254:19:0;-1:-1:-1;;;;;66254:19:0;;;;;;;;;;;;;:29;;;;;;;;;;;66332:6;66294:8;:34;66303:6;:18;66310:10;-1:-1:-1;;;;;66303:18:0;-1:-1:-1;;;;;66303:18:0;;;;;;;;;;;;:24;;;;;;;;;;-1:-1:-1;;;;;66303:24:0;-1:-1:-1;;;;;66294:34:0;-1:-1:-1;;;;;66294:34:0;;;;;;;;;;;;;:44;;;;;;;;;;;66393:9;-1:-1:-1;;;;;66356:81:0;66387:4;-1:-1:-1;;;;;66356:81:0;66375:10;-1:-1:-1;;;;;66356:81:0;;66404:16;66422:6;66430;66356:81;;;;-1:-1:-1;;;;;66356:81:0;;-1:-1:-1;;;;;66356:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62369:4076;;;;;;;;;;;;;;;:::o;54470:31::-;;;;;;;;;;;;;;;-1:-1:-1;;54470:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;70763:223::-;70860:97;:118;;70763:223::o;58487:109::-;-1:-1:-1;;;;;58572:16:0;58545:7;58572:16;;;:8;:16;;;;;;;58487:109::o;59338:202::-;-1:-1:-1;;;;;59418:13:0;;59394:4;59418:13;;;:6;:13;;;;;:25;;;:29;;;;:65;;-1:-1:-1;;;;;;59451:13:0;;;;;;:6;:13;;;;;:25;;;59480:3;-1:-1:-1;59451:32:0;59418:65;59411:72;59338:202;-1:-1:-1;;59338:202:0:o;57383:389::-;-1:-1:-1;;;;;57567:13:0;;;57439:18;57567:13;;;:6;:13;;;;;;;;:19;;57612:26;;;;57663:25;;;;57707:19;;;;;57567;;57612:26;;57663:25;;57707:19;;;;-1:-1:-1;;;57745:19:0;;;;;57383:389::o;70994:227::-;71112:7;71139:74;71155:31;71167:18;71155:11;:31::i;:::-;71188:8;71198:14;71139:15;:74::i;:::-;71132:81;70994:227;-1:-1:-1;;;;70994:227:0:o;72328:2007::-;73285:13;73301:60;73350:10;73328:11;73311:29;;;;;;;;;;;;;;;66:2:-1;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;73301:60:0;73285:76;;73372:13;73388:60;73437:10;73415:11;73398:29;;;;;;;;;;;;;;;66:2:-1;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;73388:60:0;73372:76;;73478:5;-1:-1:-1;;;;;73469:14:0;:5;-1:-1:-1;;;;;73469:14:0;;73461:43;;;;;-1:-1:-1;;;73461:43:0;;;;;;;;;;;;-1:-1:-1;;;73461:43:0;;;;;;;;;;;;;;;73517:29;;:::i;:::-;73549:30;73567:11;73549:17;:30::i;:::-;73517:62;;73590:29;;:::i;:::-;73622:30;73640:11;73622:17;:30::i;:::-;73924:16;;73904;;73590:62;;-1:-1:-1;73904:36:0;73896:64;;;;;-1:-1:-1;;;73896:64:0;;;;;;;;;;;;-1:-1:-1;;;73896:64:0;;;;;;;;;;;;;;;73973:25;74018:10;:15;;;74035:10;:19;;;74056:10;:13;;;74071:10;:16;;;74001:87;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;74001:87:0;;;;;;;;;;;;-1:-1:-1;;;;;74001:87:0;-1:-1:-1;;;;;74001:87:0;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;74001:87:0;;;73973:115;;74099:25;74144:10;:15;;;74161:10;:19;;;74182:10;:13;;;74197:10;:16;;;74127:87;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;74127:87:0;;;;;;;;;;;;-1:-1:-1;;;;;74127:87:0;-1:-1:-1;;;;;74127:87:0;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;74127:87:0;;;74099:115;;74270:12;74260:23;;;;;;74243:12;74233:23;;;;;;:50;;74225:74;;;;;-1:-1:-1;;;74225:74:0;;;;;;;;;;;;-1:-1:-1;;;74225:74:0;;;;;;;;;;;;;;;74312:15;74321:5;74312:8;:15::i;:::-;72328:2007;;;;;;;;;;:::o;58138:293::-;58217:9;52736:7;58245:33;;;58237:61;;;;;-1:-1:-1;;;58237:61:0;;;;;;;;;;;;-1:-1:-1;;;58237:61:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;58343:16:0;;;;;;:8;:16;;;;;;58330:38;;58361:6;58330:12;:38::i;:::-;-1:-1:-1;;;;;58311:16:0;;;;;;:8;:16;;;;;;;;;:57;;;;58386:37;;;;;;;58404:10;;58386:37;;;;;;;;58138:293;;:::o;54510:1314::-;54617:18;-1:-1:-1;;;;;54594:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;54594:19:0;;;;;:41;;;;;;;;54590:490;;;54660:10;-1:-1:-1;;;;;54660:19:0;;;;54652:61;;;;;-1:-1:-1;;;54652:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54728:13:0;;;;;;:6;:13;;;;;:19;;:32;;-1:-1:-1;;;;;;54728:32:0;54750:10;54728:32;-1:-1:-1;;;;54775:39:0;-1:-1:-1;;;54775:39:0;;;54590:490;;;54862:17;-1:-1:-1;;;;;54839:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;54839:19:0;;;;;:40;;;;;;;;54838:92;;;-1:-1:-1;54908:21:0;-1:-1:-1;;;;;54885:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;54885:19:0;;;;;:44;;;;;;;;54838:92;54834:246;;;-1:-1:-1;;;;;54955:13:0;;;;;;;:6;:13;;;;;:19;;;;54978:10;54955:33;54947:55;;;;;-1:-1:-1;;;54947:55:0;;;;;;;;;;;;-1:-1:-1;;;54947:55:0;;;;;;;;;;;;;;;54834:246;;;55037:31;;;-1:-1:-1;;;55037:31:0;;;;;;;;;;;;-1:-1:-1;;;55037:31:0;;;;;;;;;;;;;;54834:246;-1:-1:-1;;;;;55166:13:0;;55125:18;55166:13;;;:6;:13;;;;;:33;;55146:9;55166:33;;;;;;;55146:9;51967:7;-1:-1:-1;55310:35:0;55302:72;;;;;-1:-1:-1;;;55302:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52150:7;55436:12;:35;;55428:72;;;;;-1:-1:-1;;;55428:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52315:8;55519:12;:35;;55511:73;;;;;-1:-1:-1;;;55511:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55621:13:0;;;;;;:6;:13;;;;;;;;:26;;55605:42;;;55597:87;;;;;-1:-1:-1;;;55597:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55695:13:0;;;;;;:6;:13;;;;;;;;;:26;;;:41;;;55768:19;;55754:62;;;;;;;;;;;;;;;;;;;;;;;;54510:1314;;;:::o;56514:481::-;-1:-1:-1;;;;;56583:13:0;;;;;;;:6;:13;;;;;:19;;;;56606:10;56583:33;56575:55;;;;;-1:-1:-1;;;56575:55:0;;;;;;;;;;;;-1:-1:-1;;;56575:55:0;;;;;;;;;;;;;;;56673:17;-1:-1:-1;;;;;56650:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;56650:19:0;;;;;:40;;;;;;;;56649:92;;;-1:-1:-1;56719:21:0;-1:-1:-1;;;;;56696:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;56696:19:0;;;;;:44;;;;;;;;56649:92;56641:120;;;;;-1:-1:-1;;;56641:120:0;;;;;;;;;;;;-1:-1:-1;;;56641:120:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;56840:13:0;;;;;;:6;:13;;;;;;;;;:26;;;;56869:3;56840:32;56812:25;;;:60;;;56905:18;56883:19;;;:40;;-1:-1:-1;;;;56883:40:0;-1:-1:-1;;;56883:40:0;;;56941:46;;;;;;;;;;;;;;;;;;56514:481;:::o;57003:372::-;57061:17;57072:5;57061:10;:17::i;:::-;57053:47;;;;;-1:-1:-1;;;57053:47:0;;;;;;;;;;;;-1:-1:-1;;;57053:47:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;57119:13:0;;;;;;;:6;:13;;;;;:19;;;;57142:10;57119:33;57111:55;;;;;-1:-1:-1;;;57111:55:0;;;;;;;;;;;;-1:-1:-1;;;57111:55:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;57241:13:0;;57179:21;57241:13;;;:6;:13;;;;;;;;:19;;57273:20;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;57273:20:0;;;57306:22;57203:10;;;;57306:22;;;;;57241:19;;57306:22;;57179:21;57306:22;57241:19;57203:10;57306:22;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;57344:23:0;;;;;;;;-1:-1:-1;;;;;57344:23:0;;;;;;;;;;;;;57003:372;;;:::o;51310:269::-;51512:58;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;51512:58:0;;;;;;;51502:69;;;;;;51310:269::o;49104:1930::-;49182:7;49245:9;:16;49265:2;49245:22;49241:74;;-1:-1:-1;49300:1:0;49284:19;;49241:74;49676:4;49661:20;;49655:27;49722:4;49707:20;;49701:27;49776:4;49761:20;;49755:27;49384:9;49747:36;50706:66;50693:79;;50689:129;;;50804:1;50789:17;;;;;;;50689:129;50834:1;:7;;50839:2;50834:7;;:18;;;;;50845:1;:7;;50850:2;50845:7;;50834:18;50830:68;;;50884:1;50869:17;;;;;;;50830:68;51002:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51002:24:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;51002:24:0;;-1:-1:-1;;51002:24:0;;;49104:1930;-1:-1:-1;;;;;;;49104:1930:0:o;70478:277::-;70552:17;70583:6;70572:18;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;70572:18:0;;;70552:38;;70649:4;70643:11;70693:2;70687:4;70683:13;70728:8;70719:7;70712:25;71567:244;71664:7;71716:25;:86;;71801:1;71716:86;;;71745:52;71716:86;71691:112;;;53087:5;71691:112;;71567:244;-1:-1:-1;;71567:244:0:o;71229:330::-;71548:3;71534:9;;;71516:14;;;;:28;71515:36;;71229:330::o;71998:322::-;72076:30;;:::i;:::-;72238:43;72266:14;72238:27;:43::i;:::-;72218:16;;;72119:162;72199:17;;;72119:162;-1:-1:-1;;;;;72119:162:0;72183:14;;;72119:162;72161:20;;;72119:162;72139:20;;;72119:162;;;71998:322;;;:::o;34829:150::-;34896:6;34937:32;34958:7;34967:1;34937:20;:32::i;75004:885::-;75088:17;-1:-1:-1;;;;;75065:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;75065:19:0;;;;;:40;;;;;;;;75064:101;;;-1:-1:-1;75143:21:0;-1:-1:-1;;;;;75120:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;75120:19:0;;;;;:44;;;;;;;;75064:101;:161;;;-1:-1:-1;75206:18:0;-1:-1:-1;;;;;75183:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;75183:19:0;;;;;:41;;;;;;;;75064:161;75056:188;;;;;-1:-1:-1;;;75056:188:0;;;;;;;;;;;;-1:-1:-1;;;75056:188:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;75343:13:0;;75322:18;75343:13;;;:6;:13;;;;;:19;;75390:27;75343:19;75415:1;75390:12;:27::i;:::-;75373:44;;75428:14;75445:32;75458:10;75470:6;75445:12;:32::i;:::-;75428:49;-1:-1:-1;75517:21:0;-1:-1:-1;;;;;75494:13:0;;;;;;:6;:13;;;;;:19;;;;;-1:-1:-1;;;75494:19:0;;;;;:44;;;;;;;;75490:106;;;75560:24;;;75580:3;75560:24;;;;-1:-1:-1;;;;;75560:24:0;;;;;;;;;;;;;75490:106;-1:-1:-1;;;;;75648:13:0;;;;;;:6;:13;;;;;;;;75641:20;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;75641:20:0;;;75718:27;;;;;;75738:6;;75648:13;75718:27;75648:13;75718:27;75738:6;75648:13;75718:27;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;75804:25:0;;75783:10;;;;75804:25;;;;;75822:6;;75756:24;75804:25;75756:24;75804:25;75822:6;75783:10;75804:25;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;75847:34:0;;;-1:-1:-1;;;;;75847:34:0;;;;;;;;;;;;;;;;;;;;;;;;;75004:885;;;;;:::o;45459:184::-;45517:7;45550:1;45545;:6;;45537:49;;;;;-1:-1:-1;;;45537:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45609:5:0;;;45459:184::o;31275:711::-;31401:13;31466:5;31474:1;31466:9;31454:1;:8;:21;;31432:108;;;;-1:-1:-1;;;31432:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31721:13:0;31620:2;31721:13;31715:20;-1:-1:-1;;;;;;31865:79:0;;31275:711::o;45003:181::-;45061:7;45093:5;;;45117:6;;;;45109:46;;;;;-1:-1:-1;;;45109:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;45175:1;45003:181;-1:-1:-1;;;45003:181:0:o;37309:394::-;37388:4;37394;37400;37406:7;37415:4;37421:12;37445:33;37481:35;:26;:14;:24;:26::i;:::-;:33;:35::i;:::-;37445:71;;37572:18;:6;37579:1;37572:9;;;;;;;;;;;;;;:16;:18::i;:::-;37592;:6;37599:1;37592:9;;;;;;;:18;37612;:6;37619:1;37612:9;;;;;;;:18;37632:21;:6;37639:1;37632:9;;;;;;;;;;;;;;:19;:21::i;:::-;37655:18;:6;37662:1;37655:9;;;;;;;:18;37675:19;:6;37682:1;37675:9;;;;;;;;;;;;;;:17;:19::i;:::-;37564:131;;;;-1:-1:-1;37564:131:0;;-1:-1:-1;37564:131:0;-1:-1:-1;37564:131:0;-1:-1:-1;37564:131:0;;-1:-1:-1;37309:394:0;-1:-1:-1;;;37309:394:0:o;30359:230::-;30486:14;30535:21;30547:1;30550:5;30535:11;:21::i;46832:333::-;46890:7;46989:1;46985;:5;46977:44;;;;;-1:-1:-1;;;46977:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47032:9;47048:1;47044;:5;;;;;;;46832:333;-1:-1:-1;;;;46832:333:0:o;37764:289::-;37825:14;;:::i;:::-;37856:11;;37852:55;;-1:-1:-1;37894:13:0;;;;;;;;;-1:-1:-1;37894:13:0;;;;;;;37887:20;;37852:55;-1:-1:-1;38017:28:0;;;;;;;;;38025:11;;38017:28;;37984:4;37974:15;;;38017:28;;;;37764:289;;;:::o;38120:499::-;38180:23;38224:12;38231:4;38224:6;:12::i;:::-;38216:38;;;;;-1:-1:-1;;;38216:38:0;;;;;;;;;;;;-1:-1:-1;;;38216:38:0;;;;;;;;;;;;;;;38265:10;38278:14;38287:4;38278:8;:14::i;:::-;38265:27;;38326:5;38312:20;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;38303:29;;38343:11;38371:27;38386:4;:11;;;38371:14;:27::i;:::-;38357:11;;;;:41;;-1:-1:-1;38409:12:0;;38432:180;38453:5;38449:1;:9;38432:180;;;38490:19;38502:6;38490:11;:19::i;:::-;38480:29;;38536:24;;;;;;;;38544:7;38536:24;;;;38553:6;38536:24;;;38524:6;38531:1;38524:9;;;;;;;;;;;;;;;;;:36;38584:16;;;;38460:3;;38432:180;;;;38120:499;;;;;;:::o;42425:386::-;42485:4;42502:11;42516:27;42531:4;:11;;;42516:14;:27::i;:::-;42565:8;;42607:11;;;;;:20;;42698:13;42565:17;;;42722:12;;;42717:3;42713:22;42694:42;;;;42425:386;-1:-1:-1;;42425:386:0:o;42139:278::-;42202:7;42305:2;42293:4;:8;;;:14;;42285:85;;;;-1:-1:-1;;;42285:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42396:12;42403:4;42396:6;:12::i;42819:416::-;42880:12;42905:11;42919:27;42934:4;:11;;;42919:14;:27::i;:::-;42968:8;;43042:14;;;42968:17;;;;43042:14;;;-1:-1:-1;;43042:14:0;;;;;;;;;;;42905:41;;-1:-1:-1;43020:19:0;;42968:17;43042:14;;;;;;;21:6:-1;;104:10;43042:14:0;87:34:-1;135:17;;-1:-1;43042:14:0;;43020:36;;43067:12;43135:6;43129:4;43125:17;43114:28;;43163:40;43182:6;43168:4;:11;;;:20;43190:7;43199:3;43163:4;:40::i;:::-;-1:-1:-1;43221:6:0;42819:416;-1:-1:-1;;;;42819:416:0:o;28888:511::-;29015:14;29081:5;29089:2;29081:10;29069:1;:8;:22;;29047:110;;;;-1:-1:-1;;;29047:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29343:13:0;29241:2;29343:13;29337:20;;28888:511::o;38755:296::-;38868:11;;;;38931:13;;38815:4;;38923:22;;;;36826:4;38970:24;;38966:55;;;39016:5;39009:12;;;;;;38966:55;-1:-1:-1;39039:4:0;;38755:296;-1:-1:-1;;;38755:296:0:o;39121:396::-;39183:4;39200:10;39213:1;39200:14;;39225:12;39254:27;39269:4;:11;;;39254:14;:27::i;:::-;39240:11;;;;39320:8;;39240:41;;;;-1:-1:-1;39306:22:0;39339:148;39356:6;39346:7;:16;39339:148;;;39399:20;39411:7;39399:11;:20::i;:::-;39468:7;;;;;39389:30;;;;39339:148;;;-1:-1:-1;39504:5:0;;39121:396;-1:-1:-1;;;39121:396:0:o;40842:550::-;40981:13;;40902:4;;40973:22;;36735:4;41020:26;;41016:368;;;41068:1;41061:8;;;;;41016:368;36781:4;41089:25;;;:83;;-1:-1:-1;36826:4:0;41119:25;;;;;:52;;-1:-1:-1;36870:4:0;41148:23;;41119:52;41085:299;;;41194:1;41187:8;;;;;41085:299;36826:4;41215:24;;41211:173;;;-1:-1:-1;;41280:35:0;;-1:-1:-1;41273:42:0;;41211:173;-1:-1:-1;;41351:33:0;;-1:-1:-1;41344:40:0;;41211:173;40842:550;;;;:::o;39567:1222::-;39707:13;;39624:8;;39699:22;;36735:4;39746:26;;39742:1040;;;39794:1;39787:8;;;;;39742:1040;36781:4;39815:25;;39811:971;;;-1:-1:-1;;39862:30:0;;-1:-1:-1;39855:37:0;;39811:971;36826:4;39912:24;;39908:874;;;40007:4;40000:5;39996:16;40087:1;40079:6;40075:14;40065:24;;40223:7;40219:2;40215:16;40210:3;40206:26;40197:6;40191:13;40187:46;40317:1;40308:7;40304:15;40295:7;40291:29;40284:36;;39962:373;;;;;36870:4;40365:23;;40361:421;;;-1:-1:-1;;40412:28:0;;-1:-1:-1;40405:35:0;;40361:421;40581:1;40569:14;;;;40620:13;40648:2;40644:16;;;40536:4;40644:16;40639:3;40635:26;40616:46;;40727:29;;;-1:-1:-1;;40727:29:0;;39567:1222;-1:-1:-1;39567:1222:0:o;43394:681::-;43512:199;36908:2;43519:16;;43512:199;;43611:10;;43598:24;;36908:2;43651:16;;;;43682:17;;;;-1:-1:-1;;43537:16:0;43512:199;;;43896:10;;43968:11;;36908:2;43822:15;;;;43814:3;:24;-1:-1:-1;;43814:28:0;43908:9;;43892:26;;;43964:22;;44035:21;;;;44022:35;;43862:206::o;51662:24230::-;;;;;;;;;-1:-1:-1;51662:24230:0;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51662:24230:0;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

bzzr://ac2aa0393ce6b8813055ebaead9b1b776f47b7e48a65bcca3c6bd72394ef5d64
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.