ETH Price: $3,389.03 (-1.55%)
Gas: 2 Gwei

Contract

0x8346F3074994FD9A813c735D629B257D93780Eed
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
0xe87f37291ab37e4bd33e93a06ca8b2eb88807cd10c3f79c6a60a1dda6d583006 Trade(pending)2024-06-23 1:41:116 days ago1719106871IN
0x8346F307...D93780Eed
0.000154 ETH(Pending)(Pending)
Cancel Orders129185362021-07-29 4:04:151066 days ago1627531455IN
0x8346F307...D93780Eed
0 ETH0.008484323.68
Cancel Orders127086112021-06-26 8:31:331099 days ago1624696293IN
0x8346F307...D93780Eed
0 ETH0.0075604221.1
Cancel Orders127086062021-06-26 8:29:551099 days ago1624696195IN
0x8346F307...D93780Eed
0 ETH0.0075604221.1
Trade125876072021-06-07 13:19:261117 days ago1623071966IN
0x8346F307...D93780Eed
0.00513186 ETH0.0164008316
Trade125342292021-05-30 7:00:411126 days ago1622358041IN
0x8346F307...D93780Eed
0.01344 ETH0.0470095823
Trade121662492021-04-03 11:08:081182 days ago1617448088IN
0x8346F307...D93780Eed
0.01666 ETH0.10437275119
Cancel Orders121438832021-03-31 0:19:531186 days ago1617149993IN
0x8346F307...D93780Eed
0 ETH0.04652682136
Cancel Orders120348842021-03-14 5:49:331203 days ago1615700973IN
0x8346F307...D93780Eed
0 ETH0.0311661291.1
Cancel Orders118324192021-02-11 1:58:431234 days ago1613008723IN
0x8346F307...D93780Eed
0 ETH0.0342439100.1
Cancel Orders118067692021-02-07 3:17:471238 days ago1612667867IN
0x8346F307...D93780Eed
0 ETH0.05445862159.18500024
Trade117555802021-01-30 6:05:001246 days ago1611986700IN
0x8346F307...D93780Eed
0.008925 ETH0.0333648652
Trade117414322021-01-28 1:43:191248 days ago1611798199IN
0x8346F307...D93780Eed
0.01162 ETH0.0603587263
Trade117329772021-01-26 18:25:161249 days ago1611685516IN
0x8346F307...D93780Eed
0.01302 ETH0.0553566272.6
Trade117329312021-01-26 18:13:361249 days ago1611684816IN
0x8346F307...D93780Eed
0.01300314 ETH0.0537697592.87957848
Trade117325812021-01-26 17:00:411249 days ago1611680441IN
0x8346F307...D93780Eed
0.03024 ETH0.14006645121
Cancel Orders117280292021-01-26 0:11:281250 days ago1611619888IN
0x8346F307...D93780Eed
0 ETH0.0294213786
Cancel Orders117247302021-01-25 12:04:141250 days ago1611576254IN
0x8346F307...D93780Eed
0 ETH0.0489811191
Trade117012292021-01-21 21:25:381254 days ago1611264338IN
0x8346F307...D93780Eed
0.0196 ETH0.0848119557
Cancel Orders116926972021-01-20 14:00:421255 days ago1611151242IN
0x8346F307...D93780Eed
0 ETH0.04481627131
Trade116853012021-01-19 10:52:421256 days ago1611053562IN
0x8346F307...D93780Eed
0.0126 ETH0.0561723390
Trade116850092021-01-19 9:48:381257 days ago1611049718IN
0x8346F307...D93780Eed
0.01358 ETH0.0547287597
Trade116834142021-01-19 3:54:511257 days ago1611028491IN
0x8346F307...D93780Eed
0.00686 ETH0.0283808949
Cancel Orders116780302021-01-18 7:54:281258 days ago1610956468IN
0x8346F307...D93780Eed
0 ETH0.01881154.99118821
Cancel Orders116780282021-01-18 7:54:001258 days ago1610956440IN
0x8346F307...D93780Eed
0 ETH0.0187985954.953
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
129185362021-07-29 4:04:151066 days ago1627531455
0x8346F307...D93780Eed
0.0016576 ETH
129185362021-07-29 4:04:151066 days ago1627531455
0x8346F307...D93780Eed
0.0016576 ETH
127086112021-06-26 8:31:331099 days ago1624696293
0x8346F307...D93780Eed
0.001477 ETH
127086112021-06-26 8:31:331099 days ago1624696293
0x8346F307...D93780Eed
0.001477 ETH
127086062021-06-26 8:29:551099 days ago1624696195
0x8346F307...D93780Eed
0.001477 ETH
127086062021-06-26 8:29:551099 days ago1624696195
0x8346F307...D93780Eed
0.001477 ETH
125876072021-06-07 13:19:261117 days ago1623071966
0x8346F307...D93780Eed
0.00289186 ETH
125876072021-06-07 13:19:261117 days ago1623071966
0x8346F307...D93780Eed
0.00112 ETH
125876072021-06-07 13:19:261117 days ago1623071966
0x8346F307...D93780Eed
0.00112 ETH
125342292021-05-30 7:00:411126 days ago1622358041
0x8346F307...D93780Eed
0.007 ETH
125342292021-05-30 7:00:411126 days ago1622358041
0x8346F307...D93780Eed
0.00161 ETH
125342292021-05-30 7:00:411126 days ago1622358041
0x8346F307...D93780Eed
0.00161 ETH
125342292021-05-30 7:00:411126 days ago1622358041
0x8346F307...D93780Eed
0.00161 ETH
125342292021-05-30 7:00:411126 days ago1622358041
0x8346F307...D93780Eed
0.00161 ETH
121662492021-04-03 11:08:081182 days ago1617448088
0x8346F307...D93780Eed
0.00833 ETH
121662492021-04-03 11:08:081182 days ago1617448088
0x8346F307...D93780Eed
0.00833 ETH
121438832021-03-31 0:19:531186 days ago1617149993
0x8346F307...D93780Eed
0.00952 ETH
121438832021-03-31 0:19:531186 days ago1617149993
0x8346F307...D93780Eed
0.00952 ETH
120348842021-03-14 5:49:331203 days ago1615700973
0x8346F307...D93780Eed
0.006377 ETH
120348842021-03-14 5:49:331203 days ago1615700973
0x8346F307...D93780Eed
0.006377 ETH
118324192021-02-11 1:58:431234 days ago1613008723
0x8346F307...D93780Eed
0.007007 ETH
118324192021-02-11 1:58:431234 days ago1613008723
0x8346F307...D93780Eed
0.007007 ETH
118067692021-02-07 3:17:471238 days ago1612667867
0x8346F307...D93780Eed
0.01114295 ETH
118067692021-02-07 3:17:471238 days ago1612667867
0x8346F307...D93780Eed
0.01114295 ETH
117555802021-01-30 6:05:001246 days ago1611986700
0x8346F307...D93780Eed
0.005285 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ZeroXTrade

Compiler Version
v0.5.15+commit.6a57276f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license
File 1 of 2 : ZeroXTrade.sol
pragma experimental ABIEncoderV2;
pragma solidity 0.5.15;

contract IAugur {
    function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
    function isKnownUniverse(IUniverse _universe) public view returns (bool);
    function trustedCashTransfer(address _from, address _to, uint256 _amount) public returns (bool);
    function isTrustedSender(address _address) public returns (bool);
    function onCategoricalMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, bytes32[] memory _outcomes) public returns (bool);
    function onYesNoMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash) public returns (bool);
    function onScalarMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, int256[] memory _prices, uint256 _numTicks)  public returns (bool);
    function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, address _initialReporter, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] memory _payoutNumerators, string memory _description, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime) public returns (bool);
    function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _size, uint256 _disputeRound) public returns (bool);
    function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked, string memory description, uint256[] memory _payoutNumerators, uint256 _currentStake, uint256 _stakeRemaining, uint256 _disputeRound) public returns (bool);
    function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime, bool _pacingOn, uint256 _totalRepStakedInPayout, uint256 _totalRepStakedInMarket, uint256 _disputeRound) public returns (bool);
    function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
    function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
    function logMarketFinalized(IUniverse _universe, uint256[] memory _winningPayoutNumerators) public returns (bool);
    function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
    function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
    function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
    function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
    function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets, uint256 _fees) public returns (bool);
    function logMarketOIChanged(IUniverse _universe, IMarket _market) public returns (bool);
    function logTradingProceedsClaimed(IUniverse _universe, address _sender, address _market, uint256 _outcome, uint256 _numShares, uint256 _numPayoutTokens, uint256 _fees) public returns (bool);
    function logUniverseForked(IMarket _forkingMarket) public returns (bool);
    function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logReputationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logReputationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logShareTokensBalanceChanged(address _account, IMarket _market, uint256 _outcome, uint256 _balance) public returns (bool);
    function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logDisputeWindowCreated(IDisputeWindow _disputeWindow, uint256 _id, bool _initial) public returns (bool);
    function logParticipationTokensRedeemed(IUniverse universe, address _sender, uint256 _attoParticipationTokens, uint256 _feePayoutShare) public returns (bool);
    function logTimestampSet(uint256 _newTimestamp) public returns (bool);
    function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
    function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
    function logParticipationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logParticipationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logParticipationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logMarketRepBondTransferred(address _universe, address _from, address _to) public returns (bool);
    function logWarpSyncDataUpdated(address _universe, uint256 _warpSyncHash, uint256 _marketEndTime) public returns (bool);
    function isKnownFeeSender(address _feeSender) public view returns (bool);
    function lookup(bytes32 _key) public view returns (address);
    function getTimestamp() public view returns (uint256);
    function getMaximumMarketEndDate() public returns (uint256);
    function isKnownMarket(IMarket _market) public view returns (bool);
    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators, uint256 _numTicks, uint256 numOutcomes) public view returns (bytes32);
    function logValidityBondChanged(uint256 _validityBond) public returns (bool);
    function logDesignatedReportStakeChanged(uint256 _designatedReportStake) public returns (bool);
    function logNoShowBondChanged(uint256 _noShowBond) public returns (bool);
    function logReportingFeeChanged(uint256 _reportingFee) public returns (bool);
    function getUniverseForkIndex(IUniverse _universe) public view returns (uint256);
}

contract IAugurCreationDataGetter {
    struct MarketCreationData {
        string extraInfo;
        address marketCreator;
        bytes32[] outcomes;
        int256[] displayPrices;
        IMarket.MarketType marketType;
        uint256 recommendedTradeInterval;
    }

    function getMarketCreationData(IMarket _market) public view returns (MarketCreationData memory);
}

contract IAugurMarketDataGetter {
    function getMarketType(IMarket _market) public view returns (IMarket.MarketType _marketType);
    function getMarketOutcomes(IMarket _market) public view returns (bytes32[] memory _outcomes);
    function getMarketRecommendedTradeInterval(IMarket _market) public view returns (uint256);
}

contract IExchange {

    struct FillResults {
        uint256 makerAssetFilledAmount;  // Total amount of makerAsset(s) filled.
        uint256 takerAssetFilledAmount;  // Total amount of takerAsset(s) filled.
        uint256 makerFeePaid;            // Total amount of fees paid by maker(s) to feeRecipient(s).
        uint256 takerFeePaid;            // Total amount of fees paid by taker to feeRecipients(s).
        uint256 protocolFeePaid;         // Total amount of fees paid by taker to the staking contract.
    }

    struct OrderInfo {
        uint8 orderStatus;                    // Status that describes order's validity and fillability.
        bytes32 orderHash;                    // EIP712 hash of the order (see LibOrder.getOrderHash).
        uint256 orderTakerAssetFilledAmount;  // Amount of order that has already been filled.
    }

    // solhint-disable max-line-length
    struct Order {
        address makerAddress;           // Address that created the order.
        address takerAddress;           // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order.
        address feeRecipientAddress;    // Address that will recieve fees when order is filled.
        address senderAddress;          // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods.
        uint256 makerAssetAmount;       // Amount of makerAsset being offered by maker. Must be greater than 0.
        uint256 takerAssetAmount;       // Amount of takerAsset being bid on by maker. Must be greater than 0.
        uint256 makerFee;               // Fee paid to feeRecipient by maker when order is filled.
        uint256 takerFee;               // Fee paid to feeRecipient by taker when order is filled.
        uint256 expirationTimeSeconds;  // Timestamp in seconds at which order expires.
        uint256 salt;                   // Arbitrary number to facilitate uniqueness of the order's hash.
        bytes makerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The leading bytes4 references the id of the asset proxy.
        bytes takerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The leading bytes4 references the id of the asset proxy.
        bytes makerFeeAssetData;        // Encoded data that can be decoded by a specified proxy contract when transferring makerFeeAsset. The leading bytes4 references the id of the asset proxy.
        bytes takerFeeAssetData;        // Encoded data that can be decoded by a specified proxy contract when transferring takerFeeAsset. The leading bytes4 references the id of the asset proxy.
    }
    // solhint-enable max-line-length

    function protocolFeeMultiplier() external view returns (uint256);

    /// @dev Gets information about an order: status, hash, and amount filled.
    /// @param order Order to gather information on.
    /// @return OrderInfo Information about the order and its state.
    ///         See LibOrder.OrderInfo for a complete description.
    function getOrderInfo(Order memory order) public view returns (OrderInfo memory orderInfo);

    /// @dev Fills the input order.
    /// @param order Order struct containing order specifications.
    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
    /// @param signature Proof that order has been created by maker.
    /// @return Amounts filled and fees paid by maker and taker.
    function fillOrder(Order memory order, uint256 takerAssetFillAmount, bytes memory signature) public payable returns (FillResults memory fillResults);
}

library ContractExists {
    function exists(address _address) internal view returns (bool) {
        uint256 size;
        assembly { size := extcodesize(_address) }
        return size > 0;
    }
}

contract IOwnable {
    function getOwner() public view returns (address);
    function transferOwnership(address _newOwner) public returns (bool);
}

contract ITyped {
    function getTypeName() public view returns (bytes32);
}

contract Initializable {
    bool private initialized = false;

    modifier beforeInitialized {
        require(!initialized);
        _;
    }

    function endInitialization() internal beforeInitialized {
        initialized = true;
    }

    function getInitialized() public view returns (bool) {
        return initialized;
    }
}

library LibBytes {

    using LibBytes for bytes;

    /// @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 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)
    {
        // Ensure that the from and to positions are valid positions for a slice within
        // the byte array that is being used.
        if (from > to) {
            revert();
        }
        if (to > b.length) {
            revert();
        }

        // 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)
    {
        // Ensure that the from and to positions are valid positions for a slice within
        // the byte array that is being used.
        if (from > to) {
            revert();
        }
        if (to > b.length) {
            revert();
        }

        // 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)
    {
        if (b.length == 0) {
            revert();
        }

        // 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;
    }
}

library SafeMathUint256 {
    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);

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        return a - b;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);
        return c;
    }

    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a <= b) {
            return a;
        } else {
            return b;
        }
    }

    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a >= b) {
            return a;
        } else {
            return b;
        }
    }

    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            uint256 x = (y + 1) / 2;
            z = y;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }

    function getUint256Min() internal pure returns (uint256) {
        return 0;
    }

    function getUint256Max() internal pure returns (uint256) {
        // 2 ** 256 - 1
        return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
    }

    function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
        return a % b == 0;
    }

    // Float [fixed point] Operations
    function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
        return div(mul(a, b), base);
    }

    function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
        return div(mul(a, base), b);
    }
}

interface IERC1155 {

    /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred,
    ///      including zero value transfers as well as minting or burning.
    /// Operator will always be msg.sender.
    /// Either event from address `0x0` signifies a minting operation.
    /// An event to address `0x0` signifies a burning or melting operation.
    /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may
    /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
    /// To define a token ID with no initial balance, the contract SHOULD emit the TransferSingle event
    /// from `0x0` to `0x0`, with the token creator as `_operator`.
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );

    /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred,
    ///      including zero value transfers as well as minting or burning.
    ///Operator will always be msg.sender.
    /// Either event from address `0x0` signifies a minting operation.
    /// An event to address `0x0` signifies a burning or melting operation.
    /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may
    /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
    /// To define multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event
    /// from `0x0` to `0x0`, with the token creator as `_operator`.
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /// @dev MUST emit when an approval is updated.
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );

    /// @dev MUST emit when the URI is updated for a token ID.
    /// URIs are defined in RFC 3986.
    /// The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema".
    event URI(
        string value,
        uint256 indexed id
    );

    /// @notice Transfers value amount of an _id from the _from address to the _to address specified.
    /// @dev MUST emit TransferSingle event on success.
    /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
    /// MUST throw if `_to` is the zero address.
    /// MUST throw if balance of sender for token `_id` is lower than the `_value` sent.
    /// MUST throw on any other error.
    /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0).
    /// If so, it MUST call `onERC1155Received` on `_to` and revert if the return value
    /// is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.
    /// @param from    Source address
    /// @param to      Target address
    /// @param id      ID of the token type
    /// @param value   Transfer amount
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 value,
        bytes calldata data
    )
        external;

    /// @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call).
    /// @dev MUST emit TransferBatch event on success.
    /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
    /// MUST throw if `_to` is the zero address.
    /// MUST throw if length of `_ids` is not the same as length of `_values`.
    ///  MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_values` sent.
    /// MUST throw on any other error.
    /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0).
    /// If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return value
    /// is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`.
    /// @param from    Source addresses
    /// @param to      Target addresses
    /// @param ids     IDs of each token type
    /// @param values  Transfer amounts per token type
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    )
        external;

    /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
    /// @dev MUST emit the ApprovalForAll event on success.
    /// @param operator  Address to add to the set of authorized operators
    /// @param approved  True if the operator is approved, false to revoke approval
    function setApprovalForAll(address operator, bool approved) external;

    /// @notice Queries the approval status of an operator for a given owner.
    /// @param owner     The owner of the Tokens
    /// @param operator  Address of authorized operator
    /// @return           True if the operator is approved, false if not
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /// @notice Get the balance of an account's Tokens.
    /// @param owner  The address of the token holder
    /// @param id     ID of the Token
    /// @return        The _owner's balance of the Token type requested
    function balanceOf(address owner, uint256 id) external view returns (uint256);

    /// @notice Get the total supply of a Token.
    /// @param id     ID of the Token
    /// @return        The total supply of the Token type requested
    function totalSupply(uint256 id) external view returns (uint256);

    /// @notice Get the balance of multiple account/token pairs
    /// @param owners The addresses of the token holders
    /// @param ids    ID of the Tokens
    /// @return        The _owner's balance of the Token types requested
    function balanceOfBatch(
        address[] calldata owners,
        uint256[] calldata ids
    )
        external
        view
        returns (uint256[] memory balances_);
}

contract IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) public view returns (uint256);
    function transfer(address to, uint256 amount) public returns (bool);
    function transferFrom(address from, address to, uint256 amount) public returns (bool);
    function approve(address spender, uint256 amount) public returns (bool);
    function allowance(address owner, address spender) public view returns (uint256);

    // solhint-disable-next-line no-simple-event-func-name
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract ICash is IERC20 {
}

contract IAffiliateValidator {
    function validateReference(address _account, address _referrer) external view returns (bool);
}

contract IDisputeWindow is ITyped, IERC20 {
    function invalidMarketsTotal() external view returns (uint256);
    function validityBondTotal() external view returns (uint256);

    function incorrectDesignatedReportTotal() external view returns (uint256);
    function initialReportBondTotal() external view returns (uint256);

    function designatedReportNoShowsTotal() external view returns (uint256);
    function designatedReporterNoShowBondTotal() external view returns (uint256);

    function initialize(IAugur _augur, IUniverse _universe, uint256 _disputeWindowId, bool _participationTokensEnabled, uint256 _duration, uint256 _startTime) public;
    function trustedBuy(address _buyer, uint256 _attotokens) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getReputationToken() public view returns (IReputationToken);
    function getStartTime() public view returns (uint256);
    function getEndTime() public view returns (uint256);
    function getWindowId() public view returns (uint256);
    function isActive() public view returns (bool);
    function isOver() public view returns (bool);
    function onMarketFinalized() public;
    function redeem(address _account) public returns (bool);
}

contract IMarket is IOwnable {
    enum MarketType {
        YES_NO,
        CATEGORICAL,
        SCALAR
    }

    function initialize(IAugur _augur, IUniverse _universe, uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public;
    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators) public view returns (bytes32);
    function doInitialReport(uint256[] memory _payoutNumerators, string memory _description, uint256 _additionalStake) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getDisputeWindow() public view returns (IDisputeWindow);
    function getNumberOfOutcomes() public view returns (uint256);
    function getNumTicks() public view returns (uint256);
    function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
    function getForkingMarket() public view returns (IMarket _market);
    function getEndTime() public view returns (uint256);
    function getWinningPayoutDistributionHash() public view returns (bytes32);
    function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getWinningReportingParticipant() public view returns (IReportingParticipant);
    function getReputationToken() public view returns (IV2ReputationToken);
    function getFinalizationTime() public view returns (uint256);
    function getInitialReporter() public view returns (IInitialReporter);
    function getDesignatedReportingEndTime() public view returns (uint256);
    function getValidityBondAttoCash() public view returns (uint256);
    function affiliateFeeDivisor() external view returns (uint256);
    function getNumParticipants() public view returns (uint256);
    function getDisputePacingOn() public view returns (bool);
    function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
    function recordMarketCreatorFees(uint256 _marketCreatorFees, address _sourceAccount, bytes32 _fingerprint) public returns (bool);
    function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
    function isFinalizedAsInvalid() public view returns (bool);
    function finalize() public returns (bool);
    function isFinalized() public view returns (bool);
    function getOpenInterest() public view returns (uint256);
}

contract IReportingParticipant {
    function getStake() public view returns (uint256);
    function getPayoutDistributionHash() public view returns (bytes32);
    function liquidateLosing() public;
    function redeem(address _redeemer) public returns (bool);
    function isDisavowed() public view returns (bool);
    function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getPayoutNumerators() public view returns (uint256[] memory);
    function getMarket() public view returns (IMarket);
    function getSize() public view returns (uint256);
}

contract IInitialReporter is IReportingParticipant, IOwnable {
    function initialize(IAugur _augur, IMarket _market, address _designatedReporter) public;
    function report(address _reporter, bytes32 _payoutDistributionHash, uint256[] memory _payoutNumerators, uint256 _initialReportStake) public;
    function designatedReporterShowed() public view returns (bool);
    function initialReporterWasCorrect() public view returns (bool);
    function getDesignatedReporter() public view returns (address);
    function getReportTimestamp() public view returns (uint256);
    function migrateToNewUniverse(address _designatedReporter) public;
    function returnRepFromDisavow() public;
}

contract IReputationToken is IERC20 {
    function migrateOutByPayout(uint256[] memory _payoutNumerators, uint256 _attotokens) public returns (bool);
    function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
    function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedDisputeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getTotalMigrated() public view returns (uint256);
    function getTotalTheoreticalSupply() public view returns (uint256);
    function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
}

contract IShareToken is ITyped, IERC1155 {
    function initialize(IAugur _augur) external;
    function initializeMarket(IMarket _market, uint256 _numOutcomes, uint256 _numTicks) public;
    function unsafeTransferFrom(address _from, address _to, uint256 _id, uint256 _value) public;
    function unsafeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _values) public;
    function claimTradingProceeds(IMarket _market, address _shareHolder, bytes32 _fingerprint) external returns (uint256[] memory _outcomeFees);
    function getMarket(uint256 _tokenId) external view returns (IMarket);
    function getOutcome(uint256 _tokenId) external view returns (uint256);
    function getTokenId(IMarket _market, uint256 _outcome) public pure returns (uint256 _tokenId);
    function getTokenIds(IMarket _market, uint256[] memory _outcomes) public pure returns (uint256[] memory _tokenIds);
    function buyCompleteSets(IMarket _market, address _account, uint256 _amount) external returns (bool);
    function buyCompleteSetsForTrade(IMarket _market, uint256 _amount, uint256 _longOutcome, address _longRecipient, address _shortRecipient) external returns (bool);
    function sellCompleteSets(IMarket _market, address _holder, address _recipient, uint256 _amount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
    function sellCompleteSetsForTrade(IMarket _market, uint256 _outcome, uint256 _amount, address _shortParticipant, address _longParticipant, address _shortRecipient, address _longRecipient, uint256 _price, address _sourceAccount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
    function totalSupplyForMarketOutcome(IMarket _market, uint256 _outcome) public view returns (uint256);
    function balanceOfMarketOutcome(IMarket _market, uint256 _outcome, address _account) public view returns (uint256);
    function lowestBalanceOfMarketOutcomes(IMarket _market, uint256[] memory _outcomes, address _account) public view returns (uint256);
}

contract IUniverse {
    function creationTime() external view returns (uint256);
    function marketBalance(address) external view returns (uint256);

    function fork() public returns (bool);
    function updateForkValues() public returns (bool);
    function getParentUniverse() public view returns (IUniverse);
    function createChildUniverse(uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
    function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
    function getReputationToken() public view returns (IV2ReputationToken);
    function getForkingMarket() public view returns (IMarket);
    function getForkEndTime() public view returns (uint256);
    function getForkReputationGoal() public view returns (uint256);
    function getParentPayoutDistributionHash() public view returns (bytes32);
    function getDisputeRoundDurationInSeconds(bool _initial) public view returns (uint256);
    function getOrCreateDisputeWindowByTimestamp(uint256 _timestamp, bool _initial) public returns (IDisputeWindow);
    function getOrCreateCurrentDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOrCreateNextDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOrCreatePreviousDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOpenInterestInAttoCash() public view returns (uint256);
    function getTargetRepMarketCapInAttoCash() public view returns (uint256);
    function getOrCacheValidityBond() public returns (uint256);
    function getOrCacheDesignatedReportStake() public returns (uint256);
    function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
    function getOrCacheMarketRepBond() public returns (uint256);
    function getOrCacheReportingFeeDivisor() public returns (uint256);
    function getDisputeThresholdForFork() public view returns (uint256);
    function getDisputeThresholdForDisputePacing() public view returns (uint256);
    function getInitialReportMinValue() public view returns (uint256);
    function getPayoutNumerators() public view returns (uint256[] memory);
    function getReportingFeeDivisor() public view returns (uint256);
    function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getWinningChildPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function isOpenInterestCash(address) public view returns (bool);
    function isForkingMarket() public view returns (bool);
    function getCurrentDisputeWindow(bool _initial) public view returns (IDisputeWindow);
    function getDisputeWindowStartTimeAndDuration(uint256 _timestamp, bool _initial) public view returns (uint256, uint256);
    function isParentOf(IUniverse _shadyChild) public view returns (bool);
    function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
    function isContainerForDisputeWindow(IDisputeWindow _shadyTarget) public view returns (bool);
    function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
    function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
    function migrateMarketOut(IUniverse _destinationUniverse) public returns (bool);
    function migrateMarketIn(IMarket _market, uint256 _cashBalance, uint256 _marketOI) public returns (bool);
    function decrementOpenInterest(uint256 _amount) public returns (bool);
    function decrementOpenInterestFromMarket(IMarket _market) public returns (bool);
    function incrementOpenInterest(uint256 _amount) public returns (bool);
    function getWinningChildUniverse() public view returns (IUniverse);
    function isForking() public view returns (bool);
    function deposit(address _sender, uint256 _amount, address _market) public returns (bool);
    function withdraw(address _recipient, uint256 _amount, address _market) public returns (bool);
    function createScalarMarket(uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, int256[] memory _prices, uint256 _numTicks, string memory _extraInfo) public returns (IMarket _newMarket);
}

contract IV2ReputationToken is IReputationToken {
    function parentUniverse() external returns (IUniverse);
    function burnForMarket(uint256 _amountToBurn) public returns (bool);
    function mintForWarpSync(uint256 _amountToMint, address _target) public returns (bool);
}

contract IAugurTrading {
    function lookup(bytes32 _key) public view returns (address);
    function logProfitLossChanged(IMarket _market, address _account, uint256 _outcome, int256 _netPosition, uint256 _avgPrice, int256 _realizedProfit, int256 _frozenFunds, int256 _realizedCost) public returns (bool);
    function logOrderCreated(IUniverse _universe, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
    function logOrderCanceled(IUniverse _universe, IMarket _market, address _creator, uint256 _tokenRefund, uint256 _sharesRefund, bytes32 _orderId) public returns (bool);
    function logOrderFilled(IUniverse _universe, address _creator, address _filler, uint256 _price, uint256 _fees, uint256 _amountFilled, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
    function logMarketVolumeChanged(IUniverse _universe, address _market, uint256 _volume, uint256[] memory _outcomeVolumes, uint256 _totalTrades) public returns (bool);
    function logZeroXOrderFilled(IUniverse _universe, IMarket _market, bytes32 _orderHash, bytes32 _tradeGroupId, uint8 _orderType, address[] memory _addressData, uint256[] memory _uint256Data) public returns (bool);
    function logZeroXOrderCanceled(address _universe, address _market, address _account, uint256 _outcome, uint256 _price, uint256 _amount, uint8 _type, bytes32 _orderHash) public;
}

contract IFillOrder {
    function publicFillOrder(bytes32 _orderId, uint256 _amountFillerWants, bytes32 _tradeGroupId, bytes32 _fingerprint) external returns (uint256);
    function fillOrder(address _filler, bytes32 _orderId, uint256 _amountFillerWants, bytes32 tradeGroupId, bytes32 _fingerprint) external returns (uint256);
    function fillZeroXOrder(IMarket _market, uint256 _outcome, uint256 _price, Order.Types _orderType, address _creator, uint256 _amount, bytes32 _fingerprint, bytes32 _tradeGroupId, address _filler) external returns (uint256, uint256);
    function getMarketOutcomeValues(IMarket _market) public view returns (uint256[] memory);
    function getMarketVolume(IMarket _market) public view returns (uint256);
}

contract IOrders {
    function saveOrder(uint256[] calldata _uints, bytes32[] calldata _bytes32s, Order.Types _type, IMarket _market, address _sender) external returns (bytes32 _orderId);
    function removeOrder(bytes32 _orderId) external returns (bool);
    function getMarket(bytes32 _orderId) public view returns (IMarket);
    function getOrderType(bytes32 _orderId) public view returns (Order.Types);
    function getOutcome(bytes32 _orderId) public view returns (uint256);
    function getAmount(bytes32 _orderId) public view returns (uint256);
    function getPrice(bytes32 _orderId) public view returns (uint256);
    function getOrderCreator(bytes32 _orderId) public view returns (address);
    function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
    function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
    function getOrderDataForCancel(bytes32 _orderId) public view returns (uint256, uint256, Order.Types, IMarket, uint256, address);
    function getOrderDataForLogs(bytes32 _orderId) public view returns (Order.Types, address[] memory _addressData, uint256[] memory _uint256Data);
    function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
    function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
    function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
    function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
    function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
    function getOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
    function getTotalEscrowed(IMarket _market) public view returns (uint256);
    function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
    function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
    function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
    function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
    function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled, uint256 _fill) external returns (bool);
    function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
}

contract IZeroXTrade {

    struct AugurOrderData {
        address marketAddress;                  // Market Address
        uint256 price;                          // Price
        uint8 outcome;                          // Outcome
        uint8 orderType;                        // Order Type
    }

    function parseOrderData(IExchange.Order memory _order) public view returns (AugurOrderData memory _data);
    function unpackTokenId(uint256 _tokenId) public pure returns (address _market, uint256 _price, uint8 _outcome, uint8 _type);
}

library Order {
    using SafeMathUint256 for uint256;

    enum Types {
        Bid, Ask
    }

    enum TradeDirections {
        Long, Short
    }

    struct Data {
        // Contracts
        IMarket market;
        IAugur augur;
        IAugurTrading augurTrading;
        IShareToken shareToken;
        ICash cash;

        // Order
        bytes32 id;
        address creator;
        uint256 outcome;
        Order.Types orderType;
        uint256 amount;
        uint256 price;
        uint256 sharesEscrowed;
        uint256 moneyEscrowed;
        bytes32 betterOrderId;
        bytes32 worseOrderId;
    }

    function create(IAugur _augur, IAugurTrading _augurTrading, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data memory) {
        require(_outcome < _market.getNumberOfOutcomes(), "Order.create: Outcome is not within market range");
        require(_price != 0, "Order.create: Price may not be 0");
        require(_price < _market.getNumTicks(), "Order.create: Price is outside of market range");
        require(_attoshares > 0, "Order.create: Cannot use amount of 0");
        require(_creator != address(0), "Order.create: Creator is 0x0");

        IShareToken _shareToken = IShareToken(_augur.lookup("ShareToken"));

        return Data({
            market: _market,
            augur: _augur,
            augurTrading: _augurTrading,
            shareToken: _shareToken,
            cash: ICash(_augur.lookup("Cash")),
            id: 0,
            creator: _creator,
            outcome: _outcome,
            orderType: _type,
            amount: _attoshares,
            price: _price,
            sharesEscrowed: 0,
            moneyEscrowed: 0,
            betterOrderId: _betterOrderId,
            worseOrderId: _worseOrderId
        });
    }

    //
    // "public" functions
    //

    function getOrderId(Order.Data memory _orderData, IOrders _orders) internal view returns (bytes32) {
        if (_orderData.id == bytes32(0)) {
            bytes32 _orderId = calculateOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
            require(_orders.getAmount(_orderId) == 0, "Order.getOrderId: New order had amount. This should not be possible");
            _orderData.id = _orderId;
        }
        return _orderData.id;
    }

    function calculateOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) internal pure returns (bytes32) {
        return sha256(abi.encodePacked(_type, _market, _amount, _price, _sender, _blockNumber, _outcome, _moneyEscrowed, _sharesEscrowed));
    }

    function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
        return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
    }

    function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
        return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
    }

    function saveOrder(Order.Data memory _orderData, bytes32 _tradeGroupId, IOrders _orders) internal returns (bytes32) {
        getOrderId(_orderData, _orders);
        uint256[] memory _uints = new uint256[](5);
        _uints[0] = _orderData.amount;
        _uints[1] = _orderData.price;
        _uints[2] = _orderData.outcome;
        _uints[3] = _orderData.moneyEscrowed;
        _uints[4] = _orderData.sharesEscrowed;
        bytes32[] memory _bytes32s = new bytes32[](4);
        _bytes32s[0] = _orderData.betterOrderId;
        _bytes32s[1] = _orderData.worseOrderId;
        _bytes32s[2] = _tradeGroupId;
        _bytes32s[3] = _orderData.id;
        return _orders.saveOrder(_uints, _bytes32s, _orderData.orderType, _orderData.market, _orderData.creator);
    }
}

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

interface IWETH {
    function deposit() external payable;
    function balanceOf(address owner) external view returns (uint);
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

contract ZeroXTrade is Initializable, IZeroXTrade, IERC1155 {
    using SafeMathUint256 for uint256;
    using LibBytes for bytes;

    bool transferFromAllowed = false;

    // ERC20Token(address)
    bytes4 constant private ERC20_PROXY_ID = 0xf47261b0;

    // ERC1155Assets(address,uint256[],uint256[],bytes)
    bytes4 constant private MULTI_ASSET_PROXY_ID = 0x94cfcdd7;

    // ERC1155Assets(address,uint256[],uint256[],bytes)
    bytes4 constant private ERC1155_PROXY_ID = 0xa7cb5fb7;

    // EIP191 header for EIP712 prefix
    string constant internal EIP191_HEADER = "\x19\x01";

    // EIP712 Domain Name value
    string constant internal EIP712_DOMAIN_NAME = "0x Protocol";

    // EIP712 Domain Version value
    string constant internal EIP712_DOMAIN_VERSION = "2";

    // EIP1271 Order With Hash Selector
    bytes4 constant public EIP1271_ORDER_WITH_HASH_SELECTOR = 0x3efe50c8;

    // Hash of the EIP712 Domain Separator Schema
    bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(
        abi.encodePacked(
        "EIP712Domain(",
        "string name,",
        "string version,",
        "address verifyingContract",
        ")"
    ));

    bytes32 constant internal EIP712_ORDER_SCHEMA_HASH = keccak256(
        abi.encodePacked(
        "Order(",
        "address makerAddress,",
        "address takerAddress,",
        "address feeRecipientAddress,",
        "address senderAddress,",
        "uint256 makerAssetAmount,",
        "uint256 takerAssetAmount,",
        "uint256 makerFee,",
        "uint256 takerFee,",
        "uint256 expirationTimeSeconds,",
        "uint256 salt,",
        "bytes makerAssetData,",
        "bytes takerAssetData",
        "bytes makerFeeAssetData,",
        "bytes takerFeeAssetData",
        ")"
    ));

    // Hash of the EIP712 Domain Separator data
    // solhint-disable-next-line var-name-mixedcase
    bytes32 public EIP712_DOMAIN_HASH;

    IAugur public augur;
    IAugurTrading public augurTrading;
    IFillOrder public fillOrder;
    ICash public cash;
    IShareToken public shareToken;
    IExchange public exchange;
    IUniswapV2Pair public ethExchange;
    IWETH public WETH;
    bool public token0IsCash;

    function initialize(IAugur _augur, IAugurTrading _augurTrading) public beforeInitialized {
        endInitialization();
        augur = _augur;
        augurTrading = _augurTrading;
        cash = ICash(_augur.lookup("Cash"));
        require(cash != ICash(0));
        shareToken = IShareToken(_augur.lookup("ShareToken"));
        require(shareToken != IShareToken(0));
        exchange = IExchange(_augurTrading.lookup("ZeroXExchange"));
        require(exchange != IExchange(0));
        fillOrder = IFillOrder(_augurTrading.lookup("FillOrder"));
        require(fillOrder != IFillOrder(0));
        WETH = IWETH(_augurTrading.lookup("WETH9"));
        IUniswapV2Factory _uniswapFactory = IUniswapV2Factory(_augur.lookup("UniswapV2Factory"));
        address _ethExchangeAddress = _uniswapFactory.getPair(address(WETH), address(cash));
        if (_ethExchangeAddress == address(0)) {
            _ethExchangeAddress = _uniswapFactory.createPair(address(WETH), address(cash));
        }
        ethExchange = IUniswapV2Pair(_ethExchangeAddress);
        token0IsCash = ethExchange.token0() == address(cash);

        EIP712_DOMAIN_HASH = keccak256(
            abi.encodePacked(
                EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
                keccak256(bytes(EIP712_DOMAIN_NAME)),
                keccak256(bytes(EIP712_DOMAIN_VERSION)),
                uint256(address(this))
            )
        );
    }

    // ERC1155 Implementation
    /// @notice Transfers value amount of an _id from the _from address to the _to address specified.
    /// @dev MUST emit TransferSingle event on success.
    /// @param from    Source address
    /// @param to      Target address
    /// @param id      ID of the token type
    /// @param value   Transfer amount
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external {
        require(transferFromAllowed);
        emit TransferSingle(msg.sender, from, to, id, value);
    }

    /// @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call).
    /// @dev MUST emit TransferBatch event on success.
    /// @param from    Source addresses
    /// @param to      Target addresses
    /// @param ids     IDs of each token type
    /// @param values  Transfer amounts per token type
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external {
        require(transferFromAllowed);
        emit TransferBatch(msg.sender, from, to, ids, values);
    }

    /// @notice Get the balance of an account's Tokens.
    /// @param owner  The address of the token holder
    /// @param id     ID of the Token
    /// @return       The _owner's balance of the Token type requested
    function balanceOf(address owner, uint256 id) external view returns (uint256) {
        (address _market, uint256 _price, uint8 _outcome, uint8 _type) = unpackTokenId(id);
        // NOTE: An invalid order type will cause a failure here. That is malformed input so we don't mind reverting in such a case
        Order.Types _orderType = Order.Types(_type);
        if (_orderType == Order.Types.Ask) {
            return askBalance(owner, IMarket(_market), _outcome, _price);
        } else if (_orderType == Order.Types.Bid) {
            return bidBalance(owner, IMarket(_market), _outcome, _price);
        }
    }

    function totalSupply(uint256 id) external view returns (uint256) {
        return 0;
    }

    function bidBalance(address _owner, IMarket _market, uint8 _outcome, uint256 _price) public view returns (uint256) {
        uint256 _numberOfOutcomes = _market.getNumberOfOutcomes();
        // Figure out how many almost-complete-sets (just missing `outcome` share) the creator has
        uint256[] memory _shortOutcomes = new uint256[](_numberOfOutcomes - 1);
        uint256 _indexOutcome = 0;
        for (uint256 _i = 0; _i < _numberOfOutcomes - 1; _i++) {
            if (_i == _outcome) {
                _indexOutcome++;
            }
            _shortOutcomes[_i] = _indexOutcome;
            _indexOutcome++;
        }

        uint256 _attoSharesOwned = shareToken.lowestBalanceOfMarketOutcomes(_market, _shortOutcomes, _owner);

        uint256 _availableCash = cashAvailableForTransferFrom(_owner, address(fillOrder));
        uint256 _attoSharesPurchasable = _availableCash.div(_price);

        return _attoSharesOwned.add(_attoSharesPurchasable);
    }

    function askBalance(address _owner, IMarket _market, uint8 _outcome, uint256 _price) public view returns (uint256) {
        uint256 _attoSharesOwned = shareToken.balanceOfMarketOutcome(_market, _outcome, _owner);
        uint256 _availableCash = cashAvailableForTransferFrom(_owner, address(fillOrder));
        uint256 _attoSharesPurchasable = _availableCash.div(_market.getNumTicks().sub(_price));

        return _attoSharesOwned.add(_attoSharesPurchasable);
    }

    function cashAvailableForTransferFrom(address _owner, address _sender) public view returns (uint256) {
        uint256 _balance = cash.balanceOf(_owner);
        uint256 _allowance = cash.allowance(_owner, _sender);
        return _balance.min(_allowance);
    }

    /// @notice Get the balance of multiple account/token pairs
    /// @param owners The addresses of the token holders
    /// @param ids    ID of the Tokens
    /// @return        The _owner's balance of the Token types requested
    function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) external view returns (uint256[] memory balances_) {
        balances_ = new uint256[](owners.length);
        for (uint256 _i = 0; _i < owners.length; _i++) {
            balances_[_i] = this.balanceOf(owners[_i], ids[_i]);
        }
    }

    function setApprovalForAll(address operator, bool approved) external {
        revert("Not supported");
    }

    function isApprovedForAll(address owner, address operator) external view returns (bool) {
        return true;
    }

    // Trade functions

    /**
     * Perform Augur Trades using 0x signed orders
     *
     * @param  _requestedFillAmount  Share amount to fill
     * @param  _fingerprint          Fingerprint of the user to restrict affiliate fees
     * @param  _tradeGroupId         Random id to correlate these fills as one trade action
     * @param  _maxProtocolFeeDai    The maximum amount of DAI to spend on covering the 0x protocol fee
     * @param  _maxTrades            The maximum number of trades to actually take from the provided 0x orders
     * @param  _orders               Array of encoded Order struct data
     * @param  _signatures           Array of signature data
     * @return                       The amount the taker still wants
     */
    function trade(
        uint256 _requestedFillAmount,
        bytes32 _fingerprint,
        bytes32 _tradeGroupId,
        uint256 _maxProtocolFeeDai,
        uint256 _maxTrades,
        IExchange.Order[] memory _orders,
        bytes[] memory _signatures
    )
        public
        payable
        returns (uint256)
    {
        require(_orders.length > 0);
        uint256 _fillAmountRemaining = _requestedFillAmount;

        transferFromAllowed = true;

        uint256 _protocolFee = exchange.protocolFeeMultiplier().mul(tx.gasprice);
        coverProtocolFee(_protocolFee.mul(_maxTrades), _maxProtocolFeeDai);

        // Do the actual asset exchanges
        for (uint256 i = 0; i < _orders.length && _fillAmountRemaining != 0; i++) {
            IExchange.Order memory _order = _orders[i];
            validateOrder(_order, _fillAmountRemaining);

            // Update 0x and pay protocol fee. This will also validate signatures and order state for us.
            IExchange.FillResults memory totalFillResults = fillOrderNoThrow(
                _order,
                _fillAmountRemaining,
                _signatures[i],
                _protocolFee
            );

            if (totalFillResults.takerAssetFilledAmount == 0) {
                continue;
            }

            uint256 _amountTraded = doTrade(_order, totalFillResults.takerAssetFilledAmount, _fingerprint, _tradeGroupId, msg.sender);

            _fillAmountRemaining = _fillAmountRemaining.sub(_amountTraded);
            _maxTrades -= 1;
            if (_maxTrades == 0) {
                break;
            }
        }

        transferFromAllowed = false;

        if (address(this).balance > 0) {
            (bool _success,) = msg.sender.call.value(address(this).balance)("");
            require(_success);
        }

        return _fillAmountRemaining;
    }

    function fillOrderNoThrow(IExchange.Order memory _order, uint256 _takerAssetFillAmount, bytes memory _signature, uint256 _protocolFee) internal returns (IExchange.FillResults memory fillResults) {
        bytes memory fillOrderCalldata = abi.encodeWithSelector(
            IExchange(address(0)).fillOrder.selector,
            _order,
            _takerAssetFillAmount,
            _signature
        );

        (bool _didSucceed, bytes memory _returnData) = address(exchange).call.value(_protocolFee)(fillOrderCalldata);
        if (_didSucceed) {
            assert(_returnData.length == 160);
            fillResults = abi.decode(_returnData, (IExchange.FillResults));
        }
        return fillResults;
    }

    function coverProtocolFee(uint256 _amountEthRequired, uint256 _maxProtocolFeeDai) internal {
        if (address(this).balance < _amountEthRequired) {
            uint256 _ethDeficit = _amountEthRequired - address(this).balance;
            uint256 _cost = getTokenPurchaseCost(_ethDeficit);
            require(_cost <= _maxProtocolFeeDai, "Cost of purchasing ETH to cover protocol Fee on the exchange was too high");
            require(cash.transferFrom(msg.sender, address(ethExchange), _cost));
            ethExchange.swap(token0IsCash ? 0 : _ethDeficit, token0IsCash ? _ethDeficit : 0, address(this), "");
            WETH.withdraw(_ethDeficit);
        }
    }

    function estimateProtocolFeeCostInCash(uint256 _numOrders, uint256 _gasPrice) public view returns (uint256) {
        uint256 _protocolFee = exchange.protocolFeeMultiplier().mul(_gasPrice);
        uint256 _amountEthRequired = _protocolFee.mul(_numOrders);
        return getTokenPurchaseCost(_amountEthRequired);
    }

    function getTokenPurchaseCost(uint256 _ethAmount) private view returns (uint256) {
        (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = ethExchange.getReserves();
        return getAmountIn(_ethAmount, token0IsCash ? _reserve0 : _reserve1, token0IsCash ? _reserve1 : _reserve0);
    }

    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure returns (uint amountIn) {
        require(amountOut > 0);
        require(reserveIn > 0 && reserveOut > 0);
        uint numerator = reserveIn.mul(amountOut).mul(1000);
        uint denominator = reserveOut.sub(amountOut).mul(997);
        amountIn = (numerator / denominator).add(1);
    }

    function validateOrder(IExchange.Order memory _order, uint256 _fillAmountRemaining) internal view {
        require(_order.takerAssetData.equals(encodeTakerAssetData()));
        require(_order.takerAssetAmount == _order.makerAssetAmount);
        (IERC1155 _zeroXTradeTokenMaker, uint256 _tokenIdMaker) = getZeroXTradeTokenData(_order.makerAssetData);
        (address _market, uint256 _price, uint8 _outcome, uint8 _type) = unpackTokenId(_tokenIdMaker);
        uint256 _numTicks = IMarket(_market).getNumTicks();
        require(isOrderAmountValid(IMarket(_market), _fillAmountRemaining), "Order must be a multiple of the market trade increment");
        require(_zeroXTradeTokenMaker == this);
    }

    function isOrderAmountValid(IMarket _market, uint256 _orderAmount) public view returns (bool) {
        uint256 _tradeInterval = IAugurMarketDataGetter(address(augur)).getMarketRecommendedTradeInterval(_market);
        return _orderAmount.isMultipleOf(_tradeInterval);
    }

    function cancelOrders(IExchange.Order[] memory _orders, bytes[] memory _signatures, uint256 _maxProtocolFeeDai) public returns (bool) {
        require(_orders.length == _signatures.length);
        uint256 _protocolFee = exchange.protocolFeeMultiplier().mul(tx.gasprice);
        coverProtocolFee(_protocolFee.mul(_orders.length), _maxProtocolFeeDai);
        transferFromAllowed = true;
        for (uint256 i = 0; i < _orders.length; i++) {
            IExchange.Order memory _order = _orders[i];
            bytes memory _signature = _signatures[i];
            require(msg.sender == _order.makerAddress);
            IExchange.OrderInfo memory _orderInfo = exchange.getOrderInfo(_order);
            uint256 _amountRemaining = _order.takerAssetAmount.sub(_orderInfo.orderTakerAssetFilledAmount);
            exchange.fillOrder.value(_protocolFee)(_order, _amountRemaining, _signature);
            AugurOrderData memory _orderData = parseOrderData(_order);
            IUniverse _universe = IMarket(_orderData.marketAddress).getUniverse();
            augurTrading.logZeroXOrderCanceled(address(_universe), _orderData.marketAddress, _order.makerAddress, _orderData.outcome, _orderData.price, _amountRemaining, uint8(_orderData.orderType), _orderInfo.orderHash);
        }
        transferFromAllowed = false;
        if (address(this).balance > 0) {
            (bool _success,) = msg.sender.call.value(address(this).balance)("");
            require(_success);
        }
        return true;
    }

    function doTrade(IExchange.Order memory _order, uint256 _amount, bytes32 _fingerprint, bytes32 _tradeGroupId, address _taker) private returns (uint256 _amountFilled) {
        // parseOrderData will validate that the token being traded is the leigitmate one for the market
        AugurOrderData memory _augurOrderData = parseOrderData(_order);
        // If the signed order creator doesnt have enough funds we still want to continue and take their order out of the list
        // If the filler doesn't have funds this will just fail, which is fine
        if (!creatorHasFundsForTrade(_order, _amount)) {
            return 0;
        }
        // If the maker is also the taker we also just skip the trade but treat it as filled for amount remaining purposes
        if (_order.makerAddress == _taker) {
            return _amount;
        }
        (uint256 _amountRemaining, uint256 _fees) = fillOrder.fillZeroXOrder(IMarket(_augurOrderData.marketAddress), _augurOrderData.outcome, _augurOrderData.price, Order.Types(_augurOrderData.orderType), _order.makerAddress, _amount, _fingerprint, _tradeGroupId, _taker);
        _amountFilled = _amount.sub(_amountRemaining);
        logOrderFilled(_order, _augurOrderData, _taker, _tradeGroupId, _amountFilled, _fees);
        return _amountFilled;
    }

    function logOrderFilled(IExchange.Order memory _order, AugurOrderData memory _augurOrderData, address _taker, bytes32 _tradeGroupId, uint256 _amountFilled, uint256 _fees) private {
        bytes32 _orderHash = exchange.getOrderInfo(_order).orderHash;
        address[] memory _addressData = new address[](2);
        uint256[] memory _uint256Data = new uint256[](10);
        Order.Types _orderType = Order.Types(_augurOrderData.orderType);
        _addressData[0] = _order.makerAddress;
        _addressData[1] = _taker;
        _uint256Data[0] = _augurOrderData.price;
        _uint256Data[1] = 0;
        _uint256Data[2] = _augurOrderData.outcome;
        _uint256Data[5] = _fees;
        _uint256Data[6] = _amountFilled;
        _uint256Data[8] = 0;
        _uint256Data[9] = 0;
        augurTrading.logZeroXOrderFilled(IMarket(_augurOrderData.marketAddress).getUniverse(), IMarket(_augurOrderData.marketAddress), _orderHash, _tradeGroupId, uint8(_orderType), _addressData, _uint256Data);
    }

    function creatorHasFundsForTrade(IExchange.Order memory _order, uint256 _amount) public view returns (bool) {
        uint256 _tokenId = getTokenIdFromOrder(_order);
        return _amount <= this.balanceOf(_order.makerAddress, _tokenId);
    }

    function getTransferFromAllowed() public view returns (bool) {
        return transferFromAllowed;
    }

    /// @dev Encode MultiAsset proxy asset data into the format described in the AssetProxy contract specification.
    /// @param _market The address of the market to trade on
    /// @param _price The price used to trade
    /// @param _outcome The outcome to trade on
    /// @param _type Either BID == 0 or ASK == 1
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeAssetData(
        IMarket _market,
        uint256 _price,
        uint8 _outcome,
        uint8 _type
    )
        public
        view
        returns (bytes memory _assetData)
    {
        bytes[] memory _nestedAssetData = new bytes[](3);
        uint256[] memory _multiAssetValues = new uint256[](3);
        _nestedAssetData[0] = encodeTradeAssetData(_market, _price, _outcome, _type);
        _nestedAssetData[1] = encodeCashAssetData();
        _nestedAssetData[2] = encodeShareAssetData();
        _multiAssetValues[0] = 1;
        _multiAssetValues[1] = 0;
        _multiAssetValues[2] = 0;
        bytes memory _data = abi.encodeWithSelector(
            MULTI_ASSET_PROXY_ID,
            _multiAssetValues,
            _nestedAssetData
        );
        return _data;
    }

    /// @dev Encode ERC-1155 asset data into the format described in the AssetProxy contract specification.
    /// @param _market The address of the market to trade on
    /// @param _price The price used to trade
    /// @param _outcome The outcome to trade on
    /// @param _type Either BID == 0 or ASK == 1
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeTradeAssetData(
        IMarket _market,
        uint256 _price,
        uint8 _outcome,
        uint8 _type
    )
        private
        view
        returns (bytes memory _assetData)
    {
        uint256[] memory _tokenIds = new uint256[](1);
        uint256[] memory _tokenValues = new uint256[](1);

        uint256 _tokenId = getTokenId(address(_market), _price, _outcome, _type);
        _tokenIds[0] = _tokenId;
        _tokenValues[0] = 1;
        bytes memory _callbackData = new bytes(0);
        _assetData = abi.encodeWithSelector(
            ERC1155_PROXY_ID,
            address(this),
            _tokenIds,
            _tokenValues,
            _callbackData
        );

        return _assetData;
    }

    /// @dev Encode ERC-20 asset data into the format described in the AssetProxy contract specification.
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeCashAssetData()
        private
        view
        returns (bytes memory _assetData)
    {
        _assetData = abi.encodeWithSelector(
            ERC20_PROXY_ID,
            address(cash)
        );

        return _assetData;
    }

    /// @dev Encode ERC-1155 asset data into the format described in the AssetProxy contract specification.
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeShareAssetData()
        private
        view
        returns (bytes memory _assetData)
    {
        uint256[] memory _tokenIds = new uint256[](0);
        uint256[] memory _tokenValues = new uint256[](0);
        bytes memory _callbackData = new bytes(0);
        _assetData = abi.encodeWithSelector(
            ERC1155_PROXY_ID,
            address(shareToken),
            _tokenIds,
            _tokenValues,
            _callbackData
        );

        return _assetData;
    }

    /// @dev Encode ERC-1155 asset data into the format described in the AssetProxy contract specification.
    /// @return AssetProxy-compliant asset data describing the set of assets.
    function encodeTakerAssetData()
        private
        view
        returns (bytes memory _assetData)
    {
        uint256[] memory _tokenIds = new uint256[](0);
        uint256[] memory _tokenValues = new uint256[](0);
        bytes memory _callbackData = new bytes(0);
        _assetData = abi.encodeWithSelector(
            ERC1155_PROXY_ID,
            address(this),
            _tokenIds,
            _tokenValues,
            _callbackData
        );

        return _assetData;
    }

    function getTokenId(address _market, uint256 _price, uint8 _outcome, uint8 _type) public pure returns (uint256 _tokenId) {
        // NOTE: we're assuming no one needs a full uint256 for the price value here and cutting to uint80 so we can pack this in a uint256.
        bytes memory _tokenIdBytes = abi.encodePacked(_market, uint80(_price), _outcome, _type);
        assembly {
            _tokenId := mload(add(_tokenIdBytes, add(0x20, 0)))
        }
    }

    function unpackTokenId(uint256 _tokenId) public pure returns (address _market, uint256 _price, uint8 _outcome, uint8 _type) {
        assembly {
            _market := shr(96, and(_tokenId, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000))
            _price := shr(16,  and(_tokenId, 0x0000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFF0000))
            _outcome := shr(8, and(_tokenId, 0x000000000000000000000000000000000000000000000000000000000000FF00))
            _type :=           and(_tokenId, 0x00000000000000000000000000000000000000000000000000000000000000FF)
        }
    }

    /// @dev Decode MultiAsset asset data from the format described in the AssetProxy contract specification.
    /// @param _assetData AssetProxy-compliant asset data describing an ERC-1155 set of assets.
    /// @return The ERC-1155 AssetProxy identifier, the address of this ERC-1155
    /// contract hosting the assets, an array of the identifiers of the
    /// assets to be traded, an array of asset amounts to be traded, and
    /// callback data.  Each element of the arrays corresponds to the
    /// same-indexed element of the other array.  Return values specified as
    /// `memory` are returned as pointers to locations within the memory of
    /// the input parameter `assetData`.
    function decodeAssetData(bytes memory _assetData)
        public
        view
        returns (
            bytes4 _assetProxyId,
            address _tokenAddress,
            uint256[] memory _tokenIds,
            uint256[] memory _tokenValues,
            bytes memory _callbackData
        )
    {
         // Read the bytes4 from array memory
        assembly {
            _assetProxyId := mload(add(_assetData, 32))
            // Solidity does not require us to clean the trailing bytes. We do it anyway
            _assetProxyId := and(_assetProxyId, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
        }

        require(_assetProxyId == MULTI_ASSET_PROXY_ID, "WRONG_PROXY_ID");

        uint256[] memory _amounts;
        bytes[] memory _nestedAssetData;

        // Slice the selector off the asset data
        bytes memory _noSelectorAssetData = _assetData.slice(4, _assetData.length);

        (_amounts, _nestedAssetData) = abi.decode(_noSelectorAssetData, (uint256[], bytes[]));
        
        // Validate storage refs against the decoded values.
        {
            require(_amounts.length == 3);
            require(_amounts[0] == 1);
            require(_amounts[1] == 0);
            require(_amounts[2] == 0);
            require(_nestedAssetData[1].equals(encodeCashAssetData()));
            require(_nestedAssetData[2].equals(encodeShareAssetData()));
        }

        return decodeTradeAssetData(_nestedAssetData[0]);
    }

    /// @dev Decode ERC-1155 asset data from the format described in the AssetProxy contract specification.
    /// @param _assetData AssetProxy-compliant asset data describing an ERC-1155 set of assets.
    /// @return The ERC-1155 AssetProxy identifier, the address of this ERC-1155
    /// contract hosting the assets, an array of the identifiers of the
    /// assets to be traded, an array of asset amounts to be traded, and
    /// callback data.  Each element of the arrays corresponds to the
    /// same-indexed element of the other array.  Return values specified as
    /// `memory` are returned as pointers to locations within the memory of
    /// the input parameter `assetData`.
    function decodeTradeAssetData(bytes memory _assetData)
        public
        pure
        returns (
            bytes4 _assetProxyId,
            address _tokenAddress,
            uint256[] memory _tokenIds,
            uint256[] memory _tokenValues,
            bytes memory _callbackData
        )
    {
         // Read the bytes4 from array memory
        assembly {
            _assetProxyId := mload(add(_assetData, 32))
            // Solidity does not require us to clean the trailing bytes. We do it anyway
            _assetProxyId := and(_assetProxyId, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
        }

        require(_assetProxyId == ERC1155_PROXY_ID, "WRONG_PROXY_ID");

        assembly {
            let _length := mload(_assetData)
            // Skip the length (of bytes variable) and the selector to get to the first parameter.
            _assetData := add(_assetData, 36)
            // Read the value of the first parameter:
            _tokenAddress := mload(_assetData)
            _tokenIds := add(_assetData, mload(add(_assetData, 32)))
            _tokenValues := add(_assetData, mload(add(_assetData, 64)))
            _callbackData := add(_assetData, mload(add(_assetData, 96)))
        }

        return (
            _assetProxyId,
            _tokenAddress,
            _tokenIds,
            _tokenValues,
            _callbackData
        );
    }

    function parseOrderData(IExchange.Order memory _order) public view returns (AugurOrderData memory _data) {
        (bytes4 _assetProxyId, address _tokenAddress, uint256[] memory _tokenIds, uint256[] memory _tokenValues, bytes memory _callbackData) = decodeAssetData(_order.makerAssetData);
        (address _market, uint256 _price, uint8 _outcome, uint8 _type) = unpackTokenId(_tokenIds[0]);
        _data.marketAddress = _market;
        _data.price = _price;
        _data.orderType = _type;
        _data.outcome = _outcome;
    }

    function getZeroXTradeTokenData(bytes memory _assetData) public view returns (IERC1155 _token, uint256 _tokenId) {
        (bytes4 _assetProxyId, address _tokenAddress, uint256[] memory _tokenIds, uint256[] memory _tokenValues, bytes memory _callbackData) = decodeAssetData(_assetData);
        _tokenId = _tokenIds[0];
        _token = IERC1155(_tokenAddress);
    }

    function getTokenIdFromOrder(IExchange.Order memory _order) public view returns (uint256 _tokenId) {
        (bytes4 _assetProxyId, address _tokenAddress, uint256[] memory _tokenIds, uint256[] memory _tokenValues, bytes memory _callbackData) = decodeAssetData(_order.makerAssetData);
        _tokenId = _tokenIds[0];
    }

    function createZeroXOrder(uint8 _type, uint256 _attoshares, uint256 _price, address _market, uint8 _outcome, uint256 _expirationTimeSeconds, uint256 _salt) public view returns (IExchange.Order memory _zeroXOrder, bytes32 _orderHash) {
        return createZeroXOrderFor(msg.sender, _type, _attoshares, _price, _market, _outcome, _expirationTimeSeconds, _salt);
    }

    function createZeroXOrderFor(address _maker, uint8 _type, uint256 _attoshares, uint256 _price, address _market, uint8 _outcome, uint256 _expirationTimeSeconds, uint256 _salt) public view returns (IExchange.Order memory _zeroXOrder, bytes32 _orderHash) {
        bytes memory _assetData = encodeAssetData(IMarket(_market), _price, _outcome, _type);
        require(isOrderAmountValid(IMarket(_market), _attoshares), "Order must be a multiple of the market trade increment");
        _zeroXOrder.makerAddress = _maker;
        _zeroXOrder.makerAssetAmount = _attoshares;
        _zeroXOrder.takerAssetAmount = _attoshares;
        _zeroXOrder.expirationTimeSeconds = _expirationTimeSeconds;
        _zeroXOrder.salt = _salt;
        _zeroXOrder.makerAssetData = _assetData;
        _zeroXOrder.takerAssetData = encodeTakerAssetData();
        _orderHash = exchange.getOrderInfo(_zeroXOrder).orderHash;
    }

    function encodeEIP1271OrderWithHash(
        IExchange.Order memory _zeroXOrder,
        bytes32 _orderHash
    )
        public
        pure
        returns (bytes memory encoded)
    {
        return abi.encodeWithSelector(
            EIP1271_ORDER_WITH_HASH_SELECTOR,
            _zeroXOrder,
            _orderHash
        );
    }

    function () external payable {}
}

File 2 of 2 : Augur.sol
pragma experimental ABIEncoderV2;
pragma solidity 0.5.15;

contract IAugur {
    function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
    function isKnownUniverse(IUniverse _universe) public view returns (bool);
    function trustedCashTransfer(address _from, address _to, uint256 _amount) public returns (bool);
    function isTrustedSender(address _address) public returns (bool);
    function onCategoricalMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, bytes32[] memory _outcomes) public returns (bool);
    function onYesNoMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash) public returns (bool);
    function onScalarMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, int256[] memory _prices, uint256 _numTicks)  public returns (bool);
    function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, address _initialReporter, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] memory _payoutNumerators, string memory _description, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime) public returns (bool);
    function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _size, uint256 _disputeRound) public returns (bool);
    function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked, string memory description, uint256[] memory _payoutNumerators, uint256 _currentStake, uint256 _stakeRemaining, uint256 _disputeRound) public returns (bool);
    function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime, bool _pacingOn, uint256 _totalRepStakedInPayout, uint256 _totalRepStakedInMarket, uint256 _disputeRound) public returns (bool);
    function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
    function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool);
    function logMarketFinalized(IUniverse _universe, uint256[] memory _winningPayoutNumerators) public returns (bool);
    function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
    function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
    function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
    function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
    function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets, uint256 _fees) public returns (bool);
    function logMarketOIChanged(IUniverse _universe, IMarket _market) public returns (bool);
    function logTradingProceedsClaimed(IUniverse _universe, address _sender, address _market, uint256 _outcome, uint256 _numShares, uint256 _numPayoutTokens, uint256 _fees) public returns (bool);
    function logUniverseForked(IMarket _forkingMarket) public returns (bool);
    function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logReputationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logReputationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logShareTokensBalanceChanged(address _account, IMarket _market, uint256 _outcome, uint256 _balance) public returns (bool);
    function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logDisputeWindowCreated(IDisputeWindow _disputeWindow, uint256 _id, bool _initial) public returns (bool);
    function logParticipationTokensRedeemed(IUniverse universe, address _sender, uint256 _attoParticipationTokens, uint256 _feePayoutShare) public returns (bool);
    function logTimestampSet(uint256 _newTimestamp) public returns (bool);
    function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
    function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
    function logParticipationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool);
    function logParticipationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logParticipationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool);
    function logMarketRepBondTransferred(address _universe, address _from, address _to) public returns (bool);
    function logWarpSyncDataUpdated(address _universe, uint256 _warpSyncHash, uint256 _marketEndTime) public returns (bool);
    function isKnownFeeSender(address _feeSender) public view returns (bool);
    function lookup(bytes32 _key) public view returns (address);
    function getTimestamp() public view returns (uint256);
    function getMaximumMarketEndDate() public returns (uint256);
    function isKnownMarket(IMarket _market) public view returns (bool);
    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators, uint256 _numTicks, uint256 numOutcomes) public view returns (bytes32);
    function logValidityBondChanged(uint256 _validityBond) public returns (bool);
    function logDesignatedReportStakeChanged(uint256 _designatedReportStake) public returns (bool);
    function logNoShowBondChanged(uint256 _noShowBond) public returns (bool);
    function logReportingFeeChanged(uint256 _reportingFee) public returns (bool);
    function getUniverseForkIndex(IUniverse _universe) public view returns (uint256);
}

contract IAugurCreationDataGetter {
    struct MarketCreationData {
        string extraInfo;
        address marketCreator;
        bytes32[] outcomes;
        int256[] displayPrices;
        IMarket.MarketType marketType;
        uint256 recommendedTradeInterval;
    }

    function getMarketCreationData(IMarket _market) public view returns (MarketCreationData memory);
}

contract IUniverseFactory {
    function createUniverse(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash, uint256[] memory _payoutNumerators) public returns (IUniverse);
}

library ContractExists {
    function exists(address _address) internal view returns (bool) {
        uint256 size;
        assembly { size := extcodesize(_address) }
        return size > 0;
    }
}

contract IOwnable {
    function getOwner() public view returns (address);
    function transferOwnership(address _newOwner) public returns (bool);
}

contract ITyped {
    function getTypeName() public view returns (bytes32);
}

contract ITime is ITyped {
    function getTimestamp() external view returns (uint256);
}

library SafeMathUint256 {
    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);

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        return a - b;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);
        return c;
    }

    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a <= b) {
            return a;
        } else {
            return b;
        }
    }

    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a >= b) {
            return a;
        } else {
            return b;
        }
    }

    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            uint256 x = (y + 1) / 2;
            z = y;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }

    function getUint256Min() internal pure returns (uint256) {
        return 0;
    }

    function getUint256Max() internal pure returns (uint256) {
        // 2 ** 256 - 1
        return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
    }

    function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
        return a % b == 0;
    }

    // Float [fixed point] Operations
    function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
        return div(mul(a, b), base);
    }

    function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
        return div(mul(a, base), b);
    }
}

interface IERC1155 {

    /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred,
    ///      including zero value transfers as well as minting or burning.
    /// Operator will always be msg.sender.
    /// Either event from address `0x0` signifies a minting operation.
    /// An event to address `0x0` signifies a burning or melting operation.
    /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may
    /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
    /// To define a token ID with no initial balance, the contract SHOULD emit the TransferSingle event
    /// from `0x0` to `0x0`, with the token creator as `_operator`.
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );

    /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred,
    ///      including zero value transfers as well as minting or burning.
    ///Operator will always be msg.sender.
    /// Either event from address `0x0` signifies a minting operation.
    /// An event to address `0x0` signifies a burning or melting operation.
    /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may
    /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
    /// To define multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event
    /// from `0x0` to `0x0`, with the token creator as `_operator`.
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /// @dev MUST emit when an approval is updated.
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );

    /// @dev MUST emit when the URI is updated for a token ID.
    /// URIs are defined in RFC 3986.
    /// The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema".
    event URI(
        string value,
        uint256 indexed id
    );

    /// @notice Transfers value amount of an _id from the _from address to the _to address specified.
    /// @dev MUST emit TransferSingle event on success.
    /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
    /// MUST throw if `_to` is the zero address.
    /// MUST throw if balance of sender for token `_id` is lower than the `_value` sent.
    /// MUST throw on any other error.
    /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0).
    /// If so, it MUST call `onERC1155Received` on `_to` and revert if the return value
    /// is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.
    /// @param from    Source address
    /// @param to      Target address
    /// @param id      ID of the token type
    /// @param value   Transfer amount
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 value,
        bytes calldata data
    )
        external;

    /// @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call).
    /// @dev MUST emit TransferBatch event on success.
    /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll).
    /// MUST throw if `_to` is the zero address.
    /// MUST throw if length of `_ids` is not the same as length of `_values`.
    ///  MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_values` sent.
    /// MUST throw on any other error.
    /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0).
    /// If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return value
    /// is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`.
    /// @param from    Source addresses
    /// @param to      Target addresses
    /// @param ids     IDs of each token type
    /// @param values  Transfer amounts per token type
    /// @param data    Additional data with no specified format, sent in call to `_to`
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    )
        external;

    /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
    /// @dev MUST emit the ApprovalForAll event on success.
    /// @param operator  Address to add to the set of authorized operators
    /// @param approved  True if the operator is approved, false to revoke approval
    function setApprovalForAll(address operator, bool approved) external;

    /// @notice Queries the approval status of an operator for a given owner.
    /// @param owner     The owner of the Tokens
    /// @param operator  Address of authorized operator
    /// @return           True if the operator is approved, false if not
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /// @notice Get the balance of an account's Tokens.
    /// @param owner  The address of the token holder
    /// @param id     ID of the Token
    /// @return        The _owner's balance of the Token type requested
    function balanceOf(address owner, uint256 id) external view returns (uint256);

    /// @notice Get the total supply of a Token.
    /// @param id     ID of the Token
    /// @return        The total supply of the Token type requested
    function totalSupply(uint256 id) external view returns (uint256);

    /// @notice Get the balance of multiple account/token pairs
    /// @param owners The addresses of the token holders
    /// @param ids    ID of the Tokens
    /// @return        The _owner's balance of the Token types requested
    function balanceOfBatch(
        address[] calldata owners,
        uint256[] calldata ids
    )
        external
        view
        returns (uint256[] memory balances_);
}

contract IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) public view returns (uint256);
    function transfer(address to, uint256 amount) public returns (bool);
    function transferFrom(address from, address to, uint256 amount) public returns (bool);
    function approve(address spender, uint256 amount) public returns (bool);
    function allowance(address owner, address spender) public view returns (uint256);

    // solhint-disable-next-line no-simple-event-func-name
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract ICash is IERC20 {
}

contract IAffiliateValidator {
    function validateReference(address _account, address _referrer) external view returns (bool);
}

contract IAffiliates {
    function setFingerprint(bytes32 _fingerprint) external;
    function setReferrer(address _referrer) external;
    function getAccountFingerprint(address _account) external returns (bytes32);
    function getReferrer(address _account) external returns (address);
    function getAndValidateReferrer(address _account, IAffiliateValidator affiliateValidator) external returns (address);
    function affiliateValidators(address _affiliateValidator) external returns (bool);
}

contract IDisputeWindow is ITyped, IERC20 {
    function invalidMarketsTotal() external view returns (uint256);
    function validityBondTotal() external view returns (uint256);

    function incorrectDesignatedReportTotal() external view returns (uint256);
    function initialReportBondTotal() external view returns (uint256);

    function designatedReportNoShowsTotal() external view returns (uint256);
    function designatedReporterNoShowBondTotal() external view returns (uint256);

    function initialize(IAugur _augur, IUniverse _universe, uint256 _disputeWindowId, bool _participationTokensEnabled, uint256 _duration, uint256 _startTime) public;
    function trustedBuy(address _buyer, uint256 _attotokens) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getReputationToken() public view returns (IReputationToken);
    function getStartTime() public view returns (uint256);
    function getEndTime() public view returns (uint256);
    function getWindowId() public view returns (uint256);
    function isActive() public view returns (bool);
    function isOver() public view returns (bool);
    function onMarketFinalized() public;
    function redeem(address _account) public returns (bool);
}

contract IMarket is IOwnable {
    enum MarketType {
        YES_NO,
        CATEGORICAL,
        SCALAR
    }

    function initialize(IAugur _augur, IUniverse _universe, uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public;
    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators) public view returns (bytes32);
    function doInitialReport(uint256[] memory _payoutNumerators, string memory _description, uint256 _additionalStake) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getDisputeWindow() public view returns (IDisputeWindow);
    function getNumberOfOutcomes() public view returns (uint256);
    function getNumTicks() public view returns (uint256);
    function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
    function getForkingMarket() public view returns (IMarket _market);
    function getEndTime() public view returns (uint256);
    function getWinningPayoutDistributionHash() public view returns (bytes32);
    function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getWinningReportingParticipant() public view returns (IReportingParticipant);
    function getReputationToken() public view returns (IV2ReputationToken);
    function getFinalizationTime() public view returns (uint256);
    function getInitialReporter() public view returns (IInitialReporter);
    function getDesignatedReportingEndTime() public view returns (uint256);
    function getValidityBondAttoCash() public view returns (uint256);
    function affiliateFeeDivisor() external view returns (uint256);
    function getNumParticipants() public view returns (uint256);
    function getDisputePacingOn() public view returns (bool);
    function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
    function recordMarketCreatorFees(uint256 _marketCreatorFees, address _sourceAccount, bytes32 _fingerprint) public returns (bool);
    function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
    function isFinalizedAsInvalid() public view returns (bool);
    function finalize() public returns (bool);
    function isFinalized() public view returns (bool);
    function getOpenInterest() public view returns (uint256);
}

contract IReportingParticipant {
    function getStake() public view returns (uint256);
    function getPayoutDistributionHash() public view returns (bytes32);
    function liquidateLosing() public;
    function redeem(address _redeemer) public returns (bool);
    function isDisavowed() public view returns (bool);
    function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getPayoutNumerators() public view returns (uint256[] memory);
    function getMarket() public view returns (IMarket);
    function getSize() public view returns (uint256);
}

contract IDisputeCrowdsourcer is IReportingParticipant, IERC20 {
    function initialize(IAugur _augur, IMarket market, uint256 _size, bytes32 _payoutDistributionHash, uint256[] memory _payoutNumerators, uint256 _crowdsourcerGeneration) public;
    function contribute(address _participant, uint256 _amount, bool _overload) public returns (uint256);
    function setSize(uint256 _size) public;
    function getRemainingToFill() public view returns (uint256);
    function correctSize() public returns (bool);
    function getCrowdsourcerGeneration() public view returns (uint256);
}

contract IInitialReporter is IReportingParticipant, IOwnable {
    function initialize(IAugur _augur, IMarket _market, address _designatedReporter) public;
    function report(address _reporter, bytes32 _payoutDistributionHash, uint256[] memory _payoutNumerators, uint256 _initialReportStake) public;
    function designatedReporterShowed() public view returns (bool);
    function initialReporterWasCorrect() public view returns (bool);
    function getDesignatedReporter() public view returns (address);
    function getReportTimestamp() public view returns (uint256);
    function migrateToNewUniverse(address _designatedReporter) public;
    function returnRepFromDisavow() public;
}

contract IReputationToken is IERC20 {
    function migrateOutByPayout(uint256[] memory _payoutNumerators, uint256 _attotokens) public returns (bool);
    function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
    function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function trustedDisputeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
    function getUniverse() public view returns (IUniverse);
    function getTotalMigrated() public view returns (uint256);
    function getTotalTheoreticalSupply() public view returns (uint256);
    function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
}

contract IShareToken is ITyped, IERC1155 {
    function initialize(IAugur _augur) external;
    function initializeMarket(IMarket _market, uint256 _numOutcomes, uint256 _numTicks) public;
    function unsafeTransferFrom(address _from, address _to, uint256 _id, uint256 _value) public;
    function unsafeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _values) public;
    function claimTradingProceeds(IMarket _market, address _shareHolder, bytes32 _fingerprint) external returns (uint256[] memory _outcomeFees);
    function getMarket(uint256 _tokenId) external view returns (IMarket);
    function getOutcome(uint256 _tokenId) external view returns (uint256);
    function getTokenId(IMarket _market, uint256 _outcome) public pure returns (uint256 _tokenId);
    function getTokenIds(IMarket _market, uint256[] memory _outcomes) public pure returns (uint256[] memory _tokenIds);
    function buyCompleteSets(IMarket _market, address _account, uint256 _amount) external returns (bool);
    function buyCompleteSetsForTrade(IMarket _market, uint256 _amount, uint256 _longOutcome, address _longRecipient, address _shortRecipient) external returns (bool);
    function sellCompleteSets(IMarket _market, address _holder, address _recipient, uint256 _amount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
    function sellCompleteSetsForTrade(IMarket _market, uint256 _outcome, uint256 _amount, address _shortParticipant, address _longParticipant, address _shortRecipient, address _longRecipient, uint256 _price, address _sourceAccount, bytes32 _fingerprint) external returns (uint256 _creatorFee, uint256 _reportingFee);
    function totalSupplyForMarketOutcome(IMarket _market, uint256 _outcome) public view returns (uint256);
    function balanceOfMarketOutcome(IMarket _market, uint256 _outcome, address _account) public view returns (uint256);
    function lowestBalanceOfMarketOutcomes(IMarket _market, uint256[] memory _outcomes, address _account) public view returns (uint256);
}

contract IUniverse {
    function creationTime() external view returns (uint256);
    function marketBalance(address) external view returns (uint256);

    function fork() public returns (bool);
    function updateForkValues() public returns (bool);
    function getParentUniverse() public view returns (IUniverse);
    function createChildUniverse(uint256[] memory _parentPayoutNumerators) public returns (IUniverse);
    function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
    function getReputationToken() public view returns (IV2ReputationToken);
    function getForkingMarket() public view returns (IMarket);
    function getForkEndTime() public view returns (uint256);
    function getForkReputationGoal() public view returns (uint256);
    function getParentPayoutDistributionHash() public view returns (bytes32);
    function getDisputeRoundDurationInSeconds(bool _initial) public view returns (uint256);
    function getOrCreateDisputeWindowByTimestamp(uint256 _timestamp, bool _initial) public returns (IDisputeWindow);
    function getOrCreateCurrentDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOrCreateNextDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOrCreatePreviousDisputeWindow(bool _initial) public returns (IDisputeWindow);
    function getOpenInterestInAttoCash() public view returns (uint256);
    function getTargetRepMarketCapInAttoCash() public view returns (uint256);
    function getOrCacheValidityBond() public returns (uint256);
    function getOrCacheDesignatedReportStake() public returns (uint256);
    function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
    function getOrCacheMarketRepBond() public returns (uint256);
    function getOrCacheReportingFeeDivisor() public returns (uint256);
    function getDisputeThresholdForFork() public view returns (uint256);
    function getDisputeThresholdForDisputePacing() public view returns (uint256);
    function getInitialReportMinValue() public view returns (uint256);
    function getPayoutNumerators() public view returns (uint256[] memory);
    function getReportingFeeDivisor() public view returns (uint256);
    function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function getWinningChildPayoutNumerator(uint256 _outcome) public view returns (uint256);
    function isOpenInterestCash(address) public view returns (bool);
    function isForkingMarket() public view returns (bool);
    function getCurrentDisputeWindow(bool _initial) public view returns (IDisputeWindow);
    function getDisputeWindowStartTimeAndDuration(uint256 _timestamp, bool _initial) public view returns (uint256, uint256);
    function isParentOf(IUniverse _shadyChild) public view returns (bool);
    function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
    function isContainerForDisputeWindow(IDisputeWindow _shadyTarget) public view returns (bool);
    function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
    function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
    function migrateMarketOut(IUniverse _destinationUniverse) public returns (bool);
    function migrateMarketIn(IMarket _market, uint256 _cashBalance, uint256 _marketOI) public returns (bool);
    function decrementOpenInterest(uint256 _amount) public returns (bool);
    function decrementOpenInterestFromMarket(IMarket _market) public returns (bool);
    function incrementOpenInterest(uint256 _amount) public returns (bool);
    function getWinningChildUniverse() public view returns (IUniverse);
    function isForking() public view returns (bool);
    function deposit(address _sender, uint256 _amount, address _market) public returns (bool);
    function withdraw(address _recipient, uint256 _amount, address _market) public returns (bool);
    function createScalarMarket(uint256 _endTime, uint256 _feePerCashInAttoCash, IAffiliateValidator _affiliateValidator, uint256 _affiliateFeeDivisor, address _designatedReporterAddress, int256[] memory _prices, uint256 _numTicks, string memory _extraInfo) public returns (IMarket _newMarket);
}

contract IV2ReputationToken is IReputationToken {
    function parentUniverse() external returns (IUniverse);
    function burnForMarket(uint256 _amountToBurn) public returns (bool);
    function mintForWarpSync(uint256 _amountToMint, address _target) public returns (bool);
}

library Reporting {
    uint256 private constant DESIGNATED_REPORTING_DURATION_SECONDS = 1 days;
    uint256 private constant DISPUTE_ROUND_DURATION_SECONDS = 7 days;
    uint256 private constant INITIAL_DISPUTE_ROUND_DURATION_SECONDS = 1 days;
    uint256 private constant DISPUTE_WINDOW_BUFFER_SECONDS = 1 hours;
    uint256 private constant FORK_DURATION_SECONDS = 60 days;

    uint256 private constant BASE_MARKET_DURATION_MAXIMUM = 30 days; // A market of 30 day length can always be created
    uint256 private constant UPGRADE_CADENCE = 365 days;
    uint256 private constant INITIAL_UPGRADE_TIMESTAMP = 1627776000; // Aug 1st 2021

    uint256 private constant INITIAL_REP_SUPPLY = 11 * 10 ** 6 * 10 ** 18; // 11 Million REP

    uint256 private constant AFFILIATE_SOURCE_CUT_DIVISOR = 5; // The trader gets 20% of the affiliate fee when an affiliate fee is taken

    uint256 private constant DEFAULT_VALIDITY_BOND = 10 ether; // 10 Cash (Dai)
    uint256 private constant VALIDITY_BOND_FLOOR = 10 ether; // 10 Cash (Dai)
    uint256 private constant DEFAULT_REPORTING_FEE_DIVISOR = 10000; // .01% fees
    uint256 private constant MAXIMUM_REPORTING_FEE_DIVISOR = 10000; // Minimum .01% fees
    uint256 private constant MINIMUM_REPORTING_FEE_DIVISOR = 3; // Maximum 33.3~% fees. Note than anything less than a value of 2 here will likely result in bugs such as divide by 0 cases.

    uint256 private constant TARGET_INVALID_MARKETS_DIVISOR = 100; // 1% of markets are expected to be invalid
    uint256 private constant TARGET_INCORRECT_DESIGNATED_REPORT_MARKETS_DIVISOR = 100; // 1% of markets are expected to have an incorrect designate report
    uint256 private constant TARGET_DESIGNATED_REPORT_NO_SHOWS_DIVISOR = 20; // 5% of markets are expected to have a no show
    uint256 private constant TARGET_REP_MARKET_CAP_MULTIPLIER = 5; // We multiply and divide by constants since we may want to multiply by a fractional amount

    uint256 private constant FORK_THRESHOLD_DIVISOR = 40; // 2.5% of the total REP supply being filled in a single dispute bond will trigger a fork
    uint256 private constant MAXIMUM_DISPUTE_ROUNDS = 20; // We ensure that after 20 rounds of disputes a fork will occur
    uint256 private constant MINIMUM_SLOW_ROUNDS = 8; // We ensure that at least 8 dispute rounds take DISPUTE_ROUND_DURATION_SECONDS+ seconds to complete until the next round begins

    function getDesignatedReportingDurationSeconds() internal pure returns (uint256) { return DESIGNATED_REPORTING_DURATION_SECONDS; }
    function getInitialDisputeRoundDurationSeconds() internal pure returns (uint256) { return INITIAL_DISPUTE_ROUND_DURATION_SECONDS; }
    function getDisputeWindowBufferSeconds() internal pure returns (uint256) { return DISPUTE_WINDOW_BUFFER_SECONDS; }
    function getDisputeRoundDurationSeconds() internal pure returns (uint256) { return DISPUTE_ROUND_DURATION_SECONDS; }
    function getForkDurationSeconds() internal pure returns (uint256) { return FORK_DURATION_SECONDS; }
    function getBaseMarketDurationMaximum() internal pure returns (uint256) { return BASE_MARKET_DURATION_MAXIMUM; }
    function getUpgradeCadence() internal pure returns (uint256) { return UPGRADE_CADENCE; }
    function getInitialUpgradeTimestamp() internal pure returns (uint256) { return INITIAL_UPGRADE_TIMESTAMP; }
    function getDefaultValidityBond() internal pure returns (uint256) { return DEFAULT_VALIDITY_BOND; }
    function getValidityBondFloor() internal pure returns (uint256) { return VALIDITY_BOND_FLOOR; }
    function getTargetInvalidMarketsDivisor() internal pure returns (uint256) { return TARGET_INVALID_MARKETS_DIVISOR; }
    function getTargetIncorrectDesignatedReportMarketsDivisor() internal pure returns (uint256) { return TARGET_INCORRECT_DESIGNATED_REPORT_MARKETS_DIVISOR; }
    function getTargetDesignatedReportNoShowsDivisor() internal pure returns (uint256) { return TARGET_DESIGNATED_REPORT_NO_SHOWS_DIVISOR; }
    function getTargetRepMarketCapMultiplier() internal pure returns (uint256) { return TARGET_REP_MARKET_CAP_MULTIPLIER; }
    function getMaximumReportingFeeDivisor() internal pure returns (uint256) { return MAXIMUM_REPORTING_FEE_DIVISOR; }
    function getMinimumReportingFeeDivisor() internal pure returns (uint256) { return MINIMUM_REPORTING_FEE_DIVISOR; }
    function getDefaultReportingFeeDivisor() internal pure returns (uint256) { return DEFAULT_REPORTING_FEE_DIVISOR; }
    function getInitialREPSupply() internal pure returns (uint256) { return INITIAL_REP_SUPPLY; }
    function getAffiliateSourceCutDivisor() internal pure returns (uint256) { return AFFILIATE_SOURCE_CUT_DIVISOR; }
    function getForkThresholdDivisor() internal pure returns (uint256) { return FORK_THRESHOLD_DIVISOR; }
    function getMaximumDisputeRounds() internal pure returns (uint256) { return MAXIMUM_DISPUTE_ROUNDS; }
    function getMinimumSlowRounds() internal pure returns (uint256) { return MINIMUM_SLOW_ROUNDS; }
}

contract IAugurTrading {
    function lookup(bytes32 _key) public view returns (address);
    function logProfitLossChanged(IMarket _market, address _account, uint256 _outcome, int256 _netPosition, uint256 _avgPrice, int256 _realizedProfit, int256 _frozenFunds, int256 _realizedCost) public returns (bool);
    function logOrderCreated(IUniverse _universe, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
    function logOrderCanceled(IUniverse _universe, IMarket _market, address _creator, uint256 _tokenRefund, uint256 _sharesRefund, bytes32 _orderId) public returns (bool);
    function logOrderFilled(IUniverse _universe, address _creator, address _filler, uint256 _price, uint256 _fees, uint256 _amountFilled, bytes32 _orderId, bytes32 _tradeGroupId) public returns (bool);
    function logMarketVolumeChanged(IUniverse _universe, address _market, uint256 _volume, uint256[] memory _outcomeVolumes, uint256 _totalTrades) public returns (bool);
    function logZeroXOrderFilled(IUniverse _universe, IMarket _market, bytes32 _orderHash, bytes32 _tradeGroupId, uint8 _orderType, address[] memory _addressData, uint256[] memory _uint256Data) public returns (bool);
    function logZeroXOrderCanceled(address _universe, address _market, address _account, uint256 _outcome, uint256 _price, uint256 _amount, uint8 _type, bytes32 _orderHash) public;
}

contract IOrders {
    function saveOrder(uint256[] calldata _uints, bytes32[] calldata _bytes32s, Order.Types _type, IMarket _market, address _sender) external returns (bytes32 _orderId);
    function removeOrder(bytes32 _orderId) external returns (bool);
    function getMarket(bytes32 _orderId) public view returns (IMarket);
    function getOrderType(bytes32 _orderId) public view returns (Order.Types);
    function getOutcome(bytes32 _orderId) public view returns (uint256);
    function getAmount(bytes32 _orderId) public view returns (uint256);
    function getPrice(bytes32 _orderId) public view returns (uint256);
    function getOrderCreator(bytes32 _orderId) public view returns (address);
    function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
    function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
    function getOrderDataForCancel(bytes32 _orderId) public view returns (uint256, uint256, Order.Types, IMarket, uint256, address);
    function getOrderDataForLogs(bytes32 _orderId) public view returns (Order.Types, address[] memory _addressData, uint256[] memory _uint256Data);
    function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
    function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
    function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
    function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
    function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
    function getOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
    function getTotalEscrowed(IMarket _market) public view returns (uint256);
    function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
    function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
    function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
    function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
    function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled, uint256 _fill) external returns (bool);
    function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
}

library Order {
    using SafeMathUint256 for uint256;

    enum Types {
        Bid, Ask
    }

    enum TradeDirections {
        Long, Short
    }

    struct Data {
        // Contracts
        IMarket market;
        IAugur augur;
        IAugurTrading augurTrading;
        IShareToken shareToken;
        ICash cash;

        // Order
        bytes32 id;
        address creator;
        uint256 outcome;
        Order.Types orderType;
        uint256 amount;
        uint256 price;
        uint256 sharesEscrowed;
        uint256 moneyEscrowed;
        bytes32 betterOrderId;
        bytes32 worseOrderId;
    }

    function create(IAugur _augur, IAugurTrading _augurTrading, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data memory) {
        require(_outcome < _market.getNumberOfOutcomes(), "Order.create: Outcome is not within market range");
        require(_price != 0, "Order.create: Price may not be 0");
        require(_price < _market.getNumTicks(), "Order.create: Price is outside of market range");
        require(_attoshares > 0, "Order.create: Cannot use amount of 0");
        require(_creator != address(0), "Order.create: Creator is 0x0");

        IShareToken _shareToken = IShareToken(_augur.lookup("ShareToken"));

        return Data({
            market: _market,
            augur: _augur,
            augurTrading: _augurTrading,
            shareToken: _shareToken,
            cash: ICash(_augur.lookup("Cash")),
            id: 0,
            creator: _creator,
            outcome: _outcome,
            orderType: _type,
            amount: _attoshares,
            price: _price,
            sharesEscrowed: 0,
            moneyEscrowed: 0,
            betterOrderId: _betterOrderId,
            worseOrderId: _worseOrderId
        });
    }

    //
    // "public" functions
    //

    function getOrderId(Order.Data memory _orderData, IOrders _orders) internal view returns (bytes32) {
        if (_orderData.id == bytes32(0)) {
            bytes32 _orderId = calculateOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
            require(_orders.getAmount(_orderId) == 0, "Order.getOrderId: New order had amount. This should not be possible");
            _orderData.id = _orderId;
        }
        return _orderData.id;
    }

    function calculateOrderId(Order.Types _type, IMarket _market, uint256 _amount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) internal pure returns (bytes32) {
        return sha256(abi.encodePacked(_type, _market, _amount, _price, _sender, _blockNumber, _outcome, _moneyEscrowed, _sharesEscrowed));
    }

    function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
        return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
    }

    function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
        return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
    }

    function saveOrder(Order.Data memory _orderData, bytes32 _tradeGroupId, IOrders _orders) internal returns (bytes32) {
        getOrderId(_orderData, _orders);
        uint256[] memory _uints = new uint256[](5);
        _uints[0] = _orderData.amount;
        _uints[1] = _orderData.price;
        _uints[2] = _orderData.outcome;
        _uints[3] = _orderData.moneyEscrowed;
        _uints[4] = _orderData.sharesEscrowed;
        bytes32[] memory _bytes32s = new bytes32[](4);
        _bytes32s[0] = _orderData.betterOrderId;
        _bytes32s[1] = _orderData.worseOrderId;
        _bytes32s[2] = _tradeGroupId;
        _bytes32s[3] = _orderData.id;
        return _orders.saveOrder(_uints, _bytes32s, _orderData.orderType, _orderData.market, _orderData.creator);
    }
}

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

contract Augur is IAugur, IAugurCreationDataGetter {
    using SafeMathUint256 for uint256;
    using ContractExists for address;

    enum TokenType {
        ReputationToken,
        DisputeCrowdsourcer,
        ParticipationToken
    }

    event MarketCreated(IUniverse indexed universe, uint256 endTime, string extraInfo, IMarket market, address indexed marketCreator, address designatedReporter, uint256 feePerCashInAttoCash, int256[] prices, IMarket.MarketType marketType, uint256 numTicks, bytes32[] outcomes, uint256 noShowBond, uint256 timestamp);
    event InitialReportSubmitted(address indexed universe, address indexed reporter, address indexed market, address initialReporter, uint256 amountStaked, bool isDesignatedReporter, uint256[] payoutNumerators, string description, uint256 nextWindowStartTime, uint256 nextWindowEndTime, uint256 timestamp);
    event DisputeCrowdsourcerCreated(address indexed universe, address indexed market, address disputeCrowdsourcer, uint256[] payoutNumerators, uint256 size, uint256 disputeRound);
    event DisputeCrowdsourcerContribution(address indexed universe, address indexed reporter, address indexed market, address disputeCrowdsourcer, uint256 amountStaked, string description, uint256[] payoutNumerators, uint256 currentStake, uint256 stakeRemaining, uint256 disputeRound, uint256 timestamp);
    event DisputeCrowdsourcerCompleted(address indexed universe, address indexed market, address disputeCrowdsourcer, uint256[] payoutNumerators, uint256 nextWindowStartTime, uint256 nextWindowEndTime, bool pacingOn, uint256 totalRepStakedInPayout, uint256 totalRepStakedInMarket, uint256 disputeRound, uint256 timestamp);
    event InitialReporterRedeemed(address indexed universe, address indexed reporter, address indexed market, address initialReporter, uint256 amountRedeemed, uint256 repReceived, uint256[] payoutNumerators, uint256 timestamp);
    event DisputeCrowdsourcerRedeemed(address indexed universe, address indexed reporter, address indexed market, address disputeCrowdsourcer, uint256 amountRedeemed, uint256 repReceived, uint256[] payoutNumerators, uint256 timestamp);
    event ReportingParticipantDisavowed(address indexed universe, address indexed market, address reportingParticipant);
    event MarketParticipantsDisavowed(address indexed universe, address indexed market);
    event MarketFinalized(address indexed universe, address indexed market, uint256 timestamp, uint256[] winningPayoutNumerators);
    event MarketMigrated(address indexed market, address indexed originalUniverse, address indexed newUniverse);
    event UniverseForked(address indexed universe, IMarket forkingMarket);
    event UniverseCreated(address indexed parentUniverse, address indexed childUniverse, uint256[] payoutNumerators, uint256 creationTimestamp);
    event CompleteSetsPurchased(address indexed universe, address indexed market, address indexed account, uint256 numCompleteSets, uint256 timestamp);
    event CompleteSetsSold(address indexed universe, address indexed market, address indexed account, uint256 numCompleteSets, uint256 fees, uint256 timestamp);
    event TradingProceedsClaimed(address indexed universe, address indexed sender, address market, uint256 outcome, uint256 numShares, uint256 numPayoutTokens, uint256 fees, uint256 timestamp);
    event TokensTransferred(address indexed universe, address token, address indexed from, address indexed to, uint256 value, TokenType tokenType, address market);
    event TokensMinted(address indexed universe, address indexed token, address indexed target, uint256 amount, TokenType tokenType, address market, uint256 totalSupply);
    event TokensBurned(address indexed universe, address indexed token, address indexed target, uint256 amount, TokenType tokenType, address market, uint256 totalSupply);
    event TokenBalanceChanged(address indexed universe, address indexed owner, address token, TokenType tokenType, address market, uint256 balance, uint256 outcome);
    event DisputeWindowCreated(address indexed universe, address disputeWindow, uint256 startTime, uint256 endTime, uint256 id, bool initial);
    event InitialReporterTransferred(address indexed universe, address indexed market, address from, address to);
    event MarketTransferred(address indexed universe, address indexed market, address from, address to);
    event MarketOIChanged(address indexed universe, address indexed market, uint256 marketOI);
    event ParticipationTokensRedeemed(address indexed universe, address indexed disputeWindow, address indexed account, uint256 attoParticipationTokens, uint256 feePayoutShare, uint256 timestamp);
    event TimestampSet(uint256 newTimestamp);
    event ValidityBondChanged(address indexed universe, uint256 validityBond);
    event DesignatedReportStakeChanged(address indexed universe, uint256 designatedReportStake);
    event NoShowBondChanged(address indexed universe, uint256 noShowBond);
    event ReportingFeeChanged(address indexed universe, uint256 reportingFee);
    event ShareTokenBalanceChanged(address indexed universe, address indexed account, address indexed market, uint256 outcome, uint256 balance);
    event MarketRepBondTransferred(address indexed universe, address market, address from, address to);
    event WarpSyncDataUpdated(address indexed universe, uint256 warpSyncHash, uint256 marketEndTime);

    event RegisterContract(address contractAddress, bytes32 key);
    event FinishDeployment();

    mapping(address => bool) private markets;
    mapping(address => bool) private universes;
    mapping(address => bool) private crowdsourcers;
    mapping(address => bool) private trustedSender;

    mapping(address => MarketCreationData) private marketCreationData;

    address public uploader;
    mapping(bytes32 => address) private registry;

    ITime public time;
    IUniverse public genesisUniverse;

    uint256 public forkCounter;
    mapping (address => uint256) universeForkIndex;

    uint256 public upgradeTimestamp = Reporting.getInitialUpgradeTimestamp();

    int256 private constant DEFAULT_MIN_PRICE = 0;
    int256 private constant DEFAULT_MAX_PRICE = 1 ether;

    uint256 constant public TRADE_INTERVAL_VALUE = 10 ** 19; // Trade value of 10 DAI
    uint256 constant public MIN_TRADE_INTERVAL = 10**14; // We ignore "dust" portions of the min interval and for huge scalars have a larger min value
    uint256 constant public DEFAULT_RECOMMENDED_TRADE_INTERVAL = 10**17;
    uint256 private constant MAX_NUM_TICKS = 2 ** 256 - 2;

    ICash public cash;

    modifier onlyUploader() {
        require(msg.sender == uploader);
        _;
    }

    constructor() public {
        uploader = msg.sender;
    }

    //
    // Registry
    //

    function registerContract(bytes32 _key, address _address) public onlyUploader returns (bool) {
        require(registry[_key] == address(0), "Augur.registerContract: key has already been used in registry");
        require(_address.exists());
        registry[_key] = _address;
        if (_key == "ShareToken" || _key == "MarketFactory" || _key == "EthExchange") {
            trustedSender[_address] = true;
        } else if (_key == "Time") {
            time = ITime(_address);
        } else if (_key == "Cash") {
            cash = ICash(_address);
        }
        emit RegisterContract(_address, _key);
        return true;
    }

    /**
     * @notice Find the contract address for a particular key
     * @param _key The key to lookup
     * @return the address of the registered contract if one exists for the given key
     */
    function lookup(bytes32 _key) public view returns (address) {
        return registry[_key];
    }

    function finishDeployment() public onlyUploader returns (bool) {
        uploader = address(1);
        emit FinishDeployment();
        return true;
    }

    //
    // Universe
    //

    function createGenesisUniverse() public onlyUploader returns (IUniverse) {
        require(genesisUniverse == IUniverse(0));
        genesisUniverse = createUniverse(IUniverse(0), bytes32(0), new uint256[](0));
        return genesisUniverse;
    }

    function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) public returns (IUniverse) {
        IUniverse _parentUniverse = getAndValidateUniverse(msg.sender);
        return createUniverse(_parentUniverse, _parentPayoutDistributionHash, _parentPayoutNumerators);
    }

    function createUniverse(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash, uint256[] memory _parentPayoutNumerators) private returns (IUniverse) {
        IUniverseFactory _universeFactory = IUniverseFactory(registry["UniverseFactory"]);
        IUniverse _newUniverse = _universeFactory.createUniverse(_parentUniverse, _parentPayoutDistributionHash, _parentPayoutNumerators);
        universes[address(_newUniverse)] = true;
        trustedSender[address(_newUniverse)] = true;
        emit UniverseCreated(address(_parentUniverse), address(_newUniverse), _parentPayoutNumerators, getTimestamp());
        return _newUniverse;
    }

    function isKnownUniverse(IUniverse _universe) public view returns (bool) {
        return universes[address(_universe)];
    }

    function getUniverseForkIndex(IUniverse _universe) public view returns (uint256) {
        return universeForkIndex[address(_universe)];
    }

    //
    // Crowdsourcers
    //

    function isKnownCrowdsourcer(IDisputeCrowdsourcer _crowdsourcer) public view returns (bool) {
        return crowdsourcers[address(_crowdsourcer)];
    }

    function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _size, uint256 _disputeRound) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(IMarket(msg.sender)));
        crowdsourcers[_disputeCrowdsourcer] = true;
        emit DisputeCrowdsourcerCreated(address(_universe), _market, _disputeCrowdsourcer, _payoutNumerators, _size, _disputeRound);
        return true;
    }

    function isKnownFeeSender(address _feeSender) public view returns (bool) {
        return _feeSender == registry["ShareToken"] || markets[_feeSender];
    }

    //
    // Transfer
    //

    function trustedCashTransfer(address _from, address _to, uint256 _amount) public returns (bool) {
        require(trustedSender[msg.sender]);
        require(cash.transferFrom(_from, _to, _amount));
        return true;
    }

    function isTrustedSender(address _address) public returns (bool) {
        return trustedSender[_address];
    }

    //
    // Time
    //

    /// @notice Returns Augur’s internal Unix timestamp.
    /// @return (uint256) Augur’s internal Unix timestamp
    function getTimestamp() public view returns (uint256) {
        return time.getTimestamp();
    }

    //
    // Markets
    //

    function isKnownMarket(IMarket _market) public view returns (bool) {
        return markets[address(_market)];
    }

    function getMaximumMarketEndDate() public returns (uint256) {
        uint256 _now = getTimestamp();
        while (_now > upgradeTimestamp) {
            upgradeTimestamp = upgradeTimestamp.add(Reporting.getUpgradeCadence());
        }
        uint256 _upgradeCadenceDurationEndTime = upgradeTimestamp;
        uint256 _baseDurationEndTime = _now + Reporting.getBaseMarketDurationMaximum();
        return _baseDurationEndTime.max(_upgradeCadenceDurationEndTime);
    }

    function derivePayoutDistributionHash(uint256[] memory _payoutNumerators, uint256 _numTicks, uint256 _numOutcomes) public view returns (bytes32) {
        uint256 _sum = 0;
        // This is to force an Invalid report to be entirely payed out to Invalid
        require(_payoutNumerators[0] == 0 || _payoutNumerators[0] == _numTicks);
        require(_payoutNumerators.length == _numOutcomes, "Augur.derivePayoutDistributionHash: Malformed payout length");
        for (uint256 i = 0; i < _payoutNumerators.length; i++) {
            uint256 _value = _payoutNumerators[i];
            _sum = _sum.add(_value);
        }
        require(_sum == _numTicks, "Augur.derivePayoutDistributionHash: Malformed payout sum");
        return keccak256(abi.encodePacked(_payoutNumerators));
    }

    function getMarketCreationData(IMarket _market) public view returns (MarketCreationData memory) {
        return marketCreationData[address(_market)];
    }

    function getMarketType(IMarket _market) public view returns (IMarket.MarketType _marketType) {
        return marketCreationData[address(_market)].marketType;
    }

    function getMarketOutcomes(IMarket _market) public view returns (bytes32[] memory _outcomes) {
        return marketCreationData[address(_market)].outcomes;
    }

    function getMarketRecommendedTradeInterval(IMarket _market) public view returns (uint256) {
        return marketCreationData[address(_market)].recommendedTradeInterval;
    }

    //
    // Logging
    //

    function onCategoricalMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, bytes32[] memory _outcomes) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        markets[address(_market)] = true;
        int256[] memory _prices = new int256[](2);
        _prices[0] = DEFAULT_MIN_PRICE;
        _prices[1] = DEFAULT_MAX_PRICE;
        marketCreationData[address(_market)].extraInfo = _extraInfo;
        marketCreationData[address(_market)].marketCreator = _marketCreator;
        marketCreationData[address(_market)].outcomes = _outcomes;
        marketCreationData[address(_market)].marketType = IMarket.MarketType.CATEGORICAL;
        marketCreationData[address(_market)].recommendedTradeInterval = DEFAULT_RECOMMENDED_TRADE_INTERVAL;
        emit MarketCreated(_universe, _endTime, _extraInfo, _market, _marketCreator, _designatedReporter, _feePerCashInAttoCash, _prices, IMarket.MarketType.CATEGORICAL, 100, _outcomes, _universe.getOrCacheMarketRepBond(), getTimestamp());
        return true;
    }

    function onYesNoMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        markets[address(_market)] = true;
        int256[] memory _prices = new int256[](2);
        _prices[0] = DEFAULT_MIN_PRICE;
        _prices[1] = DEFAULT_MAX_PRICE;
        marketCreationData[address(_market)].extraInfo = _extraInfo;
        marketCreationData[address(_market)].marketCreator = _marketCreator;
        marketCreationData[address(_market)].marketType = IMarket.MarketType.YES_NO;
        marketCreationData[address(_market)].recommendedTradeInterval = DEFAULT_RECOMMENDED_TRADE_INTERVAL;
        emit MarketCreated(_universe, _endTime, _extraInfo, _market, _marketCreator, _designatedReporter, _feePerCashInAttoCash, _prices, IMarket.MarketType.YES_NO, 100, new bytes32[](0), _universe.getOrCacheMarketRepBond(), getTimestamp());
        return true;
    }

    function onScalarMarketCreated(uint256 _endTime, string memory _extraInfo, IMarket _market, address _marketCreator, address _designatedReporter, uint256 _feePerCashInAttoCash, int256[] memory _prices, uint256 _numTicks)  public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        require(_prices.length == 2);
        require(_prices[0] < _prices[1]);
        uint256 _priceRange = uint256(_prices[1] - _prices[0]);
        require(_priceRange > _numTicks);
        markets[address(_market)] = true;
        marketCreationData[address(_market)].extraInfo = _extraInfo;
        marketCreationData[address(_market)].marketCreator = _marketCreator;
        marketCreationData[address(_market)].displayPrices = _prices;
        marketCreationData[address(_market)].marketType = IMarket.MarketType.SCALAR;
        marketCreationData[address(_market)].recommendedTradeInterval = getTradeInterval(_priceRange, _numTicks);
        emit MarketCreated(_universe, _endTime, _extraInfo, _market, _marketCreator, _designatedReporter, _feePerCashInAttoCash, _prices, IMarket.MarketType.SCALAR, _numTicks, new bytes32[](0), _universe.getOrCacheMarketRepBond(), getTimestamp());
        return true;
    }

    function getTradeInterval(uint256 _displayRange, uint256 _numTicks) public pure returns (uint256) {
        // Handle Warp Sync Market
        if (_numTicks == MAX_NUM_TICKS) {
            return MIN_TRADE_INTERVAL;
        }
        uint256 _displayAmount = TRADE_INTERVAL_VALUE.mul(10**18).div(_displayRange);
        uint256 _displayInterval = MIN_TRADE_INTERVAL;
        while (_displayInterval < _displayAmount) {
            _displayInterval = _displayInterval.mul(10);
        }
        _displayAmount = _displayInterval;
        return _displayInterval.mul(_displayRange).div(_numTicks).div(10**18);
    }

    function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, address _initialReporter, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] memory _payoutNumerators, string memory _description, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(IMarket(msg.sender)));
        emit InitialReportSubmitted(address(_universe), _reporter, _market, _initialReporter, _amountStaked, _isDesignatedReporter, _payoutNumerators, _description, _nextWindowStartTime, _nextWindowEndTime, getTimestamp());
        return true;
    }

    function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked, string memory _description, uint256[] memory _payoutNumerators, uint256 _currentStake, uint256 _stakeRemaining, uint256 _disputeRound) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(IMarket(msg.sender)));
        emit DisputeCrowdsourcerContribution(address(_universe), _reporter, _market, _disputeCrowdsourcer, _amountStaked, _description, _payoutNumerators, _currentStake, _stakeRemaining, _disputeRound, getTimestamp());
        return true;
    }

    function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] memory _payoutNumerators, uint256 _nextWindowStartTime, uint256 _nextWindowEndTime, bool _pacingOn, uint256 _totalRepStakedInPayout, uint256 _totalRepStakedInMarket, uint256 _disputeRound) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(IMarket(msg.sender)));
        emit DisputeCrowdsourcerCompleted(address(_universe), _market, _disputeCrowdsourcer, _payoutNumerators, _nextWindowStartTime, _nextWindowEndTime, _pacingOn, _totalRepStakedInPayout, _totalRepStakedInMarket, _disputeRound, getTimestamp());
        return true;
    }

    function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForReportingParticipant(IReportingParticipant(msg.sender)));
        emit InitialReporterRedeemed(address(_universe), _reporter, _market, msg.sender, _amountRedeemed, _repReceived, _payoutNumerators, getTimestamp());
        return true;
    }

    function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256[] memory _payoutNumerators) public returns (bool) {
        IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
        require(isKnownCrowdsourcer(_disputeCrowdsourcer));
        emit DisputeCrowdsourcerRedeemed(address(_universe), _reporter, _market, address(_disputeCrowdsourcer), _amountRedeemed, _repReceived, _payoutNumerators, getTimestamp());
        return true;
    }

    function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForReportingParticipant(IReportingParticipant(msg.sender)));
        emit ReportingParticipantDisavowed(address(_universe), address(_market), msg.sender);
        return true;
    }

    function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool) {
        require(isKnownUniverse(_universe));
        IMarket _market = IMarket(msg.sender);
        require(_universe.isContainerForMarket(_market));
        emit MarketParticipantsDisavowed(address(_universe), address(_market));
        return true;
    }

    function logMarketFinalized(IUniverse _universe, uint256[] memory _winningPayoutNumerators) public returns (bool) {
        require(isKnownUniverse(_universe));
        IMarket _market = IMarket(msg.sender);
        require(_universe.isContainerForMarket(_market));
        emit MarketFinalized(address(_universe), address(_market), getTimestamp(), _winningPayoutNumerators);
        return true;
    }

    function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool) {
        IUniverse _newUniverse = IUniverse(msg.sender);
        require(isKnownUniverse(_newUniverse));
        emit MarketMigrated(address(_market), address(_originalUniverse), address(_newUniverse));
        return true;
    }

    function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool) {
        require(msg.sender == registry["ShareToken"] || (isKnownUniverse(_universe) && _universe.isOpenInterestCash(msg.sender)));
        emit CompleteSetsPurchased(address(_universe), address(_market), _account, _numCompleteSets, getTimestamp());
        return true;
    }

    function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets, uint256 _fees) public returns (bool) {
        require(msg.sender == registry["ShareToken"]);
        emit CompleteSetsSold(address(_universe), address(_market), _account, _numCompleteSets, _fees, getTimestamp());
        return true;
    }

    function logMarketOIChanged(IUniverse _universe, IMarket _market) public returns (bool) {
        require(msg.sender == registry["ShareToken"]);
        emit MarketOIChanged(address(_universe), address(_market), _market.getOpenInterest());
        return true;
    }

    function logTradingProceedsClaimed(IUniverse _universe, address _sender, address _market, uint256 _outcome, uint256 _numShares, uint256 _numPayoutTokens, uint256 _fees) public returns (bool) {
        require(msg.sender == registry["ShareToken"]);
        emit TradingProceedsClaimed(address(_universe), _sender, _market, _outcome, _numShares, _numPayoutTokens, _fees, getTimestamp());
        return true;
    }

    function logUniverseForked(IMarket _forkingMarket) public returns (bool) {
        require(isKnownUniverse(IUniverse(msg.sender)));
        forkCounter += 1;
        universeForkIndex[msg.sender] = forkCounter;
        emit UniverseForked(msg.sender, _forkingMarket);
        return true;
    }

    function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.getReputationToken() == IReputationToken(msg.sender));
        logTokensTransferred(address(_universe), msg.sender, _from, _to, _value, TokenType.ReputationToken, address(0), _fromBalance, _toBalance, 0);
        return true;
    }

    function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool) {
        IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
        require(isKnownCrowdsourcer(_disputeCrowdsourcer));
        logTokensTransferred(address(_universe), msg.sender, _from, _to, _value, TokenType.DisputeCrowdsourcer, address(_disputeCrowdsourcer.getMarket()), _fromBalance, _toBalance, 0);
        return true;
    }

    function logReputationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.getReputationToken() == IReputationToken(msg.sender));
        logTokensBurned(address(_universe), msg.sender, _target, _amount, TokenType.ReputationToken, address(0), _totalSupply, _balance, 0);
        return true;
    }

    function logReputationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.getReputationToken() == IReputationToken(msg.sender));
        logTokensMinted(address(_universe), msg.sender, _target, _amount, TokenType.ReputationToken, address(0), _totalSupply, _balance, 0);
        return true;
    }

    function logShareTokensBalanceChanged(address _account, IMarket _market, uint256 _outcome, uint256 _balance) public returns (bool) {
        require(msg.sender == registry["ShareToken"]);
        emit ShareTokenBalanceChanged(address(_market.getUniverse()), _account, address(_market), _outcome, _balance);
        return true;
    }

    function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
        require(isKnownCrowdsourcer(_disputeCrowdsourcer));
        logTokensBurned(address(_universe), msg.sender, _target, _amount, TokenType.DisputeCrowdsourcer, address(_disputeCrowdsourcer.getMarket()), _totalSupply, _balance, 0);
        return true;
    }

    function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
        require(isKnownCrowdsourcer(_disputeCrowdsourcer));
        logTokensMinted(address(_universe), msg.sender, _target, _amount, TokenType.DisputeCrowdsourcer, address(_disputeCrowdsourcer.getMarket()), _totalSupply, _balance, 0);
        return true;
    }

    function logDisputeWindowCreated(IDisputeWindow _disputeWindow, uint256 _id, bool _initial) public returns (bool) {
        require(isKnownUniverse(IUniverse(msg.sender)));
        emit DisputeWindowCreated(msg.sender, address(_disputeWindow), _disputeWindow.getStartTime(), _disputeWindow.getEndTime(), _id, _initial);
        return true;
    }

    function logParticipationTokensRedeemed(IUniverse _universe, address _account, uint256 _attoParticipationTokens, uint256 _feePayoutShare) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForDisputeWindow(IDisputeWindow(msg.sender)));
        emit ParticipationTokensRedeemed(address(_universe), msg.sender, _account, _attoParticipationTokens, _feePayoutShare, getTimestamp());
        return true;
    }

    function logTimestampSet(uint256 _newTimestamp) public returns (bool) {
        require(msg.sender == registry["Time"]);
        emit TimestampSet(_newTimestamp);
        return true;
    }

    function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForMarket(_market));
        require(msg.sender == address(_market.getInitialReporter()));
        emit InitialReporterTransferred(address(_universe), address(_market), _from, _to);
        return true;
    }

    function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool) {
        require(isKnownUniverse(_universe));
        IMarket _market = IMarket(msg.sender);
        require(_universe.isContainerForMarket(_market));
        emit MarketTransferred(address(_universe), address(_market), _from, _to);
        return true;
    }

    function logParticipationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value, uint256 _fromBalance, uint256 _toBalance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForDisputeWindow(IDisputeWindow(msg.sender)));
        logTokensTransferred(address(_universe), msg.sender, _from, _to, _value, TokenType.ParticipationToken, address(0), _fromBalance, _toBalance, 0);
        return true;
    }

    function logParticipationTokensBurned(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForDisputeWindow(IDisputeWindow(msg.sender)));
        logTokensBurned(address(_universe), msg.sender, _target, _amount, TokenType.ParticipationToken, address(0), _totalSupply, _balance, 0);
        return true;
    }

    function logParticipationTokensMinted(IUniverse _universe, address _target, uint256 _amount, uint256 _totalSupply, uint256 _balance) public returns (bool) {
        require(isKnownUniverse(_universe));
        require(_universe.isContainerForDisputeWindow(IDisputeWindow(msg.sender)));
        logTokensMinted(address(_universe), msg.sender, _target, _amount, TokenType.ParticipationToken, address(0), _totalSupply, _balance, 0);
        return true;
    }

    function logTokensTransferred(address _universe, address _token, address _from, address _to, uint256 _amount, TokenType _tokenType, address _market, uint256 _fromBalance, uint256 _toBalance, uint256 _outcome) private returns (bool) {
        emit TokensTransferred(_universe, _token, _from, _to, _amount, _tokenType, _market);
        emit TokenBalanceChanged(_universe, _from, _token, _tokenType, _market, _fromBalance, _outcome);
        emit TokenBalanceChanged(_universe, _to, _token, _tokenType, _market, _toBalance, _outcome);
        return true;
    }

    function logTokensBurned(address _universe, address _token, address _target, uint256 _amount, TokenType _tokenType, address _market, uint256 _totalSupply, uint256 _balance, uint256 _outcome) private returns (bool) {
        emit TokensBurned(_universe, _token, _target, _amount, _tokenType, _market, _totalSupply);
        emit TokenBalanceChanged(_universe, _target, _token, _tokenType, _market, _balance, _outcome);
        return true;
    }

    function logTokensMinted(address _universe, address _token, address _target, uint256 _amount, TokenType _tokenType, address _market, uint256 _totalSupply, uint256 _balance, uint256 _outcome) private returns (bool) {
        emit TokensMinted(_universe, _token, _target, _amount, _tokenType, _market, _totalSupply);
        emit TokenBalanceChanged(_universe, _target, _token, _tokenType, _market, _balance, _outcome);
        return true;
    }

    function logValidityBondChanged(uint256 _validityBond) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        emit ValidityBondChanged(address(_universe), _validityBond);
        return true;
    }

    function logDesignatedReportStakeChanged(uint256 _designatedReportStake) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        emit DesignatedReportStakeChanged(address(_universe), _designatedReportStake);
        return true;
    }

    function logNoShowBondChanged(uint256 _noShowBond) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        emit NoShowBondChanged(address(_universe), _noShowBond);
        return true;
    }

    function logReportingFeeChanged(uint256 _reportingFee) public returns (bool) {
        IUniverse _universe = getAndValidateUniverse(msg.sender);
        emit ReportingFeeChanged(address(_universe), _reportingFee);
        return true;
    }

    function logMarketRepBondTransferred(address _universe, address _from, address _to) public returns (bool) {
        require(isKnownMarket(IMarket(msg.sender)));
        emit MarketRepBondTransferred(_universe, msg.sender, _from, _to);
    }

    function logWarpSyncDataUpdated(address _universe, uint256 _warpSyncHash, uint256 _marketEndTime) public returns (bool) {
        require(msg.sender == registry["WarpSync"]);
        emit WarpSyncDataUpdated(_universe, _warpSyncHash, _marketEndTime);
    }

    function getAndValidateUniverse(address _untrustedUniverse) internal view returns (IUniverse) {
        IUniverse _universe = IUniverse(_untrustedUniverse);
        require(isKnownUniverse(_universe));
        return _universe;
    }
}

Settings
{
  "remappings": [
    "ROOT=/home/achapman/augur/packages/augur-core/src/contracts//"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200,
    "details": {
      "yul": true,
      "deduplicate": true,
      "cse": true,
      "constantOptimizer": true
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"EIP1271_ORDER_WITH_HASH_SELECTOR","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EIP712_DOMAIN_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"contract IMarket","name":"_market","type":"address"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"askBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"augur","outputs":[{"internalType":"contract IAugur","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"augurTrading","outputs":[{"internalType":"contract IAugurTrading","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances_","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"contract IMarket","name":"_market","type":"address"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"bidBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order[]","name":"_orders","type":"tuple[]"},{"internalType":"bytes[]","name":"_signatures","type":"bytes[]"},{"internalType":"uint256","name":"_maxProtocolFeeDai","type":"uint256"}],"name":"cancelOrders","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cash","outputs":[{"internalType":"contract ICash","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_sender","type":"address"}],"name":"cashAvailableForTransferFrom","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint8","name":"_type","type":"uint8"},{"internalType":"uint256","name":"_attoshares","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint256","name":"_expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"_salt","type":"uint256"}],"name":"createZeroXOrder","outputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_zeroXOrder","type":"tuple"},{"internalType":"bytes32","name":"_orderHash","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_maker","type":"address"},{"internalType":"uint8","name":"_type","type":"uint8"},{"internalType":"uint256","name":"_attoshares","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint256","name":"_expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"_salt","type":"uint256"}],"name":"createZeroXOrderFor","outputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_zeroXOrder","type":"tuple"},{"internalType":"bytes32","name":"_orderHash","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_order","type":"tuple"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"creatorHasFundsForTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"_assetData","type":"bytes"}],"name":"decodeAssetData","outputs":[{"internalType":"bytes4","name":"_assetProxyId","type":"bytes4"},{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_tokenValues","type":"uint256[]"},{"internalType":"bytes","name":"_callbackData","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"_assetData","type":"bytes"}],"name":"decodeTradeAssetData","outputs":[{"internalType":"bytes4","name":"_assetProxyId","type":"bytes4"},{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_tokenValues","type":"uint256[]"},{"internalType":"bytes","name":"_callbackData","type":"bytes"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IMarket","name":"_market","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint8","name":"_type","type":"uint8"}],"name":"encodeAssetData","outputs":[{"internalType":"bytes","name":"_assetData","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_zeroXOrder","type":"tuple"},{"internalType":"bytes32","name":"_orderHash","type":"bytes32"}],"name":"encodeEIP1271OrderWithHash","outputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_numOrders","type":"uint256"},{"internalType":"uint256","name":"_gasPrice","type":"uint256"}],"name":"estimateProtocolFeeCostInCash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ethExchange","outputs":[{"internalType":"contract IUniswapV2Pair","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"exchange","outputs":[{"internalType":"contract IExchange","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fillOrder","outputs":[{"internalType":"contract IFillOrder","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint8","name":"_type","type":"uint8"}],"name":"getTokenId","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_order","type":"tuple"}],"name":"getTokenIdFromOrder","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTransferFromAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"_assetData","type":"bytes"}],"name":"getZeroXTradeTokenData","outputs":[{"internalType":"contract IERC1155","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IAugur","name":"_augur","type":"address"},{"internalType":"contract IAugurTrading","name":"_augurTrading","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IMarket","name":"_market","type":"address"},{"internalType":"uint256","name":"_orderAmount","type":"uint256"}],"name":"isOrderAmountValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order","name":"_order","type":"tuple"}],"name":"parseOrderData","outputs":[{"components":[{"internalType":"address","name":"marketAddress","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint8","name":"outcome","type":"uint8"},{"internalType":"uint8","name":"orderType","type":"uint8"}],"internalType":"struct IZeroXTrade.AugurOrderData","name":"_data","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"shareToken","outputs":[{"internalType":"contract IShareToken","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token0IsCash","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_requestedFillAmount","type":"uint256"},{"internalType":"bytes32","name":"_fingerprint","type":"bytes32"},{"internalType":"bytes32","name":"_tradeGroupId","type":"bytes32"},{"internalType":"uint256","name":"_maxProtocolFeeDai","type":"uint256"},{"internalType":"uint256","name":"_maxTrades","type":"uint256"},{"components":[{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"address","name":"takerAddress","type":"address"},{"internalType":"address","name":"feeRecipientAddress","type":"address"},{"internalType":"address","name":"senderAddress","type":"address"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"expirationTimeSeconds","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"makerAssetData","type":"bytes"},{"internalType":"bytes","name":"takerAssetData","type":"bytes"},{"internalType":"bytes","name":"makerFeeAssetData","type":"bytes"},{"internalType":"bytes","name":"takerFeeAssetData","type":"bytes"}],"internalType":"struct IExchange.Order[]","name":"_orders","type":"tuple[]"},{"internalType":"bytes[]","name":"_signatures","type":"bytes[]"}],"name":"trade","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"unpackTokenId","outputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint8","name":"_outcome","type":"uint8"},{"internalType":"uint8","name":"_type","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"}]

60806040526000805461ffff1916905534801561001b57600080fd5b506147d18061002b6000396000f3fe6080604052600436106102445760003560e01c80637a0d8f8a11610139578063afc6d8ba116100b6578063e264cff11161007a578063e264cff1146106c1578063e306f779146106e1578063e985e9c5146106f6578063ee89dab414610716578063f242432a1461072b578063f94515f01461074b57610244565b8063afc6d8ba1461061e578063b3ca8e251461063e578063bd85b0391461065e578063d2f7265a1461067e578063e186955b1461069357610244565b8063961be391116100fd578063961be391146105925780639c6fbce5146105a7578063a22cb465146105c7578063ad5c22c8146105e7578063ad5c46481461060957610244565b80637a0d8f8a146105025780637b66c82a146105175780637cb111251461052c57806385f8c2591461055d5780638e1bfa731461057d57610244565b80633fc6f627116101c757806353e569a11161018b57806353e569a1146104695780635c1ad8441461048b5780635e03e6e4146104a057806361a4760b146104c05780636c9fa59e146104ed57610244565b80633fc6f627146103bc578063485cc955146103dc5780634bf1ee87146103fc5780634e1273f41461041c5780634ea96c301461044957610244565b8063235f9e081161020e578063235f9e081461030c57806326afd2e8146103395780632c52071c146103695780632eb2c2d6146103895780632f562016146103a957610244565b8062ee354214610246578062fdd58e1461027d57806309c1df9f146102aa5780631d4b44bb146102cc5780631f981bde146102ec575b005b34801561025257600080fd5b50610266610261366004613abb565b61076b565b60405161027492919061415d565b60405180910390f35b34801561028957600080fd5b5061029d610298366004613816565b6107ad565b6040516102749190614262565b3480156102b657600080fd5b506102bf610831565b6040516102749190614257565b3480156102d857600080fd5b5061029d6102e736600461362e565b61083f565b3480156102f857600080fd5b5061029d610307366004613841565b610967565b34801561031857600080fd5b5061032c610327366004613841565b6109a0565b60405161027491906142e5565b34801561034557600080fd5b50610359610354366004613c27565b610b06565b6040516102749493929190614176565b34801561037557600080fd5b5061029d6103843660046137c6565b610b2d565b34801561039557600080fd5b506102446103a4366004613666565b610cf2565b61029d6103b7366004613c57565b610d6b565b3480156103c857600080fd5b5061029d6103d7366004613ce7565b610f83565b3480156103e857600080fd5b506102446103f7366004613aed565b610ff7565b34801561040857600080fd5b5061032c610417366004613b91565b611678565b34801561042857600080fd5b5061043c610437366004613915565b6116cf565b60405161027491906141d4565b34801561045557600080fd5b506102bf61046436600461397d565b6117d7565b34801561047557600080fd5b5061047e611ba8565b6040516102749190614077565b34801561049757600080fd5b5061047e611bb7565b3480156104ac57600080fd5b5061029d6104bb3660046137c6565b611bc6565b3480156104cc57600080fd5b506104e06104db366004613b5f565b611d1f565b60405161027491906145d3565b3480156104f957600080fd5b5061047e611d9e565b34801561050e57600080fd5b5061047e611dad565b34801561052357600080fd5b506102bf611dbc565b34801561053857600080fd5b5061054c610547366004613abb565b611dcc565b604051610274959493929190614280565b34801561056957600080fd5b5061029d610578366004613d2b565b611f42565b34801561058957600080fd5b5061047e611fc2565b34801561059e57600080fd5b5061047e611fd1565b3480156105b357600080fd5b506102bf6105c2366004613816565b611fe0565b3480156105d357600080fd5b506102446105e2366004613799565b61207f565b3480156105f357600080fd5b506105fc612097565b604051610274919061426b565b34801561061557600080fd5b5061047e6120a2565b34801561062a57600080fd5b5061029d610639366004613b5f565b6120b1565b34801561064a57600080fd5b5061054c610659366004613abb565b6120f4565b34801561066a57600080fd5b5061029d610679366004613c27565b61215e565b34801561068a57600080fd5b5061047e612164565b34801561069f57600080fd5b506106b36106ae366004613893565b612173565b604051610274929190614623565b3480156106cd57600080fd5b506102bf6106dc366004613b91565b612287565b3480156106ed57600080fd5b5061029d612314565b34801561070257600080fd5b506102bf61071136600461362e565b61231a565b34801561072257600080fd5b506102bf612322565b34801561073757600080fd5b50610244610746366004613720565b61232b565b34801561075757600080fd5b506106b3610766366004613d56565b61239e565b600080600080606080606061077f88611dcc565b945094509450945094508260008151811061079657fe5b602002602001015195508396505050505050915091565b60008060008060006107be86610b06565b935093509350935060008160ff1660018111156107d757fe5b905060018160018111156107e757fe5b1415610805576107f988868587611bc6565b9550505050505061082b565b600081600181111561081357fe5b1415610825576107f988868587610b2d565b50505050505b92915050565b600054610100900460ff1690565b6005546040516370a0823160e01b815260009182916001600160a01b03909116906370a0823190610874908790600401614077565b60206040518083038186803b15801561088c57600080fd5b505afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108c49190810190613c3f565b600554604051636eb1769f60e11b81529192506000916001600160a01b039091169063dd62ed3e906108fc90889088906004016140f7565b60206040518083038186803b15801561091457600080fd5b505afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061094c9190810190613c3f565b905061095e828263ffffffff6123c816565b95945050505050565b60006060858585856040516020016109829493929190613f76565b60408051601f19818403018152919052602001519695505050505050565b60408051600380825260808201909252606091829190816020015b60608152602001906001900390816109bb5750506040805160038082526080820190925291925060609190602082018380388339019050509050610a01878787876123df565b82600081518110610a0e57fe5b6020026020010181905250610a216124d4565b82600181518110610a2e57fe5b6020026020010181905250610a41612533565b82600281518110610a4e57fe5b6020026020010181905250600181600081518110610a6857fe5b602002602001018181525050600081600181518110610a8357fe5b602002602001018181525050600081600281518110610a9e57fe5b60200260200101818152505060606394cfcdd760e01b8284604051602401610ac79291906141e7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529350505050949350505050565b606081901c9169ffffffffffffffffffff601083901c169160ff600882901c811692911690565b600080846001600160a01b03166327ce5b8c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b6957600080fd5b505afa158015610b7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ba19190810190613c3f565b9050606060018203604051908082528060200260200182016040528015610bd2578160200160208202803883390190505b5090506000805b60018403811015610c1a578660ff16811415610bf6576001909101905b81838281518110610c0357fe5b602090810291909101015260019182019101610bd9565b5060065460405163f8a2167b60e01b81526000916001600160a01b03169063f8a2167b90610c50908b9087908e906004016142f8565b60206040518083038186803b158015610c6857600080fd5b505afa158015610c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ca09190810190613c3f565b600454909150600090610cbd908b906001600160a01b031661083f565b90506000610cd1828963ffffffff6125b316565b9050610ce3838263ffffffff6125c816565b9b9a5050505050505050505050565b600054610100900460ff16610d0657600080fd5b866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb89898989604051610d5994939291906141a2565b60405180910390a45050505050505050565b600080835111610d7a57600080fd5b6000805461ff00191661010017815560075460408051631ce4c78b60e01b815290518b9392610e1b923a926001600160a01b0390921691631ce4c78b91600480820192602092909190829003018186803b158015610dd757600080fd5b505afa158015610deb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e0f9190810190613c3f565b9063ffffffff6125e116565b9050610e36610e30828863ffffffff6125e116565b88612608565b60005b855181108015610e4857508215155b15610ef957610e55613118565b868281518110610e6157fe5b60200260200101519050610e7581856127d7565b610e7d6131ab565b610e9c8286898681518110610e8e57fe5b6020026020010151876128f8565b9050806020015160001415610eb2575050610ef1565b6000610ec58383602001518f8f336129f1565b9050610ed7868263ffffffff612b3d16565b600019909a0199955089610eed57505050610ef9565b5050505b600101610e39565b506000805461ff00191690554715610f76576000336001600160a01b031647604051610f2490613ffe565b60006040518083038185875af1925050503d8060008114610f61576040519150601f19603f3d011682016040523d82523d6000602084013e610f66565b606091505b5050905080610f7457600080fd5b505b5098975050505050505050565b600080610fd883600760009054906101000a90046001600160a01b03166001600160a01b0316631ce4c78b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd757600080fd5b90506000610fec828663ffffffff6125e116565b905061095e81612b52565b60005460ff161561100757600080fd5b61100f612c37565b600280546001600160a01b038085166001600160a01b03199283168117909355600380549185169190921617905560405163f39ec1f760e01b815263f39ec1f79061105c90600401614494565b60206040518083038186803b15801561107457600080fd5b505afa158015611088573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110ac9190810190613612565b600580546001600160a01b0319166001600160a01b039283161790819055166110d457600080fd5b60405163f39ec1f760e01b81526001600160a01b0383169063f39ec1f7906110fe906004016144b5565b60206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061114e9190810190613612565b600680546001600160a01b0319166001600160a01b0392831617908190551661117657600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f7906111a0906004016144fc565b60206040518083038186803b1580156111b857600080fd5b505afa1580156111cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111f09190810190613612565b600780546001600160a01b0319166001600160a01b0392831617908190551661121857600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f790611242906004016144cb565b60206040518083038186803b15801561125a57600080fd5b505afa15801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112929190810190613612565b600480546001600160a01b0319166001600160a01b039283161790819055166112ba57600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f7906112e4906004016144a4565b60206040518083038186803b1580156112fc57600080fd5b505afa158015611310573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113349190810190613612565b600980546001600160a01b0319166001600160a01b0392831617905560405163f39ec1f760e01b815260009184169063f39ec1f790611375906004016144e0565b60206040518083038186803b15801561138d57600080fd5b505afa1580156113a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c59190810190613612565b60095460055460405163e6a4390560e01b81529293506000926001600160a01b038086169363e6a4390593611402939183169216906004016140f7565b60206040518083038186803b15801561141a57600080fd5b505afa15801561142e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114529190810190613612565b90506001600160a01b0381166114ee576009546005546040516364e329cb60e11b81526001600160a01b038086169363c9c6539693611499939183169216906004016140f7565b602060405180830381600087803b1580156114b357600080fd5b505af11580156114c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114eb9190810190613612565b90505b600880546001600160a01b0319166001600160a01b03838116919091179182905560055460408051630dfe168160e01b815290519183169390921691630dfe1681916004808301926020929190829003018186803b15801561154f57600080fd5b505afa158015611563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115879190810190613612565b6001600160a01b031614600960146101000a81548160ff0219169083151502179055506040516020016115b990614001565b60408051601f1981840301815282825280516020918201208383018352600b84526a0c1e08141c9bdd1bd8dbdb60aa1b938201939093528151808301835260018152601960f91b90820152905161165792917ff0f24618f4c4be1e62e026fb039a20ef96f4495294817d1027ffaa6d1f70e61e917fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a591309101613fc7565b60408051601f19818403018152919052805160209091012060015550505050565b6060633efe50c860e01b8383604051602401611695929190614623565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905092915050565b6040805184815260208086028201019091526060908480156116fb578160200160208202803883390190505b50905060005b848110156117ce573062fdd58e87878481811061171a57fe5b905060200201602061172f91908101906135f6565b86868581811061173b57fe5b905060200201356040518363ffffffff1660e01b815260040161175f92919061415d565b60206040518083038186803b15801561177757600080fd5b505afa15801561178b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117af9190810190613c3f565b8282815181106117bb57fe5b6020908102919091010152600101611701565b50949350505050565b600082518451146117e757600080fd5b600061183b3a600760009054906101000a90046001600160a01b03166001600160a01b0316631ce4c78b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd757600080fd5b905061185a6118548651836125e190919063ffffffff16565b84612608565b6000805461ff0019166101001781555b8551811015611b205761187b613118565b86828151811061188757fe5b60200260200101519050606086838151811061189f57fe5b6020026020010151905081600001516001600160a01b0316336001600160a01b0316146118cb57600080fd5b6118d36131da565b600754604051639d3fa4b960e01b81526001600160a01b0390911690639d3fa4b990611903908690600401614610565b60606040518083038186803b15801561191b57600080fd5b505afa15801561192f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119539190810190613b1a565b9050600061197282604001518560a00151612b3d90919063ffffffff16565b600754604051634da26aab60e11b81529192506001600160a01b031690639b44d5569088906119a990889086908990600401614645565b60a0604051808303818588803b1580156119c257600080fd5b505af11580156119d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052506119fb9190810190613aff565b50611a046131fa565b611a0d85611d1f565b9050600081600001516001600160a01b031663870c426d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4e57600080fd5b505afa158015611a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a869190810190613612565b6003548351885160408087015160208089015160608a0151918c01519351632bbddc3760e11b81529798506001600160a01b039096169663577bb86e96611adc968a96909590949391928d929190600401614111565b600060405180830381600087803b158015611af657600080fd5b505af1158015611b0a573d6000803e3d6000fd5b50506001909801975061186a9650505050505050565b506000805461ff00191690554715611b9d576000336001600160a01b031647604051611b4b90613ffe565b60006040518083038185875af1925050503d8060008114611b88576040519150601f19603f3d011682016040523d82523d6000602084013e611b8d565b606091505b5050905080611b9b57600080fd5b505b506001949350505050565b6008546001600160a01b031681565b6004546001600160a01b031681565b60065460405163d64c62f360e01b815260009182916001600160a01b039091169063d64c62f390611bff90889088908b9060040161432d565b60206040518083038186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c4f9190810190613c3f565b600454909150600090611c6c9088906001600160a01b031661083f565b90506000611d01611cf486896001600160a01b031663bad84c9e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611cb057600080fd5b505afa158015611cc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ce89190810190613c3f565b9063ffffffff612b3d16565b839063ffffffff6125b316565b9050611d13838263ffffffff6125c816565b98975050505050505050565b611d276131fa565b6000806060806060611d3d876101400151611dcc565b94509450945094509450600080600080611d6a87600081518110611d5d57fe5b6020026020010151610b06565b6001600160a01b039093168d5260208d019190915260ff91821660608d01521660408b015250979998505050505050505050565b6006546001600160a01b031681565b6002546001600160a01b031681565b600954600160a01b900460ff1681565b60208101516001600160e01b0319166000606080806394cfcdd760e01b8514611e105760405162461bcd60e51b8152600401611e07906145ab565b60405180910390fd5b6060806060611e2c60048a518b612c569092919063ffffffff16565b905080806020019051611e4291908101906139e6565b81519194509250600314611e5557600080fd5b82600081518110611e6257fe5b6020026020010151600114611e7657600080fd5b82600181518110611e8357fe5b6020026020010151600014611e9757600080fd5b82600281518110611ea457fe5b6020026020010151600014611eb857600080fd5b611ee6611ec36124d4565b83600181518110611ed057fe5b6020026020010151612cc190919063ffffffff16565b611eef57600080fd5b611f07611efa612533565b83600281518110611ed057fe5b611f1057600080fd5b611f2d82600081518110611f2057fe5b60200260200101516120f4565b939d929c50909a509850909650945050505050565b6000808411611f5057600080fd5b600083118015611f605750600082115b611f6957600080fd5b6000611f816103e8610e0f868863ffffffff6125e116565b90506000611f9b6103e5610e0f868963ffffffff612b3d16565b9050611fb86001828481611fab57fe5b049063ffffffff6125c816565b9695505050505050565b6003546001600160a01b031681565b6005546001600160a01b031681565b60025460405163f9c45f7160e01b815260009182916001600160a01b039091169063f9c45f7190612015908790600401614077565b60206040518083038186803b15801561202d57600080fd5b505afa158015612041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120659190810190613c3f565b9050612077838263ffffffff612ce716565b949350505050565b60405162461bcd60e51b8152600401611e0790614584565b6307dfca1960e31b81565b6009546001600160a01b031681565b600080600060608060606120c9876101400151611dcc565b94509450945094509450826000815181106120e057fe5b602002602001015195505050505050919050565b60208101516001600160e01b03191660006060808063a7cb5fb760e01b851461212f5760405162461bcd60e51b8152600401611e07906145ab565b505050506024828101516044840151606485015160848601519496929591820184019490820184019391010190565b50600090565b6007546001600160a01b031681565b61217b613118565b6000606061218b8789888d6109a0565b9050612197878a611fe0565b6121b35760405162461bcd60e51b8152600401611e079061443e565b6001600160a01b038b1683526080830189905260a083018990526101008301859052610120830184905261014083018190526121ed612cfb565b610160840152600754604051639d3fa4b960e01b81526001600160a01b0390911690639d3fa4b990612223908690600401614610565b60606040518083038186803b15801561223b57600080fd5b505afa15801561224f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122739190810190613b1a565b602001519150509850989650505050505050565b600080612293846120b1565b8451604051627eeac760e11b8152919250309162fdd58e916122b991859060040161415d565b60206040518083038186803b1580156122d157600080fd5b505afa1580156122e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123099190810190613c3f565b909211159392505050565b60015481565b600192915050565b60005460ff1690565b600054610100900460ff1661233f57600080fd5b846001600160a01b0316866001600160a01b0316336001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62878760405161238e929190614670565b60405180910390a4505050505050565b6123a6613118565b60006123b8338a8a8a8a8a8a8a612173565b9150915097509795505050505050565b60008183116123d857508161082b565b508061082b565b604080516001808252818301909252606091829190602080830190803883395050604080516001808252818301909252929350606092915060208083019080388339019050509050600061243588888888610967565b9050808360008151811061244557fe5b60200260200101818152505060018260008151811061246057fe5b6020908102919091018101919091526040805160008152918201905263a7cb5fb760e01b61249430868685604481016140af565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152945050505050949350505050565b600554604051606091630f47261b60e41b916124fc916001600160a01b031690602401614077565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905090565b60408051600080825260208201818152828401918252606080840190945260065490919063a7cb5fb760e01b90612579906001600160a01b0316858585608483016140af565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152935050505090565b6000808284816125bf57fe5b04949350505050565b6000828201838110156125da57600080fd5b9392505050565b6000826125f05750600061082b565b828202828482816125fd57fe5b04146125da57600080fd5b814710156127d357478203600061261e82612b52565b9050828111156126405760405162461bcd60e51b8152600401611e0790614515565b6005546008546040516323b872dd60e01b81526001600160a01b03928316926323b872dd9261267992339290911690869060040161408b565b602060405180830381600087803b15801561269357600080fd5b505af11580156126a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126cb9190810190613a9f565b6126d457600080fd5b6008546009546001600160a01b039091169063022c0d9f90600160a01b900460ff166127005783612703565b60005b600954600160a01b900460ff1661271b57600061271d565b845b306040518463ffffffff1660e01b815260040161273c9392919061467e565b600060405180830381600087803b15801561275657600080fd5b505af115801561276a573d6000803e3d6000fd5b5050600954604051632e1a7d4d60e01b81526001600160a01b039091169250632e1a7d4d915061279e908590600401614262565b600060405180830381600087803b1580156127b857600080fd5b505af11580156127cc573d6000803e3d6000fd5b5050505050505b5050565b6127f46127e2612cfb565b6101608401519063ffffffff612cc116565b6127fd57600080fd5b81608001518260a001511461281157600080fd5b60008061282284610140015161076b565b9150915060008060008061283585610b06565b93509350935093506000846001600160a01b031663bad84c9e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561287857600080fd5b505afa15801561288c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128b09190810190613c3f565b90506128bc8589611fe0565b6128d85760405162461bcd60e51b8152600401611e079061443e565b6001600160a01b03871630146128ed57600080fd5b505050505050505050565b6129006131ab565b604051606090634da26aab60e11b9061292190889088908890602401614645565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925260075491519092506000916060916001600160a01b0390911690869061297a908690613fe2565b60006040518083038185875af1925050503d80600081146129b7576040519150601f19603f3d011682016040523d82523d6000602084013e6129bc565b606091505b509150915081156129e657805160a0146129d257fe5b80806020019051611d139190810190613aff565b505050949350505050565b60006129fb6131fa565b612a0487611d1f565b9050612a108787612287565b612a1e57600091505061095e565b826001600160a01b031687600001516001600160a01b03161415612a45578591505061095e565b600080600460009054906101000a90046001600160a01b03166001600160a01b031663f5df1f24846000015185604001518660200151876060015160ff166001811115612a8e57fe5b8e600001518e8e8e8e6040518a63ffffffff1660e01b8152600401612abb99989796959493929190614353565b6040805180830381600087803b158015612ad457600080fd5b505af1158015612ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612b0c9190810190613d08565b9092509050612b21888363ffffffff612b3d16565b9350612b31898487898886612d32565b50505095945050505050565b600082821115612b4c57600080fd5b50900390565b600080600080600860009054906101000a90046001600160a01b03166001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612ba657600080fd5b505afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bde9190810190613bd3565b92509250925061095e85600960149054906101000a900460ff16612c025783612c04565b845b6001600160701b0316600960149054906101000a900460ff16612c275785612c29565b845b6001600160701b0316611f42565b60005460ff1615612c4757600080fd5b6000805460ff19166001179055565b606081831115612c6557600080fd5b8351821115612c7357600080fd5b8282036040519080825280601f01601f191660200182016040528015612ca0576020820181803883390190505b5090506125da612caf8261306c565b84612cb98761306c565b018351613072565b6000815183511480156125da575081805190602001208380519060200120149392505050565b6000818381612cf257fe5b06159392505050565b6040805160008082526020820181815282840191825260608084019094529063a7cb5fb760e01b61257930858585608483016140af565b600754604051639d3fa4b960e01b81526000916001600160a01b031690639d3fa4b990612d63908a90600401614610565b60606040518083038186803b158015612d7b57600080fd5b505afa158015612d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612db39190810190613b1a565b6020015160408051600280825260608281019093529293509091816020016020820280388339505060408051600a8082526101608201909252929350606092915060208201610140803883390190505090506000886060015160ff166001811115612e1a57fe5b9050896000015183600081518110612e2e57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508783600181518110612e5c57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050886020015182600081518110612e8e57fe5b602002602001018181525050600082600181518110612ea957fe5b602002602001018181525050886040015160ff1682600281518110612eca57fe5b6020026020010181815250508482600581518110612ee457fe5b6020026020010181815250508582600681518110612efe57fe5b602002602001018181525050600082600881518110612f1957fe5b602002602001018181525050600082600981518110612f3457fe5b602002602001018181525050600360009054906101000a90046001600160a01b03166001600160a01b03166399b537a08a600001516001600160a01b031663870c426d6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa157600080fd5b505afa158015612fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612fd99190810190613612565b8b51878b866001811115612fe957fe5b89896040518863ffffffff1660e01b815260040161300d97969594939291906143b8565b602060405180830381600087803b15801561302757600080fd5b505af115801561303b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061305f9190810190613a9f565b5050505050505050505050565b60200190565b602081101561309c576001816020036101000a038019835116818551168082178652505050613113565b828214156130a957613113565b828211156130e35760208103905080820181840181515b828510156130db5784518652602095860195909401936130c0565b905250613113565b60208103905080820181840183515b8186121561310e5782518252601f1992830192909101906130f2565b855250505b505050565b604051806101c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b803561082b81614744565b60008083601f84011261323d578182fd5b5081356001600160401b03811115613253578182fd5b602083019150836020808302850101111561326d57600080fd5b9250929050565b600082601f830112613284578081fd5b8151613297613292826146d2565b6146ac565b818152915060208083019084810160005b84811015610825578151870188603f8201126132c357600080fd5b838101516132d3613292826146f1565b8181528a60408385010111156132e857600080fd5b6132f88287830160408601614714565b8652505092820192908201906001016132a8565b600082601f83011261331c578081fd5b813561332a613292826146d2565b8181529150602080830190840160005b8381101561336757613352876020843589010161340b565b8352602092830192919091019060010161333a565b5050505092915050565b600082601f830112613381578081fd5b813561338f613292826146d2565b8181529150602080830190840160005b83811015613367576133b787602084358901016134a8565b8352602092830192919091019060010161339f565b60008083601f8401126133dd578182fd5b5081356001600160401b038111156133f3578182fd5b60208301915083602082850101111561326d57600080fd5b600082601f83011261341b578081fd5b8135613429613292826146f1565b915080825283602082850101111561344057600080fd5b8060208401602084013760009082016020015292915050565b600060a0828403121561346a578081fd5b61347460a06146ac565b9050815181526020820151602082015260408201516040820152606082015160608201526080820151608082015292915050565b60006101c08083850312156134bb578182fd5b6134c4816146ac565b9150506134d18383613221565b81526134e08360208401613221565b60208201526134f28360408401613221565b60408201526135048360608401613221565b60608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e0820152610100808301358183015250610120808301358183015250610140808301356001600160401b038082111561356557600080fd5b6135718683870161340b565b8385015261016092508285013591508082111561358d57600080fd5b6135998683870161340b565b838501526101809250828501359150808211156135b557600080fd5b6135c18683870161340b565b838501526101a09250828501359150808211156135dd57600080fd5b506135ea8582860161340b565b82840152505092915050565b600060208284031215613607578081fd5b81356125da81614744565b600060208284031215613623578081fd5b81516125da81614744565b60008060408385031215613640578081fd5b823561364b81614744565b9150602083013561365b81614744565b809150509250929050565b60008060008060008060008060a0898b031215613681578384fd5b883561368c81614744565b9750602089013561369c81614744565b965060408901356001600160401b03808211156136b7578586fd5b6136c38c838d0161322c565b909850965060608b01359150808211156136db578586fd5b6136e78c838d0161322c565b909650945060808b01359150808211156136ff578384fd5b5061370c8b828c016133cc565b999c989b5096995094979396929594505050565b60008060008060008060a08789031215613738578384fd5b863561374381614744565b9550602087013561375381614744565b9450604087013593506060870135925060808701356001600160401b0381111561377b578283fd5b61378789828a016133cc565b979a9699509497509295939492505050565b600080604083850312156137ab578182fd5b82356137b681614744565b9150602083013561365b8161475c565b600080600080608085870312156137db578182fd5b84356137e681614744565b935060208501356137f681614744565b925060408501356138068161477f565b9396929550929360600135925050565b60008060408385031215613828578182fd5b823561383381614744565b946020939093013593505050565b60008060008060808587031215613856578182fd5b843561386181614744565b93506020850135925060408501356138788161477f565b915060608501356138888161477f565b939692955090935050565b600080600080600080600080610100898b0312156138af578182fd5b88356138ba81614744565b975060208901356138ca8161477f565b9650604089013595506060890135945060808901356138e881614744565b935060a08901356138f88161477f565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806040858703121561392a578182fd5b84356001600160401b0380821115613940578384fd5b61394c8883890161322c565b90965094506020870135915080821115613964578384fd5b506139718782880161322c565b95989497509550505050565b600080600060608486031215613991578081fd5b83356001600160401b03808211156139a7578283fd5b6139b387838801613371565b945060208601359150808211156139c8578283fd5b506139d58682870161330c565b925050604084013590509250925092565b600080604083850312156139f8578182fd5b82516001600160401b0380821115613a0e578384fd5b81850186601f820112613a1f578485fd5b80519250613a2f613292846146d2565b80848252602080830192508084018a828389028701011115613a4f578889fd5b8894505b86851015613a71578051845260019490940193928101928101613a53565b508801519096509350505080821115613a88578283fd5b50613a9585828601613274565b9150509250929050565b600060208284031215613ab0578081fd5b81516125da8161475c565b600060208284031215613acc578081fd5b81356001600160401b03811115613ae1578182fd5b6120778482850161340b565b60008060408385031215613640578182fd5b600060a08284031215613b10578081fd5b6125da8383613459565b600060608284031215613b2b578081fd5b613b3560606146ac565b8251613b408161477f565b8152602083810151908201526040928301519281019290925250919050565b600060208284031215613b70578081fd5b81356001600160401b03811115613b85578182fd5b612077848285016134a8565b60008060408385031215613ba3578182fd5b82356001600160401b03811115613bb8578283fd5b613bc4858286016134a8565b95602094909401359450505050565b600080600060608486031215613be7578081fd5b8351613bf28161476a565b6020850151909350613c038161476a565b604085015190925063ffffffff81168114613c1c578182fd5b809150509250925092565b600060208284031215613c38578081fd5b5035919050565b600060208284031215613c50578081fd5b5051919050565b600080600080600080600060e0888a031215613c71578081fd5b873596506020880135955060408801359450606088013593506080880135925060a08801356001600160401b0380821115613caa578283fd5b613cb68b838c01613371565b935060c08a0135915080821115613ccb578283fd5b50613cd88a828b0161330c565b91505092959891949750929550565b60008060408385031215613cf9578182fd5b50508035926020909101359150565b60008060408385031215613d1a578182fd5b505080516020909101519092909150565b600080600060608486031215613d3f578081fd5b505081359360208301359350604090920135919050565b600080600080600080600060e0888a031215613d70578081fd5b8735613d7b8161477f565b965060208801359550604088013594506060880135613d9981614744565b93506080880135613da98161477f565b9699959850939692959460a0840135945060c09093013592915050565b6001600160a01b0316815260200190565b6001600160a01b03169052565b81835260006001600160fb1b03831115613dfc578081fd5b6020830280836020870137939093016020019283525090919050565b6000815180845260208401935060208301825b82811015613e49578151865260209586019590910190600101613e2b565b5093949350505050565b60008151808452613e6b816020860160208601614714565b601f01601f19169290920160200192915050565b60006101c0613e8f848451613dd7565b6020830151613ea16020860182613dd7565b506040830151613eb46040860182613dd7565b506060830151613ec76060860182613dd7565b506080830151608085015260a083015160a085015260c083015160c085015260e083015160e0850152610100808401518186015250610120808401518186015250610140808401518282870152613f2083870182613e53565b91505061016091508184015185820383870152613f3d8282613e53565b925050506101808084015185830382870152613f598382613e53565b9150506101a091508184015185820383870152611fb88282613e53565b60609490941b6bffffffffffffffffffffffff1916845260b09290921b6001600160b01b031916601484015260f890811b6001600160f81b0319908116601e85015291901b16601f82015260200190565b93845260208401929092526040830152606082015260800190565b60008251613ff4818460208701614714565b9190910192915050565b90565b6c08a92a06e626488dedac2d2dc5609b1b81526b1cdd1c9a5b99c81b985b594b60a21b600d8201526e1cdd1c9a5b99c81d995c9cda5bdb8b608a1b60198201527f6164647265737320766572696679696e67436f6e7472616374000000000000006028820152602960f81b604182015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03851681526080602082018190526000906140d390830186613e18565b82810360408401526140e58186613e18565b8381036060850152611d138186613e53565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039889168152968816602088015294909616604086015260ff9283166060860152608085019190915260a084015290921660c082015260e08101919091526101000190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03949094168452602084019290925260ff908116604084015216606082015260800190565b6000604082526141b6604083018688613de4565b82810360208401526141c9818587613de4565b979650505050505050565b6000602082526125da6020830184613e18565b6000604082526141fa6040830185613e18565b602083820381850152818551808452828401915082838202850101838801865b8381101561424857601f19878403018552614236838351613e53565b9486019492509085019060010161421a565b50909998505050505050505050565b901515815260200190565b90815260200190565b6001600160e01b031991909116815260200190565b6001600160e01b0319861681526001600160a01b038516602082015260a0604082018190526000906142b490830186613e18565b82810360608401526142c68186613e18565b83810360808501526142d88186613e53565b9998505050505050505050565b6000602082526125da6020830184613e53565b600060018060a01b0380861683526060602084015261431a6060840186613e18565b9150808416604084015250949350505050565b6001600160a01b03938416815260ff929092166020830152909116604082015260600190565b6001600160a01b038a8116825260ff8a166020830152604082018990526101208201906002891061438057fe5b88606084015280881660808401528660a08401528560c08401528460e0840152808416610100840152509a9950505050505050505050565b600060e0820160018060a01b03808b168452808a1660208501525087604084015286606084015260ff8616608084015260e060a08401528085516143fc8184614262565b9150602087019250835b8181101561442a57614419838551613dc6565b602094909401939250600101614406565b505083810360c0850152610ce38186613e18565b60208082526036908201527f4f72646572206d7573742062652061206d756c7469706c65206f6620746865206040820152751b585c9ad95d081d1c985919481a5b98dc995b595b9d60521b606082015260800190565b63086c2e6d60e31b815260200190565b64574554483960d81b815260200190565b6929b430b932aa37b5b2b760b11b815260200190565b682334b63627b93232b960b91b815260200190565b6f556e69737761705632466163746f727960801b815260200190565b6c5a65726f5845786368616e676560981b815260200190565b60208082526049908201527f436f7374206f662070757263686173696e672045544820746f20636f7665722060408201527f70726f746f636f6c20466565206f6e207468652065786368616e676520776173606082015268040e8dede40d0d2ced60bb1b608082015260a00190565b6020808252600d908201526c139bdd081cdd5c1c1bdc9d1959609a1b604082015260600190565b6020808252600e908201526d15d493d391d7d41493d61657d25160921b604082015260600190565b81516001600160a01b031681526020808301519082015260408083015160ff90811691830191909152606092830151169181019190915260800190565b6000602082526125da6020830184613e7f565b6000604082526146366040830185613e7f565b90508260208301529392505050565b6000606082526146586060830186613e7f565b8460208401528281036040840152611fb88185613e53565b918252602082015260400190565b92835260208301919091526001600160a01b0316604082015260806060820181905260009082015260a00190565b6040518181016001600160401b03811182821017156146ca57600080fd5b604052919050565b60006001600160401b038211156146e7578081fd5b5060209081020190565b60006001600160401b03821115614706578081fd5b50601f01601f191660200190565b60005b8381101561472f578181015183820152602001614717565b8381111561473e576000848401525b50505050565b6001600160a01b038116811461475957600080fd5b50565b801515811461475957600080fd5b6001600160701b038116811461475957600080fd5b60ff8116811461475957600080fdfea365627a7a723158209038d4e8a8c7fe935f8ee4cc5d68a9ae777dfeb32839253038dcc9376cd96e486c6578706572696d656e74616cf564736f6c634300050f0040

Deployed Bytecode

0x6080604052600436106102445760003560e01c80637a0d8f8a11610139578063afc6d8ba116100b6578063e264cff11161007a578063e264cff1146106c1578063e306f779146106e1578063e985e9c5146106f6578063ee89dab414610716578063f242432a1461072b578063f94515f01461074b57610244565b8063afc6d8ba1461061e578063b3ca8e251461063e578063bd85b0391461065e578063d2f7265a1461067e578063e186955b1461069357610244565b8063961be391116100fd578063961be391146105925780639c6fbce5146105a7578063a22cb465146105c7578063ad5c22c8146105e7578063ad5c46481461060957610244565b80637a0d8f8a146105025780637b66c82a146105175780637cb111251461052c57806385f8c2591461055d5780638e1bfa731461057d57610244565b80633fc6f627116101c757806353e569a11161018b57806353e569a1146104695780635c1ad8441461048b5780635e03e6e4146104a057806361a4760b146104c05780636c9fa59e146104ed57610244565b80633fc6f627146103bc578063485cc955146103dc5780634bf1ee87146103fc5780634e1273f41461041c5780634ea96c301461044957610244565b8063235f9e081161020e578063235f9e081461030c57806326afd2e8146103395780632c52071c146103695780632eb2c2d6146103895780632f562016146103a957610244565b8062ee354214610246578062fdd58e1461027d57806309c1df9f146102aa5780631d4b44bb146102cc5780631f981bde146102ec575b005b34801561025257600080fd5b50610266610261366004613abb565b61076b565b60405161027492919061415d565b60405180910390f35b34801561028957600080fd5b5061029d610298366004613816565b6107ad565b6040516102749190614262565b3480156102b657600080fd5b506102bf610831565b6040516102749190614257565b3480156102d857600080fd5b5061029d6102e736600461362e565b61083f565b3480156102f857600080fd5b5061029d610307366004613841565b610967565b34801561031857600080fd5b5061032c610327366004613841565b6109a0565b60405161027491906142e5565b34801561034557600080fd5b50610359610354366004613c27565b610b06565b6040516102749493929190614176565b34801561037557600080fd5b5061029d6103843660046137c6565b610b2d565b34801561039557600080fd5b506102446103a4366004613666565b610cf2565b61029d6103b7366004613c57565b610d6b565b3480156103c857600080fd5b5061029d6103d7366004613ce7565b610f83565b3480156103e857600080fd5b506102446103f7366004613aed565b610ff7565b34801561040857600080fd5b5061032c610417366004613b91565b611678565b34801561042857600080fd5b5061043c610437366004613915565b6116cf565b60405161027491906141d4565b34801561045557600080fd5b506102bf61046436600461397d565b6117d7565b34801561047557600080fd5b5061047e611ba8565b6040516102749190614077565b34801561049757600080fd5b5061047e611bb7565b3480156104ac57600080fd5b5061029d6104bb3660046137c6565b611bc6565b3480156104cc57600080fd5b506104e06104db366004613b5f565b611d1f565b60405161027491906145d3565b3480156104f957600080fd5b5061047e611d9e565b34801561050e57600080fd5b5061047e611dad565b34801561052357600080fd5b506102bf611dbc565b34801561053857600080fd5b5061054c610547366004613abb565b611dcc565b604051610274959493929190614280565b34801561056957600080fd5b5061029d610578366004613d2b565b611f42565b34801561058957600080fd5b5061047e611fc2565b34801561059e57600080fd5b5061047e611fd1565b3480156105b357600080fd5b506102bf6105c2366004613816565b611fe0565b3480156105d357600080fd5b506102446105e2366004613799565b61207f565b3480156105f357600080fd5b506105fc612097565b604051610274919061426b565b34801561061557600080fd5b5061047e6120a2565b34801561062a57600080fd5b5061029d610639366004613b5f565b6120b1565b34801561064a57600080fd5b5061054c610659366004613abb565b6120f4565b34801561066a57600080fd5b5061029d610679366004613c27565b61215e565b34801561068a57600080fd5b5061047e612164565b34801561069f57600080fd5b506106b36106ae366004613893565b612173565b604051610274929190614623565b3480156106cd57600080fd5b506102bf6106dc366004613b91565b612287565b3480156106ed57600080fd5b5061029d612314565b34801561070257600080fd5b506102bf61071136600461362e565b61231a565b34801561072257600080fd5b506102bf612322565b34801561073757600080fd5b50610244610746366004613720565b61232b565b34801561075757600080fd5b506106b3610766366004613d56565b61239e565b600080600080606080606061077f88611dcc565b945094509450945094508260008151811061079657fe5b602002602001015195508396505050505050915091565b60008060008060006107be86610b06565b935093509350935060008160ff1660018111156107d757fe5b905060018160018111156107e757fe5b1415610805576107f988868587611bc6565b9550505050505061082b565b600081600181111561081357fe5b1415610825576107f988868587610b2d565b50505050505b92915050565b600054610100900460ff1690565b6005546040516370a0823160e01b815260009182916001600160a01b03909116906370a0823190610874908790600401614077565b60206040518083038186803b15801561088c57600080fd5b505afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108c49190810190613c3f565b600554604051636eb1769f60e11b81529192506000916001600160a01b039091169063dd62ed3e906108fc90889088906004016140f7565b60206040518083038186803b15801561091457600080fd5b505afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061094c9190810190613c3f565b905061095e828263ffffffff6123c816565b95945050505050565b60006060858585856040516020016109829493929190613f76565b60408051601f19818403018152919052602001519695505050505050565b60408051600380825260808201909252606091829190816020015b60608152602001906001900390816109bb5750506040805160038082526080820190925291925060609190602082018380388339019050509050610a01878787876123df565b82600081518110610a0e57fe5b6020026020010181905250610a216124d4565b82600181518110610a2e57fe5b6020026020010181905250610a41612533565b82600281518110610a4e57fe5b6020026020010181905250600181600081518110610a6857fe5b602002602001018181525050600081600181518110610a8357fe5b602002602001018181525050600081600281518110610a9e57fe5b60200260200101818152505060606394cfcdd760e01b8284604051602401610ac79291906141e7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529350505050949350505050565b606081901c9169ffffffffffffffffffff601083901c169160ff600882901c811692911690565b600080846001600160a01b03166327ce5b8c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b6957600080fd5b505afa158015610b7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ba19190810190613c3f565b9050606060018203604051908082528060200260200182016040528015610bd2578160200160208202803883390190505b5090506000805b60018403811015610c1a578660ff16811415610bf6576001909101905b81838281518110610c0357fe5b602090810291909101015260019182019101610bd9565b5060065460405163f8a2167b60e01b81526000916001600160a01b03169063f8a2167b90610c50908b9087908e906004016142f8565b60206040518083038186803b158015610c6857600080fd5b505afa158015610c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ca09190810190613c3f565b600454909150600090610cbd908b906001600160a01b031661083f565b90506000610cd1828963ffffffff6125b316565b9050610ce3838263ffffffff6125c816565b9b9a5050505050505050505050565b600054610100900460ff16610d0657600080fd5b866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb89898989604051610d5994939291906141a2565b60405180910390a45050505050505050565b600080835111610d7a57600080fd5b6000805461ff00191661010017815560075460408051631ce4c78b60e01b815290518b9392610e1b923a926001600160a01b0390921691631ce4c78b91600480820192602092909190829003018186803b158015610dd757600080fd5b505afa158015610deb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e0f9190810190613c3f565b9063ffffffff6125e116565b9050610e36610e30828863ffffffff6125e116565b88612608565b60005b855181108015610e4857508215155b15610ef957610e55613118565b868281518110610e6157fe5b60200260200101519050610e7581856127d7565b610e7d6131ab565b610e9c8286898681518110610e8e57fe5b6020026020010151876128f8565b9050806020015160001415610eb2575050610ef1565b6000610ec58383602001518f8f336129f1565b9050610ed7868263ffffffff612b3d16565b600019909a0199955089610eed57505050610ef9565b5050505b600101610e39565b506000805461ff00191690554715610f76576000336001600160a01b031647604051610f2490613ffe565b60006040518083038185875af1925050503d8060008114610f61576040519150601f19603f3d011682016040523d82523d6000602084013e610f66565b606091505b5050905080610f7457600080fd5b505b5098975050505050505050565b600080610fd883600760009054906101000a90046001600160a01b03166001600160a01b0316631ce4c78b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd757600080fd5b90506000610fec828663ffffffff6125e116565b905061095e81612b52565b60005460ff161561100757600080fd5b61100f612c37565b600280546001600160a01b038085166001600160a01b03199283168117909355600380549185169190921617905560405163f39ec1f760e01b815263f39ec1f79061105c90600401614494565b60206040518083038186803b15801561107457600080fd5b505afa158015611088573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110ac9190810190613612565b600580546001600160a01b0319166001600160a01b039283161790819055166110d457600080fd5b60405163f39ec1f760e01b81526001600160a01b0383169063f39ec1f7906110fe906004016144b5565b60206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061114e9190810190613612565b600680546001600160a01b0319166001600160a01b0392831617908190551661117657600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f7906111a0906004016144fc565b60206040518083038186803b1580156111b857600080fd5b505afa1580156111cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111f09190810190613612565b600780546001600160a01b0319166001600160a01b0392831617908190551661121857600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f790611242906004016144cb565b60206040518083038186803b15801561125a57600080fd5b505afa15801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112929190810190613612565b600480546001600160a01b0319166001600160a01b039283161790819055166112ba57600080fd5b60405163f39ec1f760e01b81526001600160a01b0382169063f39ec1f7906112e4906004016144a4565b60206040518083038186803b1580156112fc57600080fd5b505afa158015611310573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113349190810190613612565b600980546001600160a01b0319166001600160a01b0392831617905560405163f39ec1f760e01b815260009184169063f39ec1f790611375906004016144e0565b60206040518083038186803b15801561138d57600080fd5b505afa1580156113a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c59190810190613612565b60095460055460405163e6a4390560e01b81529293506000926001600160a01b038086169363e6a4390593611402939183169216906004016140f7565b60206040518083038186803b15801561141a57600080fd5b505afa15801561142e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114529190810190613612565b90506001600160a01b0381166114ee576009546005546040516364e329cb60e11b81526001600160a01b038086169363c9c6539693611499939183169216906004016140f7565b602060405180830381600087803b1580156114b357600080fd5b505af11580156114c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114eb9190810190613612565b90505b600880546001600160a01b0319166001600160a01b03838116919091179182905560055460408051630dfe168160e01b815290519183169390921691630dfe1681916004808301926020929190829003018186803b15801561154f57600080fd5b505afa158015611563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115879190810190613612565b6001600160a01b031614600960146101000a81548160ff0219169083151502179055506040516020016115b990614001565b60408051601f1981840301815282825280516020918201208383018352600b84526a0c1e08141c9bdd1bd8dbdb60aa1b938201939093528151808301835260018152601960f91b90820152905161165792917ff0f24618f4c4be1e62e026fb039a20ef96f4495294817d1027ffaa6d1f70e61e917fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a591309101613fc7565b60408051601f19818403018152919052805160209091012060015550505050565b6060633efe50c860e01b8383604051602401611695929190614623565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905092915050565b6040805184815260208086028201019091526060908480156116fb578160200160208202803883390190505b50905060005b848110156117ce573062fdd58e87878481811061171a57fe5b905060200201602061172f91908101906135f6565b86868581811061173b57fe5b905060200201356040518363ffffffff1660e01b815260040161175f92919061415d565b60206040518083038186803b15801561177757600080fd5b505afa15801561178b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117af9190810190613c3f565b8282815181106117bb57fe5b6020908102919091010152600101611701565b50949350505050565b600082518451146117e757600080fd5b600061183b3a600760009054906101000a90046001600160a01b03166001600160a01b0316631ce4c78b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd757600080fd5b905061185a6118548651836125e190919063ffffffff16565b84612608565b6000805461ff0019166101001781555b8551811015611b205761187b613118565b86828151811061188757fe5b60200260200101519050606086838151811061189f57fe5b6020026020010151905081600001516001600160a01b0316336001600160a01b0316146118cb57600080fd5b6118d36131da565b600754604051639d3fa4b960e01b81526001600160a01b0390911690639d3fa4b990611903908690600401614610565b60606040518083038186803b15801561191b57600080fd5b505afa15801561192f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119539190810190613b1a565b9050600061197282604001518560a00151612b3d90919063ffffffff16565b600754604051634da26aab60e11b81529192506001600160a01b031690639b44d5569088906119a990889086908990600401614645565b60a0604051808303818588803b1580156119c257600080fd5b505af11580156119d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052506119fb9190810190613aff565b50611a046131fa565b611a0d85611d1f565b9050600081600001516001600160a01b031663870c426d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4e57600080fd5b505afa158015611a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a869190810190613612565b6003548351885160408087015160208089015160608a0151918c01519351632bbddc3760e11b81529798506001600160a01b039096169663577bb86e96611adc968a96909590949391928d929190600401614111565b600060405180830381600087803b158015611af657600080fd5b505af1158015611b0a573d6000803e3d6000fd5b50506001909801975061186a9650505050505050565b506000805461ff00191690554715611b9d576000336001600160a01b031647604051611b4b90613ffe565b60006040518083038185875af1925050503d8060008114611b88576040519150601f19603f3d011682016040523d82523d6000602084013e611b8d565b606091505b5050905080611b9b57600080fd5b505b506001949350505050565b6008546001600160a01b031681565b6004546001600160a01b031681565b60065460405163d64c62f360e01b815260009182916001600160a01b039091169063d64c62f390611bff90889088908b9060040161432d565b60206040518083038186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c4f9190810190613c3f565b600454909150600090611c6c9088906001600160a01b031661083f565b90506000611d01611cf486896001600160a01b031663bad84c9e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611cb057600080fd5b505afa158015611cc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ce89190810190613c3f565b9063ffffffff612b3d16565b839063ffffffff6125b316565b9050611d13838263ffffffff6125c816565b98975050505050505050565b611d276131fa565b6000806060806060611d3d876101400151611dcc565b94509450945094509450600080600080611d6a87600081518110611d5d57fe5b6020026020010151610b06565b6001600160a01b039093168d5260208d019190915260ff91821660608d01521660408b015250979998505050505050505050565b6006546001600160a01b031681565b6002546001600160a01b031681565b600954600160a01b900460ff1681565b60208101516001600160e01b0319166000606080806394cfcdd760e01b8514611e105760405162461bcd60e51b8152600401611e07906145ab565b60405180910390fd5b6060806060611e2c60048a518b612c569092919063ffffffff16565b905080806020019051611e4291908101906139e6565b81519194509250600314611e5557600080fd5b82600081518110611e6257fe5b6020026020010151600114611e7657600080fd5b82600181518110611e8357fe5b6020026020010151600014611e9757600080fd5b82600281518110611ea457fe5b6020026020010151600014611eb857600080fd5b611ee6611ec36124d4565b83600181518110611ed057fe5b6020026020010151612cc190919063ffffffff16565b611eef57600080fd5b611f07611efa612533565b83600281518110611ed057fe5b611f1057600080fd5b611f2d82600081518110611f2057fe5b60200260200101516120f4565b939d929c50909a509850909650945050505050565b6000808411611f5057600080fd5b600083118015611f605750600082115b611f6957600080fd5b6000611f816103e8610e0f868863ffffffff6125e116565b90506000611f9b6103e5610e0f868963ffffffff612b3d16565b9050611fb86001828481611fab57fe5b049063ffffffff6125c816565b9695505050505050565b6003546001600160a01b031681565b6005546001600160a01b031681565b60025460405163f9c45f7160e01b815260009182916001600160a01b039091169063f9c45f7190612015908790600401614077565b60206040518083038186803b15801561202d57600080fd5b505afa158015612041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120659190810190613c3f565b9050612077838263ffffffff612ce716565b949350505050565b60405162461bcd60e51b8152600401611e0790614584565b6307dfca1960e31b81565b6009546001600160a01b031681565b600080600060608060606120c9876101400151611dcc565b94509450945094509450826000815181106120e057fe5b602002602001015195505050505050919050565b60208101516001600160e01b03191660006060808063a7cb5fb760e01b851461212f5760405162461bcd60e51b8152600401611e07906145ab565b505050506024828101516044840151606485015160848601519496929591820184019490820184019391010190565b50600090565b6007546001600160a01b031681565b61217b613118565b6000606061218b8789888d6109a0565b9050612197878a611fe0565b6121b35760405162461bcd60e51b8152600401611e079061443e565b6001600160a01b038b1683526080830189905260a083018990526101008301859052610120830184905261014083018190526121ed612cfb565b610160840152600754604051639d3fa4b960e01b81526001600160a01b0390911690639d3fa4b990612223908690600401614610565b60606040518083038186803b15801561223b57600080fd5b505afa15801561224f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122739190810190613b1a565b602001519150509850989650505050505050565b600080612293846120b1565b8451604051627eeac760e11b8152919250309162fdd58e916122b991859060040161415d565b60206040518083038186803b1580156122d157600080fd5b505afa1580156122e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123099190810190613c3f565b909211159392505050565b60015481565b600192915050565b60005460ff1690565b600054610100900460ff1661233f57600080fd5b846001600160a01b0316866001600160a01b0316336001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62878760405161238e929190614670565b60405180910390a4505050505050565b6123a6613118565b60006123b8338a8a8a8a8a8a8a612173565b9150915097509795505050505050565b60008183116123d857508161082b565b508061082b565b604080516001808252818301909252606091829190602080830190803883395050604080516001808252818301909252929350606092915060208083019080388339019050509050600061243588888888610967565b9050808360008151811061244557fe5b60200260200101818152505060018260008151811061246057fe5b6020908102919091018101919091526040805160008152918201905263a7cb5fb760e01b61249430868685604481016140af565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152945050505050949350505050565b600554604051606091630f47261b60e41b916124fc916001600160a01b031690602401614077565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905090565b60408051600080825260208201818152828401918252606080840190945260065490919063a7cb5fb760e01b90612579906001600160a01b0316858585608483016140af565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152935050505090565b6000808284816125bf57fe5b04949350505050565b6000828201838110156125da57600080fd5b9392505050565b6000826125f05750600061082b565b828202828482816125fd57fe5b04146125da57600080fd5b814710156127d357478203600061261e82612b52565b9050828111156126405760405162461bcd60e51b8152600401611e0790614515565b6005546008546040516323b872dd60e01b81526001600160a01b03928316926323b872dd9261267992339290911690869060040161408b565b602060405180830381600087803b15801561269357600080fd5b505af11580156126a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126cb9190810190613a9f565b6126d457600080fd5b6008546009546001600160a01b039091169063022c0d9f90600160a01b900460ff166127005783612703565b60005b600954600160a01b900460ff1661271b57600061271d565b845b306040518463ffffffff1660e01b815260040161273c9392919061467e565b600060405180830381600087803b15801561275657600080fd5b505af115801561276a573d6000803e3d6000fd5b5050600954604051632e1a7d4d60e01b81526001600160a01b039091169250632e1a7d4d915061279e908590600401614262565b600060405180830381600087803b1580156127b857600080fd5b505af11580156127cc573d6000803e3d6000fd5b5050505050505b5050565b6127f46127e2612cfb565b6101608401519063ffffffff612cc116565b6127fd57600080fd5b81608001518260a001511461281157600080fd5b60008061282284610140015161076b565b9150915060008060008061283585610b06565b93509350935093506000846001600160a01b031663bad84c9e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561287857600080fd5b505afa15801561288c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506128b09190810190613c3f565b90506128bc8589611fe0565b6128d85760405162461bcd60e51b8152600401611e079061443e565b6001600160a01b03871630146128ed57600080fd5b505050505050505050565b6129006131ab565b604051606090634da26aab60e11b9061292190889088908890602401614645565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925260075491519092506000916060916001600160a01b0390911690869061297a908690613fe2565b60006040518083038185875af1925050503d80600081146129b7576040519150601f19603f3d011682016040523d82523d6000602084013e6129bc565b606091505b509150915081156129e657805160a0146129d257fe5b80806020019051611d139190810190613aff565b505050949350505050565b60006129fb6131fa565b612a0487611d1f565b9050612a108787612287565b612a1e57600091505061095e565b826001600160a01b031687600001516001600160a01b03161415612a45578591505061095e565b600080600460009054906101000a90046001600160a01b03166001600160a01b031663f5df1f24846000015185604001518660200151876060015160ff166001811115612a8e57fe5b8e600001518e8e8e8e6040518a63ffffffff1660e01b8152600401612abb99989796959493929190614353565b6040805180830381600087803b158015612ad457600080fd5b505af1158015612ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612b0c9190810190613d08565b9092509050612b21888363ffffffff612b3d16565b9350612b31898487898886612d32565b50505095945050505050565b600082821115612b4c57600080fd5b50900390565b600080600080600860009054906101000a90046001600160a01b03166001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612ba657600080fd5b505afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bde9190810190613bd3565b92509250925061095e85600960149054906101000a900460ff16612c025783612c04565b845b6001600160701b0316600960149054906101000a900460ff16612c275785612c29565b845b6001600160701b0316611f42565b60005460ff1615612c4757600080fd5b6000805460ff19166001179055565b606081831115612c6557600080fd5b8351821115612c7357600080fd5b8282036040519080825280601f01601f191660200182016040528015612ca0576020820181803883390190505b5090506125da612caf8261306c565b84612cb98761306c565b018351613072565b6000815183511480156125da575081805190602001208380519060200120149392505050565b6000818381612cf257fe5b06159392505050565b6040805160008082526020820181815282840191825260608084019094529063a7cb5fb760e01b61257930858585608483016140af565b600754604051639d3fa4b960e01b81526000916001600160a01b031690639d3fa4b990612d63908a90600401614610565b60606040518083038186803b158015612d7b57600080fd5b505afa158015612d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612db39190810190613b1a565b6020015160408051600280825260608281019093529293509091816020016020820280388339505060408051600a8082526101608201909252929350606092915060208201610140803883390190505090506000886060015160ff166001811115612e1a57fe5b9050896000015183600081518110612e2e57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508783600181518110612e5c57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050886020015182600081518110612e8e57fe5b602002602001018181525050600082600181518110612ea957fe5b602002602001018181525050886040015160ff1682600281518110612eca57fe5b6020026020010181815250508482600581518110612ee457fe5b6020026020010181815250508582600681518110612efe57fe5b602002602001018181525050600082600881518110612f1957fe5b602002602001018181525050600082600981518110612f3457fe5b602002602001018181525050600360009054906101000a90046001600160a01b03166001600160a01b03166399b537a08a600001516001600160a01b031663870c426d6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa157600080fd5b505afa158015612fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612fd99190810190613612565b8b51878b866001811115612fe957fe5b89896040518863ffffffff1660e01b815260040161300d97969594939291906143b8565b602060405180830381600087803b15801561302757600080fd5b505af115801561303b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061305f9190810190613a9f565b5050505050505050505050565b60200190565b602081101561309c576001816020036101000a038019835116818551168082178652505050613113565b828214156130a957613113565b828211156130e35760208103905080820181840181515b828510156130db5784518652602095860195909401936130c0565b905250613113565b60208103905080820181840183515b8186121561310e5782518252601f1992830192909101906130f2565b855250505b505050565b604051806101c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b803561082b81614744565b60008083601f84011261323d578182fd5b5081356001600160401b03811115613253578182fd5b602083019150836020808302850101111561326d57600080fd5b9250929050565b600082601f830112613284578081fd5b8151613297613292826146d2565b6146ac565b818152915060208083019084810160005b84811015610825578151870188603f8201126132c357600080fd5b838101516132d3613292826146f1565b8181528a60408385010111156132e857600080fd5b6132f88287830160408601614714565b8652505092820192908201906001016132a8565b600082601f83011261331c578081fd5b813561332a613292826146d2565b8181529150602080830190840160005b8381101561336757613352876020843589010161340b565b8352602092830192919091019060010161333a565b5050505092915050565b600082601f830112613381578081fd5b813561338f613292826146d2565b8181529150602080830190840160005b83811015613367576133b787602084358901016134a8565b8352602092830192919091019060010161339f565b60008083601f8401126133dd578182fd5b5081356001600160401b038111156133f3578182fd5b60208301915083602082850101111561326d57600080fd5b600082601f83011261341b578081fd5b8135613429613292826146f1565b915080825283602082850101111561344057600080fd5b8060208401602084013760009082016020015292915050565b600060a0828403121561346a578081fd5b61347460a06146ac565b9050815181526020820151602082015260408201516040820152606082015160608201526080820151608082015292915050565b60006101c08083850312156134bb578182fd5b6134c4816146ac565b9150506134d18383613221565b81526134e08360208401613221565b60208201526134f28360408401613221565b60408201526135048360608401613221565b60608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e0820152610100808301358183015250610120808301358183015250610140808301356001600160401b038082111561356557600080fd5b6135718683870161340b565b8385015261016092508285013591508082111561358d57600080fd5b6135998683870161340b565b838501526101809250828501359150808211156135b557600080fd5b6135c18683870161340b565b838501526101a09250828501359150808211156135dd57600080fd5b506135ea8582860161340b565b82840152505092915050565b600060208284031215613607578081fd5b81356125da81614744565b600060208284031215613623578081fd5b81516125da81614744565b60008060408385031215613640578081fd5b823561364b81614744565b9150602083013561365b81614744565b809150509250929050565b60008060008060008060008060a0898b031215613681578384fd5b883561368c81614744565b9750602089013561369c81614744565b965060408901356001600160401b03808211156136b7578586fd5b6136c38c838d0161322c565b909850965060608b01359150808211156136db578586fd5b6136e78c838d0161322c565b909650945060808b01359150808211156136ff578384fd5b5061370c8b828c016133cc565b999c989b5096995094979396929594505050565b60008060008060008060a08789031215613738578384fd5b863561374381614744565b9550602087013561375381614744565b9450604087013593506060870135925060808701356001600160401b0381111561377b578283fd5b61378789828a016133cc565b979a9699509497509295939492505050565b600080604083850312156137ab578182fd5b82356137b681614744565b9150602083013561365b8161475c565b600080600080608085870312156137db578182fd5b84356137e681614744565b935060208501356137f681614744565b925060408501356138068161477f565b9396929550929360600135925050565b60008060408385031215613828578182fd5b823561383381614744565b946020939093013593505050565b60008060008060808587031215613856578182fd5b843561386181614744565b93506020850135925060408501356138788161477f565b915060608501356138888161477f565b939692955090935050565b600080600080600080600080610100898b0312156138af578182fd5b88356138ba81614744565b975060208901356138ca8161477f565b9650604089013595506060890135945060808901356138e881614744565b935060a08901356138f88161477f565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806040858703121561392a578182fd5b84356001600160401b0380821115613940578384fd5b61394c8883890161322c565b90965094506020870135915080821115613964578384fd5b506139718782880161322c565b95989497509550505050565b600080600060608486031215613991578081fd5b83356001600160401b03808211156139a7578283fd5b6139b387838801613371565b945060208601359150808211156139c8578283fd5b506139d58682870161330c565b925050604084013590509250925092565b600080604083850312156139f8578182fd5b82516001600160401b0380821115613a0e578384fd5b81850186601f820112613a1f578485fd5b80519250613a2f613292846146d2565b80848252602080830192508084018a828389028701011115613a4f578889fd5b8894505b86851015613a71578051845260019490940193928101928101613a53565b508801519096509350505080821115613a88578283fd5b50613a9585828601613274565b9150509250929050565b600060208284031215613ab0578081fd5b81516125da8161475c565b600060208284031215613acc578081fd5b81356001600160401b03811115613ae1578182fd5b6120778482850161340b565b60008060408385031215613640578182fd5b600060a08284031215613b10578081fd5b6125da8383613459565b600060608284031215613b2b578081fd5b613b3560606146ac565b8251613b408161477f565b8152602083810151908201526040928301519281019290925250919050565b600060208284031215613b70578081fd5b81356001600160401b03811115613b85578182fd5b612077848285016134a8565b60008060408385031215613ba3578182fd5b82356001600160401b03811115613bb8578283fd5b613bc4858286016134a8565b95602094909401359450505050565b600080600060608486031215613be7578081fd5b8351613bf28161476a565b6020850151909350613c038161476a565b604085015190925063ffffffff81168114613c1c578182fd5b809150509250925092565b600060208284031215613c38578081fd5b5035919050565b600060208284031215613c50578081fd5b5051919050565b600080600080600080600060e0888a031215613c71578081fd5b873596506020880135955060408801359450606088013593506080880135925060a08801356001600160401b0380821115613caa578283fd5b613cb68b838c01613371565b935060c08a0135915080821115613ccb578283fd5b50613cd88a828b0161330c565b91505092959891949750929550565b60008060408385031215613cf9578182fd5b50508035926020909101359150565b60008060408385031215613d1a578182fd5b505080516020909101519092909150565b600080600060608486031215613d3f578081fd5b505081359360208301359350604090920135919050565b600080600080600080600060e0888a031215613d70578081fd5b8735613d7b8161477f565b965060208801359550604088013594506060880135613d9981614744565b93506080880135613da98161477f565b9699959850939692959460a0840135945060c09093013592915050565b6001600160a01b0316815260200190565b6001600160a01b03169052565b81835260006001600160fb1b03831115613dfc578081fd5b6020830280836020870137939093016020019283525090919050565b6000815180845260208401935060208301825b82811015613e49578151865260209586019590910190600101613e2b565b5093949350505050565b60008151808452613e6b816020860160208601614714565b601f01601f19169290920160200192915050565b60006101c0613e8f848451613dd7565b6020830151613ea16020860182613dd7565b506040830151613eb46040860182613dd7565b506060830151613ec76060860182613dd7565b506080830151608085015260a083015160a085015260c083015160c085015260e083015160e0850152610100808401518186015250610120808401518186015250610140808401518282870152613f2083870182613e53565b91505061016091508184015185820383870152613f3d8282613e53565b925050506101808084015185830382870152613f598382613e53565b9150506101a091508184015185820383870152611fb88282613e53565b60609490941b6bffffffffffffffffffffffff1916845260b09290921b6001600160b01b031916601484015260f890811b6001600160f81b0319908116601e85015291901b16601f82015260200190565b93845260208401929092526040830152606082015260800190565b60008251613ff4818460208701614714565b9190910192915050565b90565b6c08a92a06e626488dedac2d2dc5609b1b81526b1cdd1c9a5b99c81b985b594b60a21b600d8201526e1cdd1c9a5b99c81d995c9cda5bdb8b608a1b60198201527f6164647265737320766572696679696e67436f6e7472616374000000000000006028820152602960f81b604182015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03851681526080602082018190526000906140d390830186613e18565b82810360408401526140e58186613e18565b8381036060850152611d138186613e53565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039889168152968816602088015294909616604086015260ff9283166060860152608085019190915260a084015290921660c082015260e08101919091526101000190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03949094168452602084019290925260ff908116604084015216606082015260800190565b6000604082526141b6604083018688613de4565b82810360208401526141c9818587613de4565b979650505050505050565b6000602082526125da6020830184613e18565b6000604082526141fa6040830185613e18565b602083820381850152818551808452828401915082838202850101838801865b8381101561424857601f19878403018552614236838351613e53565b9486019492509085019060010161421a565b50909998505050505050505050565b901515815260200190565b90815260200190565b6001600160e01b031991909116815260200190565b6001600160e01b0319861681526001600160a01b038516602082015260a0604082018190526000906142b490830186613e18565b82810360608401526142c68186613e18565b83810360808501526142d88186613e53565b9998505050505050505050565b6000602082526125da6020830184613e53565b600060018060a01b0380861683526060602084015261431a6060840186613e18565b9150808416604084015250949350505050565b6001600160a01b03938416815260ff929092166020830152909116604082015260600190565b6001600160a01b038a8116825260ff8a166020830152604082018990526101208201906002891061438057fe5b88606084015280881660808401528660a08401528560c08401528460e0840152808416610100840152509a9950505050505050505050565b600060e0820160018060a01b03808b168452808a1660208501525087604084015286606084015260ff8616608084015260e060a08401528085516143fc8184614262565b9150602087019250835b8181101561442a57614419838551613dc6565b602094909401939250600101614406565b505083810360c0850152610ce38186613e18565b60208082526036908201527f4f72646572206d7573742062652061206d756c7469706c65206f6620746865206040820152751b585c9ad95d081d1c985919481a5b98dc995b595b9d60521b606082015260800190565b63086c2e6d60e31b815260200190565b64574554483960d81b815260200190565b6929b430b932aa37b5b2b760b11b815260200190565b682334b63627b93232b960b91b815260200190565b6f556e69737761705632466163746f727960801b815260200190565b6c5a65726f5845786368616e676560981b815260200190565b60208082526049908201527f436f7374206f662070757263686173696e672045544820746f20636f7665722060408201527f70726f746f636f6c20466565206f6e207468652065786368616e676520776173606082015268040e8dede40d0d2ced60bb1b608082015260a00190565b6020808252600d908201526c139bdd081cdd5c1c1bdc9d1959609a1b604082015260600190565b6020808252600e908201526d15d493d391d7d41493d61657d25160921b604082015260600190565b81516001600160a01b031681526020808301519082015260408083015160ff90811691830191909152606092830151169181019190915260800190565b6000602082526125da6020830184613e7f565b6000604082526146366040830185613e7f565b90508260208301529392505050565b6000606082526146586060830186613e7f565b8460208401528281036040840152611fb88185613e53565b918252602082015260400190565b92835260208301919091526001600160a01b0316604082015260806060820181905260009082015260a00190565b6040518181016001600160401b03811182821017156146ca57600080fd5b604052919050565b60006001600160401b038211156146e7578081fd5b5060209081020190565b60006001600160401b03821115614706578081fd5b50601f01601f191660200190565b60005b8381101561472f578181015183820152602001614717565b8381111561473e576000848401525b50505050565b6001600160a01b038116811461475957600080fd5b50565b801515811461475957600080fd5b6001600160701b038116811461475957600080fd5b60ff8116811461475957600080fdfea365627a7a723158209038d4e8a8c7fe935f8ee4cc5d68a9ae777dfeb32839253038dcc9376cd96e486c6578706572696d656e74616cf564736f6c634300050f0040

Deployed Bytecode Sourcemap

55760:31054:1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84455:367;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;84455:367:1;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;60947:617;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;60947:617:1;;;;;;;;:::i;:::-;;;;;;;;74267:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74267:104:1;;;:::i;:::-;;;;;;;;63116:262;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63116:262:1;;;;;;;;:::i;78535:459::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;78535:459:1;;;;;;;;:::i;74775:802::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;74775:802:1;;;;;;;;:::i;:::-;;;;;;;;79000:615;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;79000:615:1;;;;;;;;:::i;:::-;;;;;;;;;;;61666:970;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61666:970:1;;;;;;;;:::i;60476:246::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;60476:246:1;;;;;;;;:::i;64929:1855::-;;;;;;;;;:::i;68187:319::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68187:319:1;;;;;;;;:::i;57976:1416::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57976:1416:1;;;;;;;;:::i;86439:336::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;86439:336:1;;;;;;;;:::i;63617:315::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63617:315:1;;;;;;;;:::i;:::-;;;;;;;;70195:1503;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;70195:1503:1;;;;;;;;:::i;57883:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57883:33:1;;;:::i;:::-;;;;;;;;57761:27;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57761:27:1;;;:::i;62642:468::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;62642:468:1;;;;;;;;:::i;83916:533::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;83916:533:1;;;;;;;;:::i;:::-;;;;;;;;57817:29;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57817:29:1;;;:::i;57697:19::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57697:19:1;;;:::i;57945:24::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57945:24:1;;;:::i;80317:1480::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;80317:1480:1;;;;;;;;:::i;:::-;;;;;;;;;;;;68826:372;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68826:372:1;;;;;;;;:::i;57722:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57722:33:1;;;:::i;57794:17::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57794:17:1;;;:::i;69914:275::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;69914:275:1;;;;;;;;:::i;63938:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63938:109:1;;;;;;;;:::i;56585:68::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56585:68:1;;;:::i;:::-;;;;;;;;57922:17;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57922:17:1;;;:::i;84828:322::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;84828:322:1;;;;;;;;:::i;82497:1413::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;82497:1413:1;;;;;;;;:::i;61570:90::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61570:90:1;;;;;;;;:::i;57852:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57852:25:1;;;:::i;85528:905::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;85528:905:1;;;;;;;;:::i;:::-;;;;;;;;;74017:244;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;74017:244:1;;;;;;;;:::i;57657:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57657:33:1;;;:::i;64053:116::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64053:116:1;;;;;;;;:::i;12336:88::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12336:88:1;;;:::i;59832:216::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;59832:216:1;;;;;;;;:::i;85156:366::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;85156:366:1;;;;;;;;:::i;84455:367::-;84533:15;84550:16;84579:20;84601:21;84624:26;84652:29;84683:26;84713:27;84729:10;84713:15;:27::i;:::-;84578:162;;;;;;;;;;84761:9;84771:1;84761:12;;;;;;;;;;;;;;84750:23;;84801:13;84783:32;;84455:367;;;;;;;;:::o;60947:617::-;61016:7;61036:15;61053:14;61069;61085:11;61100:17;61114:2;61100:13;:17::i;:::-;61035:82;;;;;;;;61259:22;61296:5;61284:18;;;;;;;;;;61259:43;-1:-1:-1;61330:15:1;61316:10;:29;;;;;;;;;61312:246;;;61368:53;61379:5;61394:7;61404:8;61414:6;61368:10;:53::i;:::-;61361:60;;;;;;;;;61312:246;61456:15;61442:10;:29;;;;;;;;;61438:120;;;61494:53;61505:5;61520:7;61530:8;61540:6;61494:10;:53::i;61438:120::-;60947:617;;;;;;;;;;:::o;74267:104::-;74322:4;74345:19;;;;;;;74267:104::o;63116:262::-;63246:4;;:22;;-1:-1:-1;;;63246:22:1;;63208:7;;;;-1:-1:-1;;;;;63246:4:1;;;;:14;;:22;;63261:6;;63246:22;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63246:22:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63246:22:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63246:22:1;;;;;;;;;63299:4;;:31;;-1:-1:-1;;;63299:31:1;;63227:41;;-1:-1:-1;63278:18:1;;-1:-1:-1;;;;;63299:4:1;;;;:14;;:31;;63314:6;;63322:7;;63299:31;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63299:31:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63299:31:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63299:31:1;;;;;;;;;63278:52;-1:-1:-1;63347:24:1;:8;63278:52;63347:24;:12;:24;:::i;:::-;63340:31;63116:262;-1:-1:-1;;;;;63116:262:1:o;78535:459::-;78638:16;78807:26;78853:7;78869:6;78878:8;78888:5;78836:58;;;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;78836:58:1;;;49:4:-1;78945:32:1;78939:39;;78913:75;-1:-1:-1;;;;;;78913:75:1:o;74775:802::-;75018:14;;;75030:1;75018:14;;;;;;;;;74945:23;;;;75018:14;;;;;;;;;;;;;;;;;;-1:-1:-1;;75079:16:1;;;75093:1;75079:16;;;;;;;;;74984:48;;-1:-1:-1;75042:34:1;;75079:16;;;;75042:34;;105:10:-1;75079:16:1;88:34:-1;136:17;;-1:-1;75079:16:1;75042:53;;75127:54;75148:7;75157:6;75165:8;75175:5;75127:20;:54::i;:::-;75105:16;75122:1;75105:19;;;;;;;;;;;;;:76;;;;75213:21;:19;:21::i;:::-;75191:16;75208:1;75191:19;;;;;;;;;;;;;:43;;;;75266:22;:20;:22::i;:::-;75244:16;75261:1;75244:19;;;;;;;;;;;;;:44;;;;75321:1;75298:17;75316:1;75298:20;;;;;;;;;;;;;:24;;;;;75355:1;75332:17;75350:1;75332:20;;;;;;;;;;;;;:24;;;;;75389:1;75366:17;75384:1;75366:20;;;;;;;;;;;;;:24;;;;;75400:18;56123:10;75457:20;;75491:17;75522:16;75421:127;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;75421:127:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;75421:127:1;;;179:29:-1;;;;160:49;;;75421:127:1;-1:-1:-1;;;;74775:802:1;;;;;;:::o;79000:615::-;79172:2;79168:90;;;;79281:91;79285:2;79281:91;;;;;79397:89;79401:1;79397:89;;;;;;79518:81;;;79143:466::o;61666:970::-;61772:7;61791:25;61819:7;-1:-1:-1;;;;;61819:27:1;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61819:29:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61819:29:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;61819:29:1;;;;;;;;;61791:57;;61957:31;62025:1;62005:17;:21;61991:36;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;61991:36:1;-1:-1:-1;61957:70:1;-1:-1:-1;62037:21:1;;62072:224;62118:1;62098:17;:21;62093:2;:26;62072:224;;;62151:8;62145:14;;:2;:14;62141:68;;;62179:15;;;;;62141:68;62243:13;62222:14;62237:2;62222:18;;;;;;;;;;;;;;;;;:34;62270:15;;;;;62121:4;62072:224;;;-1:-1:-1;62333:10:1;;:73;;-1:-1:-1;;;62333:73:1;;62306:24;;-1:-1:-1;;;;;62333:10:1;;:40;;:73;;62374:7;;62383:14;;62399:6;;62333:73;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62333:73:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62333:73:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62333:73:1;;;;;;;;;62487:9;;62306:100;;-1:-1:-1;62417:22:1;;62442:56;;62471:6;;-1:-1:-1;;;;;62487:9:1;62442:28;:56::i;:::-;62417:81;-1:-1:-1;62508:30:1;62541:26;62417:81;62560:6;62541:26;:18;:26;:::i;:::-;62508:59;-1:-1:-1;62585:44:1;:16;62508:59;62585:44;:20;:44;:::i;:::-;62578:51;61666:970;-1:-1:-1;;;;;;;;;;;61666:970:1:o;60476:246::-;60632:19;;;;;;;60624:28;;;;;;60699:2;-1:-1:-1;;;;;60667:48:1;60693:4;-1:-1:-1;;;;;60667:48:1;60681:10;-1:-1:-1;;;;;60667:48:1;;60703:3;;60708:6;;60667:48;;;;;;;;;;;;;;;;;;60476:246;;;;;;;;:::o;64929:1855::-;65239:7;65287:1;65270:7;:14;:18;65262:27;;;;;;65299:28;65361:26;;-1:-1:-1;;65361:26:1;;;;;65421:8;;:32;;;-1:-1:-1;;;65421:32:1;;;;65330:20;;65299:28;65421:49;;65458:11;;-1:-1:-1;;;;;65421:8:1;;;;:30;;:32;;;;;;;;;;;;;;;:8;:32;;;5:2:-1;;;;30:1;27;20:12;5:2;65421:32:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65421:32:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;65421:32:1;;;;;;;;;:36;:49;:36;:49;:::i;:::-;65398:72;-1:-1:-1;65480:66:1;65497:28;65398:72;65514:10;65497:28;:16;:28;:::i;:::-;65527:18;65480:16;:66::i;:::-;65603:9;65598:940;65622:7;:14;65618:1;:18;:47;;;;-1:-1:-1;65640:25:1;;;65618:47;65598:940;;;65686:29;;:::i;:::-;65718:7;65726:1;65718:10;;;;;;;;;;;;;;65686:42;;65742:43;65756:6;65764:20;65742:13;:43::i;:::-;65906:45;;:::i;:::-;65954:154;65988:6;66012:20;66050:11;66062:1;66050:14;;;;;;;;;;;;;;66082:12;65954:16;:154::i;:::-;65906:202;;66127:16;:39;;;66170:1;66127:44;66123:91;;;66191:8;;;;66123:91;66228:21;66252:97;66260:6;66268:16;:39;;;66309:12;66323:13;66338:10;66252:7;:97::i;:::-;66228:121;-1:-1:-1;66387:39:1;:20;66228:121;66387:39;:24;:39;:::i;:::-;-1:-1:-1;;66440:15:1;;;;66364:62;-1:-1:-1;66473:15:1;66469:59;;66508:5;;;;;66469:59;65598:940;;;;65667:3;;65598:940;;;-1:-1:-1;66570:5:1;66548:27;;-1:-1:-1;;66548:27:1;;;66590:21;:25;66586:154;;66632:13;66650:10;-1:-1:-1;;;;;66650:15:1;66672:21;66650:48;;;;;;;;;;;;;;;;;;;;;;;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;;66631:67:1;;;66720:8;66712:17;;;;;;66586:154;;-1:-1:-1;66757:20:1;64929:1855;-1:-1:-1;;;;;;;;64929:1855:1:o;68187:319::-;68286:7;68305:20;68328:47;68365:9;68328:8;;;;;;;;;-1:-1:-1;;;;;68328:8:1;-1:-1:-1;;;;;68328:30:1;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;68328:47:1;68305:70;-1:-1:-1;68385:26:1;68414:28;68305:70;68431:10;68414:28;:16;:28;:::i;:::-;68385:57;;68459:40;68480:18;68459:20;:40::i;57976:1416::-;12203:11;;;;12202:12;12194:21;;;;;;58075:19;:17;:19::i;:::-;58104:5;:14;;-1:-1:-1;;;;;58104:14:1;;;-1:-1:-1;;;;;;58104:14:1;;;;;;;;58128:12;:28;;;;;;;;;;;;58179:21;;-1:-1:-1;;;58179:21:1;;:13;;:21;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58179:21:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58179:21:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58179:21:1;;;;;;;;;58166:4;:35;;-1:-1:-1;;;;;;58166:35:1;-1:-1:-1;;;;;58166:35:1;;;;;;;;58219:4;58211:25;;;;;;58271:27;;-1:-1:-1;;;58271:27:1;;-1:-1:-1;;;;;58271:13:1;;;;;:27;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58271:27:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58271:27:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58271:27:1;;;;;;;;;58246:10;:53;;-1:-1:-1;;;;;;58246:53:1;-1:-1:-1;;;;;58246:53:1;;;;;;;;58317:10;58309:37;;;;;;58377;;-1:-1:-1;;;58377:37:1;;-1:-1:-1;;;;;58377:20:1;;;;;:37;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58377:37:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58377:37:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58377:37:1;;;;;;;;;58356:8;:59;;-1:-1:-1;;;;;;58356:59:1;-1:-1:-1;;;;;58356:59:1;;;;;;;;58433:8;58425:33;;;;;;58491;;-1:-1:-1;;;58491:33:1;;-1:-1:-1;;;;;58491:20:1;;;;;:33;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58491:33:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58491:33:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58491:33:1;;;;;;;;;58468:9;:57;;-1:-1:-1;;;;;;58468:57:1;-1:-1:-1;;;;;58468:57:1;;;;;;;;58543:9;58535:35;;;;;;58593:29;;-1:-1:-1;;;58593:29:1;;-1:-1:-1;;;;;58593:20:1;;;;;:29;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58593:29:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58593:29:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58593:29:1;;;;;;;;;58580:4;:43;;-1:-1:-1;;;;;;58580:43:1;-1:-1:-1;;;;;58580:43:1;;;;;;58687:33;;-1:-1:-1;;;58687:33:1;;-1:-1:-1;;58687:13:1;;;;;:33;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58687:33:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58687:33:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58687:33:1;;;;;;;;;58793:4;;58808;;58761:53;;-1:-1:-1;;;58761:53:1;;58633:88;;-1:-1:-1;58731:27:1;;-1:-1:-1;;;;;58761:23:1;;;;;;:53;;58793:4;;;;58808;;58761:53;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58761:53:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58761:53:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58761:53:1;;;;;;;;;58731:83;-1:-1:-1;;;;;;58828:33:1;;58824:142;;58934:4;;58949;;58899:56;;-1:-1:-1;;;58899:56:1;;-1:-1:-1;;;;;58899:26:1;;;;;;:56;;58934:4;;;;58949;;58899:56;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58899:56:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58899:56:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58899:56:1;;;;;;;;;58877:78;;58824:142;58975:11;:49;;-1:-1:-1;;;;;;58975:49:1;-1:-1:-1;;;;;58975:49:1;;;;;;;;;;;59081:4;;59049:20;;;-1:-1:-1;;;59049:20:1;;;;59081:4;;;;59049:11;;;;:18;;:20;;;;;;;;;;;;;;:11;:20;;;5:2:-1;;;;30:1;27;20:12;5:2;59049:20:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59049:20:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;59049:20:1;;;;;;;;;-1:-1:-1;;;;;59049:37:1;;59034:12;;:52;;;;;;;;;;;;;;;;;;56793:148;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;56793:148:1;;;56774:168;;49:4:-1;56774:168:1;;;;59244:18;;;;;;;;-1:-1:-1;;;59244:18:1;;;;;;;59298:21;;;;;;;;;;-1:-1:-1;;;59298:21:1;;;;59141:234;;;;56774:168;59228:36;;59282:39;;59355:4;;59141:234;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;59141:234:1;;;59118:267;;49:4:-1;59118:267:1;;;;59097:18;:288;-1:-1:-1;;;;57976:1416:1:o;86439:336::-;86598:20;56643:10;86677:32;;86723:11;86748:10;86641:127;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;86641:127:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;86641:127:1;;;179:29:-1;;;;160:49;;;86641:127:1;-1:-1:-1;86439:336:1;;;;:::o;63617:315::-;63765:28;;;;;;;;;;;;;;;;63715:26;;63779:6;63765:28;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;63765:28:1;-1:-1:-1;63753:40:1;-1:-1:-1;63808:10:1;63803:123;63824:18;;;63803:123;;;63880:4;:14;63895:6;;63902:2;63895:10;;;;;;;;;;;;;;;;;;;;;;63907:3;;63911:2;63907:7;;;;;;;;;;;;;63880:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63880:35:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63880:35:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63880:35:1;;;;;;;;;63864:9;63874:2;63864:13;;;;;;;;;;;;;;;;;:51;63844:4;;63803:123;;;;63617:315;;;;;;:::o;70195:1503::-;70323:4;70365:11;:18;70347:7;:14;:36;70339:45;;;;;;70394:20;70417:49;70454:11;70417:8;;;;;;;;;-1:-1:-1;;;;;70417:8:1;-1:-1:-1;;;;;70417:30:1;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;70417:49:1;70394:72;;70476:70;70493:32;70510:7;:14;70493:12;:16;;:32;;;;:::i;:::-;70527:18;70476:16;:70::i;:::-;70556:19;:26;;-1:-1:-1;;70556:26:1;;;;;70592:879;70616:7;:14;70612:1;:18;70592:879;;;70651:29;;:::i;:::-;70683:7;70691:1;70683:10;;;;;;;;;;;;;;70651:42;;70707:23;70733:11;70745:1;70733:14;;;;;;;;;;;;;;70707:40;;70783:6;:19;;;-1:-1:-1;;;;;70769:33:1;:10;-1:-1:-1;;;;;70769:33:1;;70761:42;;;;;;70817:37;;:::i;:::-;70857:8;;:29;;-1:-1:-1;;;70857:29:1;;-1:-1:-1;;;;;70857:8:1;;;;:21;;:29;;70879:6;;70857:29;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70857:29:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70857:29:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;70857:29:1;;;;;;;;;70817:69;;70900:24;70927:67;70955:10;:38;;;70927:6;:23;;;:27;;:67;;;;:::i;:::-;71008:8;;:76;;-1:-1:-1;;;71008:76:1;;70900:94;;-1:-1:-1;;;;;;71008:8:1;;:18;;71033:12;;71008:76;;71047:6;;70900:94;;71073:10;;71008:76;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71008:76:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71008:76:1;;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71008:76:1;;;;;;;;;;71098:32;;:::i;:::-;71133:22;71148:6;71133:14;:22::i;:::-;71098:57;;71169:19;71199:10;:24;;;-1:-1:-1;;;;;71191:45:1;;:47;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71191:47:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71191:47:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71191:47:1;;;;;;;;;71252:12;;71307:24;;71333:19;;71354:18;;;;;71374:16;;;;;71416:20;;;;71439;;;;71252:208;;-1:-1:-1;;;71252:208:1;;71169:69;;-1:-1:-1;;;;;;71252:12:1;;;;:34;;:208;;71169:69;;71307:24;;71333:19;;71354:18;71374:16;;71392;;71416:20;71439;71252:208;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71252:208:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;70632:3:1;;;;;-1:-1:-1;70592:879:1;;-1:-1:-1;;;;;;;70592:879:1;;-1:-1:-1;71502:5:1;71480:27;;-1:-1:-1;;71480:27:1;;;71521:21;:25;71517:154;;71563:13;71581:10;-1:-1:-1;;;;;71581:15:1;71603:21;71581:48;;;;;;;;;;;;;;;;;;;;;;;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;;71562:67:1;;;71651:8;71643:17;;;;;;71517:154;;-1:-1:-1;71687:4:1;;70195:1503;-1:-1:-1;;;;70195:1503:1:o;57883:33::-;;;-1:-1:-1;;;;;57883:33:1;;:::o;57761:27::-;;;-1:-1:-1;;;;;57761:27:1;;:::o;62642:468::-;62794:10;;:60;;-1:-1:-1;;;62794:60:1;;62748:7;;;;-1:-1:-1;;;;;62794:10:1;;;;:33;;:60;;62828:7;;62837:8;;62847:6;;62794:60;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62794:60:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62794:60:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62794:60:1;;;;;;;;;62934:9;;62767:87;;-1:-1:-1;62864:22:1;;62889:56;;62918:6;;-1:-1:-1;;;;;62934:9:1;62889:28;:56::i;:::-;62864:81;;62955:30;62988:53;63007:33;63033:6;63007:7;-1:-1:-1;;;;;63007:19:1;;:21;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63007:21:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63007:21:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63007:21:1;;;;;;;;;:25;:33;:25;:33;:::i;:::-;62988:14;;:53;:18;:53;:::i;:::-;62955:86;-1:-1:-1;63059:44:1;:16;62955:86;63059:44;:20;:44;:::i;:::-;63052:51;62642:468;-1:-1:-1;;;;;;;;62642:468:1:o;83916:533::-;83992:27;;:::i;:::-;84032:20;84054:21;84077:26;84105:29;84136:26;84166:38;84182:6;:21;;;84166:15;:38::i;:::-;84031:173;;;;;;;;;;84215:15;84232:14;84248;84264:11;84279:27;84293:9;84303:1;84293:12;;;;;;;;;;;;;;84279:13;:27::i;:::-;-1:-1:-1;;;;;84316:29:1;;;;;84355:11;;;:20;;;;84385:23;;;;:15;;;:23;84418:24;:13;;;:24;-1:-1:-1;84316:5:1;;83916:533;-1:-1:-1;;;;;;;;;83916:533:1:o;57817:29::-;;;-1:-1:-1;;;;;57817:29:1;;:::o;57697:19::-;;;-1:-1:-1;;;;;57697:19:1;;:::o;57945:24::-;;;-1:-1:-1;;;57945:24:1;;;;;:::o;80317:1480::-;80736:2;80720:19;;80714:26;-1:-1:-1;;;;;;80859:86:1;80425:20;80494:26;;;-1:-1:-1;;;80973:37:1;;80965:64;;;;-1:-1:-1;;;80965:64:1;;;;;;;;;;;;;;;;;81040:25;81075:31;81166:33;81202:38;81219:1;81222:10;:17;81202:10;:16;;:38;;;;;:::i;:::-;81166:74;;81293:20;81282:54;;;;;;;;;;;;;;81438:15;;81251:85;;-1:-1:-1;81251:85:1;-1:-1:-1;81457:1:1;81438:20;81430:29;;;;;;81481:8;81490:1;81481:11;;;;;;;;;;;;;;81496:1;81481:16;81473:25;;;;;;81520:8;81529:1;81520:11;;;;;;;;;;;;;;81535:1;81520:16;81512:25;;;;;;81559:8;81568:1;81559:11;;;;;;;;;;;;;;81574:1;81559:16;81551:25;;;;;;81598:49;81625:21;:19;:21::i;:::-;81598:16;81615:1;81598:19;;;;;;;;;;;;;;:26;;:49;;;;:::i;:::-;81590:58;;;;;;81670:50;81697:22;:20;:22::i;:::-;81670:16;81687:1;81670:19;;;;;;;:50;81662:59;;;;;;81749:41;81770:16;81787:1;81770:19;;;;;;;;;;;;;;81749:20;:41::i;:::-;81742:48;;;;-1:-1:-1;81742:48:1;;-1:-1:-1;81742:48:1;-1:-1:-1;81742:48:1;;-1:-1:-1;80317:1480:1;-1:-1:-1;;;;;80317:1480:1:o;68826:372::-;68917:13;68962:1;68950:9;:13;68942:22;;;;;;68994:1;68982:9;:13;:31;;;;;69012:1;68999:10;:14;68982:31;68974:40;;;;;;69024:14;69041:34;69070:4;69041:24;:9;69055;69041:24;:13;:24;:::i;:34::-;69024:51;-1:-1:-1;69085:16:1;69104:34;69134:3;69104:25;:10;69119:9;69104:25;:14;:25;:::i;:34::-;69085:53;;69159:32;69189:1;69172:11;69160:9;:23;;;;;;;69159:32;:29;:32;:::i;:::-;69148:43;68826:372;-1:-1:-1;;;;;;68826:372:1:o;57722:33::-;;;-1:-1:-1;;;;;57722:33:1;;:::o;57794:17::-;;;-1:-1:-1;;;;;57794:17:1;;:::o;69914:275::-;70074:5;;70043:81;;-1:-1:-1;;;70043:81:1;;70002:4;;;;-1:-1:-1;;;;;70074:5:1;;;;70043:72;;:81;;70116:7;;70043:81;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70043:81:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70043:81:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;70043:81:1;;;;;;;;;70018:106;-1:-1:-1;70141:41:1;:12;70018:106;70141:41;:25;:41;:::i;:::-;70134:48;69914:275;-1:-1:-1;;;;69914:275:1:o;63938:109::-;64017:23;;-1:-1:-1;;;64017:23:1;;;;;;;;56585:68;-1:-1:-1;;;56585:68:1;:::o;57922:17::-;;;-1:-1:-1;;;;;57922:17:1;;:::o;84828:322::-;84909:16;84938:20;84960:21;84983:26;85011:29;85042:26;85072:38;85088:6;:21;;;85072:15;:38::i;:::-;84937:173;;;;;;;;;;85131:9;85141:1;85131:12;;;;;;;;;;;;;;85120:23;;84828:322;;;;;;;;:::o;82497:1413::-;82921:2;82905:19;;82899:26;-1:-1:-1;;;;;;83044:86:1;82610:20;82679:26;;;-1:-1:-1;;;83158:33:1;;83150:60;;;;-1:-1:-1;;;83150:60:1;;;;;;;;;-1:-1:-1;;;;83418:2:1;83402:19;;;83505:17;83570:19;;;83564:26;83642:19;;;83636:26;83715:19;;;83709:26;82497:1413;;83505:17;;83548:43;;;;;;83620;;;;;;83693;;;;82497:1413::o;61570:90::-;-1:-1:-1;61626:7:1;;61570:90::o;57852:25::-;;;-1:-1:-1;;;;;57852:25:1;;:::o;85528:905::-;85724:34;;:::i;:::-;85760:18;85790:23;85816:58;85840:7;85850:6;85858:8;85868:5;85816:15;:58::i;:::-;85790:84;;85892:49;85919:7;85929:11;85892:18;:49::i;:::-;85884:116;;;;-1:-1:-1;;;85884:116:1;;;;;;;;;-1:-1:-1;;;;;86010:33:1;;;;86053:28;;;:42;;;86105:28;;;:42;;;86157:33;;;:58;;;86225:16;;;:24;;;86259:26;;;:39;;;86337:22;:20;:22::i;:::-;86308:26;;;:51;86382:8;;:34;;-1:-1:-1;;;86382:34:1;;-1:-1:-1;;;;;86382:8:1;;;;:21;;:34;;86308:11;;86382:34;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;86382:34:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;86382:34:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;86382:34:1;;;;;;;;;:44;;;86369:57;;85528:905;;;;;;;;;;;;:::o;74017:244::-;74119:4;74135:16;74154:27;74174:6;74154:19;:27::i;:::-;74224:19;;74209:45;;-1:-1:-1;;;74209:45:1;;74135:46;;-1:-1:-1;74209:4:1;;:14;;:45;;74135:46;;74209:45;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74209:45:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74209:45:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;74209:45:1;;;;;;;;;74198:56;;;;;74017:244;-1:-1:-1;;;74017:244:1:o;57657:33::-;;;;:::o;64053:116::-;64158:4;64053:116;;;;:::o;12336:88::-;12383:4;12406:11;;;12336:88;:::o;59832:216::-;59959:19;;;;;;;59951:28;;;;;;60027:2;-1:-1:-1;;;;;59994:47:1;60021:4;-1:-1:-1;;;;;59994:47:1;60009:10;-1:-1:-1;;;;;59994:47:1;;60031:2;60035:5;59994:47;;;;;;;;;;;;;;;;59832:216;;;;;;:::o;85156:366::-;85333:34;;:::i;:::-;85369:18;85406:109;85426:10;85438:5;85445:11;85458:6;85466:7;85475:8;85485:22;85509:5;85406:19;:109::i;:::-;85399:116;;;;85156:366;;;;;;;;;;:::o;21761:167::-;21819:7;21847:1;21842;:6;21838:84;;-1:-1:-1;21871:1:1;21864:8;;21838:84;-1:-1:-1;21910:1:1;21903:8;;75973:737;76217:16;;;76231:1;76217:16;;;;;;;;;76149:23;;;;76217:16;;;;;;;105:10:-1;76217:16:1;88:34:-1;-1:-1;;76275:16:1;;;76289:1;76275:16;;;;;;;;;76188:45;;-1:-1:-1;76243:29:1;;76275:16;-1:-1:-1;76275:16:1;;;;;;105:10:-1;76275:16:1;88:34:-1;136:17;;-1:-1;76275:16:1;76243:48;;76302:16;76321:53;76340:7;76350:6;76358:8;76368:5;76321:10;:53::i;:::-;76302:72;;76399:8;76384:9;76394:1;76384:12;;;;;;;;;;;;;:23;;;;;76435:1;76417:12;76430:1;76417:15;;;;;;;;;;;;;;;;;;:19;;;;76475:12;;;76485:1;76475:12;;;;;;;-1:-1:-1;;;76510:165:1;76584:4;76603:9;76626:12;76475;76510:165;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;76510:165:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;76510:165:1;;;179:29:-1;;;;160:49;;;76510:165:1;-1:-1:-1;;;;;75973:737:1;;;;;;:::o;76900:251::-;77101:4;;77029:87;;76977:23;;-1:-1:-1;;;77065:14:1;77029:87;;-1:-1:-1;;;;;77101:4:1;;77029:87;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;77029:87:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;77029:87:1;;;179:29:-1;;;;160:49;;;77029:87:1;-1:-1:-1;76900:251:1;:::o;77343:500::-;77489:16;;;77503:1;77489:16;;;;;;77547;;;;;;77602:12;;;77421:23;77602:12;;;;;;77711:10;;77489:16;;77547;-1:-1:-1;;;77673:16:1;77637:171;;-1:-1:-1;;;;;77711:10:1;77489:16;;77547;77637:171;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;77637:171:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;77637:171:1;;;179:29:-1;;;;160:49;;;77637:171:1;-1:-1:-1;;;;77343:500:1;:::o;21195:283::-;21253:7;21350:9;21366:1;21362;:5;;;;;;;21195:283;-1:-1:-1;;;;21195:283:1:o;21611:144::-;21669:7;21700:5;;;21723:6;;;;21715:15;;;;;;21747:1;21611:144;-1:-1:-1;;;21611:144:1:o;20768:421::-;20826:7;21066:6;21062:45;;-1:-1:-1;21095:1:1;21088:8;;21062:45;21129:5;;;21133:1;21129;:5;:1;21152:5;;;;;:10;21144:19;;;;;67513:668;67642:18;67618:21;:42;67614:561;;;67719:21;67698:42;;67676:19;67770:33;67698:42;67770:20;:33::i;:::-;67754:49;;67834:18;67825:5;:27;;67817:113;;;;-1:-1:-1;;;67817:113:1;;;;;;;;;67952:4;;67990:11;;67952:58;;-1:-1:-1;;;67952:58:1;;-1:-1:-1;;;;;67952:4:1;;;;:17;;:58;;67970:10;;67990:11;;;;68004:5;;67952:58;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67952:58:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67952:58:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;67952:58:1;;;;;;;;;67944:67;;;;;;68025:11;;68042:12;;-1:-1:-1;;;;;68025:11:1;;;;:16;;-1:-1:-1;;;68042:12:1;;;;:30;;68061:11;68042:30;;;68057:1;68042:30;68074:12;;-1:-1:-1;;;68074:12:1;;;;:30;;68103:1;68074:30;;;68089:11;68074:30;68114:4;68025:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68025:99:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;68138:4:1;;:26;;-1:-1:-1;;;68138:26:1;;-1:-1:-1;;;;;68138:4:1;;;;-1:-1:-1;68138:13:1;;-1:-1:-1;68138:26:1;;68152:11;;68138:26;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68138:26:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68138:26:1;;;;67614:561;;;67513:668;;:::o;69204:704::-;69320:52;69349:22;:20;:22::i;:::-;69320:21;;;;;:52;:28;:52;:::i;:::-;69312:61;;;;;;69418:6;:23;;;69391:6;:23;;;:50;69383:59;;;;;;69453:30;69485:21;69510:45;69533:6;:21;;;69510:22;:45::i;:::-;69452:103;;;;69566:15;69583:14;69599;69615:11;69630:28;69644:13;69630;:28::i;:::-;69565:93;;;;;;;;69668:17;69696:7;-1:-1:-1;;;;;69688:28:1;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69688:30:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69688:30:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;69688:30:1;;;;;;;;;69668:50;;69736:58;69763:7;69773:20;69736:18;:58::i;:::-;69728:125;;;;-1:-1:-1;;;69728:125:1;;;;;;;;;-1:-1:-1;;;;;69871:29:1;;69896:4;69871:29;69863:38;;;;;;69204:704;;;;;;;;;:::o;66790:717::-;66943:40;;:::i;:::-;67028:165;;66995:30;;-1:-1:-1;;;67064:40:1;67028:165;;67118:6;;67138:21;;67173:10;;67028:165;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;67028:165:1;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;67028:165:1;;;179:29:-1;;;;160:49;;;67259:8:1;;67251:61;;67028:165;;-1:-1:-1;;;67223:24:1;;-1:-1:-1;;;;;67259:8:1;;;;67280:12;;67251:61;;67028:165;;67251:61;;;;;;;;;;;;;;;;;;;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;;67204:108:1;;;;67326:11;67322:151;;;67360:11;:18;67382:3;67360:25;67353:33;;;;67425:11;67414:48;;;;;;;;;;;;;67322:151;-1:-1:-1;;;66790:717:1;;;;;;:::o;71704:1303::-;71847:21;71985:37;;:::i;:::-;72025:22;72040:6;72025:14;:22::i;:::-;71985:62;;72268:40;72292:6;72300:7;72268:23;:40::i;:::-;72263:80;;72331:1;72324:8;;;;;72263:80;72502:6;-1:-1:-1;;;;;72479:29:1;:6;:19;;;-1:-1:-1;;;;;72479:29:1;;72475:74;;;72531:7;72524:14;;;;;72475:74;72559:24;72585:13;72602:9;;;;;;;;;-1:-1:-1;;;;;72602:9:1;-1:-1:-1;;;;;72602:24:1;;72635:15;:29;;;72667:15;:23;;;72692:15;:21;;;72727:15;:25;;;72715:38;;;;;;;;;;72755:6;:19;;;72776:7;72785:12;72799:13;72814:6;72602:219;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72602:219:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72602:219:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;72602:219:1;;;;;;;;;72558:263;;-1:-1:-1;72558:263:1;-1:-1:-1;72847:29:1;:7;72558:263;72847:29;:11;:29;:::i;:::-;72831:45;;72886:84;72901:6;72909:15;72926:6;72934:13;72949;72964:5;72886:14;:84::i;:::-;-1:-1:-1;;;71704:1303:1;;;;;;;:::o;21484:121::-;21542:7;21574:1;21569;:6;;21561:15;;;;;;-1:-1:-1;21593:5:1;;;21484:121::o;68512:308::-;68584:7;68604:17;68623;68642:26;68672:11;;;;;;;;;-1:-1:-1;;;;;68672:11:1;-1:-1:-1;;;;;68672:23:1;;:25;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68672:25:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68672:25:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68672:25:1;;;;;;;;;68603:94;;;;;;68714:99;68726:10;68738:12;;;;;;;;;;;:36;;68765:9;68738:36;;;68753:9;68738:36;-1:-1:-1;;;;;68714:99:1;68776:12;;;;;;;;;;;:36;;68803:9;68776:36;;;68791:9;68776:36;-1:-1:-1;;;;;68714:99:1;:11;:99::i;12239:91::-;12203:11;;;;12202:12;12194:21;;;;;;12305:11;:18;;-1:-1:-1;;12305:18:1;12319:4;12305:18;;;12239:91::o;18365:669::-;18499:19;18679:2;18672:4;:9;18668:48;;;18697:8;;;18668:48;18734:1;:8;18729:2;:13;18725:52;;;18758:8;;;18725:52;18869:4;18864:2;:9;18854:20;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;18854:20:1;87:34:-1;135:17;;-1:-1;18854:20:1;;18845:29;;18884:120;18905:23;:6;:21;:23::i;:::-;18963:4;18942:18;:1;:16;:18::i;:::-;:25;18981:6;:13;18884:7;:120::i;12690:403::-;12811:10;13040:3;:10;13026:3;:10;:24;:60;;;;;13082:3;13072:14;;;;;;13064:3;13054:14;;;;;;:32;13019:67;12690:403;-1:-1:-1;;;12690:403:1:o;22681:107::-;22748:4;22775:1;22771;:5;;;;;;:10;;22681:107;-1:-1:-1;;;22681:107:1:o;78035:494::-;78181:16;;;78195:1;78181:16;;;;;;78239;;;;;;78294:12;;;78113:23;78294:12;;;;;;78181:16;-1:-1:-1;;;78329:165:1;78403:4;78181:16;;78239;78329:165;;;;;73013:998;73223:8;;:29;;-1:-1:-1;;;73223:29:1;;73202:18;;-1:-1:-1;;;;;73223:8:1;;:21;;:29;;73245:6;;73223:29;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73223:29:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73223:29:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73223:29:1;;;;;;;;;:39;;;73304:16;;;73318:1;73304:16;;;73272:29;73304:16;;;;;;73223:39;;-1:-1:-1;73272:29:1;;73304:16;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;;73362:17:1;;;73376:2;73362:17;;;;;;;;;73272:48;;-1:-1:-1;73330:29:1;;73362:17;-1:-1:-1;73362:17:1;;;17:15:-1;;105:10;73362:17:1;88:34:-1;136:17;;-1:-1;73362:17:1;73330:49;;73389:22;73426:15;:25;;;73414:38;;;;;;;;;;73389:63;;73480:6;:19;;;73462:12;73475:1;73462:15;;;;;;;;;;;;;:37;-1:-1:-1;;;;;73462:37:1;;;-1:-1:-1;;;;;73462:37:1;;;;;73527:6;73509:12;73522:1;73509:15;;;;;;;;;;;;;:24;-1:-1:-1;;;;;73509:24:1;;;-1:-1:-1;;;;;73509:24:1;;;;;73561:15;:21;;;73543:12;73556:1;73543:15;;;;;;;;;;;;;:39;;;;;73610:1;73592:12;73605:1;73592:15;;;;;;;;;;;;;:19;;;;;73639:15;:23;;;73621:41;;:12;73634:1;73621:15;;;;;;;;;;;;;:41;;;;;73690:5;73672:12;73685:1;73672:15;;;;;;;;;;;;;:23;;;;;73723:13;73705:12;73718:1;73705:15;;;;;;;;;;;;;:31;;;;;73764:1;73746:12;73759:1;73746:15;;;;;;;;;;;;;:19;;;;;73793:1;73775:12;73788:1;73775:15;;;;;;;;;;;;;:19;;;;;73804:12;;;;;;;;;-1:-1:-1;;;;;73804:12:1;-1:-1:-1;;;;;73804:32:1;;73845:15;:29;;;-1:-1:-1;;;;;73837:50:1;;:52;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73837:52:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73837:52:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73837:52:1;;;;;;;;;73899:29;;73931:10;73943:13;73964:10;73958:17;;;;;;;;73977:12;73991;73804:200;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73804:200:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73804:200:1;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73804:200:1;;;;;;;;;;73013:998;;;;;;;;;;:::o;13293:228::-;13472:2;13461:14;;13293:228::o;13760:4297::-;13910:2;13901:6;:11;13897:4154;;;14199:1;14189:6;14185:2;14181:15;14176:3;14172:25;14168:33;14250:4;14246:9;14237:6;14231:13;14227:29;14299:4;14292;14286:11;14282:22;14340:1;14337;14334:8;14328:4;14321:22;;;;14138:219;;;14461:4;14451:6;:14;14447:59;;;14485:7;;14447:59;15195:4;15186:6;:13;15182:2859;;;15521:2;15513:6;15509:15;15499:25;;15569:6;15561;15557:19;15619:6;15613:4;15609:17;15926:4;15920:11;16194:198;16212:4;16204:6;16201:16;16194:198;;;16260:13;;16247:27;;16321:2;16357:13;;;;16309:15;;;;16194:198;;;16461:18;;-1:-1:-1;15228:1269:1;;;16742:2;16734:6;16730:15;16720:25;;16790:6;16782;16778:19;16840:6;16834:4;16830:17;17150:6;17144:13;17729:191;17746:4;17740;17736:15;17729:191;;;17794:11;;17781:25;;-1:-1:-1;;17839:13:1;;;;17885;;;;17729:191;;;17990:19;;-1:-1:-1;;16544:1483:1;13760:4297;;;:::o;55760:31054::-;;;;;;;;;;-1:-1:-1;;;;;55760:31054:1;;;;;;-1:-1:-1;;;;;55760:31054:1;;;;;;-1:-1:-1;;;;;55760:31054:1;;;;;;-1:-1:-1;;;;;55760:31054:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;55760:31054:1;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;55760:31054:1;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;301:352;;;431:3;424:4;416:6;412:17;408:27;398:2;;-1:-1;;439:12;398:2;-1:-1;469:20;;-1:-1;;;;;498:30;;495:2;;;-1:-1;;531:12;495:2;575:4;567:6;563:17;551:29;;626:3;575:4;;610:6;606:17;567:6;592:32;;589:41;586:2;;;643:1;;633:12;586:2;391:262;;;;;;677:693;;806:3;799:4;791:6;787:17;783:27;773:2;;-1:-1;;814:12;773:2;854:6;848:13;876:81;891:65;949:6;891:65;;;876:81;;;985:21;;;867:90;-1:-1;1029:4;1042:14;;;;1017:17;;;1137:1;1122:242;1147:6;1144:1;1141:13;1122:242;;;1223:3;1217:10;1021:6;1205:23;5441:3;5422:17;1205:23;5422:17;5418:27;5408:2;;1137:1;;5449:12;5408:2;1029:4;1205:23;;5483:13;5511:60;5526:44;5563:6;5526:44;;5511:60;5591:6;5584:5;5577:21;5695:3;5615:17;5686:6;1205:23;5677:16;;5674:25;5671:2;;;1137:1;;5702:12;5671:2;5722:39;5754:6;1029:4;5653:5;5649:16;5615:17;1205:23;5615:17;5722:39;;;1235:66;;-1:-1;;1315:14;;;;1343;;;;1169:1;1162:9;1122:242;;1394:693;;1516:3;1509:4;1501:6;1497:17;1493:27;1483:2;;-1:-1;;1524:12;1483:2;1571:6;1558:20;1593:85;1608:69;1670:6;1608:69;;1593:85;1706:21;;;1584:94;-1:-1;1750:4;1763:14;;;;1738:17;;1858:1;1843:238;1868:6;1865:1;1862:13;1843:238;;;1975:42;2013:3;1750:4;1951:3;1938:17;1742:6;1926:30;;1975:42;;;1963:55;;1750:4;2032:14;;;;2060;;;;;1890:1;1883:9;1843:238;;;1847:14;;;;1476:611;;;;;2128:735;;2264:3;2257:4;2249:6;2245:17;2241:27;2231:2;;-1:-1;;2272:12;2231:2;2319:6;2306:20;2341:99;2356:83;2432:6;2356:83;;2341:99;2468:21;;;2332:108;-1:-1;2512:4;2525:14;;;;2500:17;;2620:1;2605:252;2630:6;2627:1;2624:13;2605:252;;;2737:56;2789:3;2512:4;2713:3;2700:17;2504:6;2688:30;;2737:56;;;2725:69;;2512:4;2808:14;;;;2836;;;;;2652:1;2645:9;2605:252;;4547:336;;;4661:3;4654:4;4646:6;4642:17;4638:27;4628:2;;-1:-1;;4669:12;4628:2;-1:-1;4699:20;;-1:-1;;;;;4728:30;;4725:2;;;-1:-1;;4761:12;4725:2;4805:4;4797:6;4793:17;4781:29;;4856:3;4805:4;4836:17;4797:6;4822:32;;4819:41;4816:2;;;4873:1;;4863:12;4892:432;;4989:3;4982:4;4974:6;4970:17;4966:27;4956:2;;-1:-1;;4997:12;4956:2;5044:6;5031:20;5066:60;5081:44;5118:6;5081:44;;5066:60;5057:69;;5146:6;5139:5;5132:21;5250:3;5182:4;5241:6;5174;5232:16;;5229:25;5226:2;;;5267:1;;5257:12;5226:2;86852:6;5182:4;5174:6;5170:17;5182:4;5208:5;5204:16;86829:30;86908:1;86890:16;;;5182:4;86890:16;86883:27;5208:5;4949:375;-1:-1;;4949:375;6953:1029;;7078:4;7066:9;7061:3;7057:19;7053:30;7050:2;;;-1:-1;;7086:12;7050:2;7114:20;7078:4;7114:20;;;7105:29;;15660:6;15654:13;7216:16;7209:86;7374:2;7443:9;7439:22;15654:13;7374:2;7393:5;7389:16;7382:86;7537:2;7606:9;7602:22;15654:13;7537:2;7556:5;7552:16;7545:86;7700:2;7769:9;7765:22;15654:13;7700:2;7719:5;7715:16;7708:86;7866:3;7936:9;7932:22;15654:13;7866:3;7886:5;7882:16;7875:86;7044:938;;;;;9823:2714;;9931:6;;9919:9;9914:3;9910:19;9906:32;9903:2;;;-1:-1;;9941:12;9903:2;9969:22;9931:6;9969:22;;;9960:31;;;10081:49;10126:3;10102:22;10081:49;;;10063:16;10056:75;10233:49;10278:3;10200:2;10258:9;10254:22;10233:49;;;10200:2;10219:5;10215:16;10208:75;10392:49;10437:3;10359:2;10417:9;10413:22;10392:49;;;10359:2;10378:5;10374:16;10367:75;10545:49;10590:3;10512:2;10570:9;10566:22;10545:49;;;10512:2;10531:5;10527:16;10520:75;10668:3;10727:9;10723:22;15506:20;10668:3;10688:5;10684:16;10677:75;10825:3;10884:9;10880:22;15506:20;10825:3;10845:5;10841:16;10834:75;10974:3;11033:9;11029:22;15506:20;10974:3;10994:5;10990:16;10983:75;11123:3;11182:9;11178:22;15506:20;11123:3;11143:5;11139:16;11132:75;11285:3;;11346:9;11342:22;15506:20;11285:3;11305:5;11301:18;11294:77;;11432:3;;11493:9;11489:22;15506:20;11432:3;11452:5;11448:18;11441:77;;11617:3;;11606:9;11602:19;11589:33;-1:-1;;;;;11642:18;11634:6;11631:30;11628:2;;;10049:1;;11664:12;11628:2;11711:54;11761:3;11752:6;11741:9;11737:22;11711:54;;;11617:3;11695:5;11691:18;11684:82;11865:3;;;;11854:9;11850:19;11837:33;11823:47;;11642:18;11882:6;11879:30;11876:2;;;10049:1;;11912:12;11876:2;11959:54;12009:3;12000:6;11989:9;11985:22;11959:54;;;11865:3;11943:5;11939:18;11932:82;12116:3;;;;12105:9;12101:19;12088:33;12074:47;;11642:18;12133:6;12130:30;12127:2;;;10049:1;;12163:12;12127:2;12210:54;12260:3;12251:6;12240:9;12236:22;12210:54;;;12116:3;12194:5;12190:18;12183:82;12367:3;;;;12356:9;12352:19;12339:33;12325:47;;11642:18;12384:6;12381:30;12378:2;;;10049:1;;12414:12;12378:2;;12461:54;12511:3;12502:6;12491:9;12487:22;12461:54;;;12367:3;12445:5;12441:18;12434:82;;;9897:2640;;;;;16126:241;;16230:2;16218:9;16209:7;16205:23;16201:32;16198:2;;;-1:-1;;16236:12;16198:2;85:6;72:20;97:33;124:5;97:33;;16374:263;;16489:2;16477:9;16468:7;16464:23;16460:32;16457:2;;;-1:-1;;16495:12;16457:2;226:6;220:13;238:33;265:5;238:33;;16644:366;;;16765:2;16753:9;16744:7;16740:23;16736:32;16733:2;;;-1:-1;;16771:12;16733:2;85:6;72:20;97:33;124:5;97:33;;;16823:63;-1:-1;16923:2;16962:22;;72:20;97:33;72:20;97:33;;;16931:63;;;;16727:283;;;;;;17017:1179;;;;;;;;;17278:3;17266:9;17257:7;17253:23;17249:33;17246:2;;;-1:-1;;17285:12;17246:2;85:6;72:20;97:33;124:5;97:33;;;17337:63;-1:-1;17437:2;17476:22;;72:20;97:33;72:20;97:33;;;17445:63;-1:-1;17573:2;17558:18;;17545:32;-1:-1;;;;;17586:30;;;17583:2;;;-1:-1;;17619:12;17583:2;17657:80;17729:7;17720:6;17709:9;17705:22;17657:80;;;17647:90;;-1:-1;17647:90;-1:-1;17802:2;17787:18;;17774:32;;-1:-1;17815:30;;;17812:2;;;-1:-1;;17848:12;17812:2;17886:80;17958:7;17949:6;17938:9;17934:22;17886:80;;;17876:90;;-1:-1;17876:90;-1:-1;18031:3;18016:19;;18003:33;;-1:-1;18045:30;;;18042:2;;;-1:-1;;18078:12;18042:2;;18116:64;18172:7;18163:6;18152:9;18148:22;18116:64;;;17240:956;;;;-1:-1;17240:956;;-1:-1;17240:956;;;;;;18106:74;-1:-1;;;17240:956;18203:867;;;;;;;18394:3;18382:9;18373:7;18369:23;18365:33;18362:2;;;-1:-1;;18401:12;18362:2;85:6;72:20;97:33;124:5;97:33;;;18453:63;-1:-1;18553:2;18592:22;;72:20;97:33;72:20;97:33;;;18561:63;-1:-1;18661:2;18700:22;;15506:20;;-1:-1;18769:2;18808:22;;15506:20;;-1:-1;18905:3;18890:19;;18877:33;-1:-1;;;;;18919:30;;18916:2;;;-1:-1;;18952:12;18916:2;18990:64;19046:7;19037:6;19026:9;19022:22;18990:64;;;18356:714;;;;-1:-1;18356:714;;-1:-1;18356:714;;18980:74;;18356:714;-1:-1;;;18356:714;19077:360;;;19195:2;19183:9;19174:7;19170:23;19166:32;19163:2;;;-1:-1;;19201:12;19163:2;85:6;72:20;97:33;124:5;97:33;;;19253:63;-1:-1;19353:2;19389:22;;4053:20;4078:30;4053:20;4078:30;;19444:645;;;;;19613:3;19601:9;19592:7;19588:23;19584:33;19581:2;;;-1:-1;;19620:12;19581:2;85:6;72:20;97:33;124:5;97:33;;;19672:63;-1:-1;19772:2;19827:22;;6655:20;6680:49;6655:20;6680:49;;;19780:79;-1:-1;19896:2;19933:22;;15921:20;15946:31;15921:20;15946:31;;;19575:514;;;;-1:-1;19904:61;;20002:2;20041:22;15506:20;;-1:-1;;19575:514;20096:366;;;20217:2;20205:9;20196:7;20192:23;20188:32;20185:2;;;-1:-1;;20223:12;20185:2;85:6;72:20;97:33;124:5;97:33;;;20275:63;20375:2;20414:22;;;;15506:20;;-1:-1;;;20179:283;20469:609;;;;;20620:3;20608:9;20599:7;20595:23;20591:33;20588:2;;;-1:-1;;20627:12;20588:2;85:6;72:20;97:33;124:5;97:33;;;20679:63;-1:-1;20779:2;20818:22;;15506:20;;-1:-1;20887:2;20924:22;;15921:20;15946:31;15921:20;15946:31;;;20895:61;-1:-1;20993:2;21030:22;;15921:20;15946:31;15921:20;15946:31;;;20582:496;;;;-1:-1;20582:496;;-1:-1;;20582:496;21085:1113;;;;;;;;;21304:3;21292:9;21283:7;21279:23;21275:33;21272:2;;;-1:-1;;21311:12;21272:2;85:6;72:20;97:33;124:5;97:33;;;21363:63;-1:-1;21463:2;21500:22;;15921:20;15946:31;15921:20;15946:31;;;21471:61;-1:-1;21569:2;21608:22;;15506:20;;-1:-1;21677:2;21716:22;;15506:20;;-1:-1;21785:3;21825:22;;72:20;97:33;72:20;97:33;;;21794:63;-1:-1;21894:3;21932:22;;15921:20;15946:31;15921:20;15946:31;;;21266:932;;;;-1:-1;21266:932;;;;;;21903:61;;-1:-1;;;22001:3;22041:22;;15506:20;;22110:3;22150:22;15506:20;;21266:932;22205:678;;;;;22396:2;22384:9;22375:7;22371:23;22367:32;22364:2;;;-1:-1;;22402:12;22364:2;22460:17;22447:31;-1:-1;;;;;22498:18;22490:6;22487:30;22484:2;;;-1:-1;;22520:12;22484:2;22558:80;22630:7;22621:6;22610:9;22606:22;22558:80;;;22548:90;;-1:-1;22548:90;-1:-1;22703:2;22688:18;;22675:32;;-1:-1;22716:30;;;22713:2;;;-1:-1;;22749:12;22713:2;;22787:80;22859:7;22850:6;22839:9;22835:22;22787:80;;;22358:525;;;;-1:-1;22777:90;-1:-1;;;;22358:525;22890:811;;;;23102:2;23090:9;23081:7;23077:23;23073:32;23070:2;;;-1:-1;;23108:12;23070:2;23166:17;23153:31;-1:-1;;;;;23204:18;23196:6;23193:30;23190:2;;;-1:-1;;23226:12;23190:2;23256:97;23345:7;23336:6;23325:9;23321:22;23256:97;;;23246:107;;23418:2;23407:9;23403:18;23390:32;23376:46;;23204:18;23434:6;23431:30;23428:2;;;-1:-1;;23464:12;23428:2;;23494:83;23569:7;23560:6;23549:9;23545:22;23494:83;;;23484:93;;;23614:2;23657:9;23653:22;15506:20;23622:63;;23064:637;;;;;;23708:651;;;23887:2;23875:9;23866:7;23862:23;23858:32;23855:2;;;-1:-1;;23893:12;23855:2;23944:17;23938:24;-1:-1;;;;;23982:18;23974:6;23971:30;23968:2;;;-1:-1;;24004:12;23968:2;24102:6;24091:9;24087:22;3391:3;3384:4;3376:6;3372:17;3368:27;3358:2;;-1:-1;;3399:12;3358:2;3439:6;3433:13;3419:27;;3461:76;3476:60;3529:6;3476:60;;3461:76;3543:16;3579:6;3572:5;3565:21;3609:4;;3626:3;3622:14;3615:21;;3609:4;3601:6;3597:17;3731:3;3609:4;;3715:6;3711:17;3601:6;3702:27;;3699:36;3696:2;;;-1:-1;;3738:12;3696:2;-1:-1;3764:10;;3758:217;3783:6;3780:1;3777:13;3758:217;;;15654:13;;3851:61;;3805:1;3798:9;;;;;3926:14;;;;3954;;3758:217;;;-1:-1;24162:18;;24156:25;24024:95;;-1:-1;24156:25;-1:-1;;;24190:30;;;24187:2;;;-1:-1;;24223:12;24187:2;;24253:90;24335:7;24326:6;24315:9;24311:22;24253:90;;;24243:100;;;23849:510;;;;;;24366:257;;24478:2;24466:9;24457:7;24453:23;24449:32;24446:2;;;-1:-1;;24484:12;24446:2;4201:6;4195:13;4213:30;4237:5;4213:30;;24630:345;;24743:2;24731:9;24722:7;24718:23;24714:32;24711:2;;;-1:-1;;24749:12;24711:2;24807:17;24794:31;-1:-1;;;;;24837:6;24834:30;24831:2;;;-1:-1;;24867:12;24831:2;24897:62;24951:7;24942:6;24931:9;24927:22;24897:62;;24982:440;;;25140:2;25128:9;25119:7;25115:23;25111:32;25108:2;;;-1:-1;;25146:12;26788:314;;26928:3;26916:9;26907:7;26903:23;26899:33;26896:2;;;-1:-1;;26935:12;26896:2;26997:89;27078:7;27054:22;26997:89;;27438:317;;27580:2;27568:9;27559:7;27555:23;27551:32;27548:2;;;-1:-1;;27586:12;27548:2;9260:20;27580:2;9260:20;;;16071:6;16065:13;16083:31;16108:5;16083:31;;;9344:84;;9494:2;9559:22;;;4470:13;9509:16;;;9502:86;9672:2;9737:22;;;15654:13;9687:16;;;9680:86;;;;-1:-1;9351:16;27542:213;-1:-1;27542:213;27762:373;;27889:2;27877:9;27868:7;27864:23;27860:32;27857:2;;;-1:-1;;27895:12;27857:2;27953:17;27940:31;-1:-1;;;;;27983:6;27980:30;27977:2;;;-1:-1;;28013:12;27977:2;28043:76;28111:7;28102:6;28091:9;28087:22;28043:76;;28142:498;;;28286:2;28274:9;28265:7;28261:23;28257:32;28254:2;;;-1:-1;;28292:12;28254:2;28350:17;28337:31;-1:-1;;;;;28380:6;28377:30;28374:2;;;-1:-1;;28410:12;28374:2;28440:76;28508:7;28499:6;28488:9;28484:22;28440:76;;;28430:86;28553:2;28592:22;;;;4322:20;;-1:-1;;;;28248:392;29152:533;;;;29300:2;29288:9;29279:7;29275:23;29271:32;29268:2;;;-1:-1;;29306:12;29268:2;15382:6;15376:13;15394:33;15421:5;15394:33;;;29469:2;29519:22;;15376:13;29358:74;;-1:-1;15394:33;15376:13;15394:33;;;29588:2;29637:22;;15794:13;29477:74;;-1:-1;82662:10;82651:22;;89585:34;;89575:2;;-1:-1;;89623:12;89575:2;29596:73;;;;29262:423;;;;;;29692:241;;29796:2;29784:9;29775:7;29771:23;29767:32;29764:2;;;-1:-1;;29802:12;29764:2;-1:-1;15506:20;;29758:175;-1:-1;29758:175;29940:263;;30055:2;30043:9;30034:7;30030:23;30026:32;30023:2;;;-1:-1;;30061:12;30023:2;-1:-1;15654:13;;30017:186;-1:-1;30017:186;30210:1315;;;;;;;;30490:3;30478:9;30469:7;30465:23;30461:33;30458:2;;;-1:-1;;30497:12;30458:2;15519:6;15506:20;30549:63;;30649:2;30692:9;30688:22;4322:20;30657:63;;30757:2;30800:9;30796:22;4322:20;30765:63;;30865:2;30908:9;30904:22;15506:20;30873:63;;30973:3;31017:9;31013:22;15506:20;30982:63;;31110:3;31099:9;31095:19;31082:33;-1:-1;;;;;31135:18;31127:6;31124:30;31121:2;;;-1:-1;;31157:12;31121:2;31187:97;31276:7;31267:6;31256:9;31252:22;31187:97;;;31177:107;;31349:3;31338:9;31334:19;31321:33;31307:47;;31135:18;31366:6;31363:30;31360:2;;;-1:-1;;31396:12;31360:2;;31426:83;31501:7;31492:6;31481:9;31477:22;31426:83;;;31416:93;;;30452:1073;;;;;;;;;;;31532:366;;;31653:2;31641:9;31632:7;31628:23;31624:32;31621:2;;;-1:-1;;31659:12;31621:2;-1:-1;;15506:20;;;31811:2;31850:22;;;15506:20;;-1:-1;31615:283;31905:399;;;32037:2;32025:9;32016:7;32012:23;32008:32;32005:2;;;-1:-1;;32043:12;32005:2;-1:-1;;15654:13;;32206:2;32256:22;;;15654:13;;;;;-1:-1;31999:305;32311:491;;;;32449:2;32437:9;32428:7;32424:23;32420:32;32417:2;;;-1:-1;;32455:12;32417:2;-1:-1;;15506:20;;;32607:2;32646:22;;15506:20;;-1:-1;32715:2;32754:22;;;15506:20;;32411:391;-1:-1;32411:391;32809:987;;;;;;;;33011:3;32999:9;32990:7;32986:23;32982:33;32979:2;;;-1:-1;;33018:12;32979:2;15934:6;15921:20;15946:31;15971:5;15946:31;;;33070:61;-1:-1;33168:2;33207:22;;15506:20;;-1:-1;33276:2;33315:22;;15506:20;;-1:-1;33384:2;33423:22;;72:20;97:33;72:20;97:33;;;33392:63;-1:-1;33492:3;33530:22;;15921:20;15946:31;15921:20;15946:31;;;32973:823;;;;-1:-1;32973:823;;;;33501:61;33599:3;33639:22;;15506:20;;-1:-1;33708:3;33748:22;;;15506:20;;32973:823;-1:-1;;32973:823;33804:173;-1:-1;;;;;82445:54;34589:45;;33966:4;33957:14;;33884:93;34502:137;-1:-1;;;;;82445:54;34589:45;;34583:56;36718:467;79887:19;;;36718:467;-1:-1;;;;;36966:78;;36963:2;;;-1:-1;;37047:12;36963:2;79936:4;37082:6;37078:17;86852:6;86847:3;79936:4;79931:3;79927:14;86829:30;86890:16;;;;79936:4;86890:16;86883:27;;;-1:-1;86890:16;;36850:335;-1:-1;36850:335;37224:690;;37417:5;78832:12;79899:6;79894:3;79887:19;79936:4;79931:3;79927:14;37429:93;;79936:4;37593:5;78365:14;-1:-1;37632:260;37657:6;37654:1;37651:13;37632:260;;;37718:13;;38104:37;;79936:4;34325:14;;;;79507;;;;37679:1;37672:9;37632:260;;;-1:-1;37898:10;;37348:566;-1:-1;;;;37348:566;38429:343;;38571:5;78832:12;79899:6;79894:3;79887:19;38664:52;38709:6;79936:4;79931:3;79927:14;79936:4;38690:5;38686:16;38664:52;;;87836:7;87820:14;-1:-1;;87816:28;38728:39;;;;79936:4;38728:39;;38519:253;-1:-1;;38519:253;47336:2780;;47483:6;47588:63;47636:14;47565:16;47559:23;47588:63;;;47738:4;47731:5;47727:16;47721:23;47750:63;47738:4;47802:3;47798:14;47784:12;47750:63;;;;47907:4;47900:5;47896:16;47890:23;47919:63;47907:4;47971:3;47967:14;47953:12;47919:63;;;;48070:4;48063:5;48059:16;48053:23;48082:63;48070:4;48134:3;48130:14;48116:12;48082:63;;;;48236:4;48229:5;48225:16;48219:23;48236:4;48300:3;48296:14;38104:37;48402:4;48395:5;48391:16;48385:23;48402:4;48466:3;48462:14;38104:37;48560:4;48553:5;48549:16;48543:23;48560:4;48624:3;48620:14;38104:37;48718:4;48711:5;48707:16;48701:23;48718:4;48782:3;48778:14;38104:37;48889:6;;48882:5;48878:18;48872:25;48889:6;48955:3;48951:16;38104:37;;49047:6;;49040:5;49036:18;49030:25;49047:6;49113:3;49109:16;38104:37;;49215:6;;49208:5;49204:18;49198:25;47483:6;49215;49247:3;49243:16;49236:40;49291:67;47483:6;47478:3;47474:16;49339:12;49291:67;;;49283:75;;;49453:6;;;;49446:5;49442:18;49436:25;49509:3;49503:4;49499:14;49453:6;49485:3;49481:16;49474:40;49529:67;49591:4;49577:12;49529:67;;;49521:75;;;;49694:6;;49687:5;49683:18;49677:25;49750:3;49744:4;49740:14;49694:6;49726:3;49722:16;49715:40;49770:67;49832:4;49818:12;49770:67;;;49762:75;;;49935:6;;;;49928:5;49924:18;49918:25;49991:3;49985:4;49981:14;49935:6;49967:3;49963:16;49956:40;50011:67;50073:4;50059:12;50011:67;;51165:639;88139:2;88135:14;;;;-1:-1;;88135:14;34965:58;;87928:15;;;;;-1:-1;;;;;;87928:15;51455:2;51446:12;;50599:56;88032:15;;;;-1:-1;;;;;;88032:15;;;51555:12;;;51099:54;88032:15;;;;51662:11;;;51099:54;51768:11;;;51346:458;51811:661;38104:37;;;52111:2;52102:12;;38104:37;;;;52213:12;;;38104:37;52324:12;;;38104:37;52435:12;;;52002:470;52479:262;;38939:5;78832:12;39050:52;39095:6;39090:3;39083:4;39076:5;39072:16;39050:52;;;39114:16;;;;;52604:137;-1:-1;;52604:137;52748:370;53103:10;52927:191;53125:1440;-1:-1;;;45663:36;;-1:-1;;;45647:2;45718:12;;41749:35;-1:-1;;;41803:12;;;43737:38;42867:27;43794:12;;;42847:48;-1:-1;;;42914:12;;;43392:24;43435:11;;;53709:856;54572:213;-1:-1;;;;;82445:54;;;;34589:45;;54690:2;54675:18;;54661:124;54792:451;-1:-1;;;;;82445:54;;;34432:58;;82445:54;;;;55146:2;55131:18;;34589:45;55229:2;55214:18;;38104:37;;;;54974:2;54959:18;;54945:298;55250:959;-1:-1;;;;;82445:54;;34589:45;;55586:3;55721:2;55706:18;;55699:48;;;55250:959;;55761:108;;55571:19;;55855:6;55761:108;;;55917:9;55911:4;55907:20;55902:2;55891:9;55887:18;55880:48;55942:108;56045:4;56036:6;55942:108;;;56098:9;56092:4;56088:20;56083:2;56072:9;56068:18;56061:48;56123:76;56194:4;56185:6;56123:76;;56216:324;-1:-1;;;;;82445:54;;;34589:45;;82445:54;;56526:2;56511:18;;34589:45;56362:2;56347:18;;56333:207;56547:983;-1:-1;;;;;82445:54;;;34589:45;;82445:54;;;57020:2;57005:18;;34589:45;82445:54;;;;57103:2;57088:18;;34589:45;82756:4;82745:16;;;57184:2;57169:18;;50736:48;57267:3;57252:19;;38104:37;;;;82456:42;57336:19;;38104:37;82745:16;;;57431:3;57416:19;;50853:35;57515:3;57500:19;;38104:37;;;;56855:3;56840:19;;56826:704;58471:324;-1:-1;;;;;82445:54;;;;34589:45;;58781:2;58766:18;;38104:37;58617:2;58602:18;;58588:207;58802:531;-1:-1;;;;;82445:54;;;;34589:45;;59161:2;59146:18;;38104:37;;;;82756:4;82745:16;;;59240:2;59225:18;;50853:35;82745:16;59319:2;59304:18;;50853:35;58996:3;58981:19;;58967:366;59340:660;;59606:2;59627:17;59620:47;59681:118;59606:2;59595:9;59591:18;59785:6;59777;59681:118;;;59847:9;59841:4;59837:20;59832:2;59821:9;59817:18;59810:48;59872:118;59985:4;59976:6;59968;59872:118;;;59864:126;59577:423;-1:-1;;;;;;;59577:423;60007:361;;60175:2;60196:17;60189:47;60250:108;60175:2;60164:9;60160:18;60344:6;60250:108;;60375:640;;60631:2;60652:17;60645:47;60706:108;60631:2;60620:9;60616:18;60800:6;60706:108;;;60847:2;60862:9;60856:4;60852:20;60847:2;60836:9;60832:18;60825:48;60887:118;35999:5;78832:12;79899:6;79894:3;79887:19;60847:2;79931:3;79927:14;36011:98;;60847:2;;36166:6;36162:17;79931:3;36153:27;;60847:2;36256:5;78365:14;-1:-1;36295:345;36320:6;36317:1;36314:13;36295:345;;;87836:7;;79931:3;36376:4;36372:20;;36367:3;36360:33;34097:60;34153:3;36427:6;36421:13;34097:60;;;36619:14;;;;36441:82;-1:-1;79507:14;;;;36342:1;36335:9;36295:345;;;-1:-1;60879:126;;60602:413;-1:-1;;;;;;;;;60602:413;61022:201;81415:13;;81408:21;37987:34;;61134:2;61119:18;;61105:118;61230:213;38104:37;;;61348:2;61333:18;;61319:124;61450:209;-1:-1;;;;;;81581:78;;;;38381:36;;61566:2;61551:18;;61537:122;61666:1035;-1:-1;;;;;;81581:78;;38381:36;;-1:-1;;;;;82445:54;;62175:2;62160:18;;34589:45;82456:42;62212:2;62197:18;;62190:48;;;61666:1035;;62252:108;;61997:19;;62346:6;62252:108;;;62408:9;62402:4;62398:20;62393:2;62382:9;62378:18;62371:48;62433:108;62536:4;62527:6;62433:108;;;62590:9;62584:4;62580:20;62574:3;62563:9;62559:19;62552:49;62615:76;62686:4;62677:6;62615:76;;;62607:84;61983:718;-1:-1;;;;;;;;;61983:718;62708:297;;62844:2;62865:17;62858:47;62919:76;62844:2;62833:9;62829:18;62981:6;62919:76;;64905:615;;509:18;;82456:42;;;;81225:5;82445:54;39564:3;39557:72;65145:2;65279;65268:9;65264:18;65257:48;65319:108;65145:2;65134:9;65130:18;65413:6;65319:108;;;65311:116;;82456:42;34627:5;82445:54;65506:2;65495:9;65491:18;34589:45;;65116:404;;;;;;;65527:463;-1:-1;;;;;82445:54;;;39557:72;;82756:4;82745:16;;;;65893:2;65878:18;;50736:48;82445:54;;;65976:2;65961:18;;34589:45;65715:2;65700:18;;65686:304;65997:1151;-1:-1;;;;;82445:54;;;39557:72;;82756:4;82745:16;;66540:2;66525:18;;50736:48;66623:2;66608:18;;38104:37;;;66361:3;66346:19;;;88246:1;88236:12;;88226:2;;88252:9;88226:2;86370:34;66714:2;66703:9;66699:18;41402:58;82456:42;34627:5;82445:54;66797:3;66786:9;66782:19;34589:45;38134:5;66881:3;66870:9;66866:19;38104:37;38134:5;66965:3;66954:9;66950:19;38104:37;38134:5;67049:3;67038:9;67034:19;38104:37;82456:42;34627:5;82445:54;67133:3;67122:9;67118:19;34589:45;;66332:816;;;;;;;;;;;;;67683:1239;;68099:3;68088:9;68084:19;509:18;;82456:42;;;;81225:5;82445:54;39564:3;39557:72;82456:42;81225:5;82445:54;68298:2;68287:9;68283:18;39557:72;;38134:5;68381:2;68370:9;68366:18;38104:37;38134:5;68464:2;68453:9;68449:18;38104:37;82756:4;50881:5;82745:16;68543:3;68532:9;68528:19;50853:35;68099:3;68581;68570:9;68566:19;68559:49;68622:108;35259:5;78832:12;35278:86;35357:6;35352:3;35278:86;;;35271:93;;68298:2;35435:5;78365:14;35447:21;;-1:-1;35474:260;35499:6;35496:1;35493:13;35474:260;;;35587:63;35646:3;35566:6;35560:13;35587:63;;;68298:2;79507:14;;;;;35580:70;-1:-1;35521:1;35514:9;35474:260;;;35478:14;;68779:9;68773:4;68769:20;68763:3;68752:9;68748:19;68741:49;68804:108;68907:4;68898:6;68804:108;;69179:407;69370:2;69384:47;;;42054:2;69355:18;;;79887:19;42090:34;79927:14;;;42070:55;-1:-1;;;42145:12;;;42138:46;42203:12;;;69341:245;69593:339;-1:-1;;;42366:19;;69774:2;69759:18;;69745:187;69939:339;-1:-1;;;42536:20;;70120:2;70105:18;;70091:187;70285:339;-1:-1;;;43077:25;;70466:2;70451:18;;70437:187;70631:339;-1:-1;;;43957:24;;70812:2;70797:18;;70783:187;70977:339;-1:-1;;;44132:31;;71158:2;71143:18;;71129:187;71323:339;-1:-1;;;44888:28;;71504:2;71489:18;;71475:187;71669:407;71860:2;71874:47;;;45155:2;71845:18;;;79887:19;45191:34;79927:14;;;45171:55;45260:34;45246:12;;;45239:56;-1:-1;;;45315:12;;;45308:33;45360:12;;;71831:245;72083:407;72274:2;72288:47;;;45969:2;72259:18;;;79887:19;-1:-1;;;79927:14;;;45985:36;46040:12;;;72245:245;72497:407;72688:2;72702:47;;;46291:2;72673:18;;;79887:19;-1:-1;;;79927:14;;;46307:37;46363:12;;;72659:245;72911:342;46698:23;;-1:-1;;;;;82445:54;34589:45;;46870:4;46859:16;;;46853:23;46930:14;;;38104:37;47027:4;47016:16;;;47010:23;82756:4;82745:16;;;47083:14;;;50853:35;;;;47182:4;47171:16;;;47165:23;82745:16;47238:14;;;50853:35;;;;73093:3;73078:19;;73064:189;73260:353;;73424:2;73445:17;73438:47;73499:104;73424:2;73413:9;73409:18;73589:6;73499:104;;73620:464;;73812:2;73833:17;73826:47;73887:104;73812:2;73801:9;73797:18;73977:6;73887:104;;;73879:112;;38134:5;74070:2;74059:9;74055:18;38104:37;73783:301;;;;;;74091:659;;74329:2;74350:17;74343:47;74404:104;74329:2;74318:9;74314:18;74494:6;74404:104;;;38134:5;74587:2;74576:9;74572:18;38104:37;74639:9;74633:4;74629:20;74624:2;74613:9;74609:18;74602:48;74664:76;74735:4;74726:6;74664:76;;74977:324;38104:37;;;75287:2;75272:18;;38104:37;75123:2;75108:18;;75094:207;75308:755;38104:37;;;75755:2;75740:18;;38104:37;;;;-1:-1;;;;;82445:54;75846:2;75831:18;;34432:58;75590:3;75883:2;75868:18;;75861:48;;;75308:755;75575:19;;;79887;82456:42;79927:14;;75561:502;76070:256;76132:2;76126:9;76158:17;;;-1:-1;;;;;76218:34;;76254:22;;;76215:62;76212:2;;;76290:1;;76280:12;76212:2;76132;76299:22;76110:216;;-1:-1;76110:216;76333:305;;-1:-1;;;;;76485:6;76482:30;76479:2;;;-1:-1;;76515:12;76479:2;-1:-1;76560:4;76548:17;;;76613:15;;76416:222;77598:317;;-1:-1;;;;;77729:6;77726:30;77723:2;;;-1:-1;;77759:12;77723:2;-1:-1;87836:7;77813:17;-1:-1;;77809:33;77900:4;77890:15;;77660:255;86925:268;86990:1;86997:101;87011:6;87008:1;87005:13;86997:101;;;87078:11;;;87072:18;87059:11;;;87052:39;87033:2;87026:10;86997:101;;;87113:6;87110:1;87107:13;87104:2;;;86990:1;87169:6;87164:3;87160:16;87153:27;87104:2;;86974:219;;;;88275:117;-1:-1;;;;;82445:54;;88334:35;;88324:2;;88383:1;;88373:12;88324:2;88318:74;;88399:111;88480:5;81415:13;81408:21;88458:5;88455:32;88445:2;;88501:1;;88491:12;89279:117;-1:-1;;;;;89366:5;82329:42;89341:5;89338:35;89328:2;;89387:1;;89377:12;89649:113;82756:4;89732:5;82745:16;89709:5;89706:33;89696:2;;89753:1;;89743:12

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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