ETH Price: $3,321.29 (-0.75%)
Gas: 4.49 Gwei
 

Overview

Max Total Supply

15 ARTO

Holders

13

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
mp25.eth
Balance
2 ARTO
0x18D6dC7eE387D54226C848175B20594A9e66d77c
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Media

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-09-22
*/

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
pragma experimental ABIEncoderV2 ;

library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

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

        return c;
    }

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

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

}

interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}


interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
      * @dev Safely transfers `tokenId` token from `from` to `to`.
      *
      * Requirements:
      *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
      * - `tokenId` token must exist and be owned by `from`.
      * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
      *
      * Emits a {Transfer} event.
      */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


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

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

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


    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

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

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

library Decimal {
    using SafeMath for uint256;

    // ============ Constants ============

    uint256 constant BASE_POW = 18;
    uint256 constant BASE = 10**BASE_POW;

    // ============ Structs ============

    struct D256 {
        uint256 value;
    }

    // ============ Functions ============

    function one() internal pure returns (D256 memory) {
        return D256({value: BASE});
    }

    function onePlus(D256 memory d) internal pure returns (D256 memory) {
        return D256({value: d.value.add(BASE)});
    }

    function mul(uint256 target, D256 memory d)
        internal
        pure
        returns (uint256)
    {
        return Math.getPartial(target, d.value, BASE);
    }

    function div(uint256 target, D256 memory d)
        internal
        pure
        returns (uint256)
    {
        return Math.getPartial(target, BASE, d.value);
    }
}


contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

interface IMedia {
    struct EIP712Signature {
        uint256 deadline;
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    struct MediaData {
        // A valid URI of the content represented by this token
        string tokenURI;
        // A valid URI of the metadata associated with this token
        string metadataURI;
        // A SHA256 hash of the content pointed to by tokenURI
        bytes32 contentHash;
        // A SHA256 hash of the content pointed to by metadataURI
        bytes32 metadataHash;
    }

    event TokenURIUpdated(uint256 indexed _tokenId, address owner, string _uri);
    event TokenMetadataURIUpdated(
        uint256 indexed _tokenId,
        address owner,
        string _uri
    );

    /**
     * @notice Return the metadata URI for a piece of media given the token URI
     */
    function tokenMetadataURI(uint256 tokenId)
        external
        view
        returns (string memory);

    /**
     * @notice Mint new media for msg.sender.
     */
    function mint(MediaData calldata data, IMarket.BidShares calldata bidShares)
        external;

    /**
     * @notice EIP-712 mintWithSig method. Mints new media for a creator given a valid signature.
     */
    function mintWithSig(
        address creator,
        MediaData calldata data,
        IMarket.BidShares calldata bidShares,
        EIP712Signature calldata sig
    ) external;

    /**
     * @notice Transfer the token with the given ID to a given address.
     * Save the previous owner before the transfer, in case there is a sell-on fee.
     * @dev This can only be called by the auction contract specified at deployment
     */
    function auctionTransfer(uint256 tokenId, address recipient) external;

    /**
     * @notice Set the ask on a piece of media
     */
    function setAsk(uint256 tokenId, IMarket.Ask calldata ask) external;

    /**
     * @notice Remove the ask on a piece of media
     */
    function removeAsk(uint256 tokenId) external;

    /**
     * @notice Set the bid on a piece of media
     */
    function setBid(uint256 tokenId, IMarket.Bid calldata bid) external;

    /**
     * @notice Remove the bid on a piece of media
     */
    function removeBid(uint256 tokenId) external;

    function getTreasurerAddress() external view returns(address);

    function owner() external view returns(address);

    function authorize(address _address) external view returns(bool);

    function acceptBid(uint256 tokenId, IMarket.Bid calldata bid) external;

    /**
     * @notice Revoke approval for a piece of media
     */
    function revokeApproval(uint256 tokenId) external;

    /**
     * @notice Update the token URI
     */
    function updateTokenURI(uint256 tokenId, string calldata tokenURI) external;

    /**
     * @notice Update the token metadata uri
     */
    function updateTokenMetadataURI(
        uint256 tokenId,
        string calldata metadataURI
    ) external;

    /**
     * @notice EIP-712 permit method. Sets an approved spender given a valid signature.
     */
    function permit(
        address spender,
        uint256 tokenId,
        EIP712Signature calldata sig
    ) external;
}


interface IMarket {
    struct Bid {
        // Amount of the currency being bid
        uint256 amount;
        // Address to the ERC20 token being used to bid
        address currency;
        // Address of the bidder
        address bidder;
        // Address of the recipient
        address recipient;
        // % of the next sale to award the current owner
        Decimal.D256 sellOnShare;
    }

    struct Ask {
        // Amount of the currency being asked
        uint256 amount;
        // Address to the ERC20 token being asked
        address currency;
    }

    struct BidShares {
        // % of sale value that goes to the _previous_ owner of the nft
        Decimal.D256 prevOwner;
        // % of sale value that goes to the original creator of the nft
        Decimal.D256 creator;
        // % of sale value that goes to the seller (current owner) of the nft
        Decimal.D256 owner;
    }

    event BidCreated(uint256 indexed tokenId, Bid bid);
    event BidRemoved(uint256 indexed tokenId, Bid bid);
    event BidFinalized(uint256 indexed tokenId, Bid bid);
    event AskCreated(uint256 indexed tokenId, Ask ask);
    event AskRemoved(uint256 indexed tokenId, Ask ask);
    event BidShareUpdated(uint256 indexed tokenId, BidShares bidShares);

    function bidForTokenBidder(uint256 tokenId, address bidder)
        external
        view
        returns (Bid memory);

    function currentAskForToken(uint256 tokenId)
        external
        view
        returns (Ask memory);

    function bidSharesForToken(uint256 tokenId)
        external
        view
        returns (BidShares memory);

    function isValidBid(uint256 tokenId, uint256 bidAmount)
        external
        view
        returns (bool);

    function isValidBidShares(BidShares calldata bidShares)
        external
        pure
        returns (bool);

    function splitShare(Decimal.D256 calldata sharePercentage, uint256 amount)
        external
        pure
        returns (uint256);

    function configure(address mediaContractAddress) external;

    function setBidShares(uint256 tokenId, BidShares calldata bidShares)
        external;

    function setAsk(uint256 tokenId, Ask calldata ask) external;

    function removeAsk(uint256 tokenId) external;

    function setBid(
        uint256 tokenId,
        Bid calldata bid,
        address spender
    ) external;

    function removeBid(uint256 tokenId, address bidder) external;

    function acceptBid(uint256 tokenId, Bid calldata expectedBid) external;
}




library Math {
    using SafeMath for uint256;

    // ============ Library Functions ============

    /*
     * Return target * (numerator / denominator).
     */
    function getPartial(
        uint256 target,
        uint256 numerator,
        uint256 denominator
    ) internal pure returns (uint256) {
        return target.mul(numerator).div(denominator);
    }

    /*
     * Return target * (numerator / denominator), but rounded up.
     */
    function getPartialRoundUp(
        uint256 target,
        uint256 numerator,
        uint256 denominator
    ) internal pure returns (uint256) {
        if (target == 0 || numerator == 0) {
            // SafeMath will check for zero denominator
            return SafeMath.div(0, denominator);
        }
        return target.mul(numerator).sub(1).div(denominator).add(1);
    }

    function to128(uint256 number) internal pure returns (uint128) {
        uint128 result = uint128(number);
        require(result == number, "Math: Unsafe cast to uint128");
        return result;
    }

    function to96(uint256 number) internal pure returns (uint96) {
        uint96 result = uint96(number);
        require(result == number, "Math: Unsafe cast to uint96");
        return result;
    }

    function to32(uint256 number) internal pure returns (uint32) {
        uint32 result = uint32(number);
        require(result == number, "Math: Unsafe cast to uint32");
        return result;
    }

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

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

    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        // The {SafeMath} overflow check can be skipped here, see the comment at the top
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}

abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}


interface IERC721Metadata is IERC721 {

    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}



interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}


interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data)
    external returns (bytes4);
}



contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

contract ERC721 is
    Context,
    ERC165,
    IERC721,
    IERC721Metadata,
    IERC721Enumerable
{
    using SafeMath for uint256;
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from holder address to their (enumerable) set of owned tokens
    mapping(address => EnumerableSet.UintSet) private _holderTokens;

    // Enumerable mapping from token ids to their owners
    EnumerableMap.UintToAddressMap private _tokenOwners;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping(uint256 => string) internal _tokenURIs;

    // Base URI
    string internal _baseURI;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        require(
            owner != address(0),
            "ERC721: balance query for the zero address"
        );

        return _holderTokens[owner].length();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return
            _tokenOwners.get(
                tokenId,
                "ERC721: owner query for nonexistent token"
            );
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        string memory _tokenURI = _tokenURIs[tokenId];

        // If there is no base URI, return the token URI.
        if (bytes(_baseURI).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(_baseURI, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(_baseURI, tokenId.toString()));
    }

    /**
     * @dev Returns the base URI set via {_setBaseURI}. This will be
     * automatically added as a prefix in {tokenURI} to each token's URI, or
     * to the token ID if no specific URI is set for that token ID.
     */
    function baseURI() public view returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index)
        public
        view
        override
        returns (uint256)
    {
        return _holderTokens[owner].at(index);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view override returns (uint256) {
        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
        return _tokenOwners.length();
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index)
        public
        view
        override
        returns (uint256)
    {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId)
        public
        view
        override
        returns (address)
    {
        require(
            _exists(tokenId),
            "ERC721: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator)
        public
        view
        override
        returns (bool)
    {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(
            _checkOnERC721Received(from, to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return _tokenOwners.contains(tokenId);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId)
        internal
        view
        returns (bool)
    {
        require(
            _exists(tokenId),
            "ERC721: operator query for nonexistent token"
        );
        address owner = ownerOf(tokenId);
        return (spender == owner ||
            getApproved(tokenId) == spender ||
            isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     d*
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(
            ownerOf(tokenId) == from,
            "ERC721: transfer of token that is not own"
        );
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI)
        internal
        virtual
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI set of nonexistent token"
        );
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI},
     * or to the token ID if {tokenURI} is empty.
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (!to.isContract()) {
            return true;
        }
        bytes memory returndata =
            to.functionCall(
                abi.encodeWithSelector(
                    IERC721Receiver(to).onERC721Received.selector,
                    _msgSender(),
                    from,
                    tokenId,
                    _data
                ),
                "ERC721: transfer to non ERC721Receiver implementer"
            );
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

    function _approve(address to, uint256 tokenId) internal {
        _tokenApprovals[tokenId] = to;
        emit Approval(ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}



abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721Burnable: caller is not owner nor approved"
        );
        _burn(tokenId);
    }
}


library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint256(_at(set._inner, index)));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}



/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public _owner;


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


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
    _owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(isOwner(),"Ownable: caller is not the SuperAdmin");
    _;
  }

  /**
   * @return true if `msg.sender` is the owner of the contract.
   */
  function isOwner() public view returns(bool) {
    return msg.sender == _owner;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   * @notice Renouncing to ownership will leave the contract without an owner.
   * It will not be possible to call the functions with the `onlyOwner`
   * modifier anymore.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipRenounced(_owner);
    _owner = address(0);
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    _transferOwnership(newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address newOwner) internal {
    require(newOwner != address(0),"Ownable: new SuperAdmin is the zero address");
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
  }
}

contract Authorizable is Ownable {

    mapping(address => bool) public authorized;
    mapping(address => bool) public addAuthorizedAddress;
    address[] public adminList;

    event AddAuthorized(address indexed _address);
    event AcceptOwnership(address indexed _address);
    event RemoveAuthorized(address indexed _address, uint index);


    modifier onlyAuthorized() {
        require(authorized[msg.sender] || _owner == msg.sender,"Authorizable: caller is not the SuperAdmin or Admin");
        _;
    }

    function addAuthorized(address _toAdd) onlyOwner public {
        require(_toAdd != address(0),"is not a vaild address");
        addAuthorizedAddress[_toAdd] = true;
        emit AddAuthorized(_toAdd);
    }

    function acceptOwnership() public {
        require(addAuthorizedAddress[msg.sender],"Authorizable:Only authorized owner");
        authorized[msg.sender] = true;
        adminList.push(msg.sender);
        emit AcceptOwnership(msg.sender);
    }

    function removeAuthorized(address _toRemove,uint _index) onlyOwner public {
        require(_toRemove != address(0),"is not a vaild address");
        require(_toRemove != msg.sender);
        require(adminList[_index] == _toRemove,"not a valid index");
        addAuthorizedAddress[_toRemove] = false;
        authorized[_toRemove] = false;
        delete adminList[_index];
        emit RemoveAuthorized(_toRemove,_index);
    }

    function getAdminList() public view returns(address[] memory ){
        return adminList;
    }

}

library EnumerableMap {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;

        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) { // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({ _key: key, _value: value }));
            // The entry is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }


    /**
     * @dev Removes a key-value pair from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function _remove(Map storage map, bytes32 key) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex != 0) { // Equivalent to contains(map, key)
            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
            // in the array, and then remove the last entry (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;

            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            MapEntry storage lastEntry = map._entries[lastIndex];

            // Move the last entry to the index where the entry to delete is
            map._entries[toDeleteIndex] = lastEntry;
            // Update the index for the moved entry
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved entry was stored
            map._entries.pop();

            // Delete the index for the deleted slot
            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function _contains(Map storage map, bytes32 key) private view returns (bool) {
        return map._indexes[key] != 0;
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._entries.length;
    }

   /**
    * @dev Returns the key-value pair stored at position `index` in the map. O(1).
    *
    * Note that there are no guarantees on the ordering of entries inside the
    * array, and it may change when more entries are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
        require(map._entries.length > index, "EnumerableMap: index out of bounds");

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        return _get(map, key, "EnumerableMap: nonexistent key");
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     */
    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(value)));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
        return _remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
        return _contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToAddressMap storage map) internal view returns (uint256) {
        return _length(map._inner);
    }

   /**
    * @dev Returns the element stored at position `index` in the set. O(1).
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
        (bytes32 key, bytes32 value) = _at(map._inner, index);
        return (uint256(key), address(uint256(value)));
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint256(_get(map._inner, bytes32(key))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     */
    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint256(_get(map._inner, bytes32(key), errorMessage)));
    }
}


library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index--] = byte(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }
}

contract Media is IMedia, ERC721Burnable, ReentrancyGuard,Authorizable {
    using Counters for Counters.Counter;
    using SafeMath for uint256;

    /* *******
     * Globals
     * *******
     */

    address public treasurerAddress;

    // Address for the market
    address public marketContract;

    // Mapping from token to previous owner of the token
    mapping(uint256 => address) public previousTokenOwners;

    // Mapping from token id to creator address
    mapping(uint256 => address) public tokenCreators;

    // Mapping from creator address to their (enumerable) set of created tokens
    mapping(address => EnumerableSet.UintSet) private _creatorTokens;

    // Mapping from token id to sha256 hash of content
    mapping(uint256 => bytes32) public tokenContentHashes;

    // Mapping from token id to sha256 hash of metadata
    mapping(uint256 => bytes32) public tokenMetadataHashes;

    // Mapping from token id to metadataURI
    mapping(uint256 => string) private _tokenMetadataURIs;

    // Mapping from contentHash to bool
    mapping(bytes32 => bool) private _contentHashes;

    //keccak256("Permit(address spender,uint256 tokenId,uint256 nonce,uint256 deadline)");
    bytes32 public constant PERMIT_TYPEHASH =
        0x49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad;

    //keccak256("MintWithSig(bytes32 contentHash,bytes32 metadataHash,uint256 creatorShare,uint256 nonce,uint256 deadline)");
    bytes32 public constant MINT_WITH_SIG_TYPEHASH =
        0x2952e482b8e2b192305f87374d7af45dc2eafafe4f50d26a0c02e90f2fdbe14b;

    // Mapping from address to token id to permit nonce
    mapping(address => mapping(uint256 => uint256)) public permitNonces;

    // Mapping from address to mint with sig nonce
    mapping(address => uint256) public mintWithSigNonces;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *     bytes4(keccak256('tokenMetadataURI(uint256)')) == 0x157c3df9
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd ^ 0x157c3df9 == 0x4e222e66
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x4e222e66;

    Counters.Counter private _tokenIdTracker;

    /* *********
     * Modifiers
     * *********
     */

    /**
     * @notice Require that the token has not been burned and has been minted
     */
    modifier onlyExistingToken(uint256 tokenId) {
        require(_exists(tokenId), "Media: nonexistent token");
        _;
    }

    /**
     * @notice Require that the token has had a content hash set
     */
    modifier onlyTokenWithContentHash(uint256 tokenId) {
        require(
            tokenContentHashes[tokenId] != 0,
            "Media: token does not have hash of created content"
        );
        _;
    }

    /**
     * @notice Require that the token has had a metadata hash set
     */
    modifier onlyTokenWithMetadataHash(uint256 tokenId) {
        require(
            tokenMetadataHashes[tokenId] != 0,
            "Media: token does not have hash of its metadata"
        );
        _;
    }

    /**
     * @notice Ensure that the provided spender is the approved or the owner of
     * the media for the specified tokenId
     */
    modifier onlyApprovedOrOwner(address spender, uint256 tokenId) {
        require(
            _isApprovedOrOwner(spender, tokenId),
            "Media: Only approved or owner"
        );
        _;
    }

    /**
     * @notice Ensure the token has been created (even if it has been burned)
     */
    modifier onlyTokenCreated(uint256 tokenId) {
        require(
            _tokenIdTracker.current() > tokenId,
            "Media: token with that id does not exist"
        );
        _;
    }

    /**
     * @notice Ensure that the provided URI is not empty
     */
    modifier onlyValidURI(string memory uri) {
        require(
            bytes(uri).length != 0,
            "Media: specified uri must be non-empty"
        );
        _;
    }

    /**
     * @notice On deployment, set the market contract address and register the
     * ERC721 metadata interface
     */
    constructor(address marketContractAddr) public ERC721("ARTOFFICIAL", "ARTO") {
        marketContract = marketContractAddr;
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
    }

    /* **************
     * View Functions
     * **************
     */

    /**
     * @notice return the URI for a particular piece of media with the specified tokenId
     * @dev This function is an override of the base OZ implementation because we
     * will return the tokenURI even if the media has been burned. In addition, this
     * protocol does not support a base URI, so relevant conditionals are removed.
     * @return the URI for a token
     */
    function tokenURI(uint256 tokenId)
        public
        view
        override
        onlyTokenCreated(tokenId)
        returns (string memory)
    {
        string memory _tokenURI = _tokenURIs[tokenId];

        return _tokenURI;
    }

    /**
     * @notice Return the metadata URI for a piece of media given the token URI
     * @return the metadata URI for the token
     */
    function tokenMetadataURI(uint256 tokenId)
        external
        view
        override
        onlyTokenCreated(tokenId)
        returns (string memory)
    {
        return _tokenMetadataURIs[tokenId];
    }


    function getTreasurerAddress() public override view returns(address){
        return treasurerAddress;
    }

    /**
   * @return the address of the owner.
   */
    function owner() public override view returns(address) {
        return _owner;
    }

    function authorize(address _address) public override view returns(bool){
        return authorized[_address];   
    }

    /* ****************
     * Public Functions
     * ****************
     */


    function configureRewardAddress(address _treasurerAddress) public onlyOwner {
        require(_treasurerAddress != address(0), "not a valid address");
        treasurerAddress = _treasurerAddress;
    }

    function transferToken(
        address to,
        uint256 tokenId
    ) public onlyOwner onlyTokenCreated(tokenId) {
        address from = ownerOf(tokenId);
        require(
            owner() == to || authorized[to],
            "not a valid owner address"
        );
        require(
            authorized[from],
            "not a valid owner address"
        );
        super._transfer(from, to, tokenId);
    }

    /**
     * @notice see IMedia
     */
    function mint(MediaData memory data, IMarket.BidShares memory bidShares)
        public
        onlyAuthorized
        override
        nonReentrant
    {
        _mintForCreator(msg.sender, data, bidShares);
    }

    /**
     * @notice see IMedia
     */
    function mintWithSig(
        address creator,
        MediaData memory data,
        IMarket.BidShares memory bidShares,
        EIP712Signature memory sig
    ) public override nonReentrant {
        require(
            sig.deadline == 0 || sig.deadline >= block.timestamp,
            "Media: mintWithSig expired"
        );

        bytes32 domainSeparator = _calculateDomainSeparator();

        bytes32 digest =
            keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    domainSeparator,
                    keccak256(
                        abi.encode(
                            MINT_WITH_SIG_TYPEHASH,
                            data.contentHash,
                            data.metadataHash,
                            bidShares.creator.value,
                            mintWithSigNonces[creator]++,
                            sig.deadline
                        )
                    )
                )
            );

        address recoveredAddress = ecrecover(digest, sig.v, sig.r, sig.s);

        require(
            recoveredAddress != address(0) && creator == recoveredAddress && (owner() == recoveredAddress || authorized[recoveredAddress]),
            "Media: Signature invalid"
        );

        _mintForCreator(recoveredAddress, data, bidShares);
    }

    /**
     * @notice see IMedia
     */
    function auctionTransfer(uint256 tokenId, address recipient)
        external
        override
    {
        require(msg.sender == marketContract, "Media: only market contract");
        previousTokenOwners[tokenId] = ownerOf(tokenId);
        _safeTransfer(ownerOf(tokenId), recipient, tokenId, "");
    }

    /**
     * @notice see IMedia
     */
    function setAsk(uint256 tokenId, IMarket.Ask memory ask)
        public
        override
        nonReentrant
        onlyApprovedOrOwner(msg.sender, tokenId)
    {
        IMarket(marketContract).setAsk(tokenId, ask);
    }

    /**
     * @notice see IMedia
     */
    function removeAsk(uint256 tokenId)
        external
        override
        nonReentrant
        onlyApprovedOrOwner(msg.sender, tokenId)
    {
        IMarket(marketContract).removeAsk(tokenId);
    }

    /**
     * @notice see IMedia
     */
    function setBid(uint256 tokenId, IMarket.Bid memory bid)
        public
        override
        nonReentrant
        onlyExistingToken(tokenId)
    {
        require(msg.sender == bid.bidder, "Market: Bidder must be msg sender");
        IMarket(marketContract).setBid(tokenId, bid, msg.sender);
    }

    /**
     * @notice see IMedia
     */
    function removeBid(uint256 tokenId)
        external
        override
        nonReentrant
        onlyTokenCreated(tokenId)
    {
        IMarket(marketContract).removeBid(tokenId, msg.sender);
    }

    /**
     * @notice see IMedia
     */
    function acceptBid(uint256 tokenId, IMarket.Bid memory bid)
        public
        override
        nonReentrant
        onlyApprovedOrOwner(msg.sender, tokenId)
    {
        IMarket(marketContract).acceptBid(tokenId, bid);
    }

    /**
     * @notice Burn a token.
     * @dev Only callable if the media owner is also the creator.
     */
    function burn(uint256 tokenId)
        public
        override
        nonReentrant
        onlyExistingToken(tokenId)
        onlyApprovedOrOwner(msg.sender, tokenId)
    {
        //address owner = ownerOf(tokenId);

        //require(
        //    tokenCreators[tokenId] == owner,
        //    "Media: owner is not creator of media"
        //);

        _burn(tokenId);
    }

    /**
     * @notice Revoke the approvals for a token. The provided `approve` function is not sufficient
     * for this protocol, as it does not allow an approved address to revoke it's own approval.
     * In instances where a 3rd party is interacting on a user's behalf via `permit`, they should
     * revoke their approval once their task is complete as a best practice.
     */
    function revokeApproval(uint256 tokenId) external override nonReentrant {
        require(
            msg.sender == getApproved(tokenId),
            "Media: caller not approved address"
        );
        _approve(address(0), tokenId);
    }

    /**
     * @notice see IMedia
     * @dev only callable by approved or owner
     */
    function updateTokenURI(uint256 tokenId, string calldata tokenURI)
        external
        override
        nonReentrant
        onlyApprovedOrOwner(msg.sender, tokenId)
        onlyTokenWithContentHash(tokenId)
        onlyValidURI(tokenURI)
    {
        _setTokenURI(tokenId, tokenURI);
        emit TokenURIUpdated(tokenId, msg.sender, tokenURI);
    }

    /**
     * @notice see IMedia
     * @dev only callable by approved or owner
     */
    function updateTokenMetadataURI(
        uint256 tokenId,
        string calldata metadataURI
    )
        external
        override
        nonReentrant
        onlyApprovedOrOwner(msg.sender, tokenId)
        onlyTokenWithMetadataHash(tokenId)
        onlyValidURI(metadataURI)
    {
        _setTokenMetadataURI(tokenId, metadataURI);
        emit TokenMetadataURIUpdated(tokenId, msg.sender, metadataURI);
    }

    /**
     * @notice See IMedia
     * @dev This method is loosely based on the permit for ERC-20 tokens in  EIP-2612, but modified
     * for ERC-721.
     */
    function permit(
        address spender,
        uint256 tokenId,
        EIP712Signature memory sig
    ) public override nonReentrant onlyExistingToken(tokenId) {
        require(
            sig.deadline == 0 || sig.deadline >= block.timestamp,
            "Media: Permit expired"
        );
        require(spender != address(0), "Media: spender cannot be 0x0");
        bytes32 domainSeparator = _calculateDomainSeparator();

        bytes32 digest =
            keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    domainSeparator,
                    keccak256(
                        abi.encode(
                            PERMIT_TYPEHASH,
                            spender,
                            tokenId,
                            permitNonces[ownerOf(tokenId)][tokenId]++,
                            sig.deadline
                        )
                    )
                )
            );

        address recoveredAddress = ecrecover(digest, sig.v, sig.r, sig.s);

        require(
            recoveredAddress != address(0) &&
                ownerOf(tokenId) == recoveredAddress,
            "Media: Signature invalid"
        );

        _approve(spender, tokenId);
    }

    /* *****************
     * Private Functions
     * *****************
     */

    /**
     * @notice Creates a new token for `creator`. Its token ID will be automatically
     * assigned (and available on the emitted {IERC721-Transfer} event), and the token
     * URI autogenerated based on the base URI passed at construction.
     *
     * See {ERC721-_safeMint}.
     *
     * On mint, also set the sha256 hashes of the content and its metadata for integrity
     * checks, along with the initial URIs to point to the content and metadata. Attribute
     * the token ID to the creator, mark the content hash as used, and set the bid shares for
     * the media's market.
     *
     * Note that although the content hash must be unique for future mints to prevent duplicate media,
     * metadata has no such requirement.
     */
    function _mintForCreator(
        address creator,
        MediaData memory data,
        IMarket.BidShares memory bidShares
    ) internal onlyValidURI(data.tokenURI) onlyValidURI(data.metadataURI) {
        require(data.contentHash != 0, "Media: content hash must be non-zero");
        require(
            _contentHashes[data.contentHash] == false,
            "Media: a token has already been created with this content hash"
        );
        require(
            data.metadataHash != 0,
            "Media: metadata hash must be non-zero"
        );

        uint256 tokenId = _tokenIdTracker.current();

        _safeMint(creator, tokenId);
        _tokenIdTracker.increment();
        _setTokenContentHash(tokenId, data.contentHash);
        _setTokenMetadataHash(tokenId, data.metadataHash);
        _setTokenMetadataURI(tokenId, data.metadataURI);
        _setTokenURI(tokenId, data.tokenURI);
        _creatorTokens[creator].add(tokenId);
        _contentHashes[data.contentHash] = true;

        tokenCreators[tokenId] = creator;
        previousTokenOwners[tokenId] = creator;
        IMarket(marketContract).setBidShares(tokenId, bidShares);
    }

    function _setTokenContentHash(uint256 tokenId, bytes32 contentHash)
        internal
        virtual
        onlyExistingToken(tokenId)
    {
        tokenContentHashes[tokenId] = contentHash;
    }

    function _setTokenMetadataHash(uint256 tokenId, bytes32 metadataHash)
        internal
        virtual
        onlyExistingToken(tokenId)
    {
        tokenMetadataHashes[tokenId] = metadataHash;
    }

    function _setTokenMetadataURI(uint256 tokenId, string memory metadataURI)
        internal
        virtual
        onlyExistingToken(tokenId)
    {
        _tokenMetadataURIs[tokenId] = metadataURI;
    }

    /**
     * @notice Destroys `tokenId`.
     * @dev We modify the OZ _burn implementation to
     * maintain metadata and to remove the
     * previous token owner from the piece
     */
    function _burn(uint256 tokenId) internal override {
        string memory tokenURI = _tokenURIs[tokenId];

        super._burn(tokenId);

        if (bytes(tokenURI).length != 0) {
            _tokenURIs[tokenId] = tokenURI;
        }

        delete previousTokenOwners[tokenId];
    }

    /**
     * @notice transfer a token and remove the ask for it.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override {
        IMarket(marketContract).removeAsk(tokenId);

        super._transfer(from, to, tokenId);
    }

    /**
     * @dev Calculates EIP712 DOMAIN_SEPARATOR based on the current contract and chain ID.
     */
    function _calculateDomainSeparator() internal view returns (bytes32) {
        uint256 chainID;
        /* solium-disable-next-line */
        assembly {
            chainID := chainid()
        }

        return
            keccak256(
                abi.encode(
                    keccak256(
                        "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
                    ),
                    keccak256(bytes("Arto")),
                    keccak256(bytes("1")),
                    chainID,
                    address(this)
                )
            );
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"marketContractAddr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"}],"name":"AcceptOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"}],"name":"AddAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"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":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"RemoveAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"string","name":"_uri","type":"string"}],"name":"TokenMetadataURIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"string","name":"_uri","type":"string"}],"name":"TokenURIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MINT_WITH_SIG_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Decimal.D256","name":"sellOnShare","type":"tuple"}],"internalType":"struct IMarket.Bid","name":"bid","type":"tuple"}],"name":"acceptBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_toAdd","type":"address"}],"name":"addAuthorized","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addAuthorizedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"adminList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"auctionTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"authorize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasurerAddress","type":"address"}],"name":"configureRewardAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdminList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasurerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"tokenURI","type":"string"},{"internalType":"string","name":"metadataURI","type":"string"},{"internalType":"bytes32","name":"contentHash","type":"bytes32"},{"internalType":"bytes32","name":"metadataHash","type":"bytes32"}],"internalType":"struct IMedia.MediaData","name":"data","type":"tuple"},{"components":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Decimal.D256","name":"prevOwner","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Decimal.D256","name":"creator","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Decimal.D256","name":"owner","type":"tuple"}],"internalType":"struct IMarket.BidShares","name":"bidShares","type":"tuple"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"},{"components":[{"internalType":"string","name":"tokenURI","type":"string"},{"internalType":"string","name":"metadataURI","type":"string"},{"internalType":"bytes32","name":"contentHash","type":"bytes32"},{"internalType":"bytes32","name":"metadataHash","type":"bytes32"}],"internalType":"struct IMedia.MediaData","name":"data","type":"tuple"},{"components":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Decimal.D256","name":"prevOwner","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Decimal.D256","name":"creator","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Decimal.D256","name":"owner","type":"tuple"}],"internalType":"struct IMarket.BidShares","name":"bidShares","type":"tuple"},{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IMedia.EIP712Signature","name":"sig","type":"tuple"}],"name":"mintWithSig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintWithSigNonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IMedia.EIP712Signature","name":"sig","type":"tuple"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"permitNonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"previousTokenOwners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"removeAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_toRemove","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"removeAuthorized","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"removeBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"revokeApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"currency","type":"address"}],"internalType":"struct IMarket.Ask","name":"ask","type":"tuple"}],"name":"setAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Decimal.D256","name":"sellOnShare","type":"tuple"}],"internalType":"struct IMarket.Bid","name":"bid","type":"tuple"}],"name":"setBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenContentHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenCreators","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenMetadataHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenMetadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasurerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"metadataURI","type":"string"}],"name":"updateTokenMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"tokenURI","type":"string"}],"name":"updateTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604051620047db380380620047db833981016040819052620000349162000214565b604080518082018252600b81526a10549513d1919250d2505360aa1b602080830191909152825180840190935260048352634152544f60e01b9083015290620000846301ffc9a760e01b6200011d565b81516200009990600690602085019062000178565b508051620000af90600790602084019062000178565b50620000c26380ac58cd60e01b6200011d565b620000d463780e9d6360e01b6200011d565b50506001600a55600b8054336001600160a01b031991821617909155601080549091166001600160a01b03831617905562000116632711173360e11b6200011d565b506200027b565b6001600160e01b03198082161415620001535760405162461bcd60e51b81526004016200014a9062000244565b60405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620001bb57805160ff1916838001178555620001eb565b82800160010185558215620001eb579182015b82811115620001eb578251825591602001919060010190620001ce565b50620001f9929150620001fd565b5090565b5b80821115620001f95760008155600101620001fe565b60006020828403121562000226578081fd5b81516001600160a01b03811681146200023d578182fd5b9392505050565b6020808252601c908201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604082015260600190565b614550806200028b6000396000f3fe608060405234801561001057600080fd5b50600436106103835760003560e01c806370a08231116101de578063b320f4591161010f578063d9f774fc116100ad578063f2fde38b1161007c578063f2fde38b1461071e578063f6b630f014610731578063f8ccd5de14610744578063fad321971461075757610383565b8063d9f774fc146106db578063de5236fb146106f0578063e0fd045f146106f8578063e985e9c51461070b57610383565b8063b9181611116100e9578063b91816111461068f578063ba339399146106a2578063c87b56dd146106b5578063cf1c316a146106c857610383565b8063b320f45914610656578063b6a5d7de14610669578063b88d4fde1461067c57610383565b806395d89b411161017c578063a1e622f211610156578063a1e622f214610615578063a22cb46514610628578063b1e130fc1461063b578063b2bdfa7b1461064e57610383565b806395d89b41146105f25780639d8e7260146105fa578063a1794bcd1461060d57610383565b806379ba5097116101b857806379ba5097146105c75780637a7a1202146105cf5780638da5cb5b146105e25780638f32d59b146105ea57610383565b806370a0823114610599578063715018a6146105ac57806375682e79146105b457610383565b80632cca3237116102b85780635bf6242211610256578063676b2b6811610230578063676b2b681461056e5780636a368973146105765780636b34a45a146105895780636c0360eb1461059157610383565b80635bf624221461053557806362f24b70146105485780636352211e1461055b57610383565b806342842e0e1161029257806342842e0e146104e957806342966c68146104fc57806342f1181e1461050f5780634f6ccce71461052257610383565b80632cca3237146104bb5780632f745c59146104ce57806330adf81f146104e157610383565b80631072cbea1161032557806318160ddd116102ff57806318160ddd1461047a57806318e97fd11461048257806323b872dd1461049557806328220f35146104a857610383565b80631072cbea1461044157806311117fc814610454578063157c3df91461046757610383565b8063081812fc11610361578063081812fc146103e6578063095ea7b3146104065780630bcd899b1461041b5780630e2a17781461042e57610383565b806301ddc3b51461038857806301ffc9a7146103b157806306fdde03146103d1575b600080fd5b61039b610396366004613538565b61076a565b6040516103a8919061385b565b60405180910390f35b6103c46103bf3660046134bc565b61077c565b6040516103a89190613850565b6103d961079b565b6040516103a89190613902565b6103f96103f4366004613538565b610831565b6040516103a89190613772565b610419610414366004613454565b61087d565b005b61039b6104293660046132b1565b610915565b61041961043c36600461347e565b610927565b61041961044f366004613454565b610b4b565b6103f9610462366004613538565b610c49565b6103d9610475366004613538565b610c70565b61039b610d3b565b610419610490366004613573565b610d4c565b6104196104a3366004613300565b610eab565b6104196104b6366004613538565b610ee3565b6104196104c93660046134f4565b610f91565b61039b6104dc366004613454565b611011565b61039b61103c565b6104196104f7366004613300565b611060565b61041961050a366004613538565b61107b565b6103c461051d3660046132b1565b611105565b61039b610530366004613538565b61111a565b610419610543366004613641565b611130565b6104196105563660046135ea565b6111e7565b6103f9610569366004613538565b6112a6565b6103f96112ce565b6104196105843660046132b1565b6112dd565b6103f9611349565b6103d9611358565b61039b6105a73660046132b1565b6113b9565b610419611402565b6104196105c2366004613573565b611470565b6104196115b9565b6104196105dd3660046133e3565b61166a565b6103f961186a565b6103c4611879565b6103d961188a565b6103f9610608366004613538565b6118eb565b6103f9611906565b610419610623366004613454565b611915565b6104196106363660046133a8565b611a61565b610419610649366004613538565b611b2f565b6103f9611ba3565b610419610664366004613538565b611bb2565b6103c46106773660046132b1565b611c70565b61041961068a366004613340565b611c8e565b6103c461069d3660046132b1565b611cc7565b6104196106b0366004613641565b611cdc565b6103d96106c3366004613538565b611d5e565b6104196106d63660046132b1565b611e2c565b6106e3611ec2565b6040516103a89190613803565b61039b611f23565b6103f9610706366004613538565b611f47565b6103c46107193660046132cc565b611f62565b61041961072c3660046132b1565b611f90565b61041961073f366004613550565b611fc0565b61039b610752366004613454565b612046565b61039b610765366004613538565b612063565b60156020526000908152604090205481565b6001600160e01b03191660009081526020819052604090205460ff1690565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108275780601f106107fc57610100808354040283529160200191610827565b820191906000526020600020905b81548152906001019060200180831161080a57829003601f168201915b5050505050905090565b600061083c82612075565b6108615760405162461bcd60e51b815260040161085890613f94565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610888826112a6565b9050806001600160a01b0316836001600160a01b031614156108bc5760405162461bcd60e51b815260040161085890614185565b806001600160a01b03166108ce612082565b6001600160a01b031614806108ea57506108ea81610719612082565b6109065760405162461bcd60e51b815260040161085890613db3565b6109108383612086565b505050565b60196020526000908152604090205481565b6002600a54141561094a5760405162461bcd60e51b81526004016108589061431e565b6002600a558161095981612075565b6109755760405162461bcd60e51b8152600401610858906142e7565b81511580610984575081514211155b6109a05760405162461bcd60e51b815260040161085890613e5a565b6001600160a01b0384166109c65760405162461bcd60e51b815260040161085890613ac0565b60006109d06120f4565b90506000817f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad8787601885610a04836112a6565b6001600160a01b03168152602080820192909252604090810160009081208c825283528190208054600181019091558a519151610a479695949391929101613864565b60405160208183030381529060405280519060200120604051602001610a6e929190613757565b604051602081830303815290604052805190602001209050600060018286602001518760400151886060015160405160008152602001604052604051610ab794939291906138e4565b6020604051602081039080840390855afa158015610ad9573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610b175750806001600160a01b0316610b0c876112a6565b6001600160a01b0316145b610b335760405162461bcd60e51b8152600401610858906142b0565b610b3d8787612086565b50506001600a555050505050565b610b53611879565b610b6f5760405162461bcd60e51b815260040161085890613957565b8080610b7b601a6121ba565b11610b985760405162461bcd60e51b81526004016108589061399c565b6000610ba3836112a6565b9050836001600160a01b0316610bb761186a565b6001600160a01b03161480610be457506001600160a01b0384166000908152600c602052604090205460ff165b610c005760405162461bcd60e51b8152600401610858906139e4565b6001600160a01b0381166000908152600c602052604090205460ff16610c385760405162461bcd60e51b8152600401610858906139e4565b610c438185856121be565b50505050565b600e8181548110610c5657fe5b6000918252602090912001546001600160a01b0316905081565b60608180610c7e601a6121ba565b11610c9b5760405162461bcd60e51b81526004016108589061399c565b60008381526016602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015610d2e5780601f10610d0357610100808354040283529160200191610d2e565b820191906000526020600020905b815481529060010190602001808311610d1157829003601f168201915b5050505050915050919050565b6000610d4760026122cc565b905090565b6002600a541415610d6f5760405162461bcd60e51b81526004016108589061431e565b6002600a553383610d8082826122d7565b610d9c5760405162461bcd60e51b81526004016108589061402c565b6000858152601460205260409020548590610dc95760405162461bcd60e51b8152600401610858906140ee565b84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825115159150610e2190505760405162461bcd60e51b815260040161085890614355565b610e618787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061235c92505050565b867f702fe2dc2dc0f68023540aa4a1e11811c0f29112f6ebf01e61b90538e4f29810338888604051610e95939291906137c3565b60405180910390a250506001600a555050505050565b610ebc610eb6612082565b826122d7565b610ed85760405162461bcd60e51b815260040161085890614228565b6109108383836123a0565b6002600a541415610f065760405162461bcd60e51b81526004016108589061431e565b6002600a553381610f1782826122d7565b610f335760405162461bcd60e51b81526004016108589061402c565b6010546040516328220f3560e01b81526001600160a01b03909116906328220f3590610f6390869060040161385b565b600060405180830381600087803b158015610f7d57600080fd5b505af1158015610b3d573d6000803e3d6000fd5b336000908152600c602052604090205460ff1680610fb95750600b546001600160a01b031633145b610fd55760405162461bcd60e51b815260040161085890613a6d565b6002600a541415610ff85760405162461bcd60e51b81526004016108589061431e565b6002600a5561100833838361240d565b50506001600a55565b6001600160a01b038216600090815260016020526040812061103390836125fd565b90505b92915050565b7f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad81565b61091083838360405180602001604052806000815250611c8e565b6002600a54141561109e5760405162461bcd60e51b81526004016108589061431e565b6002600a55806110ad81612075565b6110c95760405162461bcd60e51b8152600401610858906142e7565b33826110d582826122d7565b6110f15760405162461bcd60e51b81526004016108589061402c565b6110fa84612609565b50506001600a555050565b600d6020526000908152604090205460ff1681565b6000806111286002846126f5565b509392505050565b6002600a5414156111535760405162461bcd60e51b81526004016108589061431e565b6002600a558161116281612075565b61117e5760405162461bcd60e51b8152600401610858906142e7565b81604001516001600160a01b0316336001600160a01b0316146111b35760405162461bcd60e51b815260040161085890613b5b565b6010546040516317b6b0d360e31b81526001600160a01b039091169063bdb5869890610f6390869086903390600401614414565b6002600a54141561120a5760405162461bcd60e51b81526004016108589061431e565b6002600a55338261121b82826122d7565b6112375760405162461bcd60e51b81526004016108589061402c565b60105460405163062f24b760e41b81526001600160a01b03909116906362f24b709061126990879087906004016143b2565b600060405180830381600087803b15801561128357600080fd5b505af1158015611297573d6000803e3d6000fd5b50506001600a55505050505050565b6000611036826040518060600160405280602981526020016144f26029913960029190612711565b600f546001600160a01b031690565b6112e5611879565b6113015760405162461bcd60e51b815260040161085890613957565b6001600160a01b0381166113275760405162461bcd60e51b815260040161085890613af7565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600f546001600160a01b031681565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108275780601f106107fc57610100808354040283529160200191610827565b60006001600160a01b0382166113e15760405162461bcd60e51b815260040161085890613e10565b6001600160a01b0382166000908152600160205260409020611036906122cc565b61140a611879565b6114265760405162461bcd60e51b815260040161085890613957565b600b546040516001600160a01b03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600b80546001600160a01b0319169055565b6002600a5414156114935760405162461bcd60e51b81526004016108589061431e565b6002600a5533836114a482826122d7565b6114c05760405162461bcd60e51b81526004016108589061402c565b60008581526015602052604090205485906114ed5760405162461bcd60e51b815260040161085890613cd4565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082511515915061154590505760405162461bcd60e51b815260040161085890614355565b6115858787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061272892505050565b867fe3df41127db820c79e5b8d541a63e40e3e97b9af96f7a50bded13091b70df9ae338888604051610e95939291906137c3565b336000908152600d602052604090205460ff166115e85760405162461bcd60e51b815260040161085890614063565b336000818152600c6020526040808220805460ff19166001908117909155600e8054918201815583527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b03191684179055517f7f877120c72766f4eac00144c86c9e57ed52f31bac01ef5c4c223c4768a876739190a2565b6002600a54141561168d5760405162461bcd60e51b81526004016108589061431e565b6002600a55805115806116a1575080514211155b6116bd5760405162461bcd60e51b8152600401610858906141f1565b60006116c76120f4565b6040808601516060870151602080880151516001600160a01b038b166000908152601983528581208054600181019091558951965197985090968896611735967f2952e482b8e2b192305f87374d7af45dc2eafafe4f50d26a0c02e90f2fdbe14b96909590949392016138bc565b6040516020818303038152906040528051906020012060405160200161175c929190613757565b6040516020818303038152906040528051906020012090506000600182856020015186604001518760600151604051600081526020016040526040516117a594939291906138e4565b6020604051602081039080840390855afa1580156117c7573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906117fd5750806001600160a01b0316876001600160a01b0316145b80156118435750806001600160a01b031661181661186a565b6001600160a01b0316148061184357506001600160a01b0381166000908152600c602052604090205460ff165b61185f5760405162461bcd60e51b8152600401610858906142b0565b610b3d81878761240d565b600b546001600160a01b031690565b600b546001600160a01b0316331490565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108275780601f106107fc57610100808354040283529160200191610827565b6011602052600090815260409020546001600160a01b031681565b6010546001600160a01b031681565b61191d611879565b6119395760405162461bcd60e51b815260040161085890613957565b6001600160a01b03821661195f5760405162461bcd60e51b815260040161085890613be7565b6001600160a01b03821633141561197557600080fd5b816001600160a01b0316600e828154811061198c57fe5b6000918252602090912001546001600160a01b0316146119be5760405162461bcd60e51b8152600401610858906141c6565b6001600160a01b0382166000908152600d60209081526040808320805460ff19908116909155600c90925290912080549091169055600e805482908110611a0157fe5b600091825260209091200180546001600160a01b03191690556040516001600160a01b038316907f4351fca1a489ee987699b3c49344da8a6c88963c20d8e6e1c0a9b9650b54115990611a5590849061385b565b60405180910390a25050565b611a69612082565b6001600160a01b0316826001600160a01b03161415611a9a5760405162461bcd60e51b815260040161085890613c9d565b8060056000611aa7612082565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611aeb612082565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611b239190613850565b60405180910390a35050565b6002600a541415611b525760405162461bcd60e51b81526004016108589061431e565b6002600a55611b6081610831565b6001600160a01b0316336001600160a01b031614611b905760405162461bcd60e51b815260040161085890613c17565b611b9b600082612086565b506001600a55565b600b546001600160a01b031681565b6002600a541415611bd55760405162461bcd60e51b81526004016108589061431e565b6002600a558080611be6601a6121ba565b11611c035760405162461bcd60e51b81526004016108589061399c565b60105460405163776a083560e01b81526001600160a01b039091169063776a083590611c35908590339060040161439b565b600060405180830381600087803b158015611c4f57600080fd5b505af1158015611c63573d6000803e3d6000fd5b50506001600a5550505050565b6001600160a01b03166000908152600c602052604090205460ff1690565b611c9f611c99612082565b836122d7565b611cbb5760405162461bcd60e51b815260040161085890614228565b610c438484848461276d565b600c6020526000908152604090205460ff1681565b6002600a541415611cff5760405162461bcd60e51b81526004016108589061431e565b6002600a553382611d1082826122d7565b611d2c5760405162461bcd60e51b81526004016108589061402c565b60105460405163ba33939960e01b81526001600160a01b039091169063ba339399906112699087908790600401614400565b60608180611d6c601a6121ba565b11611d895760405162461bcd60e51b81526004016108589061399c565b60008381526008602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015611e1e5780601f10611df357610100808354040283529160200191611e1e565b820191906000526020600020905b815481529060010190602001808311611e0157829003601f168201915b509398975050505050505050565b611e34611879565b611e505760405162461bcd60e51b815260040161085890613957565b6001600160a01b038116611e765760405162461bcd60e51b815260040161085890613be7565b6001600160a01b0381166000818152600d6020526040808220805460ff19166001179055517fa6f04ef390ee5829dc9be99664fd8d9aeea059278dbda4f988499726455801ce9190a250565b6060600e80548060200260200160405190810160405280929190818152602001828054801561082757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611efc575050505050905090565b7f2952e482b8e2b192305f87374d7af45dc2eafafe4f50d26a0c02e90f2fdbe14b81565b6012602052600090815260409020546001600160a01b031681565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b611f98611879565b611fb45760405162461bcd60e51b815260040161085890613957565b611fbd816127a0565b50565b6010546001600160a01b03163314611fea5760405162461bcd60e51b815260040161085890613f28565b611ff3826112a6565b600083815260116020526040902080546001600160a01b0319166001600160a01b039290921691909117905561204261202b836112a6565b82846040518060200160405280600081525061276d565b5050565b601860209081526000928352604080842090915290825290205481565b60146020526000908152604090205481565b6000611036600283612822565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906120bb826112a6565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60408051808201825260048152634172746f60e01b6020918201528151808301835260018152603160f81b908201529051600091469161219e917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f917f64e5e55c6a2790759ed01c581dcc6ee14925b98404a095158e9a67c6cf3fd21f917fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6918691309101613890565b6040516020818303038152906040528051906020012091505090565b5490565b826001600160a01b03166121d1826112a6565b6001600160a01b0316146121f75760405162461bcd60e51b8152600401610858906140a5565b6001600160a01b03821661221d5760405162461bcd60e51b815260040161085890613c59565b612228838383610910565b612233600082612086565b6001600160a01b0383166000908152600160205260409020612255908261282e565b506001600160a01b0382166000908152600160205260409020612278908261283a565b5061228560028284612846565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000611036826121ba565b60006122e282612075565b6122fe5760405162461bcd60e51b815260040161085890613d67565b6000612309836112a6565b9050806001600160a01b0316846001600160a01b031614806123445750836001600160a01b031661233984610831565b6001600160a01b0316145b8061235457506123548185611f62565b949350505050565b61236582612075565b6123815760405162461bcd60e51b815260040161085890613fe0565b600082815260086020908152604090912082516109109284019061300c565b6010546040516328220f3560e01b81526001600160a01b03909116906328220f35906123d090849060040161385b565b600060405180830381600087803b1580156123ea57600080fd5b505af11580156123fe573d6000803e3d6000fd5b505050506109108383836121be565b8151805161242d5760405162461bcd60e51b815260040161085890614355565b602083015180516124505760405162461bcd60e51b815260040161085890614355565b60408401516124715760405162461bcd60e51b815260040161085890613d23565b60408085015160009081526017602052205460ff16156124a35760405162461bcd60e51b815260040161085890613e89565b60608401516124c45760405162461bcd60e51b815260040161085890614140565b60006124d0601a6121ba565b90506124dc868261285c565b6124e6601a612876565b6124f481866040015161287f565b6125028186606001516128b8565b612510818660200151612728565b61251e81866000015161235c565b6001600160a01b0386166000908152601360205260409020612540908261283a565b50604080860151600090815260176020908152828220805460ff191660011790558382526012815282822080546001600160a01b03808c166001600160a01b0319928316811790935560119093529284902080549093161790915560105491516375aab41d60e11b815291169063eb55683a906125c390849088906004016143d6565b600060405180830381600087803b1580156125dd57600080fd5b505af11580156125f1573d6000803e3d6000fd5b50505050505050505050565b600061103383836128f1565b60008181526008602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526060939283018282801561269e5780601f106126735761010080835404028352916020019161269e565b820191906000526020600020905b81548152906001019060200180831161268157829003601f168201915b505050505090506126ae82612936565b8051156126d657600082815260086020908152604090912082516126d49284019061300c565b505b50600090815260116020526040902080546001600160a01b0319169055565b60008080806127048686612a03565b9097909650945050505050565b600061271e848484612a5f565b90505b9392505050565b8161273281612075565b61274e5760405162461bcd60e51b8152600401610858906142e7565b60008381526016602090815260409091208351610c439285019061300c565b6127788484846123a0565b61278484848484612abe565b610c435760405162461bcd60e51b815260040161085890613a1b565b6001600160a01b0381166127c65760405162461bcd60e51b815260040161085890613b9c565b600b546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60006110338383612b9d565b60006110338383612bb5565b60006110338383612c7b565b600061271e84846001600160a01b038516612cc5565b612042828260405180602001604052806000815250612d5c565b80546001019055565b8161288981612075565b6128a55760405162461bcd60e51b8152600401610858906142e7565b5060009182526014602052604090912055565b816128c281612075565b6128de5760405162461bcd60e51b8152600401610858906142e7565b5060009182526015602052604090912055565b815460009082106129145760405162461bcd60e51b815260040161085890613915565b82600001828154811061292357fe5b9060005260206000200154905092915050565b6000612941826112a6565b905061294f81600084610910565b61295a600083612086565b60008281526008602052604090205460026000196101006001841615020190911604156129985760008281526008602052604081206129989161308a565b6001600160a01b03811660009081526001602052604090206129ba908361282e565b506129c6600283612d8f565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b815460009081908310612a285760405162461bcd60e51b815260040161085890613ee6565b6000846000018481548110612a3957fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008281526001840160205260408120548281612a8f5760405162461bcd60e51b81526004016108589190613902565b50846000016001820381548110612aa257fe5b9060005260206000209060020201600101549150509392505050565b6000612ad2846001600160a01b0316612d9b565b612ade57506001612354565b6060612b66630a85bd0160e11b612af3612082565b888787604051602401612b099493929190613786565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518060600160405280603281526020016144c0603291396001600160a01b0388169190612da1565b9050600081806020019051810190612b7e91906134d8565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015612c715783546000198083019190810190600090879083908110612be857fe5b9060005260206000200154905080876000018481548110612c0557fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612c3557fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611036565b6000915050611036565b6000612c878383612b9d565b612cbd57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611036565b506000611036565b600082815260018401602052604081205480612d2a575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055612721565b82856000016001830381548110612d3d57fe5b9060005260206000209060020201600101819055506000915050612721565b612d668383612db0565b612d736000848484612abe565b6109105760405162461bcd60e51b815260040161085890613a1b565b60006110338383612e74565b3b151590565b606061271e8484600085612f48565b6001600160a01b038216612dd65760405162461bcd60e51b815260040161085890613f5f565b612ddf81612075565b15612dfc5760405162461bcd60e51b815260040161085890613b24565b612e0860008383610910565b6001600160a01b0382166000908152600160205260409020612e2a908261283a565b50612e3760028284612846565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008181526001830160205260408120548015612c715783546000198083019190810190600090879083908110612ea757fe5b9060005260206000209060020201905080876000018481548110612ec757fe5b600091825260208083208454600290930201918255600193840154918401919091558354825289830190526040902090840190558654879080612f0657fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506110369350505050565b6060612f5385612d9b565b612f6f5760405162461bcd60e51b815260040161085890614279565b60006060866001600160a01b03168587604051612f8c919061373b565b60006040518083038185875af1925050503d8060008114612fc9576040519150601f19603f3d011682016040523d82523d6000602084013e612fce565b606091505b50915091508115612fe25791506123549050565b805115612ff25780518082602001fd5b8360405162461bcd60e51b81526004016108589190613902565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061304d57805160ff191683800117855561307a565b8280016001018555821561307a579182015b8281111561307a57825182559160200191906001019061305f565b506130869291506130ca565b5090565b50805460018160011615610100020316600290046000825580601f106130b05750611fbd565b601f016020900490600052602060002090810190611fbd91905b5b8082111561308657600081556001016130cb565b80356001600160a01b038116811461103657600080fd5b600082601f830112613106578081fd5b813567ffffffffffffffff81111561311c578182fd5b61312f601f8201601f1916602001614441565b915080825283602082850101111561314657600080fd5b8060208401602084013760009082016020015292915050565b600060608284031215613170578081fd5b61317a6060614441565b905061318683836131b2565b815261319583602084016131b2565b60208201526131a783604084016131b2565b604082015292915050565b6000602082840312156131c3578081fd5b6131cd6020614441565b9135825250919050565b6000608082840312156131e8578081fd5b6131f26080614441565b905081358152602082013560ff8116811461320c57600080fd5b80602083015250604082013560408201526060820135606082015292915050565b60006080828403121561323e578081fd5b6132486080614441565b9050813567ffffffffffffffff8082111561326257600080fd5b61326e858386016130f6565b8352602084013591508082111561328457600080fd5b50613291848285016130f6565b602083015250604082013560408201526060820135606082015292915050565b6000602082840312156132c2578081fd5b61103383836130df565b600080604083850312156132de578081fd5b6132e884846130df565b91506132f784602085016130df565b90509250929050565b600080600060608486031215613314578081fd5b833561331f81614494565b9250602084013561332f81614494565b929592945050506040919091013590565b60008060008060808587031215613355578081fd5b61335f86866130df565b935061336e86602087016130df565b925060408501359150606085013567ffffffffffffffff811115613390578182fd5b61339c878288016130f6565b91505092959194509250565b600080604083850312156133ba578182fd5b6133c484846130df565b9150602083013580151581146133d8578182fd5b809150509250929050565b60008060008061012085870312156133f9578081fd5b61340386866130df565b9350602085013567ffffffffffffffff81111561341e578182fd5b61342a8782880161322d565b93505061343a866040870161315f565b91506134498660a087016131d7565b905092959194509250565b60008060408385031215613466578182fd5b61347084846130df565b946020939093013593505050565b600080600060c08486031215613492578081fd5b833561349d81614494565b9250602084013591506134b385604086016131d7565b90509250925092565b6000602082840312156134cd578081fd5b8135612721816144a9565b6000602082840312156134e9578081fd5b8151612721816144a9565b60008060808385031215613506578182fd5b823567ffffffffffffffff81111561351c578283fd5b6135288582860161322d565b9250506132f7846020850161315f565b600060208284031215613549578081fd5b5035919050565b60008060408385031215613562578182fd5b823591506132f784602085016130df565b600080600060408486031215613587578081fd5b83359250602084013567ffffffffffffffff808211156135a5578283fd5b818601915086601f8301126135b8578283fd5b8135818111156135c6578384fd5b8760208285010111156135d7578384fd5b6020830194508093505050509250925092565b60008082840360608112156135fd578283fd5b833592506040601f1982011215613612578182fd5b5061361d6040614441565b6020840135815261363185604086016130df565b6020820152809150509250929050565b60008082840360c0811215613654578283fd5b8335925060a0601f1982011215613669578182fd5b5061367460a0614441565b6020840135815261368885604086016130df565b602082015261369a85606086016130df565b60408201526136ac85608086016130df565b60608201526136be8560a086016131b2565b6080820152809150509250929050565b600081518084526136e6816020860160208601614468565b601f01601f19169290920160200192915050565b805182526020808201516001600160a01b03908116918401919091526040808301518216908401526060808301519091169083015260809081015151910152565b6000825161374d818460208701614468565b9190910192915050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906137b9908301846136ce565b9695505050505050565b6001600160a01b03841681526040602082018190528101829052600082846060840137818301606090810191909152601f909201601f1916010192915050565b6020808252825182820181905260009190848201906040850190845b818110156138445783516001600160a01b03168352928401929184019160010161381f565b50909695505050505050565b901515815260200190565b90815260200190565b9485526001600160a01b0393909316602085015260408401919091526060830152608082015260a00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b958652602086019490945260408501929092526060840152608083015260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b60006020825261103360208301846136ce565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526025908201527f4f776e61626c653a2063616c6c6572206973206e6f742074686520537570657260408201526420b236b4b760d91b606082015260800190565b60208082526028908201527f4d656469613a20746f6b656e2077697468207468617420696420646f6573206e6040820152671bdd08195e1a5cdd60c21b606082015260800190565b60208082526019908201527f6e6f7420612076616c6964206f776e6572206164647265737300000000000000604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526033908201527f417574686f72697a61626c653a2063616c6c6572206973206e6f74207468652060408201527229bab832b920b236b4b71037b91020b236b4b760691b606082015260800190565b6020808252601c908201527f4d656469613a207370656e6465722063616e6e6f742062652030783000000000604082015260600190565b6020808252601390820152726e6f7420612076616c6964206164647265737360681b604082015260600190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526021908201527f4d61726b65743a20426964646572206d757374206265206d73672073656e64656040820152603960f91b606082015260800190565b6020808252602b908201527f4f776e61626c653a206e657720537570657241646d696e20697320746865207a60408201526a65726f206164647265737360a81b606082015260800190565b6020808252601690820152756973206e6f742061207661696c64206164647265737360501b604082015260600190565b60208082526022908201527f4d656469613a2063616c6c6572206e6f7420617070726f766564206164647265604082015261737360f01b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602f908201527f4d656469613a20746f6b656e20646f6573206e6f74206861766520686173682060408201526e6f6620697473206d6574616461746160881b606082015260800190565b60208082526024908201527f4d656469613a20636f6e74656e742068617368206d757374206265206e6f6e2d6040820152637a65726f60e01b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252601590820152741359591a584e8814195c9b5a5d08195e1c1a5c9959605a1b604082015260600190565b6020808252603e908201527f4d656469613a206120746f6b656e2068617320616c7265616479206265656e2060408201527f637265617465642077697468207468697320636f6e74656e7420686173680000606082015260800190565b60208082526022908201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252601b908201527f4d656469613a206f6e6c79206d61726b657420636f6e74726163740000000000604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252602c908201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601d908201527f4d656469613a204f6e6c7920617070726f766564206f72206f776e6572000000604082015260600190565b60208082526022908201527f417574686f72697a61626c653a4f6e6c7920617574686f72697a6564206f776e60408201526132b960f11b606082015260800190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526032908201527f4d656469613a20746f6b656e20646f6573206e6f7420686176652068617368206040820152711bd98818dc99585d19590818dbdb9d195b9d60721b606082015260800190565b60208082526025908201527f4d656469613a206d657461646174612068617368206d757374206265206e6f6e6040820152642d7a65726f60d81b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b6020808252601190820152700dcdee840c240ecc2d8d2c840d2dcc8caf607b1b604082015260600190565b6020808252601a908201527f4d656469613a206d696e74576974685369672065787069726564000000000000604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526018908201527f4d656469613a205369676e617475726520696e76616c69640000000000000000604082015260600190565b60208082526018908201527f4d656469613a206e6f6e6578697374656e7420746f6b656e0000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526026908201527f4d656469613a2073706563696669656420757269206d757374206265206e6f6e6040820152652d656d70747960d01b606082015260800190565b9182526001600160a01b0316602082015260400190565b918252805160208084019190915201516001600160a01b0316604082015260600190565b91825280515160208084019190915281015151604080840191909152015151606082015260800190565b82815260c0810161272160208301846136fa565b83815260e0810161442860208301856136fa565b6001600160a01b039290921660c0919091015292915050565b60405181810167ffffffffffffffff8111828210171561446057600080fd5b604052919050565b60005b8381101561448357818101518382015260200161446b565b83811115610c435750506000910152565b6001600160a01b0381168114611fbd57600080fd5b6001600160e01b031981168114611fbd57600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212203f49cdfbced025dd615fc21625c8ca5d4c7978f7ae78e70d36498689bf44dd0464736f6c634300060c0033000000000000000000000000a7321f4eeb92abb8e33dddceff93ee7bfbb8a9cb

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103835760003560e01c806370a08231116101de578063b320f4591161010f578063d9f774fc116100ad578063f2fde38b1161007c578063f2fde38b1461071e578063f6b630f014610731578063f8ccd5de14610744578063fad321971461075757610383565b8063d9f774fc146106db578063de5236fb146106f0578063e0fd045f146106f8578063e985e9c51461070b57610383565b8063b9181611116100e9578063b91816111461068f578063ba339399146106a2578063c87b56dd146106b5578063cf1c316a146106c857610383565b8063b320f45914610656578063b6a5d7de14610669578063b88d4fde1461067c57610383565b806395d89b411161017c578063a1e622f211610156578063a1e622f214610615578063a22cb46514610628578063b1e130fc1461063b578063b2bdfa7b1461064e57610383565b806395d89b41146105f25780639d8e7260146105fa578063a1794bcd1461060d57610383565b806379ba5097116101b857806379ba5097146105c75780637a7a1202146105cf5780638da5cb5b146105e25780638f32d59b146105ea57610383565b806370a0823114610599578063715018a6146105ac57806375682e79146105b457610383565b80632cca3237116102b85780635bf6242211610256578063676b2b6811610230578063676b2b681461056e5780636a368973146105765780636b34a45a146105895780636c0360eb1461059157610383565b80635bf624221461053557806362f24b70146105485780636352211e1461055b57610383565b806342842e0e1161029257806342842e0e146104e957806342966c68146104fc57806342f1181e1461050f5780634f6ccce71461052257610383565b80632cca3237146104bb5780632f745c59146104ce57806330adf81f146104e157610383565b80631072cbea1161032557806318160ddd116102ff57806318160ddd1461047a57806318e97fd11461048257806323b872dd1461049557806328220f35146104a857610383565b80631072cbea1461044157806311117fc814610454578063157c3df91461046757610383565b8063081812fc11610361578063081812fc146103e6578063095ea7b3146104065780630bcd899b1461041b5780630e2a17781461042e57610383565b806301ddc3b51461038857806301ffc9a7146103b157806306fdde03146103d1575b600080fd5b61039b610396366004613538565b61076a565b6040516103a8919061385b565b60405180910390f35b6103c46103bf3660046134bc565b61077c565b6040516103a89190613850565b6103d961079b565b6040516103a89190613902565b6103f96103f4366004613538565b610831565b6040516103a89190613772565b610419610414366004613454565b61087d565b005b61039b6104293660046132b1565b610915565b61041961043c36600461347e565b610927565b61041961044f366004613454565b610b4b565b6103f9610462366004613538565b610c49565b6103d9610475366004613538565b610c70565b61039b610d3b565b610419610490366004613573565b610d4c565b6104196104a3366004613300565b610eab565b6104196104b6366004613538565b610ee3565b6104196104c93660046134f4565b610f91565b61039b6104dc366004613454565b611011565b61039b61103c565b6104196104f7366004613300565b611060565b61041961050a366004613538565b61107b565b6103c461051d3660046132b1565b611105565b61039b610530366004613538565b61111a565b610419610543366004613641565b611130565b6104196105563660046135ea565b6111e7565b6103f9610569366004613538565b6112a6565b6103f96112ce565b6104196105843660046132b1565b6112dd565b6103f9611349565b6103d9611358565b61039b6105a73660046132b1565b6113b9565b610419611402565b6104196105c2366004613573565b611470565b6104196115b9565b6104196105dd3660046133e3565b61166a565b6103f961186a565b6103c4611879565b6103d961188a565b6103f9610608366004613538565b6118eb565b6103f9611906565b610419610623366004613454565b611915565b6104196106363660046133a8565b611a61565b610419610649366004613538565b611b2f565b6103f9611ba3565b610419610664366004613538565b611bb2565b6103c46106773660046132b1565b611c70565b61041961068a366004613340565b611c8e565b6103c461069d3660046132b1565b611cc7565b6104196106b0366004613641565b611cdc565b6103d96106c3366004613538565b611d5e565b6104196106d63660046132b1565b611e2c565b6106e3611ec2565b6040516103a89190613803565b61039b611f23565b6103f9610706366004613538565b611f47565b6103c46107193660046132cc565b611f62565b61041961072c3660046132b1565b611f90565b61041961073f366004613550565b611fc0565b61039b610752366004613454565b612046565b61039b610765366004613538565b612063565b60156020526000908152604090205481565b6001600160e01b03191660009081526020819052604090205460ff1690565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108275780601f106107fc57610100808354040283529160200191610827565b820191906000526020600020905b81548152906001019060200180831161080a57829003601f168201915b5050505050905090565b600061083c82612075565b6108615760405162461bcd60e51b815260040161085890613f94565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610888826112a6565b9050806001600160a01b0316836001600160a01b031614156108bc5760405162461bcd60e51b815260040161085890614185565b806001600160a01b03166108ce612082565b6001600160a01b031614806108ea57506108ea81610719612082565b6109065760405162461bcd60e51b815260040161085890613db3565b6109108383612086565b505050565b60196020526000908152604090205481565b6002600a54141561094a5760405162461bcd60e51b81526004016108589061431e565b6002600a558161095981612075565b6109755760405162461bcd60e51b8152600401610858906142e7565b81511580610984575081514211155b6109a05760405162461bcd60e51b815260040161085890613e5a565b6001600160a01b0384166109c65760405162461bcd60e51b815260040161085890613ac0565b60006109d06120f4565b90506000817f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad8787601885610a04836112a6565b6001600160a01b03168152602080820192909252604090810160009081208c825283528190208054600181019091558a519151610a479695949391929101613864565b60405160208183030381529060405280519060200120604051602001610a6e929190613757565b604051602081830303815290604052805190602001209050600060018286602001518760400151886060015160405160008152602001604052604051610ab794939291906138e4565b6020604051602081039080840390855afa158015610ad9573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610b175750806001600160a01b0316610b0c876112a6565b6001600160a01b0316145b610b335760405162461bcd60e51b8152600401610858906142b0565b610b3d8787612086565b50506001600a555050505050565b610b53611879565b610b6f5760405162461bcd60e51b815260040161085890613957565b8080610b7b601a6121ba565b11610b985760405162461bcd60e51b81526004016108589061399c565b6000610ba3836112a6565b9050836001600160a01b0316610bb761186a565b6001600160a01b03161480610be457506001600160a01b0384166000908152600c602052604090205460ff165b610c005760405162461bcd60e51b8152600401610858906139e4565b6001600160a01b0381166000908152600c602052604090205460ff16610c385760405162461bcd60e51b8152600401610858906139e4565b610c438185856121be565b50505050565b600e8181548110610c5657fe5b6000918252602090912001546001600160a01b0316905081565b60608180610c7e601a6121ba565b11610c9b5760405162461bcd60e51b81526004016108589061399c565b60008381526016602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015610d2e5780601f10610d0357610100808354040283529160200191610d2e565b820191906000526020600020905b815481529060010190602001808311610d1157829003601f168201915b5050505050915050919050565b6000610d4760026122cc565b905090565b6002600a541415610d6f5760405162461bcd60e51b81526004016108589061431e565b6002600a553383610d8082826122d7565b610d9c5760405162461bcd60e51b81526004016108589061402c565b6000858152601460205260409020548590610dc95760405162461bcd60e51b8152600401610858906140ee565b84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825115159150610e2190505760405162461bcd60e51b815260040161085890614355565b610e618787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061235c92505050565b867f702fe2dc2dc0f68023540aa4a1e11811c0f29112f6ebf01e61b90538e4f29810338888604051610e95939291906137c3565b60405180910390a250506001600a555050505050565b610ebc610eb6612082565b826122d7565b610ed85760405162461bcd60e51b815260040161085890614228565b6109108383836123a0565b6002600a541415610f065760405162461bcd60e51b81526004016108589061431e565b6002600a553381610f1782826122d7565b610f335760405162461bcd60e51b81526004016108589061402c565b6010546040516328220f3560e01b81526001600160a01b03909116906328220f3590610f6390869060040161385b565b600060405180830381600087803b158015610f7d57600080fd5b505af1158015610b3d573d6000803e3d6000fd5b336000908152600c602052604090205460ff1680610fb95750600b546001600160a01b031633145b610fd55760405162461bcd60e51b815260040161085890613a6d565b6002600a541415610ff85760405162461bcd60e51b81526004016108589061431e565b6002600a5561100833838361240d565b50506001600a55565b6001600160a01b038216600090815260016020526040812061103390836125fd565b90505b92915050565b7f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad81565b61091083838360405180602001604052806000815250611c8e565b6002600a54141561109e5760405162461bcd60e51b81526004016108589061431e565b6002600a55806110ad81612075565b6110c95760405162461bcd60e51b8152600401610858906142e7565b33826110d582826122d7565b6110f15760405162461bcd60e51b81526004016108589061402c565b6110fa84612609565b50506001600a555050565b600d6020526000908152604090205460ff1681565b6000806111286002846126f5565b509392505050565b6002600a5414156111535760405162461bcd60e51b81526004016108589061431e565b6002600a558161116281612075565b61117e5760405162461bcd60e51b8152600401610858906142e7565b81604001516001600160a01b0316336001600160a01b0316146111b35760405162461bcd60e51b815260040161085890613b5b565b6010546040516317b6b0d360e31b81526001600160a01b039091169063bdb5869890610f6390869086903390600401614414565b6002600a54141561120a5760405162461bcd60e51b81526004016108589061431e565b6002600a55338261121b82826122d7565b6112375760405162461bcd60e51b81526004016108589061402c565b60105460405163062f24b760e41b81526001600160a01b03909116906362f24b709061126990879087906004016143b2565b600060405180830381600087803b15801561128357600080fd5b505af1158015611297573d6000803e3d6000fd5b50506001600a55505050505050565b6000611036826040518060600160405280602981526020016144f26029913960029190612711565b600f546001600160a01b031690565b6112e5611879565b6113015760405162461bcd60e51b815260040161085890613957565b6001600160a01b0381166113275760405162461bcd60e51b815260040161085890613af7565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600f546001600160a01b031681565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108275780601f106107fc57610100808354040283529160200191610827565b60006001600160a01b0382166113e15760405162461bcd60e51b815260040161085890613e10565b6001600160a01b0382166000908152600160205260409020611036906122cc565b61140a611879565b6114265760405162461bcd60e51b815260040161085890613957565b600b546040516001600160a01b03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600b80546001600160a01b0319169055565b6002600a5414156114935760405162461bcd60e51b81526004016108589061431e565b6002600a5533836114a482826122d7565b6114c05760405162461bcd60e51b81526004016108589061402c565b60008581526015602052604090205485906114ed5760405162461bcd60e51b815260040161085890613cd4565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082511515915061154590505760405162461bcd60e51b815260040161085890614355565b6115858787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061272892505050565b867fe3df41127db820c79e5b8d541a63e40e3e97b9af96f7a50bded13091b70df9ae338888604051610e95939291906137c3565b336000908152600d602052604090205460ff166115e85760405162461bcd60e51b815260040161085890614063565b336000818152600c6020526040808220805460ff19166001908117909155600e8054918201815583527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b03191684179055517f7f877120c72766f4eac00144c86c9e57ed52f31bac01ef5c4c223c4768a876739190a2565b6002600a54141561168d5760405162461bcd60e51b81526004016108589061431e565b6002600a55805115806116a1575080514211155b6116bd5760405162461bcd60e51b8152600401610858906141f1565b60006116c76120f4565b6040808601516060870151602080880151516001600160a01b038b166000908152601983528581208054600181019091558951965197985090968896611735967f2952e482b8e2b192305f87374d7af45dc2eafafe4f50d26a0c02e90f2fdbe14b96909590949392016138bc565b6040516020818303038152906040528051906020012060405160200161175c929190613757565b6040516020818303038152906040528051906020012090506000600182856020015186604001518760600151604051600081526020016040526040516117a594939291906138e4565b6020604051602081039080840390855afa1580156117c7573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906117fd5750806001600160a01b0316876001600160a01b0316145b80156118435750806001600160a01b031661181661186a565b6001600160a01b0316148061184357506001600160a01b0381166000908152600c602052604090205460ff165b61185f5760405162461bcd60e51b8152600401610858906142b0565b610b3d81878761240d565b600b546001600160a01b031690565b600b546001600160a01b0316331490565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108275780601f106107fc57610100808354040283529160200191610827565b6011602052600090815260409020546001600160a01b031681565b6010546001600160a01b031681565b61191d611879565b6119395760405162461bcd60e51b815260040161085890613957565b6001600160a01b03821661195f5760405162461bcd60e51b815260040161085890613be7565b6001600160a01b03821633141561197557600080fd5b816001600160a01b0316600e828154811061198c57fe5b6000918252602090912001546001600160a01b0316146119be5760405162461bcd60e51b8152600401610858906141c6565b6001600160a01b0382166000908152600d60209081526040808320805460ff19908116909155600c90925290912080549091169055600e805482908110611a0157fe5b600091825260209091200180546001600160a01b03191690556040516001600160a01b038316907f4351fca1a489ee987699b3c49344da8a6c88963c20d8e6e1c0a9b9650b54115990611a5590849061385b565b60405180910390a25050565b611a69612082565b6001600160a01b0316826001600160a01b03161415611a9a5760405162461bcd60e51b815260040161085890613c9d565b8060056000611aa7612082565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611aeb612082565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611b239190613850565b60405180910390a35050565b6002600a541415611b525760405162461bcd60e51b81526004016108589061431e565b6002600a55611b6081610831565b6001600160a01b0316336001600160a01b031614611b905760405162461bcd60e51b815260040161085890613c17565b611b9b600082612086565b506001600a55565b600b546001600160a01b031681565b6002600a541415611bd55760405162461bcd60e51b81526004016108589061431e565b6002600a558080611be6601a6121ba565b11611c035760405162461bcd60e51b81526004016108589061399c565b60105460405163776a083560e01b81526001600160a01b039091169063776a083590611c35908590339060040161439b565b600060405180830381600087803b158015611c4f57600080fd5b505af1158015611c63573d6000803e3d6000fd5b50506001600a5550505050565b6001600160a01b03166000908152600c602052604090205460ff1690565b611c9f611c99612082565b836122d7565b611cbb5760405162461bcd60e51b815260040161085890614228565b610c438484848461276d565b600c6020526000908152604090205460ff1681565b6002600a541415611cff5760405162461bcd60e51b81526004016108589061431e565b6002600a553382611d1082826122d7565b611d2c5760405162461bcd60e51b81526004016108589061402c565b60105460405163ba33939960e01b81526001600160a01b039091169063ba339399906112699087908790600401614400565b60608180611d6c601a6121ba565b11611d895760405162461bcd60e51b81526004016108589061399c565b60008381526008602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015611e1e5780601f10611df357610100808354040283529160200191611e1e565b820191906000526020600020905b815481529060010190602001808311611e0157829003601f168201915b509398975050505050505050565b611e34611879565b611e505760405162461bcd60e51b815260040161085890613957565b6001600160a01b038116611e765760405162461bcd60e51b815260040161085890613be7565b6001600160a01b0381166000818152600d6020526040808220805460ff19166001179055517fa6f04ef390ee5829dc9be99664fd8d9aeea059278dbda4f988499726455801ce9190a250565b6060600e80548060200260200160405190810160405280929190818152602001828054801561082757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611efc575050505050905090565b7f2952e482b8e2b192305f87374d7af45dc2eafafe4f50d26a0c02e90f2fdbe14b81565b6012602052600090815260409020546001600160a01b031681565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b611f98611879565b611fb45760405162461bcd60e51b815260040161085890613957565b611fbd816127a0565b50565b6010546001600160a01b03163314611fea5760405162461bcd60e51b815260040161085890613f28565b611ff3826112a6565b600083815260116020526040902080546001600160a01b0319166001600160a01b039290921691909117905561204261202b836112a6565b82846040518060200160405280600081525061276d565b5050565b601860209081526000928352604080842090915290825290205481565b60146020526000908152604090205481565b6000611036600283612822565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906120bb826112a6565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60408051808201825260048152634172746f60e01b6020918201528151808301835260018152603160f81b908201529051600091469161219e917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f917f64e5e55c6a2790759ed01c581dcc6ee14925b98404a095158e9a67c6cf3fd21f917fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6918691309101613890565b6040516020818303038152906040528051906020012091505090565b5490565b826001600160a01b03166121d1826112a6565b6001600160a01b0316146121f75760405162461bcd60e51b8152600401610858906140a5565b6001600160a01b03821661221d5760405162461bcd60e51b815260040161085890613c59565b612228838383610910565b612233600082612086565b6001600160a01b0383166000908152600160205260409020612255908261282e565b506001600160a01b0382166000908152600160205260409020612278908261283a565b5061228560028284612846565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000611036826121ba565b60006122e282612075565b6122fe5760405162461bcd60e51b815260040161085890613d67565b6000612309836112a6565b9050806001600160a01b0316846001600160a01b031614806123445750836001600160a01b031661233984610831565b6001600160a01b0316145b8061235457506123548185611f62565b949350505050565b61236582612075565b6123815760405162461bcd60e51b815260040161085890613fe0565b600082815260086020908152604090912082516109109284019061300c565b6010546040516328220f3560e01b81526001600160a01b03909116906328220f35906123d090849060040161385b565b600060405180830381600087803b1580156123ea57600080fd5b505af11580156123fe573d6000803e3d6000fd5b505050506109108383836121be565b8151805161242d5760405162461bcd60e51b815260040161085890614355565b602083015180516124505760405162461bcd60e51b815260040161085890614355565b60408401516124715760405162461bcd60e51b815260040161085890613d23565b60408085015160009081526017602052205460ff16156124a35760405162461bcd60e51b815260040161085890613e89565b60608401516124c45760405162461bcd60e51b815260040161085890614140565b60006124d0601a6121ba565b90506124dc868261285c565b6124e6601a612876565b6124f481866040015161287f565b6125028186606001516128b8565b612510818660200151612728565b61251e81866000015161235c565b6001600160a01b0386166000908152601360205260409020612540908261283a565b50604080860151600090815260176020908152828220805460ff191660011790558382526012815282822080546001600160a01b03808c166001600160a01b0319928316811790935560119093529284902080549093161790915560105491516375aab41d60e11b815291169063eb55683a906125c390849088906004016143d6565b600060405180830381600087803b1580156125dd57600080fd5b505af11580156125f1573d6000803e3d6000fd5b50505050505050505050565b600061103383836128f1565b60008181526008602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526060939283018282801561269e5780601f106126735761010080835404028352916020019161269e565b820191906000526020600020905b81548152906001019060200180831161268157829003601f168201915b505050505090506126ae82612936565b8051156126d657600082815260086020908152604090912082516126d49284019061300c565b505b50600090815260116020526040902080546001600160a01b0319169055565b60008080806127048686612a03565b9097909650945050505050565b600061271e848484612a5f565b90505b9392505050565b8161273281612075565b61274e5760405162461bcd60e51b8152600401610858906142e7565b60008381526016602090815260409091208351610c439285019061300c565b6127788484846123a0565b61278484848484612abe565b610c435760405162461bcd60e51b815260040161085890613a1b565b6001600160a01b0381166127c65760405162461bcd60e51b815260040161085890613b9c565b600b546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60006110338383612b9d565b60006110338383612bb5565b60006110338383612c7b565b600061271e84846001600160a01b038516612cc5565b612042828260405180602001604052806000815250612d5c565b80546001019055565b8161288981612075565b6128a55760405162461bcd60e51b8152600401610858906142e7565b5060009182526014602052604090912055565b816128c281612075565b6128de5760405162461bcd60e51b8152600401610858906142e7565b5060009182526015602052604090912055565b815460009082106129145760405162461bcd60e51b815260040161085890613915565b82600001828154811061292357fe5b9060005260206000200154905092915050565b6000612941826112a6565b905061294f81600084610910565b61295a600083612086565b60008281526008602052604090205460026000196101006001841615020190911604156129985760008281526008602052604081206129989161308a565b6001600160a01b03811660009081526001602052604090206129ba908361282e565b506129c6600283612d8f565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b815460009081908310612a285760405162461bcd60e51b815260040161085890613ee6565b6000846000018481548110612a3957fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008281526001840160205260408120548281612a8f5760405162461bcd60e51b81526004016108589190613902565b50846000016001820381548110612aa257fe5b9060005260206000209060020201600101549150509392505050565b6000612ad2846001600160a01b0316612d9b565b612ade57506001612354565b6060612b66630a85bd0160e11b612af3612082565b888787604051602401612b099493929190613786565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518060600160405280603281526020016144c0603291396001600160a01b0388169190612da1565b9050600081806020019051810190612b7e91906134d8565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015612c715783546000198083019190810190600090879083908110612be857fe5b9060005260206000200154905080876000018481548110612c0557fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612c3557fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611036565b6000915050611036565b6000612c878383612b9d565b612cbd57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611036565b506000611036565b600082815260018401602052604081205480612d2a575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055612721565b82856000016001830381548110612d3d57fe5b9060005260206000209060020201600101819055506000915050612721565b612d668383612db0565b612d736000848484612abe565b6109105760405162461bcd60e51b815260040161085890613a1b565b60006110338383612e74565b3b151590565b606061271e8484600085612f48565b6001600160a01b038216612dd65760405162461bcd60e51b815260040161085890613f5f565b612ddf81612075565b15612dfc5760405162461bcd60e51b815260040161085890613b24565b612e0860008383610910565b6001600160a01b0382166000908152600160205260409020612e2a908261283a565b50612e3760028284612846565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008181526001830160205260408120548015612c715783546000198083019190810190600090879083908110612ea757fe5b9060005260206000209060020201905080876000018481548110612ec757fe5b600091825260208083208454600290930201918255600193840154918401919091558354825289830190526040902090840190558654879080612f0657fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506110369350505050565b6060612f5385612d9b565b612f6f5760405162461bcd60e51b815260040161085890614279565b60006060866001600160a01b03168587604051612f8c919061373b565b60006040518083038185875af1925050503d8060008114612fc9576040519150601f19603f3d011682016040523d82523d6000602084013e612fce565b606091505b50915091508115612fe25791506123549050565b805115612ff25780518082602001fd5b8360405162461bcd60e51b81526004016108589190613902565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061304d57805160ff191683800117855561307a565b8280016001018555821561307a579182015b8281111561307a57825182559160200191906001019061305f565b506130869291506130ca565b5090565b50805460018160011615610100020316600290046000825580601f106130b05750611fbd565b601f016020900490600052602060002090810190611fbd91905b5b8082111561308657600081556001016130cb565b80356001600160a01b038116811461103657600080fd5b600082601f830112613106578081fd5b813567ffffffffffffffff81111561311c578182fd5b61312f601f8201601f1916602001614441565b915080825283602082850101111561314657600080fd5b8060208401602084013760009082016020015292915050565b600060608284031215613170578081fd5b61317a6060614441565b905061318683836131b2565b815261319583602084016131b2565b60208201526131a783604084016131b2565b604082015292915050565b6000602082840312156131c3578081fd5b6131cd6020614441565b9135825250919050565b6000608082840312156131e8578081fd5b6131f26080614441565b905081358152602082013560ff8116811461320c57600080fd5b80602083015250604082013560408201526060820135606082015292915050565b60006080828403121561323e578081fd5b6132486080614441565b9050813567ffffffffffffffff8082111561326257600080fd5b61326e858386016130f6565b8352602084013591508082111561328457600080fd5b50613291848285016130f6565b602083015250604082013560408201526060820135606082015292915050565b6000602082840312156132c2578081fd5b61103383836130df565b600080604083850312156132de578081fd5b6132e884846130df565b91506132f784602085016130df565b90509250929050565b600080600060608486031215613314578081fd5b833561331f81614494565b9250602084013561332f81614494565b929592945050506040919091013590565b60008060008060808587031215613355578081fd5b61335f86866130df565b935061336e86602087016130df565b925060408501359150606085013567ffffffffffffffff811115613390578182fd5b61339c878288016130f6565b91505092959194509250565b600080604083850312156133ba578182fd5b6133c484846130df565b9150602083013580151581146133d8578182fd5b809150509250929050565b60008060008061012085870312156133f9578081fd5b61340386866130df565b9350602085013567ffffffffffffffff81111561341e578182fd5b61342a8782880161322d565b93505061343a866040870161315f565b91506134498660a087016131d7565b905092959194509250565b60008060408385031215613466578182fd5b61347084846130df565b946020939093013593505050565b600080600060c08486031215613492578081fd5b833561349d81614494565b9250602084013591506134b385604086016131d7565b90509250925092565b6000602082840312156134cd578081fd5b8135612721816144a9565b6000602082840312156134e9578081fd5b8151612721816144a9565b60008060808385031215613506578182fd5b823567ffffffffffffffff81111561351c578283fd5b6135288582860161322d565b9250506132f7846020850161315f565b600060208284031215613549578081fd5b5035919050565b60008060408385031215613562578182fd5b823591506132f784602085016130df565b600080600060408486031215613587578081fd5b83359250602084013567ffffffffffffffff808211156135a5578283fd5b818601915086601f8301126135b8578283fd5b8135818111156135c6578384fd5b8760208285010111156135d7578384fd5b6020830194508093505050509250925092565b60008082840360608112156135fd578283fd5b833592506040601f1982011215613612578182fd5b5061361d6040614441565b6020840135815261363185604086016130df565b6020820152809150509250929050565b60008082840360c0811215613654578283fd5b8335925060a0601f1982011215613669578182fd5b5061367460a0614441565b6020840135815261368885604086016130df565b602082015261369a85606086016130df565b60408201526136ac85608086016130df565b60608201526136be8560a086016131b2565b6080820152809150509250929050565b600081518084526136e6816020860160208601614468565b601f01601f19169290920160200192915050565b805182526020808201516001600160a01b03908116918401919091526040808301518216908401526060808301519091169083015260809081015151910152565b6000825161374d818460208701614468565b9190910192915050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906137b9908301846136ce565b9695505050505050565b6001600160a01b03841681526040602082018190528101829052600082846060840137818301606090810191909152601f909201601f1916010192915050565b6020808252825182820181905260009190848201906040850190845b818110156138445783516001600160a01b03168352928401929184019160010161381f565b50909695505050505050565b901515815260200190565b90815260200190565b9485526001600160a01b0393909316602085015260408401919091526060830152608082015260a00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b958652602086019490945260408501929092526060840152608083015260a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b60006020825261103360208301846136ce565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526025908201527f4f776e61626c653a2063616c6c6572206973206e6f742074686520537570657260408201526420b236b4b760d91b606082015260800190565b60208082526028908201527f4d656469613a20746f6b656e2077697468207468617420696420646f6573206e6040820152671bdd08195e1a5cdd60c21b606082015260800190565b60208082526019908201527f6e6f7420612076616c6964206f776e6572206164647265737300000000000000604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526033908201527f417574686f72697a61626c653a2063616c6c6572206973206e6f74207468652060408201527229bab832b920b236b4b71037b91020b236b4b760691b606082015260800190565b6020808252601c908201527f4d656469613a207370656e6465722063616e6e6f742062652030783000000000604082015260600190565b6020808252601390820152726e6f7420612076616c6964206164647265737360681b604082015260600190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526021908201527f4d61726b65743a20426964646572206d757374206265206d73672073656e64656040820152603960f91b606082015260800190565b6020808252602b908201527f4f776e61626c653a206e657720537570657241646d696e20697320746865207a60408201526a65726f206164647265737360a81b606082015260800190565b6020808252601690820152756973206e6f742061207661696c64206164647265737360501b604082015260600190565b60208082526022908201527f4d656469613a2063616c6c6572206e6f7420617070726f766564206164647265604082015261737360f01b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602f908201527f4d656469613a20746f6b656e20646f6573206e6f74206861766520686173682060408201526e6f6620697473206d6574616461746160881b606082015260800190565b60208082526024908201527f4d656469613a20636f6e74656e742068617368206d757374206265206e6f6e2d6040820152637a65726f60e01b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252601590820152741359591a584e8814195c9b5a5d08195e1c1a5c9959605a1b604082015260600190565b6020808252603e908201527f4d656469613a206120746f6b656e2068617320616c7265616479206265656e2060408201527f637265617465642077697468207468697320636f6e74656e7420686173680000606082015260800190565b60208082526022908201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252601b908201527f4d656469613a206f6e6c79206d61726b657420636f6e74726163740000000000604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252602c908201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601d908201527f4d656469613a204f6e6c7920617070726f766564206f72206f776e6572000000604082015260600190565b60208082526022908201527f417574686f72697a61626c653a4f6e6c7920617574686f72697a6564206f776e60408201526132b960f11b606082015260800190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526032908201527f4d656469613a20746f6b656e20646f6573206e6f7420686176652068617368206040820152711bd98818dc99585d19590818dbdb9d195b9d60721b606082015260800190565b60208082526025908201527f4d656469613a206d657461646174612068617368206d757374206265206e6f6e6040820152642d7a65726f60d81b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b6020808252601190820152700dcdee840c240ecc2d8d2c840d2dcc8caf607b1b604082015260600190565b6020808252601a908201527f4d656469613a206d696e74576974685369672065787069726564000000000000604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526018908201527f4d656469613a205369676e617475726520696e76616c69640000000000000000604082015260600190565b60208082526018908201527f4d656469613a206e6f6e6578697374656e7420746f6b656e0000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526026908201527f4d656469613a2073706563696669656420757269206d757374206265206e6f6e6040820152652d656d70747960d01b606082015260800190565b9182526001600160a01b0316602082015260400190565b918252805160208084019190915201516001600160a01b0316604082015260600190565b91825280515160208084019190915281015151604080840191909152015151606082015260800190565b82815260c0810161272160208301846136fa565b83815260e0810161442860208301856136fa565b6001600160a01b039290921660c0919091015292915050565b60405181810167ffffffffffffffff8111828210171561446057600080fd5b604052919050565b60005b8381101561448357818101518382015260200161446b565b83811115610c435750506000910152565b6001600160a01b0381168114611fbd57600080fd5b6001600160e01b031981168114611fbd57600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212203f49cdfbced025dd615fc21625c8ca5d4c7978f7ae78e70d36498689bf44dd0464736f6c634300060c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000a7321f4eeb92abb8e33dddceff93ee7bfbb8a9cb

-----Decoded View---------------
Arg [0] : marketContractAddr (address): 0xa7321F4Eeb92abb8e33dDDCeff93Ee7bFbB8a9cb

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a7321f4eeb92abb8e33dddceff93ee7bfbb8a9cb


Deployed Bytecode Sourcemap

74180:18187:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75059:54;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36005:142;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;40510:92::-;;;:::i;:::-;;;;;;;:::i;43392:291::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;42922:404::-;;;;;;:::i;:::-;;:::i;:::-;;75989:52;;;;;;:::i;:::-;;:::i;86811:1286::-;;;;;;:::i;:::-;;:::i;80504:434::-;;;;;;:::i;:::-;;:::i;64128:26::-;;;;;;:::i;:::-;;:::i;79577:219::-;;;;;;:::i;:::-;;:::i;42375:203::-;;;:::i;85739:367::-;;;;;;:::i;:::-;;:::i;44417:376::-;;;;;;:::i;:::-;;:::i;83347:210::-;;;;;;:::i;:::-;;:::i;80991:221::-;;;;;;:::i;:::-;;:::i;42104:195::-;;;;;;:::i;:::-;;:::i;75418:117::-;;;:::i;44864:185::-;;;;;;:::i;:::-;;:::i;84593:396::-;;;;;;:::i;:::-;;:::i;64069:52::-;;;;;;:::i;:::-;;:::i;42655:205::-;;;;;;:::i;:::-;;:::i;83610:310::-;;;;;;:::i;:::-;;:::i;83063:231::-;;;;;;:::i;:::-;;:::i;40212:::-;;;;;;:::i;:::-;;:::i;79806:110::-;;;:::i;80291:205::-;;;;;;:::i;:::-;;:::i;74394:31::-;;;:::i;41931:89::-;;;:::i;39898:252::-;;;;;;:::i;:::-;;:::i;63226:116::-;;;:::i;86207:429::-;;;;;;:::i;:::-;;:::i;64734:251::-;;;:::i;81265:1379::-;;;;;;:::i;:::-;;:::i;79980:87::-;;;:::i;62869:85::-;;;:::i;40671:96::-;;;:::i;74561:54::-;;;;;;:::i;:::-;;:::i;74465:29::-;;;:::i;64993:438::-;;;;;;:::i;:::-;;:::i;43755:327::-;;;;;;:::i;:::-;;:::i;85389:249::-;;;;;;:::i;:::-;;:::i;62229:21::-;;;:::i;83973:207::-;;;;;;:::i;:::-;;:::i;80075:120::-;;;;;;:::i;:::-;;:::i;45120:365::-;;;;;;:::i;:::-;;:::i;64020:42::-;;;;;;:::i;:::-;;:::i;84233:237::-;;;;;;:::i;:::-;;:::i;79174:249::-;;;;;;:::i;:::-;;:::i;64514:212::-;;;;;;:::i;:::-;;:::i;65439:97::-;;;:::i;:::-;;;;;;;:::i;75671:124::-;;;:::i;74673:48::-;;;;;;:::i;:::-;;:::i;44153:197::-;;;;;;:::i;:::-;;:::i;63509:103::-;;;;;;:::i;:::-;;:::i;82697:313::-;;;;;;:::i;:::-;;:::i;75861:67::-;;;;;;:::i;:::-;;:::i;74940:53::-;;;;;;:::i;:::-;;:::i;75059:54::-;;;;;;;;;;;;;:::o;36005:142::-;-1:-1:-1;;;;;;36106:33:0;36082:4;36106:33;;;;;;;;;;;;;;36005:142::o;40510:92::-;40589:5;40582:12;;;;;;;;-1:-1:-1;;40582:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40556:13;;40582:12;;40589:5;;40582:12;;40589:5;40582:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40510:92;:::o;43392:291::-;43496:7;43543:16;43551:7;43543;:16::i;:::-;43521:110;;;;-1:-1:-1;;;43521:110:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;43651:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;43651:24:0;;43392:291::o;42922:404::-;43003:13;43019:16;43027:7;43019;:16::i;:::-;43003:32;;43060:5;-1:-1:-1;;;;;43054:11:0;:2;-1:-1:-1;;;;;43054:11:0;;;43046:57;;;;-1:-1:-1;;;43046:57:0;;;;;;;:::i;:::-;43154:5;-1:-1:-1;;;;;43138:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;43138:21:0;;:62;;;;43163:37;43180:5;43187:12;:10;:12::i;43163:37::-;43116:168;;;;-1:-1:-1;;;43116:168:0;;;;;;;:::i;:::-;43297:21;43306:2;43310:7;43297:8;:21::i;:::-;42922:404;;;:::o;75989:52::-;;;;;;;;;;;;;:::o;86811:1286::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;86970:7;76751:16:::1;86970:7:::0;76751::::1;:16::i;:::-;76743:53;;;;-1:-1:-1::0;;;76743:53:0::1;;;;;;;:::i;:::-;87012:12:::0;;:17;;:52:::2;;-1:-1:-1::0;87033:12:0;;87049:15:::2;-1:-1:-1::0;87033:31:0::2;87012:52;86990:123;;;;-1:-1:-1::0;;;86990:123:0::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;87132:21:0;::::2;87124:62;;;;-1:-1:-1::0;;;87124:62:0::2;;;;;;;:::i;:::-;87197:23;87223:27;:25;:27::i;:::-;87197:53:::0;-1:-1:-1;87263:14:0::2;87197:53:::0;75469:66:::2;87554:7:::0;87592;87630:12:::2;87263:14:::0;87643:16:::2;87592:7:::0;87643::::2;:16::i;:::-;-1:-1:-1::0;;;;;87630:30:0::2;::::0;;::::2;::::0;;::::2;::::0;;;;;;;;-1:-1:-1;87630:30:0;;;:39;;;;;;;;:41;;::::2;::::0;::::2;::::0;;;87702:12;;87467:274;;::::2;::::0;;;;87630:41;;87702:12;87467:274:::2;;:::i;:::-;;;;;;;;;;;;;87431:333;;;;;;87321:462;;;;;;;;;:::i;:::-;;;;;;;;;;;;;87293:505;;;;;;87263:535;;87811:24;87838:38;87848:6;87856:3;:5;;;87863:3;:5;;;87870:3;:5;;;87838:38;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;87838:38:0::2;::::0;-1:-1:-1;;87838:38:0;;;-1:-1:-1;;;;;;;87911:30:0;::::2;::::0;;::::2;::::0;:87:::2;;;87982:16;-1:-1:-1::0;;;;;87962:36:0::2;:16;87970:7;87962;:16::i;:::-;-1:-1:-1::0;;;;;87962:36:0::2;;87911:87;87889:161;;;;-1:-1:-1::0;;;87889:161:0::2;;;;;;;:::i;:::-;88063:26;88072:7;88081;88063:8;:26::i;:::-;-1:-1:-1::0;;23287:1:0;24249:7;:22;-1:-1:-1;;;;;86811:1286:0:o;80504:434::-;62720:9;:7;:9::i;:::-;62712:58;;;;-1:-1:-1;;;62712:58:0;;;;;;;:::i;:::-;80615:7:::1;77997;77969:25;:15;:23;:25::i;:::-;:35;77947:125;;;;-1:-1:-1::0;;;77947:125:0::1;;;;;;;:::i;:::-;80635:12:::2;80650:16;80658:7;80650;:16::i;:::-;80635:31;;80710:2;-1:-1:-1::0;;;;;80699:13:0::2;:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;80699:13:0::2;;:31;;;-1:-1:-1::0;;;;;;80716:14:0;::::2;;::::0;;;:10:::2;:14;::::0;;;;;::::2;;80699:31;80677:106;;;;-1:-1:-1::0;;;80677:106:0::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;80816:16:0;::::2;;::::0;;;:10:::2;:16;::::0;;;;;::::2;;80794:91;;;;-1:-1:-1::0;;;80794:91:0::2;;;;;;;:::i;:::-;80896:34;80912:4;80918:2;80922:7;80896:15;:34::i;:::-;78083:1;62777::::1;80504:434:::0;;:::o;64128:26::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64128:26:0;;-1:-1:-1;64128:26:0;:::o;79577:219::-;79723:13;79696:7;77997;77969:25;:15;:23;:25::i;:::-;:35;77947:125;;;;-1:-1:-1;;;77947:125:0;;;;;;;:::i;:::-;79761:27:::1;::::0;;;:18:::1;:27;::::0;;;;;;;;79754:34;;;;::::1;;-1:-1:-1::0;;79754:34:0::1;;::::0;::::1;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;;79761:27;;79754:34;::::1;79761:27:::0;79754:34;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79577:219:::0;;;;:::o;42375:203::-;42428:7;42549:21;:12;:19;:21::i;:::-;42542:28;;42375:203;:::o;85739:367::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;85893:10:::1;85905:7:::0;77675:36:::1;85893:10:::0;85905:7;77675:18:::1;:36::i;:::-;77653:115;;;;-1:-1:-1::0;;;77653:115:0::1;;;;;;;:::i;:::-;76992:27:::2;::::0;;;:18:::2;:27;::::0;;;;;85948:7;;76970:132:::2;;;;-1:-1:-1::0;;;76970:132:0::2;;;;;;;:::i;:::-;85979:8:::3;;78176:182;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;::::0;;;;-1:-1:-1;;78250:17:0;;:22;::::3;::::0;-1:-1:-1;78228:110:0::3;::::0;-1:-1:-1;78228:110:0::3;;;-1:-1:-1::0;;;78228:110:0::3;;;;;;;:::i;:::-;86005:31:::4;86018:7;86027:8;;86005:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::4;::::0;;;;-1:-1:-1;86005:12:0::4;::::0;-1:-1:-1;;;86005:31:0:i:4;:::-;86068:7;86052:46;86077:10;86089:8;;86052:46;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;23287:1:0;24249:7;:22;-1:-1:-1;;;;;85739:367:0:o;44417:376::-;44626:41;44645:12;:10;:12::i;:::-;44659:7;44626:18;:41::i;:::-;44604:140;;;;-1:-1:-1;;;44604:140:0;;;;;;;:::i;:::-;44757:28;44767:4;44773:2;44777:7;44757:9;:28::i;83347:210::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;83470:10:::1;83482:7:::0;77675:36:::1;83470:10:::0;83482:7;77675:18:::1;:36::i;:::-;77653:115;;;;-1:-1:-1::0;;;77653:115:0::1;;;;;;;:::i;:::-;83515:14:::2;::::0;83507:42:::2;::::0;-1:-1:-1;;;83507:42:0;;-1:-1:-1;;;;;83515:14:0;;::::2;::::0;83507:33:::2;::::0;:42:::2;::::0;83541:7;;83507:42:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;80991:221:::0;64396:10;64385:22;;;;:10;:22;;;;;;;;;:46;;-1:-1:-1;64411:6:0;;-1:-1:-1;;;;;64411:6:0;64421:10;64411:20;64385:46;64377:109;;;;-1:-1:-1;;;64377:109:0;;;;;;;:::i;:::-;23331:1:::1;23937:7;;:19;;23929:63;;;;-1:-1:-1::0;;;23929:63:0::1;;;;;;;:::i;:::-;23331:1;24070:7;:18:::0;81160:44:::2;81176:10;81188:4:::0;81194:9;81160:15:::2;:44::i;:::-;-1:-1:-1::0;;23287:1:0::1;24249:7;:22:::0;80991:221::o;42104:195::-;-1:-1:-1;;;;;42261:20:0;;42229:7;42261:20;;;:13;:20;;;;;:30;;42285:5;42261:23;:30::i;:::-;42254:37;;42104:195;;;;;:::o;75418:117::-;75469:66;75418:117;:::o;44864:185::-;45002:39;45019:4;45025:2;45029:7;45002:39;;;;;;;;;;;;:16;:39::i;84593:396::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;84707:7;76751:16:::1;84707:7:::0;76751::::1;:16::i;:::-;76743:53;;;;-1:-1:-1::0;;;76743:53:0::1;;;;;;;:::i;:::-;84745:10:::2;84757:7;77675:36;77694:7;77703;77675:18;:36::i;:::-;77653:115;;;;-1:-1:-1::0;;;77653:115:0::2;;;;;;;:::i;:::-;84967:14:::3;84973:7;84967:5;:14::i;:::-;-1:-1:-1::0;;23287:1:0;24249:7;:22;-1:-1:-1;;84593:396:0:o;64069:52::-;;;;;;;;;;;;;;;:::o;42655:205::-;42758:7;;42805:22;:12;42821:5;42805:15;:22::i;:::-;-1:-1:-1;42783:44:0;42655:205;-1:-1:-1;;;42655:205:0:o;83610:310::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;83750:7;76751:16:::1;83750:7:::0;76751::::1;:16::i;:::-;76743:53;;;;-1:-1:-1::0;;;76743:53:0::1;;;;;;;:::i;:::-;83797:3:::2;:10;;;-1:-1:-1::0;;;;;83783:24:0::2;:10;-1:-1:-1::0;;;;;83783:24:0::2;;83775:70;;;;-1:-1:-1::0;;;83775:70:0::2;;;;;;;:::i;:::-;83864:14;::::0;83856:56:::2;::::0;-1:-1:-1;;;83856:56:0;;-1:-1:-1;;;;;83864:14:0;;::::2;::::0;83856:30:::2;::::0;:56:::2;::::0;83887:7;;83896:3;;83901:10:::2;::::0;83856:56:::2;;;:::i;83063:231::-:0;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;83205:10:::1;83217:7:::0;77675:36:::1;83205:10:::0;83217:7;77675:18:::1;:36::i;:::-;77653:115;;;;-1:-1:-1::0;;;77653:115:0::1;;;;;;;:::i;:::-;83250:14:::2;::::0;83242:44:::2;::::0;-1:-1:-1;;;83242:44:0;;-1:-1:-1;;;;;83250:14:0;;::::2;::::0;83242:30:::2;::::0;:44:::2;::::0;83273:7;;83282:3;;83242:44:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;23287:1:0;24249:7;:22;-1:-1:-1;;;;;;83063:231:0:o;40212:::-;40276:7;40316:119;40351:7;40316:119;;;;;;;;;;;;;;;;;:12;;:119;:16;:119::i;79806:110::-;79892:16;;-1:-1:-1;;;;;79892:16:0;79806:110;:::o;80291:205::-;62720:9;:7;:9::i;:::-;62712:58;;;;-1:-1:-1;;;62712:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;80386:31:0;::::1;80378:63;;;;-1:-1:-1::0;;;80378:63:0::1;;;;;;;:::i;:::-;80452:16;:36:::0;;-1:-1:-1;;;;;;80452:36:0::1;-1:-1:-1::0;;;;;80452:36:0;;;::::1;::::0;;;::::1;::::0;;80291:205::o;74394:31::-;;;-1:-1:-1;;;;;74394:31:0;;:::o;41931:89::-;42004:8;41997:15;;;;;;;;-1:-1:-1;;41997:15:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41971:13;;41997:15;;42004:8;;41997:15;;42004:8;41997:15;;;;;;;;;;;;;;;;;;;;;;;;39898:252;39962:7;-1:-1:-1;;;;;40004:19:0;;39982:111;;;;-1:-1:-1;;;39982:111:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40113:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;63226:116::-;62720:9;:7;:9::i;:::-;62712:58;;;;-1:-1:-1;;;62712:58:0;;;;;;;:::i;:::-;63303:6:::1;::::0;63284:26:::1;::::0;-1:-1:-1;;;;;63303:6:0;;::::1;::::0;63284:26:::1;::::0;63303:6:::1;::::0;63284:26:::1;63317:6;:19:::0;;-1:-1:-1;;;;;;63317:19:0::1;::::0;;63226:116::o;86207:429::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;86397:10:::1;86409:7:::0;77675:36:::1;86397:10:::0;86409:7;77675:18:::1;:36::i;:::-;77653:115;;;;-1:-1:-1::0;;;77653:115:0::1;;;;;;;:::i;:::-;77300:28:::2;::::0;;;:19:::2;:28;::::0;;;;;86453:7;;77278:130:::2;;;;-1:-1:-1::0;;;77278:130:0::2;;;;;;;:::i;:::-;86484:11:::3;;78176:182;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;::::0;;;;-1:-1:-1;;78250:17:0;;:22;::::3;::::0;-1:-1:-1;78228:110:0::3;::::0;-1:-1:-1;78228:110:0::3;;;-1:-1:-1::0;;;78228:110:0::3;;;;;;;:::i;:::-;86513:42:::4;86534:7;86543:11;;86513:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::4;::::0;;;;-1:-1:-1;86513:20:0::4;::::0;-1:-1:-1;;;86513:42:0:i:4;:::-;86595:7;86571:57;86604:10;86616:11;;86571:57;;;;;;;;:::i;64734:251::-:0;64808:10;64787:32;;;;:20;:32;;;;;;;;64779:78;;;;-1:-1:-1;;;64779:78:0;;;;;;;:::i;:::-;64879:10;64868:22;;;;:10;:22;;;;;;:29;;-1:-1:-1;;64868:29:0;64893:4;64868:29;;;;;;64908:9;:26;;;;;;;;;;;;;-1:-1:-1;;;;;;64908:26:0;;;;;64950:27;;;64868:22;64950:27;64734:251::o;81265:1379::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;81495:12;;:17;;:52:::1;;-1:-1:-1::0;81516:12:0;;81532:15:::1;-1:-1:-1::0;81516:31:0::1;81495:52;81473:128;;;;-1:-1:-1::0;;;81473:128:0::1;;;;;;;:::i;:::-;81614:23;81640:27;:25;:27::i;:::-;81978:16;::::0;;::::1;::::0;82025:17:::1;::::0;::::1;::::0;82073::::1;::::0;;::::1;::::0;:23;-1:-1:-1;;;;;82127:26:0;::::1;81680:14;82127:26:::0;;;:17:::1;:26:::0;;;;;:28;;::::1;::::0;::::1;::::0;;;82186:12;;81884:341;;81614:53;;-1:-1:-1;81680:14:0;;81614:53;;81884:341:::1;::::0;75729:66:::1;::::0;81978:16;;82025:17;;82073:23;82127:28;81884:341:::1;;:::i;:::-;;;;;;;;;;;;;81848:400;;;;;;81738:529;;;;;;;;;:::i;:::-;;;;;;;;;;;;;81710:572;;;;;;81680:602;;82295:24;82322:38;82332:6;82340:3;:5;;;82347:3;:5;;;82354:3;:5;;;82322:38;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;82322:38:0::1;::::0;-1:-1:-1;;82322:38:0;;;-1:-1:-1;;;;;;;82395:30:0;::::1;::::0;;::::1;::::0;:61:::1;;;82440:16;-1:-1:-1::0;;;;;82429:27:0::1;:7;-1:-1:-1::0;;;;;82429:27:0::1;;82395:61;:126;;;;;82472:16;-1:-1:-1::0;;;;;82461:27:0::1;:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;82461:27:0::1;;:59;;;-1:-1:-1::0;;;;;;82492:28:0;::::1;;::::0;;;:10:::1;:28;::::0;;;;;::::1;;82461:59;82373:200;;;;-1:-1:-1::0;;;82373:200:0::1;;;;;;;:::i;:::-;82586:50;82602:16;82620:4;82626:9;82586:15;:50::i;79980:87::-:0;80053:6;;-1:-1:-1;;;;;80053:6:0;79980:87;:::o;62869:85::-;62942:6;;-1:-1:-1;;;;;62942:6:0;62928:10;:20;;62869:85::o;40671:96::-;40752:7;40745:14;;;;;;;;-1:-1:-1;;40745:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40719:13;;40745:14;;40752:7;;40745:14;;40752:7;40745:14;;;;;;;;;;;;;;;;;;;;;;;;74561:54;;;;;;;;;;;;-1:-1:-1;;;;;74561:54:0;;:::o;74465:29::-;;;-1:-1:-1;;;;;74465:29:0;;:::o;64993:438::-;62720:9;:7;:9::i;:::-;62712:58;;;;-1:-1:-1;;;62712:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;65086:23:0;::::1;65078:57;;;;-1:-1:-1::0;;;65078:57:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;65154:23:0;::::1;65167:10;65154:23;;65146:32;;;::::0;::::1;;65218:9;-1:-1:-1::0;;;;;65197:30:0::1;:9;65207:6;65197:17;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;65197:17:0::1;:30;65189:59;;;;-1:-1:-1::0;;;65189:59:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;65259:31:0;::::1;65293:5;65259:31:::0;;;:20:::1;:31;::::0;;;;;;;:39;;-1:-1:-1;;65259:39:0;;::::1;::::0;;;65309:10:::1;:21:::0;;;;;;:29;;;;::::1;::::0;;65356:9:::1;:17:::0;;65366:6;;65356:17;::::1;;;;;;::::0;;;::::1;::::0;;;::::1;65349:24:::0;;-1:-1:-1;;;;;;65349:24:0::1;::::0;;65389:34:::1;::::0;-1:-1:-1;;;;;65389:34:0;::::1;::::0;::::1;::::0;::::1;::::0;65416:6;;65389:34:::1;:::i;:::-;;;;;;;;64993:438:::0;;:::o;43755:327::-;43902:12;:10;:12::i;:::-;-1:-1:-1;;;;;43890:24:0;:8;-1:-1:-1;;;;;43890:24:0;;;43882:62;;;;-1:-1:-1;;;43882:62:0;;;;;;;:::i;:::-;44002:8;43957:18;:32;43976:12;:10;:12::i;:::-;-1:-1:-1;;;;;43957:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;43957:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;43957:53:0;;;;;;;;;;;44041:12;:10;:12::i;:::-;-1:-1:-1;;;;;44026:48:0;;44065:8;44026:48;;;;;;:::i;:::-;;;;;;;;43755:327;;:::o;85389:249::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;85508:20:::1;85520:7:::0;85508:11:::1;:20::i;:::-;-1:-1:-1::0;;;;;85494:34:0::1;:10;-1:-1:-1::0;;;;;85494:34:0::1;;85472:118;;;;-1:-1:-1::0;;;85472:118:0::1;;;;;;;:::i;:::-;85601:29;85618:1;85622:7;85601:8;:29::i;:::-;-1:-1:-1::0;23287:1:0;24249:7;:22;85389:249::o;62229:21::-;;;-1:-1:-1;;;;;62229:21:0;;:::o;83973:207::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;84093:7;;77969:25:::1;:15;:23;:25::i;:::-;:35;77947:125;;;;-1:-1:-1::0;;;77947:125:0::1;;;;;;;:::i;:::-;84126:14:::2;::::0;84118:54:::2;::::0;-1:-1:-1;;;84118:54:0;;-1:-1:-1;;;;;84126:14:0;;::::2;::::0;84118:33:::2;::::0;:54:::2;::::0;84152:7;;84161:10:::2;::::0;84118:54:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;23287:1:0;24249:7;:22;-1:-1:-1;;;;83973:207:0:o;80075:120::-;-1:-1:-1;;;;;80164:20:0;80141:4;80164:20;;;:10;:20;;;;;;;;;80075:120::o;45120:365::-;45309:41;45328:12;:10;:12::i;:::-;45342:7;45309:18;:41::i;:::-;45287:140;;;;-1:-1:-1;;;45287:140:0;;;;;;;:::i;:::-;45438:39;45452:4;45458:2;45462:7;45471:5;45438:13;:39::i;64020:42::-;;;;;;;;;;;;;;;:::o;84233:237::-;23331:1;23937:7;;:19;;23929:63;;;;-1:-1:-1;;;23929:63:0;;;;;;;:::i;:::-;23331:1;24070:7;:18;84378:10:::1;84390:7:::0;77675:36:::1;84378:10:::0;84390:7;77675:18:::1;:36::i;:::-;77653:115;;;;-1:-1:-1::0;;;77653:115:0::1;;;;;;;:::i;:::-;84423:14:::2;::::0;84415:47:::2;::::0;-1:-1:-1;;;84415:47:0;;-1:-1:-1;;;;;84423:14:0;;::::2;::::0;84415:33:::2;::::0;:47:::2;::::0;84449:7;;84458:3;;84415:47:::2;;;:::i;79174:249::-:0;79310:13;79283:7;77997;77969:25;:15;:23;:25::i;:::-;:35;77947:125;;;;-1:-1:-1;;;77947:125:0;;;;;;;:::i;:::-;79367:19:::1;::::0;;;:10:::1;:19;::::0;;;;;;;;79341:45;;;;::::1;;-1:-1:-1::0;;79341:45:0::1;;::::0;::::1;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;;:23:::1;::::0;:45;;::::1;79367:19:::0;79341:45;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;79341:45:0;;79174:249;-1:-1:-1;;;;;;;;79174:249:0:o;64514:212::-;62720:9;:7;:9::i;:::-;62712:58;;;;-1:-1:-1;;;62712:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64589:20:0;::::1;64581:54;;;;-1:-1:-1::0;;;64581:54:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;64646:28:0;::::1;;::::0;;;:20:::1;:28;::::0;;;;;:35;;-1:-1:-1;;64646:35:0::1;64677:4;64646:35;::::0;;64697:21;::::1;::::0;64646:28;64697:21:::1;64514:212:::0;:::o;65439:97::-;65483:16;65519:9;65512:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65512:16:0;;;;;;;;;;;;;;;;;;;;;;65439:97;:::o;75671:124::-;75729:66;75671:124;:::o;74673:48::-;;;;;;;;;;;;-1:-1:-1;;;;;74673:48:0;;:::o;44153:197::-;-1:-1:-1;;;;;44307:25:0;;;44278:4;44307:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;44153:197::o;63509:103::-;62720:9;:7;:9::i;:::-;62712:58;;;;-1:-1:-1;;;62712:58:0;;;;;;;:::i;:::-;63578:28:::1;63597:8;63578:18;:28::i;:::-;63509:103:::0;:::o;82697:313::-;82832:14;;-1:-1:-1;;;;;82832:14:0;82818:10;:28;82810:68;;;;-1:-1:-1;;;82810:68:0;;;;;;;:::i;:::-;82920:16;82928:7;82920;:16::i;:::-;82889:28;;;;:19;:28;;;;;:47;;-1:-1:-1;;;;;;82889:47:0;-1:-1:-1;;;;;82889:47:0;;;;;;;;;;82947:55;82961:16;82889:28;82961:7;:16::i;:::-;82979:9;82990:7;82947:55;;;;;;;;;;;;:13;:55::i;:::-;82697:313;;:::o;75861:67::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;74940:53::-;;;;;;;;;;;;;:::o;47032:119::-;47089:4;47113:30;:12;47135:7;47113:21;:30::i;33037:106::-;33125:10;33037:106;:::o;53295:159::-;53362:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;53362:29:0;-1:-1:-1;;;;;53362:29:0;;;;;;;;:24;;53416:16;53362:24;53416:7;:16::i;:::-;-1:-1:-1;;;;;53407:39:0;;;;;;;;;;;53295:159;;:::o;91728:636::-;92198:13;;;;;;;;;;;-1:-1:-1;;;92198:13:0;;;;;92245:10;;;;;;;;;;-1:-1:-1;;;92245:10:0;;;;91989:352;;91788:7;;91909:9;;91989:352;;92022:143;;92188:24;;92235:21;;91909:9;;92317:4;;91989:352;;:::i;:::-;;;;;;;;;;;;;91961:395;;;;;;91941:415;;;91728:636;:::o;32576:114::-;32668:14;;32576:114::o;50573:645::-;50739:4;-1:-1:-1;;;;;50719:24:0;:16;50727:7;50719;:16::i;:::-;-1:-1:-1;;;;;50719:24:0;;50697:115;;;;-1:-1:-1;;;50697:115:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;50831:16:0;;50823:65;;;;-1:-1:-1;;;50823:65:0;;;;;;;:::i;:::-;50901:39;50922:4;50928:2;50932:7;50901:20;:39::i;:::-;51005:29;51022:1;51026:7;51005:8;:29::i;:::-;-1:-1:-1;;;;;51047:19:0;;;;;;:13;:19;;;;;:35;;51074:7;51047:26;:35::i;:::-;-1:-1:-1;;;;;;51093:17:0;;;;;;:13;:17;;;;;:30;;51115:7;51093:21;:30::i;:::-;-1:-1:-1;51136:29:0;:12;51153:7;51162:2;51136:16;:29::i;:::-;;51202:7;51198:2;-1:-1:-1;;;;;51183:27:0;51192:4;-1:-1:-1;;;;;51183:27:0;;;;;;;;;;;50573:645;;;:::o;71979:123::-;72048:7;72075:19;72083:3;72075:7;:19::i;47318:428::-;47430:4;47474:16;47482:7;47474;:16::i;:::-;47452:110;;;;-1:-1:-1;;;47452:110:0;;;;;;;:::i;:::-;47573:13;47589:16;47597:7;47589;:16::i;:::-;47573:32;;47635:5;-1:-1:-1;;;;;47624:16:0;:7;-1:-1:-1;;;;;47624:16:0;;:64;;;;47681:7;-1:-1:-1;;;;;47657:31:0;:20;47669:7;47657:11;:20::i;:::-;-1:-1:-1;;;;;47657:31:0;;47624:64;:113;;;;47705:32;47722:5;47729:7;47705:16;:32::i;:::-;47616:122;47318:428;-1:-1:-1;;;;47318:428:0:o;51374:275::-;51511:16;51519:7;51511;:16::i;:::-;51489:110;;;;-1:-1:-1;;;51489:110:0;;;;;;;:::i;:::-;51610:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;91388:222::-;91521:14;;91513:42;;-1:-1:-1;;;91513:42:0;;-1:-1:-1;;;;;91521:14:0;;;;91513:33;;:42;;91547:7;;91513:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91568:34;91584:4;91590:2;91594:7;91568:15;:34::i;88965:1191::-;89122:13;;78250:17;;78228:110;;;;-1:-1:-1;;;78228:110:0;;;;;;;:::i;:::-;89150:16:::1;::::0;::::1;::::0;78250:17;;78228:110:::1;;;;-1:-1:-1::0;;;78228:110:0::1;;;;;;;:::i;:::-;89187:16:::2;::::0;::::2;::::0;89179:70:::2;;;;-1:-1:-1::0;;;89179:70:0::2;;;;;;;:::i;:::-;89297:16;::::0;;::::2;::::0;89282:32:::2;::::0;;;:14:::2;:32;::::0;;;::::2;;:41;89260:153;;;;-1:-1:-1::0;;;89260:153:0::2;;;;;;;:::i;:::-;89446:17;::::0;::::2;::::0;89424:109:::2;;;;-1:-1:-1::0;;;89424:109:0::2;;;;;;;:::i;:::-;89546:15;89564:25;:15;:23;:25::i;:::-;89546:43;;89602:27;89612:7;89621;89602:9;:27::i;:::-;89640;:15;:25;:27::i;:::-;89678:47;89699:7;89708:4;:16;;;89678:20;:47::i;:::-;89736:49;89758:7;89767:4;:17;;;89736:21;:49::i;:::-;89796:47;89817:7;89826:4;:16;;;89796:20;:47::i;:::-;89854:36;89867:7;89876:4;:13;;;89854:12;:36::i;:::-;-1:-1:-1::0;;;;;89901:23:0;::::2;;::::0;;;:14:::2;:23;::::0;;;;:36:::2;::::0;89929:7;89901:27:::2;:36::i;:::-;-1:-1:-1::0;89963:16:0::2;::::0;;::::2;::::0;89948:32:::2;::::0;;;:14:::2;:32;::::0;;;;;;:39;;-1:-1:-1;;89948:39:0::2;89983:4;89948:39;::::0;;90000:22;;;:13:::2;:22:::0;;;;;:32;;-1:-1:-1;;;;;90000:32:0;;::::2;-1:-1:-1::0;;;;;;90000:32:0;;::::2;::::0;::::2;::::0;;;90043:19:::2;:28:::0;;;;;;;:38;;;;::::2;;::::0;;;90100:14:::2;::::0;90092:56;;-1:-1:-1;;;90092:56:0;;90100:14;::::2;::::0;90092:36:::2;::::0;:56:::2;::::0;90014:7;;90138:9;;90092:56:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;78349:1;::::1;88965:1191:::0;;;;:::o;61864:137::-;61935:7;61970:22;61974:3;61986:5;61970:3;:22::i;91006:296::-;91092:19;;;;:10;:19;;;;;;;;;91067:44;;;;;;-1:-1:-1;;91067:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:22;;:44;;;91092:19;91067:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91124:20;91136:7;91124:11;:20::i;:::-;91161:22;;:27;91157:90;;91205:19;;;;:10;:19;;;;;;;;:30;;;;;;;;:::i;:::-;;91157:90;-1:-1:-1;91266:28:0;;;;:19;:28;;;;;91259:35;;-1:-1:-1;;;;;;91259:35:0;;;91006:296::o;72441:227::-;72521:7;;;;72581:22;72585:3;72597:5;72581:3;:22::i;:::-;72550:53;;;;-1:-1:-1;72441:227:0;-1:-1:-1;;;;;72441:227:0:o;73103:204::-;73210:7;73253:44;73258:3;73278;73284:12;73253:4;:44::i;:::-;73245:53;-1:-1:-1;73103:204:0;;;;;;:::o;90592:210::-;90728:7;76751:16;76759:7;76751;:16::i;:::-;76743:53;;;;-1:-1:-1;;;76743:53:0;;;;;;;:::i;:::-;90753:27:::1;::::0;;;:18:::1;:27;::::0;;;;;;;:41;;::::1;::::0;;::::1;::::0;::::1;:::i;46367:352::-:0;46524:28;46534:4;46540:2;46544:7;46524:9;:28::i;:::-;46585:48;46608:4;46614:2;46618:7;46627:5;46585:22;:48::i;:::-;46563:148;;;;-1:-1:-1;;;46563:148:0;;;;;;;:::i;63752:219::-;-1:-1:-1;;;;;63822:22:0;;63814:77;;;;-1:-1:-1;;;63814:77:0;;;;;;;:::i;:::-;63924:6;;63903:38;;-1:-1:-1;;;;;63903:38:0;;;;63924:6;;63903:38;;63924:6;;63903:38;63948:6;:17;;-1:-1:-1;;;;;;63948:17:0;-1:-1:-1;;;;;63948:17:0;;;;;;;;;;63752:219::o;71740:151::-;71824:4;71848:35;71858:3;71878;71848:9;:35::i;60951:137::-;61021:4;61045:35;61053:3;61073:5;61045:7;:35::i;60644:131::-;60711:4;60735:32;60740:3;60760:5;60735:4;:32::i;71172:176::-;71261:4;71285:55;71290:3;71310;-1:-1:-1;;;;;71324:14:0;;71285:4;:55::i;48089:110::-;48165:26;48175:2;48179:7;48165:26;;;;;;;;;;;;:9;:26::i;32698:181::-;32852:19;;32870:1;32852:19;;;32698:181::o;90164:204::-;90294:7;76751:16;76759:7;76751;:16::i;:::-;76743:53;;;;-1:-1:-1;;;76743:53:0;;;;;;;:::i;:::-;-1:-1:-1;90319:27:0::1;::::0;;;:18:::1;:27;::::0;;;;;:41;90164:204::o;90376:208::-;90508:7;76751:16;76759:7;76751;:16::i;:::-;76743:53;;;;-1:-1:-1;;;76743:53:0;;;;;;;:::i;:::-;-1:-1:-1;90533:28:0::1;::::0;;;:19:::1;:28;::::0;;;;;:43;90376:208::o;58528:204::-;58623:18;;58595:7;;58623:26;-1:-1:-1;58615:73:0;;;;-1:-1:-1;;;58615:73:0;;;;;;;:::i;:::-;58706:3;:11;;58718:5;58706:18;;;;;;;;;;;;;;;;58699:25;;58528:204;;;;:::o;49716:520::-;49776:13;49792:16;49800:7;49792;:16::i;:::-;49776:32;;49821:48;49842:5;49857:1;49861:7;49821:20;:48::i;:::-;49910:29;49927:1;49931:7;49910:8;:29::i;:::-;49998:19;;;;:10;:19;;;;;49992:33;;-1:-1:-1;;49992:33:0;;;;;;;;;;;:38;49988:97;;50054:19;;;;:10;:19;;;;;50047:26;;;:::i;:::-;-1:-1:-1;;;;;50097:20:0;;;;;;:13;:20;;;;;:36;;50125:7;50097:27;:36::i;:::-;-1:-1:-1;50146:28:0;:12;50166:7;50146:19;:28::i;:::-;-1:-1:-1;50192:36:0;;50220:7;;50216:1;;-1:-1:-1;;;;;50192:36:0;;;;;50216:1;;50192:36;49716:520;;:::o;69827:279::-;69931:19;;69894:7;;;;69931:27;-1:-1:-1;69923:74:0;;;;-1:-1:-1;;;69923:74:0;;;;;;;:::i;:::-;70010:22;70035:3;:12;;70048:5;70035:19;;;;;;;;;;;;;;;;;;70010:44;;70073:5;:10;;;70085:5;:12;;;70065:33;;;;;69827:279;;;;;:::o;70529:319::-;70623:7;70662:17;;;:12;;;:17;;;;;;70713:12;70698:13;70690:36;;;;-1:-1:-1;;;70690:36:0;;;;;;;;:::i;:::-;;70780:3;:12;;70804:1;70793:8;:12;70780:26;;;;;;;;;;;;;;;;;;:33;;;70773:40;;;70529:319;;;;;:::o;52544:743::-;52699:4;52721:15;:2;-1:-1:-1;;;;;52721:13:0;;:15::i;:::-;52716:60;;-1:-1:-1;52760:4:0;52753:11;;52716:60;52786:23;52825:349;-1:-1:-1;;;52972:12:0;:10;:12::i;:::-;53007:4;53034:7;53064:5;52859:229;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;52859:229:0;;;;;;;-1:-1:-1;;;;;52859:229:0;;;;;;;;;;;52825:349;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52825:15:0;;;:349;:15;:349::i;:::-;52786:388;;53185:13;53212:10;53201:32;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;53252:26:0;-1:-1:-1;;;53252:26:0;;-1:-1:-1;;;52544:743:0;;;;;;:::o;69142:125::-;69213:4;69237:17;;;:12;;;;;:17;;;;;;:22;;;69142:125::o;56230:1544::-;56296:4;56435:19;;;:12;;;:19;;;;;;56471:15;;56467:1300;;56906:18;;-1:-1:-1;;56857:14:0;;;;56906:22;;;;56833:21;;56906:3;;:22;;57193;;;;;;;;;;;;;;57173:42;;57339:9;57310:3;:11;;57322:13;57310:26;;;;;;;;;;;;;;;;;;;:38;;;;57416:23;;;57458:1;57416:12;;;:23;;;;;;57442:17;;;57416:43;;57568:17;;57416:3;;57568:17;;;;;;;;;;;;;;;;;;;;;;57663:3;:12;;:19;57676:5;57663:19;;;;;;;;;;;57656:26;;;57706:4;57699:11;;;;;;;;56467:1300;57750:5;57743:12;;;;;55640:414;55703:4;55725:21;55735:3;55740:5;55725:9;:21::i;:::-;55720:327;;-1:-1:-1;55763:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;55946:18;;55924:19;;;:12;;;:19;;;;;;:40;;;;55979:11;;55720:327;-1:-1:-1;56030:5:0;56023:12;;66640:692;66716:4;66851:17;;;:12;;;:17;;;;;;66885:13;66881:444;;-1:-1:-1;;66970:38:0;;;;;;;;;;;;;;;;;;66952:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;67167:19;;67147:17;;;:12;;;:17;;;;;;;:39;67201:11;;66881:444;67281:5;67245:3;:12;;67269:1;67258:8;:12;67245:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;67308:5;67301:12;;;;;48426:321;48556:18;48562:2;48566:7;48556:5;:18::i;:::-;48607:54;48638:1;48642:2;48646:7;48655:5;48607:22;:54::i;:::-;48585:154;;;;-1:-1:-1;;;48585:154:0;;;;;;;:::i;71514:142::-;71591:4;71615:33;71623:3;71643;71615:7;:33::i;715:422::-;1082:20;1121:8;;;715:422::o;3633:196::-;3736:12;3768:53;3791:6;3799:4;3805:1;3808:12;3768:22;:53::i;49083:404::-;-1:-1:-1;;;;;49163:16:0;;49155:61;;;;-1:-1:-1;;;49155:61:0;;;;;;;:::i;:::-;49236:16;49244:7;49236;:16::i;:::-;49235:17;49227:58;;;;-1:-1:-1;;;49227:58:0;;;;;;;:::i;:::-;49298:45;49327:1;49331:2;49335:7;49298:20;:45::i;:::-;-1:-1:-1;;;;;49356:17:0;;;;;;:13;:17;;;;;:30;;49378:7;49356:21;:30::i;:::-;-1:-1:-1;49399:29:0;:12;49416:7;49425:2;49399:16;:29::i;:::-;-1:-1:-1;49446:33:0;;49471:7;;-1:-1:-1;;;;;49446:33:0;;;49463:1;;49446:33;;49463:1;;49446:33;49083:404;;:::o;67509:1549::-;67573:4;67708:17;;;:12;;;:17;;;;;;67742:13;;67738:1313;;68174:19;;-1:-1:-1;;68127:12:0;;;;68174:23;;;;68103:21;;68174:3;;:23;;68471;;;;;;;;;;;;;;;;68442:52;;68619:9;68589:3;:12;;68602:13;68589:27;;;;;;;;;;;;;;;;:39;;:27;;;;;:39;;;;;;;;;;;;;;;68709:14;;68696:28;;:12;;;:28;;;;;68727:17;;;68696:48;;68853:18;;68696:3;;68853:18;;;;;;;;;;;;;;-1:-1:-1;;68853:18:0;;;;;;;;;;;;;;;;;;;;;68949:17;;;:12;;;:17;;;;;;68942:24;;;;68853:18;-1:-1:-1;68983:11:0;;-1:-1:-1;;;;68983:11:0;5010:979;5140:12;5173:18;5184:6;5173:10;:18::i;:::-;5165:60;;;;-1:-1:-1;;;5165:60:0;;;;;;;:::i;:::-;5299:12;5313:23;5340:6;-1:-1:-1;;;;;5340:11:0;5360:8;5371:4;5340:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5298:78;;;;5391:7;5387:595;;;5422:10;-1:-1:-1;5415:17:0;;-1:-1:-1;5415:17:0;5387:595;5536:17;;:21;5532:439;;5799:10;5793:17;5860:15;5847:10;5843:2;5839:19;5832:44;5747:148;5942:12;5935:20;;-1:-1:-1;;;5935:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:130;72:20;;-1:-1;;;;;64372:54;;65660:35;;65650:2;;65709:1;;65699:12;685:440;;786:3;779:4;771:6;767:17;763:27;753:2;;-1:-1;;794:12;753:2;841:6;828:20;61759:18;61751:6;61748:30;61745:2;;;-1:-1;;61781:12;61745:2;863:64;61854:9;61835:17;;-1:-1;;61831:33;61922:4;61912:15;863:64;:::i;:::-;854:73;;947:6;940:5;933:21;1051:3;61922:4;1042:6;975;1033:16;;1030:25;1027:2;;;1068:1;;1058:12;1027:2;65066:6;61922:4;975:6;971:17;61922:4;1009:5;1005:16;65043:30;65122:1;65104:16;;;61922:4;65104:16;65097:27;1009:5;746:379;-1:-1;;746:379::o;2476:685::-;;2592:4;2580:9;2575:3;2571:19;2567:30;2564:2;;;-1:-1;;2600:12;2564:2;2628:20;2592:4;2628:20;:::i;:::-;2619:29;;2735:70;2801:3;2777:22;2735:70;:::i;:::-;2717:16;2710:96;2903:70;2969:3;2870:2;2949:9;2945:22;2903:70;:::i;:::-;2870:2;2889:5;2885:16;2878:96;3069:70;3135:3;3036:2;3115:9;3111:22;3069:70;:::i;:::-;3036:2;3055:5;3051:16;3044:96;2558:603;;;;:::o;4163:320::-;;4273:4;4261:9;4256:3;4252:19;4248:30;4245:2;;;-1:-1;;4281:12;4245:2;4309:20;4273:4;4309:20;:::i;:::-;6366;;4387:75;;-1:-1;4300:29;4239:244;-1:-1;4239:244::o;4526:755::-;;4647:4;4635:9;4630:3;4626:19;4622:30;4619:2;;;-1:-1;;4655:12;4619:2;4683:20;4647:4;4683:20;:::i;:::-;4674:29;;6379:6;6366:20;4771:16;4764:75;4897:2;4953:9;4949:22;6501:20;64588:4;66296:5;64577:16;66273:5;66270:33;66260:2;;66317:1;;66307:12;66260:2;4930:47;4897:2;4916:5;4912:16;4905:73;;5036:2;5094:9;5090:22;340:20;5036:2;5055:5;5051:16;5044:75;5177:2;5235:9;5231:22;340:20;5177:2;5196:5;5192:16;5185:75;4613:668;;;;:::o;5318:974::-;;5433:4;5421:9;5416:3;5412:19;5408:30;5405:2;;;-1:-1;;5441:12;5405:2;5469:20;5433:4;5469:20;:::i;:::-;5460:29;;5556:17;5543:31;5594:18;;5586:6;5583:30;5580:2;;;5571:1;;5616:12;5580:2;5661:59;5716:3;5707:6;5696:9;5692:22;5661:59;:::i;:::-;5643:16;5636:85;5817:2;5806:9;5802:18;5789:32;5775:46;;5594:18;5833:6;5830:30;5827:2;;;5571:1;;5863:12;5827:2;;5908:59;5963:3;5954:6;5943:9;5939:22;5908:59;:::i;:::-;5817:2;5894:5;5890:16;5883:85;;6036:2;6094:9;6090:22;340:20;6036:2;6055:5;6051:16;6044:75;6188:2;6246:9;6242:22;340:20;6188:2;6207:5;6203:16;6196:75;5399:893;;;;:::o;6569:241::-;;6673:2;6661:9;6652:7;6648:23;6644:32;6641:2;;;-1:-1;;6679:12;6641:2;6741:53;6786:7;6762:22;6741:53;:::i;6817:366::-;;;6938:2;6926:9;6917:7;6913:23;6909:32;6906:2;;;-1:-1;;6944:12;6906:2;7006:53;7051:7;7027:22;7006:53;:::i;:::-;6996:63;;7114:53;7159:7;7096:2;7139:9;7135:22;7114:53;:::i;:::-;7104:63;;6900:283;;;;;:::o;7190:491::-;;;;7328:2;7316:9;7307:7;7303:23;7299:32;7296:2;;;-1:-1;;7334:12;7296:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;7386:63;-1:-1;7486:2;7525:22;;72:20;97:33;72:20;97:33;:::i;:::-;7290:391;;7494:63;;-1:-1;;;7594:2;7633:22;;;;6366:20;;7290:391::o;7688:721::-;;;;;7852:3;7840:9;7831:7;7827:23;7823:33;7820:2;;;-1:-1;;7859:12;7820:2;7921:53;7966:7;7942:22;7921:53;:::i;:::-;7911:63;;8029:53;8074:7;8011:2;8054:9;8050:22;8029:53;:::i;:::-;8019:63;;8119:2;8162:9;8158:22;6366:20;8127:63;;8255:2;8244:9;8240:18;8227:32;8279:18;8271:6;8268:30;8265:2;;;-1:-1;;8301:12;8265:2;8331:62;8385:7;8376:6;8365:9;8361:22;8331:62;:::i;:::-;8321:72;;;7814:595;;;;;;;:::o;8416:360::-;;;8534:2;8522:9;8513:7;8509:23;8505:32;8502:2;;;-1:-1;;8540:12;8502:2;8602:53;8647:7;8623:22;8602:53;:::i;:::-;8592:63;;8692:2;8732:9;8728:22;206:20;65806:5;64054:13;64047:21;65784:5;65781:32;65771:2;;-1:-1;;65817:12;65771:2;8700:60;;;;8496:280;;;;;:::o;8783:874::-;;;;;9023:3;9011:9;9002:7;8998:23;8994:33;8991:2;;;-1:-1;;9030:12;8991:2;9092:53;9137:7;9113:22;9092:53;:::i;:::-;9082:63;;9210:2;9199:9;9195:18;9182:32;9234:18;9226:6;9223:30;9220:2;;;-1:-1;;9256:12;9220:2;9286:79;9357:7;9348:6;9337:9;9333:22;9286:79;:::i;:::-;9276:89;;;9420:80;9492:7;9402:2;9472:9;9468:22;9420:80;:::i;:::-;9410:90;;9556:85;9633:7;9537:3;9613:9;9609:22;9556:85;:::i;:::-;9546:95;;8985:672;;;;;;;:::o;9664:366::-;;;9785:2;9773:9;9764:7;9760:23;9756:32;9753:2;;;-1:-1;;9791:12;9753:2;9853:53;9898:7;9874:22;9853:53;:::i;:::-;9843:63;9943:2;9982:22;;;;6366:20;;-1:-1;;;9747:283::o;10037:556::-;;;;10207:3;10195:9;10186:7;10182:23;10178:33;10175:2;;;-1:-1;;10214:12;10175:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;10266:63;-1:-1;10366:2;10405:22;;6366:20;;-1:-1;10492:85;10569:7;10474:2;10545:22;;10492:85;:::i;:::-;10482:95;;10169:424;;;;;:::o;10600:239::-;;10703:2;10691:9;10682:7;10678:23;10674:32;10671:2;;;-1:-1;;10709:12;10671:2;489:6;476:20;501:32;527:5;501:32;:::i;10846:261::-;;10960:2;10948:9;10939:7;10935:23;10931:32;10928:2;;;-1:-1;;10966:12;10928:2;628:6;622:13;640:32;666:5;640:32;:::i;11114:559::-;;;11288:3;11276:9;11267:7;11263:23;11259:33;11256:2;;;-1:-1;;11295:12;11256:2;11353:17;11340:31;11391:18;11383:6;11380:30;11377:2;;;-1:-1;;11413:12;11377:2;11443:79;11514:7;11505:6;11494:9;11490:22;11443:79;:::i;:::-;11433:89;;;11577:80;11649:7;11559:2;11629:9;11625:22;11577:80;:::i;11680:241::-;;11784:2;11772:9;11763:7;11759:23;11755:32;11752:2;;;-1:-1;;11790:12;11752:2;-1:-1;6366:20;;11746:175;-1:-1;11746:175::o;11928:366::-;;;12049:2;12037:9;12028:7;12024:23;12020:32;12017:2;;;-1:-1;;12055:12;12017:2;6379:6;6366:20;12107:63;;12225:53;12270:7;12207:2;12250:9;12246:22;12225:53;:::i;12301:492::-;;;;12442:2;12430:9;12421:7;12417:23;12413:32;12410:2;;;-1:-1;;12448:12;12410:2;6379:6;6366:20;12500:63;;12628:2;12617:9;12613:18;12600:32;12652:18;;12644:6;12641:30;12638:2;;;-1:-1;;12674:12;12638:2;12760:6;12749:9;12745:22;;;1263:3;1256:4;1248:6;1244:17;1240:27;1230:2;;-1:-1;;1271:12;1230:2;1314:6;1301:20;12652:18;1333:6;1330:30;1327:2;;;-1:-1;;1363:12;1327:2;1458:3;12628:2;1438:17;1399:6;1424:32;;1421:41;1418:2;;;-1:-1;;1465:12;1418:2;12628;1399:6;1395:17;12694:83;;;;;;;;12404:389;;;;;:::o;12800:408::-;;;12930:9;12921:7;12917:23;12942:2;12917:23;12913:32;12910:2;;;-1:-1;;12948:12;12910:2;6366:20;;;-1:-1;2079:4;-1:-1;;2058:19;;2054:30;2051:2;;;-1:-1;;2087:12;2051:2;;2115:20;2079:4;2115:20;:::i;:::-;13100:2;13164:9;13160:22;6366:20;2201:16;2194:75;2367:49;2412:3;2079:4;13164:9;2388:22;2367:49;:::i;:::-;13100:2;2353:5;2349:16;2342:75;13108:84;;;;12904:304;;;;;:::o;13215:409::-;;;13345:9;13336:7;13332:23;13357:3;13332:23;13328:33;13325:2;;;-1:-1;;13364:12;13325:2;6366:20;;;-1:-1;3303:4;-1:-1;;3282:19;;3278:30;3275:2;;;-1:-1;;3311:12;3275:2;;3339:20;3303:4;3339:20;:::i;:::-;13516:2;13580:9;13576:22;6366:20;3425:16;3418:75;3591:49;3636:3;3612:22;13580:9;3612:22;3591:49;:::i;:::-;13516:2;3577:5;3573:16;3566:75;3737:49;3782:3;3758:22;13580:9;3758:22;3737:49;:::i;:::-;3612:22;3723:5;3719:16;3712:75;3886:49;3931:3;3907:22;13580:9;3907:22;3886:49;:::i;:::-;3758:22;3872:5;3868:16;3861:75;4038:70;4104:3;3303:4;13580:9;4080:22;4038:70;:::i;:::-;3907:22;4024:5;4020:16;4013:96;13524:84;;;;13319:305;;;;;:::o;15455:343::-;;15597:5;62534:12;63078:6;63073:3;63066:19;15690:52;15735:6;63115:4;63110:3;63106:14;63115:4;15716:5;15712:16;15690:52;:::i;:::-;61854:9;65564:14;-1:-1;;65560:28;15754:39;;;;63115:4;15754:39;;15545:253;-1:-1;;15545:253::o;33722:992::-;33925:23;;15247:37;;34100:4;34089:16;;;34083:23;-1:-1;;;;;64372:54;;;34160:14;;;14049:45;;;;34256:4;34245:16;;;34239:23;64372:54;;34316:14;;;14049:45;34415:4;34404:16;;;34398:23;64372:54;;;34475:14;;;14049:45;34576:4;34565:16;;;34559:23;34962;34678:14;;15247:37;33830:884::o;35426:271::-;;15965:5;62534:12;16076:52;16121:6;16116:3;16109:4;16102:5;16098:16;16076:52;:::i;:::-;16140:16;;;;;35560:137;-1:-1;;35560:137::o;35704:659::-;-1:-1;;;20788:87;;20773:1;20894:11;;15247:37;;;;36215:12;;;15247:37;36326:12;;;35949:414::o;36370:222::-;-1:-1;;;;;64372:54;;;;14049:45;;36497:2;36482:18;;36468:124::o;36599:672::-;-1:-1;;;;;64372:54;;;14049:45;;64372:54;;37025:2;37010:18;;14049:45;37108:2;37093:18;;15247:37;;;36844:3;37145:2;37130:18;;37123:48;;;36599:672;;37185:76;;36829:19;;37247:6;37185:76;:::i;:::-;37177:84;36815:456;-1:-1;;;;;;36815:456::o;37278:457::-;-1:-1;;;;;64372:54;;13892:58;;37471:2;37597;37582:18;;37575:48;;;37456:18;;63066:19;;;37278:457;63078:6;65061:3;63106:14;;;65043:30;65104:16;;;63106:14;65104:16;;;65097:27;;;;61854:9;65564:14;;;-1:-1;;65560:28;16448:39;;;37442:293;-1:-1;;37442:293::o;37742:370::-;37919:2;37933:47;;;62534:12;;37904:18;;;63066:19;;;37742:370;;37919:2;62388:14;;;;63106;;;;37742:370;14775:260;14800:6;14797:1;14794:13;14775:260;;;14861:13;;-1:-1;;;;;64372:54;14049:45;;62921:14;;;;13785;;;;64383:42;14815:9;14775:260;;;-1:-1;37986:116;;37890:222;-1:-1;;;;;;37890:222::o;38119:210::-;64054:13;;64047:21;15130:34;;38240:2;38225:18;;38211:118::o;38336:222::-;15247:37;;;38463:2;38448:18;;38434:124::o;38565:668::-;15247:37;;;-1:-1;;;;;64372:54;;;;38969:2;38954:18;;14049:45;39052:2;39037:18;;15247:37;;;;39135:2;39120:18;;15247:37;39218:3;39203:19;;15247:37;38804:3;38789:19;;38775:458::o;39240:668::-;15247:37;;;39644:2;39629:18;;15247:37;;;;39727:2;39712:18;;15247:37;;;;39810:2;39795:18;;15247:37;-1:-1;;;;;64372:54;39893:3;39878:19;;14049:45;39479:3;39464:19;;39450:458::o;39915:780::-;15247:37;;;40347:2;40332:18;;15247:37;;;;40430:2;40415:18;;15247:37;;;;40513:2;40498:18;;15247:37;40596:3;40581:19;;15247:37;40680:3;40665:19;;15247:37;40182:3;40167:19;;40153:542::o;40702:548::-;15247:37;;;64588:4;64577:16;;;;41070:2;41055:18;;35379:35;41153:2;41138:18;;15247:37;41236:2;41221:18;;15247:37;40909:3;40894:19;;40880:370::o;41257:310::-;;41404:2;41425:17;41418:47;41479:78;41404:2;41393:9;41389:18;41543:6;41479:78;:::i;41574:416::-;41774:2;41788:47;;;17080:2;41759:18;;;63066:19;17116:34;63106:14;;;17096:55;-1:-1;;;17171:12;;;17164:26;17209:12;;;41745:245::o;41997:416::-;42197:2;42211:47;;;17460:2;42182:18;;;63066:19;17496:34;63106:14;;;17476:55;-1:-1;;;17551:12;;;17544:29;17592:12;;;42168:245::o;42420:416::-;42620:2;42634:47;;;17843:2;42605:18;;;63066:19;17879:34;63106:14;;;17859:55;-1:-1;;;17934:12;;;17927:32;17978:12;;;42591:245::o;42843:416::-;43043:2;43057:47;;;18229:2;43028:18;;;63066:19;18265:27;63106:14;;;18245:48;18312:12;;;43014:245::o;43266:416::-;43466:2;43480:47;;;18563:2;43451:18;;;63066:19;18599:34;63106:14;;;18579:55;-1:-1;;;18654:12;;;18647:42;18708:12;;;43437:245::o;43689:416::-;43889:2;43903:47;;;18959:2;43874:18;;;63066:19;18995:34;63106:14;;;18975:55;-1:-1;;;19050:12;;;19043:43;19105:12;;;43860:245::o;44112:416::-;44312:2;44326:47;;;19356:2;44297:18;;;63066:19;19392:30;63106:14;;;19372:51;19442:12;;;44283:245::o;44535:416::-;44735:2;44749:47;;;19693:2;44720:18;;;63066:19;-1:-1;;;63106:14;;;19709:42;19770:12;;;44706:245::o;44958:416::-;45158:2;45172:47;;;20021:2;45143:18;;;63066:19;20057:30;63106:14;;;20037:51;20107:12;;;45129:245::o;45381:416::-;45581:2;45595:47;;;20358:2;45566:18;;;63066:19;20394:34;63106:14;;;20374:55;-1:-1;;;20449:12;;;20442:25;20486:12;;;45552:245::o;45804:416::-;46004:2;46018:47;;;21144:2;45989:18;;;63066:19;21180:34;63106:14;;;21160:55;-1:-1;;;21235:12;;;21228:35;21282:12;;;45975:245::o;46227:416::-;46427:2;46441:47;;;21533:2;46412:18;;;63066:19;-1:-1;;;63106:14;;;21549:45;21613:12;;;46398:245::o;46650:416::-;46850:2;46864:47;;;21864:2;46835:18;;;63066:19;21900:34;63106:14;;;21880:55;-1:-1;;;21955:12;;;21948:26;21993:12;;;46821:245::o;47073:416::-;47273:2;47287:47;;;22244:2;47258:18;;;63066:19;22280:34;63106:14;;;22260:55;-1:-1;;;22335:12;;;22328:28;22375:12;;;47244:245::o;47496:416::-;47696:2;47710:47;;;22626:2;47681:18;;;63066:19;22662:27;63106:14;;;22642:48;22709:12;;;47667:245::o;47919:416::-;48119:2;48133:47;;;22960:2;48104:18;;;63066:19;22996:34;63106:14;;;22976:55;-1:-1;;;23051:12;;;23044:39;23102:12;;;48090:245::o;48342:416::-;48542:2;48556:47;;;23353:2;48527:18;;;63066:19;23389:34;63106:14;;;23369:55;-1:-1;;;23444:12;;;23437:28;23484:12;;;48513:245::o;48765:416::-;48965:2;48979:47;;;23735:2;48950:18;;;63066:19;23771:34;63106:14;;;23751:55;-1:-1;;;23826:12;;;23819:36;23874:12;;;48936:245::o;49188:416::-;49388:2;49402:47;;;24125:2;49373:18;;;63066:19;24161:34;63106:14;;;24141:55;24230:26;24216:12;;;24209:48;24276:12;;;49359:245::o;49611:416::-;49811:2;49825:47;;;24527:2;49796:18;;;63066:19;24563:34;63106:14;;;24543:55;-1:-1;;;24618:12;;;24611:34;24664:12;;;49782:245::o;50034:416::-;50234:2;50248:47;;;24915:2;50219:18;;;63066:19;-1:-1;;;63106:14;;;24931:44;24994:12;;;50205:245::o;50457:416::-;50657:2;50671:47;;;25245:2;50642:18;;;63066:19;25281:34;63106:14;;;25261:55;25350:32;25336:12;;;25329:54;25402:12;;;50628:245::o;50880:416::-;51080:2;51094:47;;;25653:2;51065:18;;;63066:19;25689:34;63106:14;;;25669:55;-1:-1;;;25744:12;;;25737:26;25782:12;;;51051:245::o;51303:416::-;51503:2;51517:47;;;26033:2;51488:18;;;63066:19;26069:29;63106:14;;;26049:50;26118:12;;;51474:245::o;51726:416::-;51926:2;51940:47;;;51911:18;;;63066:19;26405:34;63106:14;;;26385:55;26459:12;;;51897:245::o;52149:416::-;52349:2;52363:47;;;26710:2;52334:18;;;63066:19;26746:34;63106:14;;;26726:55;-1:-1;;;26801:12;;;26794:36;26849:12;;;52320:245::o;52572:416::-;52772:2;52786:47;;;27100:2;52757:18;;;63066:19;27136:34;63106:14;;;27116:55;-1:-1;;;27191:12;;;27184:36;27239:12;;;52743:245::o;52995:416::-;53195:2;53209:47;;;27490:2;53180:18;;;63066:19;27526:31;63106:14;;;27506:52;27577:12;;;53166:245::o;53418:416::-;53618:2;53632:47;;;27828:2;53603:18;;;63066:19;27864:34;63106:14;;;27844:55;-1:-1;;;27919:12;;;27912:26;27957:12;;;53589:245::o;53841:416::-;54041:2;54055:47;;;28208:2;54026:18;;;63066:19;28244:34;63106:14;;;28224:55;-1:-1;;;28299:12;;;28292:33;28344:12;;;54012:245::o;54264:416::-;54464:2;54478:47;;;28595:2;54449:18;;;63066:19;28631:34;63106:14;;;28611:55;-1:-1;;;28686:12;;;28679:42;28740:12;;;54435:245::o;54687:416::-;54887:2;54901:47;;;28991:2;54872:18;;;63066:19;29027:34;63106:14;;;29007:55;-1:-1;;;29082:12;;;29075:29;29123:12;;;54858:245::o;55110:416::-;55310:2;55324:47;;;29374:2;55295:18;;;63066:19;29410:34;63106:14;;;29390:55;-1:-1;;;29465:12;;;29458:25;29502:12;;;55281:245::o;55533:416::-;55733:2;55747:47;;;29753:2;55718:18;;;63066:19;-1:-1;;;63106:14;;;29769:40;29828:12;;;55704:245::o;55956:416::-;56156:2;56170:47;;;30079:2;56141:18;;;63066:19;30115:28;63106:14;;;30095:49;30163:12;;;56127:245::o;56379:416::-;56579:2;56593:47;;;30414:2;56564:18;;;63066:19;30450:34;63106:14;;;30430:55;-1:-1;;;30505:12;;;30498:41;30558:12;;;56550:245::o;56802:416::-;57002:2;57016:47;;;30809:2;56987:18;;;63066:19;30845:31;63106:14;;;30825:52;30896:12;;;56973:245::o;57225:416::-;57425:2;57439:47;;;31147:2;57410:18;;;63066:19;31183:26;63106:14;;;31163:47;31229:12;;;57396:245::o;57648:416::-;57848:2;57862:47;;;31480:2;57833:18;;;63066:19;31516:26;63106:14;;;31496:47;31562:12;;;57819:245::o;58071:416::-;58271:2;58285:47;;;31813:2;58256:18;;;63066:19;31849:33;63106:14;;;31829:54;31902:12;;;58242:245::o;58494:416::-;58694:2;58708:47;;;32153:2;58679:18;;;63066:19;32189:34;63106:14;;;32169:55;-1:-1;;;32244:12;;;32237:30;32286:12;;;58665:245::o;59146:349::-;15247:37;;;-1:-1;;;;;64372:54;59481:2;59466:18;;13892:58;59309:2;59294:18;;59280:215::o;59502:417::-;15247:37;;;32562:23;;59905:2;59890:18;;;15247:37;;;;32726:16;32720:23;-1:-1;;;;;64372:54;32797:14;;;14049:45;59699:2;59684:18;;59670:249::o;59926:442::-;15247:37;;;33117:23;;34962;60354:2;60339:18;;;15247:37;;;;33322:16;;33316:23;34962;33435:14;;;;15247:37;;;;33519:16;33513:23;34962;33632:14;;;15247:37;60135:3;60120:19;;60106:262::o;60375:418::-;15247:37;;;60572:3;60557:19;;60669:114;60779:2;60764:18;;60755:6;60669:114;:::i;60800:546::-;15247:37;;;61033:3;61018:19;;61130:114;61240:2;61225:18;;61216:6;61130:114;:::i;:::-;-1:-1;;;;;64372:54;;;;61331:3;61316:19;;;;13892:58;61004:342;;-1:-1;;61004:342::o;61353:256::-;61415:2;61409:9;61441:17;;;61516:18;61501:34;;61537:22;;;61498:62;61495:2;;;61573:1;;61563:12;61495:2;61415;61582:22;61393:216;;-1:-1;61393:216::o;65139:268::-;65204:1;65211:101;65225:6;65222:1;65219:13;65211:101;;;65292:11;;;65286:18;65273:11;;;65266:39;65247:2;65240:10;65211:101;;;65327:6;65324:1;65321:13;65318:2;;;-1:-1;;65204:1;65374:16;;65367:27;65188:219::o;65601:117::-;-1:-1;;;;;64372:54;;65660:35;;65650:2;;65709:1;;65699:12;65967:115;-1:-1;;;;;;64220:78;;66025:34;;66015:2;;66073:1;;66063:12

Swarm Source

ipfs://3f49cdfbced025dd615fc21625c8ca5d4c7978f7ae78e70d36498689bf44dd04
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.