Token MakersTokenV2

Collectibles NFT  
 

Overview [ERC-20]

Max Total Supply:
75,313 MKT2

Holders:
10,819 (0.00%)
 
Balance
53 MKT2

Value
$0.00
0xa6b74e78b02caa5eeff8de506c5be1659744aadf
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

OVERVIEW

Premier rare digital art market.

# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DigitalMediaCore

Compiler Version
v0.4.25+commit.59dbf8f1

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

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

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

pragma solidity ^0.4.21;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
    if (a == 0) {
      return 0;
    }
    c = a * b;
    assert(c / a == b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    // uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return a / b;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
    c = a + b;
    assert(c >= a);
    return c;
  }
}

// File: REMIX_FILE_SYNC/ApprovedCreatorRegistryInterface.sol

pragma solidity ^0.4.22;


/**
 * Interface to the digital media store external contract that is 
 * responsible for storing the common digital media and collection data.
 * This allows for new token contracts to be deployed and continue to reference
 * the digital media and collection data.
 */
contract ApprovedCreatorRegistryInterface {

    function getVersion() public pure returns (uint);
    function typeOfContract() public pure returns (string);
    function isOperatorApprovedForCustodialAccount(
        address _operator,
        address _custodialAddress) public view returns (bool);

}

// File: REMIX_FILE_SYNC/DigitalMediaStoreInterface.sol

pragma solidity 0.4.25;


/**
 * Interface to the digital media store external contract that is 
 * responsible for storing the common digital media and collection data.
 * This allows for new token contracts to be deployed and continue to reference
 * the digital media and collection data.
 */
contract DigitalMediaStoreInterface {

    function getDigitalMediaStoreVersion() public pure returns (uint);

    function getStartingDigitalMediaId() public view returns (uint256);

    function registerTokenContractAddress() external;

    /**
     * Creates a new digital media object in storage
     * @param  _creator address the address of the creator
     * @param  _printIndex uint32 the current print index for the limited edition media
     * @param  _totalSupply uint32 the total allowable prints for this media
     * @param  _collectionId uint256 the collection id that this media belongs to
     * @param  _metadataPath string the ipfs metadata path
     * @return the id of the new digital media created
     */
    function createDigitalMedia(
                address _creator, 
                uint32 _printIndex, 
                uint32 _totalSupply, 
                uint256 _collectionId, 
                string _metadataPath) external returns (uint);

    /**
     * Increments the current print index of the digital media object
     * @param  _digitalMediaId uint256 the id of the digital media
     * @param  _increment uint32 the amount to increment by
     */
    function incrementDigitalMediaPrintIndex(
                uint256 _digitalMediaId, 
                uint32 _increment)  external;

    /**
     * Retrieves the digital media object by id
     * @param  _digitalMediaId uint256 the address of the creator
     */
    function getDigitalMedia(uint256 _digitalMediaId) external view returns(
                uint256 id,
                uint32 totalSupply,
                uint32 printIndex,
                uint256 collectionId,
                address creator,
                string metadataPath);

    /**
     * Creates a new collection
     * @param  _creator address the address of the creator
     * @param  _metadataPath string the ipfs metadata path
     * @return the id of the new collection created
     */
    function createCollection(address _creator, string _metadataPath) external returns (uint);

    /**
     * Retrieves a collection by id
     * @param  _collectionId uint256
     */
    function getCollection(uint256 _collectionId) external view
            returns(
                uint256 id,
                address creator,
                string metadataPath);
}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/ownership/Ownable.sol

pragma solidity ^0.4.21;


/**
 * @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 OwnershipTransferred(address indexed previousOwner, address indexed newOwner);


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

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @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 {
    require(newOwner != address(0));
    emit OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/lifecycle/Pausable.sol

pragma solidity ^0.4.21;



/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is Ownable {
  event Pause();
  event Unpause();

  bool public paused = false;


  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   */
  modifier whenNotPaused() {
    require(!paused);
    _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   */
  modifier whenPaused() {
    require(paused);
    _;
  }

  /**
   * @dev called by the owner to pause, triggers stopped state
   */
  function pause() onlyOwner whenNotPaused public {
    paused = true;
    emit Pause();
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() onlyOwner whenPaused public {
    paused = false;
    emit Unpause();
  }
}

// File: REMIX_FILE_SYNC/MediaStoreVersionControl.sol

pragma solidity 0.4.25;



/**
 * A special control class that is used to configure and manage a token contract's 
 * different digital media store versions.
 *
 * Older versions of token contracts had the ability to increment the digital media's
 * print edition in the media store, which was necessary in the early stages to provide
 * upgradeability and flexibility.
 *
 * New verions will get rid of this ability now that token contract logic
 * is more stable and we've built in burn capabilities.  
 *
 * In order to support the older tokens, we need to be able to look up the appropriate digital
 * media store associated with a given digital media id on the latest token contract.
 */
contract MediaStoreVersionControl is Pausable {

    // The single allowed creator for this digital media contract.
    DigitalMediaStoreInterface public v1DigitalMediaStore;

    // The current digitial media store, used for this tokens creation.
    DigitalMediaStoreInterface public currentDigitalMediaStore;
    uint256 public currentStartingDigitalMediaId;


    /**
     * Validates that the managers are initialized.
     */
    modifier managersInitialized() {
        require(v1DigitalMediaStore != address(0));
        require(currentDigitalMediaStore != address(0));
        _;
    }

    /**
     * Sets a digital media store address upon construction.  
     * Once set it's immutable, so that a token contract is always
     * tied to one digital media store.
     */
    function setDigitalMediaStoreAddress(address _dmsAddress)  
            internal {
        DigitalMediaStoreInterface candidateDigitalMediaStore = DigitalMediaStoreInterface(_dmsAddress);
        require(candidateDigitalMediaStore.getDigitalMediaStoreVersion() == 2, "Incorrect version.");
        currentDigitalMediaStore = candidateDigitalMediaStore;
        currentDigitalMediaStore.registerTokenContractAddress();
        currentStartingDigitalMediaId = currentDigitalMediaStore.getStartingDigitalMediaId();
    }

    /**
     * Publicly callable by the owner, but can only be set one time, so don't make 
     * a mistake when setting it.
     *
     * Will also check that the version on the other end of the contract is in fact correct.
     */
    function setV1DigitalMediaStoreAddress(address _dmsAddress) public onlyOwner {
        require(address(v1DigitalMediaStore) == 0, "V1 media store already set.");
        DigitalMediaStoreInterface candidateDigitalMediaStore = DigitalMediaStoreInterface(_dmsAddress);
        require(candidateDigitalMediaStore.getDigitalMediaStoreVersion() == 1, "Incorrect version.");
        v1DigitalMediaStore = candidateDigitalMediaStore;
        v1DigitalMediaStore.registerTokenContractAddress();
    }

    /**
     * Depending on the digital media id, determines whether to return the previous
     * version of the digital media manager.
     */
    function _getDigitalMediaStore(uint256 _digitalMediaId) 
            internal 
            view
            managersInitialized
            returns (DigitalMediaStoreInterface) {
        if (_digitalMediaId < currentStartingDigitalMediaId) {
            return v1DigitalMediaStore;
        } else {
            return currentDigitalMediaStore;
        }
    }  
}

// File: REMIX_FILE_SYNC/DigitalMediaManager.sol

pragma solidity 0.4.25;




/**
 * Manager that interfaces with the underlying digital media store contract.
 */
contract DigitalMediaManager is MediaStoreVersionControl {

    struct DigitalMedia {
        uint256 id;
        uint32 totalSupply;
        uint32 printIndex;
        uint256 collectionId;
        address creator;
        string metadataPath;
    }

    struct DigitalMediaCollection {
        uint256 id;
        address creator;
        string metadataPath;
    }

    ApprovedCreatorRegistryInterface public creatorRegistryStore;

    // Set the creator registry address upon construction. Immutable.
    function setCreatorRegistryStore(address _crsAddress) internal {
        ApprovedCreatorRegistryInterface candidateCreatorRegistryStore = ApprovedCreatorRegistryInterface(_crsAddress);
        require(candidateCreatorRegistryStore.getVersion() == 1);
        // Simple check to make sure we are adding the registry contract indeed
        // https://fravoll.github.io/solidity-patterns/string_equality_comparison.html
        require(keccak256(candidateCreatorRegistryStore.typeOfContract()) == keccak256("approvedCreatorRegistry"));
        creatorRegistryStore = candidateCreatorRegistryStore;
    }

    /**
     * Validates that the Registered store is initialized.
     */
    modifier registryInitialized() {
        require(creatorRegistryStore != address(0));
        _;
    }

    /**
     * Retrieves a collection object by id.
     */
    function _getCollection(uint256 _id) 
            internal 
            view 
            managersInitialized 
            returns(DigitalMediaCollection) {
        uint256 id;
        address creator;
        string memory metadataPath;
        (id, creator, metadataPath) = currentDigitalMediaStore.getCollection(_id);
        DigitalMediaCollection memory collection = DigitalMediaCollection({
            id: id,
            creator: creator,
            metadataPath: metadataPath
        });
        return collection;
    }

    /**
     * Retrieves a digital media object by id.
     */
    function _getDigitalMedia(uint256 _id) 
            internal 
            view 
            managersInitialized 
            returns(DigitalMedia) {
        uint256 id;
        uint32 totalSupply;
        uint32 printIndex;
        uint256 collectionId;
        address creator;
        string memory metadataPath;
        DigitalMediaStoreInterface _digitalMediaStore = _getDigitalMediaStore(_id);
        (id, totalSupply, printIndex, collectionId, creator, metadataPath) = _digitalMediaStore.getDigitalMedia(_id);
        DigitalMedia memory digitalMedia = DigitalMedia({
            id: id,
            creator: creator,
            totalSupply: totalSupply,
            printIndex: printIndex,
            collectionId: collectionId,
            metadataPath: metadataPath
        });
        return digitalMedia;
    }

    /**
     * Increments the print index of a digital media object by some increment.
     */
    function _incrementDigitalMediaPrintIndex(DigitalMedia _dm, uint32 _increment) 
            internal 
            managersInitialized {
        DigitalMediaStoreInterface _digitalMediaStore = _getDigitalMediaStore(_dm.id);
        _digitalMediaStore.incrementDigitalMediaPrintIndex(_dm.id, _increment);
    }

    // Check if the token operator is approved for the owner address
    function isOperatorApprovedForCustodialAccount(
        address _operator, 
        address _owner) internal view registryInitialized returns(bool) {
        return creatorRegistryStore.isOperatorApprovedForCustodialAccount(
            _operator, _owner);
    }
}

// File: REMIX_FILE_SYNC/SingleCreatorControl.sol

pragma solidity 0.4.25;


/**
 * A special control class that's used to help enforce that a DigitalMedia contract
 * will service only a single creator's address.  This is used when deploying a 
 * custom token contract owned and managed by a single creator.
 */
contract SingleCreatorControl {

    // The single allowed creator for this digital media contract.
    address public singleCreatorAddress;

    // The single creator has changed.
    event SingleCreatorChanged(
        address indexed previousCreatorAddress, 
        address indexed newCreatorAddress);

    /**
     * Sets the single creator associated with this contract.  This function
     * can only ever be called once, and should ideally be called at the point
     * of constructing the smart contract.
     */
    function setSingleCreator(address _singleCreatorAddress) internal {
        require(singleCreatorAddress == address(0), "Single creator address already set.");
        singleCreatorAddress = _singleCreatorAddress;
    }

    /**
     * Checks whether a given creator address matches the single creator address.
     * Will always return true if a single creator address was never set.
     */
    function isAllowedSingleCreator(address _creatorAddress) internal view returns (bool) {
        require(_creatorAddress != address(0), "0x0 creator addresses are not allowed.");
        return singleCreatorAddress == address(0) || singleCreatorAddress == _creatorAddress;
    }

    /**
     * A publicly accessible function that allows the current single creator
     * assigned to this contract to change to another address.
     */
    function changeSingleCreator(address _newCreatorAddress) public {
        require(_newCreatorAddress != address(0));
        require(msg.sender == singleCreatorAddress, "Not approved to change single creator.");
        singleCreatorAddress = _newCreatorAddress;
        emit SingleCreatorChanged(singleCreatorAddress, _newCreatorAddress);
    }
}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/token/ERC721/ERC721Basic.sol

pragma solidity ^0.4.21;


/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Basic {
  event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
  event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
  event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

  function balanceOf(address _owner) public view returns (uint256 _balance);
  function ownerOf(uint256 _tokenId) public view returns (address _owner);
  function exists(uint256 _tokenId) public view returns (bool _exists);

  function approve(address _to, uint256 _tokenId) public;
  function getApproved(uint256 _tokenId) public view returns (address _operator);

  function setApprovalForAll(address _operator, bool _approved) public;
  function isApprovedForAll(address _owner, address _operator) public view returns (bool);

  function transferFrom(address _from, address _to, uint256 _tokenId) public;
  function safeTransferFrom(address _from, address _to, uint256 _tokenId) public;
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    public;
}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/token/ERC721/ERC721.sol

pragma solidity ^0.4.21;



/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Enumerable is ERC721Basic {
  function totalSupply() public view returns (uint256);
  function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256 _tokenId);
  function tokenByIndex(uint256 _index) public view returns (uint256);
}


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Metadata is ERC721Basic {
  function name() public view returns (string _name);
  function symbol() public view returns (string _symbol);
  function tokenURI(uint256 _tokenId) public view returns (string);
}


/**
 * @title ERC-721 Non-Fungible Token Standard, full implementation interface
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/token/ERC721/ERC721Receiver.sol

pragma solidity ^0.4.21;


/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 *  from ERC721 asset contracts.
 */
contract ERC721Receiver {
  /**
   * @dev Magic value to be returned upon successful reception of an NFT
   *  Equals to `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`,
   *  which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
   */
  bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba;

  /**
   * @notice Handle the receipt of an NFT
   * @dev The ERC721 smart contract calls this function on the recipient
   *  after a `safetransfer`. This function MAY throw to revert and reject the
   *  transfer. This function MUST use 50,000 gas or less. Return of other
   *  than the magic value MUST result in the transaction being reverted.
   *  Note: the contract address is always the message sender.
   * @param _from The sending address
   * @param _tokenId The NFT identifier which is being transfered
   * @param _data Additional data with no specified format
   * @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
   */
  function onERC721Received(address _from, uint256 _tokenId, bytes _data) public returns(bytes4);
}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/AddressUtils.sol

pragma solidity ^0.4.21;


/**
 * Utility library of inline functions on addresses
 */
library AddressUtils {

  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract,
   *  as the code is not actually created until after the constructor finishes.
   * @param addr address to check
   * @return whether the target address is a contract
   */
  function isContract(address addr) internal view returns (bool) {
    uint256 size;
    // XXX Currently there is no better way to check if there is a contract in an address
    // than to check the size of the code at that address.
    // See https://ethereum.stackexchange.com/a/14016/36603
    // for more details about how this works.
    // TODO Check this again before the Serenity release, because all addresses will be
    // contracts then.
    assembly { size := extcodesize(addr) }  // solium-disable-line security/no-inline-assembly
    return size > 0;
  }

}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/token/ERC721/ERC721BasicToken.sol

pragma solidity ^0.4.21;






/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721BasicToken is ERC721Basic {
  using SafeMath for uint256;
  using AddressUtils for address;

  // Equals to `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
  // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
  bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba;

  // Mapping from token ID to owner
  mapping (uint256 => address) internal tokenOwner;

  // Mapping from token ID to approved address
  mapping (uint256 => address) internal tokenApprovals;

  // Mapping from owner to number of owned token
  mapping (address => uint256) internal ownedTokensCount;

  // Mapping from owner to operator approvals
  mapping (address => mapping (address => bool)) internal operatorApprovals;

  /**
   * @dev Guarantees msg.sender is owner of the given token
   * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender
   */
  modifier onlyOwnerOf(uint256 _tokenId) {
    require(ownerOf(_tokenId) == msg.sender);
    _;
  }

  /**
   * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator
   * @param _tokenId uint256 ID of the token to validate
   */
  modifier canTransfer(uint256 _tokenId) {
    require(isApprovedOrOwner(msg.sender, _tokenId));
    _;
  }

  /**
   * @dev Gets the balance of the specified address
   * @param _owner address to query the balance of
   * @return uint256 representing the amount owned by the passed address
   */
  function balanceOf(address _owner) public view returns (uint256) {
    require(_owner != address(0));
    return ownedTokensCount[_owner];
  }

  /**
   * @dev Gets the owner of the specified token ID
   * @param _tokenId uint256 ID of the token to query the owner of
   * @return owner address currently marked as the owner of the given token ID
   */
  function ownerOf(uint256 _tokenId) public view returns (address) {
    address owner = tokenOwner[_tokenId];
    require(owner != address(0));
    return owner;
  }

  /**
   * @dev Returns whether the specified token exists
   * @param _tokenId uint256 ID of the token to query the existance of
   * @return whether the token exists
   */
  function exists(uint256 _tokenId) public view returns (bool) {
    address owner = tokenOwner[_tokenId];
    return owner != address(0);
  }

  /**
   * @dev Approves another address to transfer the given token ID
   * @dev The zero address indicates there is no approved address.
   * @dev There can only be one approved address per token at a given time.
   * @dev Can only be called by the token owner or an approved operator.
   * @param _to address to be approved for the given token ID
   * @param _tokenId uint256 ID of the token to be approved
   */
  function approve(address _to, uint256 _tokenId) public {
    address owner = ownerOf(_tokenId);
    require(_to != owner);
    require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

    if (getApproved(_tokenId) != address(0) || _to != address(0)) {
      tokenApprovals[_tokenId] = _to;
      emit Approval(owner, _to, _tokenId);
    }
  }

  /**
   * @dev Gets the approved address for a token ID, or zero if no address set
   * @param _tokenId uint256 ID of the token to query the approval of
   * @return address currently approved for a the given token ID
   */
  function getApproved(uint256 _tokenId) public view returns (address) {
    return tokenApprovals[_tokenId];
  }

  /**
   * @dev Sets or unsets the approval of a given operator
   * @dev An operator is allowed to transfer all tokens of the sender on their behalf
   * @param _to operator address to set the approval
   * @param _approved representing the status of the approval to be set
   */
  function setApprovalForAll(address _to, bool _approved) public {
    require(_to != msg.sender);
    operatorApprovals[msg.sender][_to] = _approved;
    emit ApprovalForAll(msg.sender, _to, _approved);
  }

  /**
   * @dev Tells whether an operator is approved by a given owner
   * @param _owner owner address which you want to query the approval of
   * @param _operator operator address which you want to query the approval of
   * @return bool whether the given operator is approved by the given owner
   */
  function isApprovedForAll(address _owner, address _operator) public view returns (bool) {
    return operatorApprovals[_owner][_operator];
  }

  /**
   * @dev Transfers the ownership of a given token ID to another address
   * @dev Usage of this method is discouraged, use `safeTransferFrom` whenever possible
   * @dev Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
  */
  function transferFrom(address _from, address _to, uint256 _tokenId) public canTransfer(_tokenId) {
    require(_from != address(0));
    require(_to != address(0));

    clearApproval(_from, _tokenId);
    removeTokenFrom(_from, _tokenId);
    addTokenTo(_to, _tokenId);

    emit Transfer(_from, _to, _tokenId);
  }

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * @dev If the target address is a contract, it must implement `onERC721Received`,
   *  which is called upon a safe transfer, and return the magic value
   *  `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`; otherwise,
   *  the transfer is reverted.
   * @dev Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
  */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    public
    canTransfer(_tokenId)
  {
    // solium-disable-next-line arg-overflow
    safeTransferFrom(_from, _to, _tokenId, "");
  }

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * @dev If the target address is a contract, it must implement `onERC721Received`,
   *  which is called upon a safe transfer, and return the magic value
   *  `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`; otherwise,
   *  the transfer is reverted.
   * @dev Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
   * @param _data bytes data to send along with a safe transfer check
   */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    public
    canTransfer(_tokenId)
  {
    transferFrom(_from, _to, _tokenId);
    // solium-disable-next-line arg-overflow
    require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
  }

  /**
   * @dev Returns whether the given spender can transfer a given token ID
   * @param _spender address of the spender to query
   * @param _tokenId uint256 ID of the token to be transferred
   * @return bool whether the msg.sender is approved for the given token ID,
   *  is an operator of the owner, or is the owner of the token
   */
  function isApprovedOrOwner(address _spender, uint256 _tokenId) internal view returns (bool) {
    address owner = ownerOf(_tokenId);
    return _spender == owner || getApproved(_tokenId) == _spender || isApprovedForAll(owner, _spender);
  }

  /**
   * @dev Internal function to mint a new token
   * @dev Reverts if the given token ID already exists
   * @param _to The address that will own the minted token
   * @param _tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address _to, uint256 _tokenId) internal {
    require(_to != address(0));
    addTokenTo(_to, _tokenId);
    emit Transfer(address(0), _to, _tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * @dev Reverts if the token does not exist
   * @param _tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address _owner, uint256 _tokenId) internal {
    clearApproval(_owner, _tokenId);
    removeTokenFrom(_owner, _tokenId);
    emit Transfer(_owner, address(0), _tokenId);
  }

  /**
   * @dev Internal function to clear current approval of a given token ID
   * @dev Reverts if the given address is not indeed the owner of the token
   * @param _owner owner of the token
   * @param _tokenId uint256 ID of the token to be transferred
   */
  function clearApproval(address _owner, uint256 _tokenId) internal {
    require(ownerOf(_tokenId) == _owner);
    if (tokenApprovals[_tokenId] != address(0)) {
      tokenApprovals[_tokenId] = address(0);
      emit Approval(_owner, address(0), _tokenId);
    }
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * @param _to address representing the new owner of the given token ID
   * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function addTokenTo(address _to, uint256 _tokenId) internal {
    require(tokenOwner[_tokenId] == address(0));
    tokenOwner[_tokenId] = _to;
    ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * @param _from address representing the previous owner of the given token ID
   * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function removeTokenFrom(address _from, uint256 _tokenId) internal {
    require(ownerOf(_tokenId) == _from);
    ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
    tokenOwner[_tokenId] = address(0);
  }

  /**
   * @dev Internal function to invoke `onERC721Received` on a target address
   * @dev 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 whether the call correctly returned the expected magic value
   */
  function checkAndCallSafeTransfer(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    internal
    returns (bool)
  {
    if (!_to.isContract()) {
      return true;
    }
    bytes4 retval = ERC721Receiver(_to).onERC721Received(_from, _tokenId, _data);
    return (retval == ERC721_RECEIVED);
  }
}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/token/ERC721/ERC721Token.sol

pragma solidity ^0.4.21;




/**
 * @title Full ERC721 Token
 * This implementation includes all the required and some optional functionality of the ERC721 standard
 * Moreover, it includes approve all functionality using operator terminology
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Token is ERC721, ERC721BasicToken {
  // Token name
  string internal name_;

  // Token symbol
  string internal symbol_;

  // Mapping from owner to list of owned token IDs
  mapping (address => uint256[]) internal ownedTokens;

  // Mapping from token ID to index of the owner tokens list
  mapping(uint256 => uint256) internal ownedTokensIndex;

  // Array with all token ids, used for enumeration
  uint256[] internal allTokens;

  // Mapping from token id to position in the allTokens array
  mapping(uint256 => uint256) internal allTokensIndex;

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

  /**
   * @dev Constructor function
   */
  function ERC721Token(string _name, string _symbol) public {
    name_ = _name;
    symbol_ = _symbol;
  }

  /**
   * @dev Gets the token name
   * @return string representing the token name
   */
  function name() public view returns (string) {
    return name_;
  }

  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
  function symbol() public view returns (string) {
    return symbol_;
  }

  /**
   * @dev Returns an URI for a given token ID
   * @dev Throws if the token ID does not exist. May return an empty string.
   * @param _tokenId uint256 ID of the token to query
   */
  function tokenURI(uint256 _tokenId) public view returns (string) {
    require(exists(_tokenId));
    return tokenURIs[_tokenId];
  }

  /**
   * @dev Gets the token ID at a given index of the tokens list of the requested owner
   * @param _owner address owning the tokens list to be accessed
   * @param _index uint256 representing the index to be accessed of the requested tokens list
   * @return uint256 token ID at the given index of the tokens list owned by the requested address
   */
  function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256) {
    require(_index < balanceOf(_owner));
    return ownedTokens[_owner][_index];
  }

  /**
   * @dev Gets the total amount of tokens stored by the contract
   * @return uint256 representing the total amount of tokens
   */
  function totalSupply() public view returns (uint256) {
    return allTokens.length;
  }

  /**
   * @dev Gets the token ID at a given index of all the tokens in this contract
   * @dev Reverts if the index is greater or equal to the total number of tokens
   * @param _index uint256 representing the index to be accessed of the tokens list
   * @return uint256 token ID at the given index of the tokens list
   */
  function tokenByIndex(uint256 _index) public view returns (uint256) {
    require(_index < totalSupply());
    return allTokens[_index];
  }

  /**
   * @dev Internal function to set the token URI for a given token
   * @dev Reverts if the token ID does not exist
   * @param _tokenId uint256 ID of the token to set its URI
   * @param _uri string URI to assign
   */
  function _setTokenURI(uint256 _tokenId, string _uri) internal {
    require(exists(_tokenId));
    tokenURIs[_tokenId] = _uri;
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * @param _to address representing the new owner of the given token ID
   * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function addTokenTo(address _to, uint256 _tokenId) internal {
    super.addTokenTo(_to, _tokenId);
    uint256 length = ownedTokens[_to].length;
    ownedTokens[_to].push(_tokenId);
    ownedTokensIndex[_tokenId] = length;
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * @param _from address representing the previous owner of the given token ID
   * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function removeTokenFrom(address _from, uint256 _tokenId) internal {
    super.removeTokenFrom(_from, _tokenId);

    uint256 tokenIndex = ownedTokensIndex[_tokenId];
    uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
    uint256 lastToken = ownedTokens[_from][lastTokenIndex];

    ownedTokens[_from][tokenIndex] = lastToken;
    ownedTokens[_from][lastTokenIndex] = 0;
    // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
    // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
    // the lastToken to the first position, and then dropping the element placed in the last position of the list

    ownedTokens[_from].length--;
    ownedTokensIndex[_tokenId] = 0;
    ownedTokensIndex[lastToken] = tokenIndex;
  }

  /**
   * @dev Internal function to mint a new token
   * @dev Reverts if the given token ID already exists
   * @param _to address the beneficiary that will own the minted token
   * @param _tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address _to, uint256 _tokenId) internal {
    super._mint(_to, _tokenId);

    allTokensIndex[_tokenId] = allTokens.length;
    allTokens.push(_tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * @dev Reverts if the token does not exist
   * @param _owner owner of the token to burn
   * @param _tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address _owner, uint256 _tokenId) internal {
    super._burn(_owner, _tokenId);

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

    // Reorg all tokens array
    uint256 tokenIndex = allTokensIndex[_tokenId];
    uint256 lastTokenIndex = allTokens.length.sub(1);
    uint256 lastToken = allTokens[lastTokenIndex];

    allTokens[tokenIndex] = lastToken;
    allTokens[lastTokenIndex] = 0;

    allTokens.length--;
    allTokensIndex[_tokenId] = 0;
    allTokensIndex[lastToken] = tokenIndex;
  }

}

// File: REMIX_FILE_SYNC/ERC721Safe.sol

pragma solidity 0.4.25;

// We have to specify what version of compiler this code will compile with



contract ERC721Safe is ERC721Token {
    bytes4 constant internal InterfaceSignature_ERC165 =
        bytes4(keccak256('supportsInterface(bytes4)'));

    bytes4 constant internal InterfaceSignature_ERC721 =
        bytes4(keccak256('name()')) ^
        bytes4(keccak256('symbol()')) ^
        bytes4(keccak256('totalSupply()')) ^
        bytes4(keccak256('balanceOf(address)')) ^
        bytes4(keccak256('ownerOf(uint256)')) ^
        bytes4(keccak256('approve(address,uint256)')) ^
        bytes4(keccak256('safeTransferFrom(address,address,uint256)'));
	
   function supportsInterface(bytes4 _interfaceID) external view returns (bool);
}

// File: REMIX_FILE_SYNC/Memory.sol

pragma solidity 0.4.25;


library Memory {

    // Size of a word, in bytes.
    uint internal constant WORD_SIZE = 32;
    // Size of the header of a 'bytes' array.
    uint internal constant BYTES_HEADER_SIZE = 32;
    // Address of the free memory pointer.
    uint internal constant FREE_MEM_PTR = 0x40;

    // Compares the 'len' bytes starting at address 'addr' in memory with the 'len'
    // bytes starting at 'addr2'.
    // Returns 'true' if the bytes are the same, otherwise 'false'.
    function equals(uint addr, uint addr2, uint len) internal pure returns (bool equal) {
        assembly {
            equal := eq(keccak256(addr, len), keccak256(addr2, len))
        }
    }

    // Compares the 'len' bytes starting at address 'addr' in memory with the bytes stored in
    // 'bts'. It is allowed to set 'len' to a lower value then 'bts.length', in which case only
    // the first 'len' bytes will be compared.
    // Requires that 'bts.length >= len'
    function equals(uint addr, uint len, bytes memory bts) internal pure returns (bool equal) {
        require(bts.length >= len);
        uint addr2;
        assembly {
            addr2 := add(bts, /*BYTES_HEADER_SIZE*/32)
        }
        return equals(addr, addr2, len);
    }

    // Allocates 'numBytes' bytes in memory. This will prevent the Solidity compiler
    // from using this area of memory. It will also initialize the area by setting
    // each byte to '0'.
    function allocate(uint numBytes) internal pure returns (uint addr) {
        // Take the current value of the free memory pointer, and update.
        assembly {
            addr := mload(/*FREE_MEM_PTR*/0x40)
            mstore(/*FREE_MEM_PTR*/0x40, add(addr, numBytes))
        }
        uint words = (numBytes + WORD_SIZE - 1) / WORD_SIZE;
        for (uint i = 0; i < words; i++) {
            assembly {
                mstore(add(addr, mul(i, /*WORD_SIZE*/32)), 0)
            }
        }
    }

    // Copy 'len' bytes from memory address 'src', to address 'dest'.
    // This function does not check the or destination, it only copies
    // the bytes.
    function copy(uint src, uint dest, uint len) internal pure {
        // Copy word-length chunks while possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += WORD_SIZE;
            src += WORD_SIZE;
        }

        // Copy remaining bytes
        uint mask = 256 ** (WORD_SIZE - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }
    }

    // Returns a memory pointer to the provided bytes array.
    function ptr(bytes memory bts) internal pure returns (uint addr) {
        assembly {
            addr := bts
        }
    }

    // Returns a memory pointer to the data portion of the provided bytes array.
    function dataPtr(bytes memory bts) internal pure returns (uint addr) {
        assembly {
            addr := add(bts, /*BYTES_HEADER_SIZE*/32)
        }
    }

    // This function does the same as 'dataPtr(bytes memory)', but will also return the
    // length of the provided bytes array.
    function fromBytes(bytes memory bts) internal pure returns (uint addr, uint len) {
        len = bts.length;
        assembly {
            addr := add(bts, /*BYTES_HEADER_SIZE*/32)
        }
    }

    // Creates a 'bytes memory' variable from the memory address 'addr', with the
    // length 'len'. The function will allocate new memory for the bytes array, and
    // the 'len bytes starting at 'addr' will be copied into that new memory.
    function toBytes(uint addr, uint len) internal pure returns (bytes memory bts) {
        bts = new bytes(len);
        uint btsptr;
        assembly {
            btsptr := add(bts, /*BYTES_HEADER_SIZE*/32)
        }
        copy(addr, btsptr, len);
    }

    // Get the word stored at memory address 'addr' as a 'uint'.
    function toUint(uint addr) internal pure returns (uint n) {
        assembly {
            n := mload(addr)
        }
    }

    // Get the word stored at memory address 'addr' as a 'bytes32'.
    function toBytes32(uint addr) internal pure returns (bytes32 bts) {
        assembly {
            bts := mload(addr)
        }
    }

    /*
    // Get the byte stored at memory address 'addr' as a 'byte'.
    function toByte(uint addr, uint8 index) internal pure returns (byte b) {
        require(index < WORD_SIZE);
        uint8 n;
        assembly {
            n := byte(index, mload(addr))
        }
        b = byte(n);
    }
    */
}

// File: REMIX_FILE_SYNC/HelperUtils.sol

pragma solidity 0.4.25;


/**
 * Internal helper functions
 */
contract HelperUtils {

    // converts bytes32 to a string
    // enable this when you use it. Saving gas for now
    // function bytes32ToString(bytes32 x) private pure returns (string) {
    //     bytes memory bytesString = new bytes(32);
    //     uint charCount = 0;
    //     for (uint j = 0; j < 32; j++) {
    //         byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
    //         if (char != 0) {
    //             bytesString[charCount] = char;
    //             charCount++;
    //         }
    //     }
    //     bytes memory bytesStringTrimmed = new bytes(charCount);
    //     for (j = 0; j < charCount; j++) {
    //         bytesStringTrimmed[j] = bytesString[j];
    //     }
    //     return string(bytesStringTrimmed);
    // } 

    /**
     * Concatenates two strings
     * @param  _a string
     * @param  _b string
     * @return string concatenation of two string
     */
    function strConcat(string _a, string _b) internal pure returns (string) {
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
        string memory ab = new string(_ba.length + _bb.length);
        bytes memory bab = bytes(ab);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++) bab[k++] = _ba[i];
        for (i = 0; i < _bb.length; i++) bab[k++] = _bb[i];
        return string(bab);
    }
}

// File: REMIX_FILE_SYNC/DigitalMediaToken.sol

pragma solidity 0.4.25;





/**
 * The DigitalMediaToken contract.  Fully implements the ERC721 contract
 * from OpenZeppelin without any modifications to it.
 * 
 * This contract allows for the creation of:
 *  1. New Collections
 *  2. New DigitalMedia objects
 *  3. New DigitalMediaRelease objects
 * 
 * The primary piece of logic is to ensure that an ERC721 token can 
 * have a supply and print edition that is enforced by this contract.
 */
contract DigitalMediaToken is DigitalMediaManager, ERC721Safe, HelperUtils, SingleCreatorControl {

    event DigitalMediaReleaseCreateEvent(
        uint256 id, 
        address owner,
        uint32 printEdition,
        string tokenURI, 
        uint256 digitalMediaId);

    // Event fired when a new digital media is created
    event DigitalMediaCreateEvent(
        uint256 id, 
        address storeContractAddress,
        address creator, 
        uint32 totalSupply, 
        uint32 printIndex, 
        uint256 collectionId, 
        string metadataPath);

    // Event fired when a digital media's collection is 
    event DigitalMediaCollectionCreateEvent(
        uint256 id, 
        address storeContractAddress,
        address creator, 
        string metadataPath);

    // Event fired when a digital media is burned
    event DigitalMediaBurnEvent(
        uint256 id,
        address caller,
        address storeContractAddress);

    // Event fired when burning a token
    event DigitalMediaReleaseBurnEvent(
        uint256 tokenId, 
        address owner);

    event UpdateDigitalMediaPrintIndexEvent(
        uint256 digitalMediaId,
        uint32 printEdition);

    // Event fired when a creator assigns a new creator address.
    event ChangedCreator(
        address creator,
        address newCreator);

    struct DigitalMediaRelease {
        // The unique edition number of this digital media release
        uint32 printEdition;

        // Reference ID to the digital media metadata
        uint256 digitalMediaId;
    }

    // Maps internal ERC721 token ID to digital media release object.
    mapping (uint256 => DigitalMediaRelease) public tokenIdToDigitalMediaRelease;

    // Maps a creator address to a new creator address.  Useful if a creator
    // changes their address or the previous address gets compromised.
    mapping (address => address) public approvedCreators;

    // Token ID counter
    uint256 internal tokenIdCounter = 0;

    constructor (string _tokenName, string _tokenSymbol, uint256 _tokenIdStartingCounter) 
            public ERC721Token(_tokenName, _tokenSymbol) {
        tokenIdCounter = _tokenIdStartingCounter;
    }

    /**
     * Creates a new digital media object.
     * @param  _creator address  the creator of this digital media
     * @param  _totalSupply uint32 the total supply a creation could have
     * @param  _collectionId uint256 the collectionId that it belongs to
     * @param  _metadataPath string the path to the ipfs metadata
     * @return uint the new digital media id
     */
    function _createDigitalMedia(
          address _creator, uint32 _totalSupply, uint256 _collectionId, string _metadataPath) 
          internal 
          returns (uint) {

        require(_validateCollection(_collectionId, _creator), "Creator for collection not approved.");

        uint256 newDigitalMediaId = currentDigitalMediaStore.createDigitalMedia(
            _creator,
            0, 
            _totalSupply,
            _collectionId,
            _metadataPath);

        emit DigitalMediaCreateEvent(
            newDigitalMediaId,
            address(currentDigitalMediaStore),
            _creator,
            _totalSupply,
            0,
            _collectionId,
            _metadataPath);

        return newDigitalMediaId;
    }

    /**
     * Burns a token for a given tokenId and caller.
     * @param  _tokenId the id of the token to burn.
     * @param  _caller the address of the caller.
     */
    function _burnToken(uint256 _tokenId, address _caller) internal {
        address owner = ownerOf(_tokenId);
        require(_caller == owner || 
                getApproved(_tokenId) == _caller || 
                isApprovedForAll(owner, _caller),
                "Failed token burn.  Caller is not approved.");
        _burn(owner, _tokenId);
        delete tokenIdToDigitalMediaRelease[_tokenId];
        emit DigitalMediaReleaseBurnEvent(_tokenId, owner);
    }

    /**
     * Burns a digital media.  Once this function succeeds, this digital media
     * will no longer be able to mint any more tokens.  Existing tokens need to be 
     * burned individually though.
     * @param  _digitalMediaId the id of the digital media to burn
     * @param  _caller the address of the caller.
     */
    function _burnDigitalMedia(uint256 _digitalMediaId, address _caller) internal {
        DigitalMedia memory _digitalMedia = _getDigitalMedia(_digitalMediaId);
        require(_checkApprovedCreator(_digitalMedia.creator, _caller) || 
                isApprovedForAll(_digitalMedia.creator, _caller), 
                "Failed digital media burn.  Caller not approved.");

        uint32 increment = _digitalMedia.totalSupply - _digitalMedia.printIndex;
        _incrementDigitalMediaPrintIndex(_digitalMedia, increment);
        address _burnDigitalMediaStoreAddress = address(_getDigitalMediaStore(_digitalMedia.id));
        emit DigitalMediaBurnEvent(
          _digitalMediaId, _caller, _burnDigitalMediaStoreAddress);
    }

    /**
     * Creates a new collection
     * @param  _creator address the creator of this collection
     * @param  _metadataPath string the path to the collection ipfs metadata
     * @return uint the new collection id
     */
    function _createCollection(
          address _creator, string _metadataPath) 
          internal 
          returns (uint) {
        uint256 newCollectionId = currentDigitalMediaStore.createCollection(
            _creator,
            _metadataPath);

        emit DigitalMediaCollectionCreateEvent(
            newCollectionId,
            address(currentDigitalMediaStore),
            _creator,
            _metadataPath);

        return newCollectionId;
    }

    /**
     * Creates _count number of new digital media releases (i.e a token).  
     * Bumps up the print index by _count.
     * @param  _owner address the owner of the digital media object
     * @param  _digitalMediaId uint256 the digital media id
     */
    function _createDigitalMediaReleases(
        address _owner, uint256 _digitalMediaId, uint32 _count)
        internal {

        require(_count > 0, "Failed print edition.  Creation count must be > 0.");
        require(_count < 10000, "Cannot print more than 10K tokens at once");
        DigitalMedia memory _digitalMedia = _getDigitalMedia(_digitalMediaId);
        uint32 currentPrintIndex = _digitalMedia.printIndex;
        require(_checkApprovedCreator(_digitalMedia.creator, _owner), "Creator not approved.");
        require(isAllowedSingleCreator(_owner), "Creator must match single creator address.");
        require(_count + currentPrintIndex <= _digitalMedia.totalSupply, "Total supply exceeded.");
        
        string memory tokenURI = HelperUtils.strConcat("ipfs://ipfs/", _digitalMedia.metadataPath);

        for (uint32 i=0; i < _count; i++) {
            uint32 newPrintEdition = currentPrintIndex + 1 + i;
            DigitalMediaRelease memory _digitalMediaRelease = DigitalMediaRelease({
                printEdition: newPrintEdition,
                digitalMediaId: _digitalMediaId
            });

            uint256 newDigitalMediaReleaseId = _getNextTokenId();
            tokenIdToDigitalMediaRelease[newDigitalMediaReleaseId] = _digitalMediaRelease;
        
            emit DigitalMediaReleaseCreateEvent(
                newDigitalMediaReleaseId,
                _owner,
                newPrintEdition,
                tokenURI,
                _digitalMediaId
            );

            // This will assign ownership and also emit the Transfer event as per ERC721
            _mint(_owner, newDigitalMediaReleaseId);
            _setTokenURI(newDigitalMediaReleaseId, tokenURI);
            tokenIdCounter = tokenIdCounter.add(1);

        }
        _incrementDigitalMediaPrintIndex(_digitalMedia, _count);
        emit UpdateDigitalMediaPrintIndexEvent(_digitalMediaId, currentPrintIndex + _count);
    }

    /**
     * Checks that a given caller is an approved creator and is allowed to mint or burn
     * tokens.  If the creator was changed it will check against the updated creator.
     * @param  _caller the calling address
     * @return bool allowed or not
     */
    function _checkApprovedCreator(address _creator, address _caller) 
            internal 
            view 
            returns (bool) {
        address approvedCreator = approvedCreators[_creator];
        if (approvedCreator != address(0)) {
            return approvedCreator == _caller;
        } else {
            return _creator == _caller;
        }
    }

    /**
     * Validates the an address is allowed to create a digital media on a
     * given collection.  Collections are tied to addresses.
     */
    function _validateCollection(uint256 _collectionId, address _address) 
            private 
            view 
            returns (bool) {
        if (_collectionId == 0 ) {
            return true;
        }

        DigitalMediaCollection memory collection = _getCollection(_collectionId);
        return _checkApprovedCreator(collection.creator, _address);
    }

    /**
    * Generates a new token id.
    */
    function _getNextTokenId() private view returns (uint256) {
        return tokenIdCounter.add(1); 
    }

    /**
     * Changes the creator that is approved to printing new tokens and creations.
     * Either the _caller must be the _creator or the _caller must be the existing
     * approvedCreator.
     * @param _caller the address of the caller
     * @param  _creator the address of the current creator
     * @param  _newCreator the address of the new approved creator
     */
    function _changeCreator(address _caller, address _creator, address _newCreator) internal {
        address approvedCreator = approvedCreators[_creator];
        require(_caller != address(0) && _creator != address(0), "Creator must be valid non 0x0 address.");
        require(_caller == _creator || _caller == approvedCreator, "Unauthorized caller.");
        if (approvedCreator == address(0)) {
            approvedCreators[_caller] = _newCreator;
        } else {
            require(_caller == approvedCreator, "Unauthorized caller.");
            approvedCreators[_creator] = _newCreator;
        }
        emit ChangedCreator(_creator, _newCreator);
    }

    /**
     * Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165).
     */
    function supportsInterface(bytes4 _interfaceID) external view returns (bool) {
        return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721));
    }

}

// File: REMIX_FILE_SYNC/OBOControl.sol

pragma solidity 0.4.25;



contract OBOControl is Pausable {
	// List of approved on behalf of users.
    mapping (address => bool) public approvedOBOs;

	/**
     * Add a new approved on behalf of user address.
     */
    function addApprovedOBO(address _oboAddress) external onlyOwner {
        approvedOBOs[_oboAddress] = true;
    }

    /**
     * Removes an approved on bhealf of user address.
     */
    function removeApprovedOBO(address _oboAddress) external onlyOwner {
        delete approvedOBOs[_oboAddress];
    }

    /**
    * @dev Modifier to make the obo calls only callable by approved addressess
    */
    modifier isApprovedOBO() {
        require(approvedOBOs[msg.sender] == true);
        _;
    }
}

// File: REMIX_FILE_SYNC/WithdrawFundsControl.sol

pragma solidity 0.4.25;



contract WithdrawFundsControl is Pausable {

	// List of approved on withdraw addresses
    mapping (address => uint256) public approvedWithdrawAddresses;

    // Full day wait period before an approved withdraw address becomes active
    uint256 constant internal withdrawApprovalWaitPeriod = 60 * 60 * 24;

    event WithdrawAddressAdded(address withdrawAddress);
    event WithdrawAddressRemoved(address widthdrawAddress);

	/**
     * Add a new approved on behalf of user address.
     */
    function addApprovedWithdrawAddress(address _withdrawAddress) external onlyOwner {
        approvedWithdrawAddresses[_withdrawAddress] = now;
        emit WithdrawAddressAdded(_withdrawAddress);
    }

    /**
     * Removes an approved on bhealf of user address.
     */
    function removeApprovedWithdrawAddress(address _withdrawAddress) external onlyOwner {
        delete approvedWithdrawAddresses[_withdrawAddress];
        emit WithdrawAddressRemoved(_withdrawAddress);
    }

    /**
     * Checks that a given withdraw address ia approved and is past it's required
     * wait time.
     */
    function isApprovedWithdrawAddress(address _withdrawAddress) internal view returns (bool)  {
        uint256 approvalTime = approvedWithdrawAddresses[_withdrawAddress];
        require (approvalTime > 0);
        return now - approvalTime > withdrawApprovalWaitPeriod;
    }
}

// File: REMIX_FILE_SYNC/openzeppelin-solidity/contracts/token/ERC721/ERC721Holder.sol

pragma solidity ^0.4.21;



contract ERC721Holder is ERC721Receiver {
  function onERC721Received(address, uint256, bytes) public returns(bytes4) {
    return ERC721_RECEIVED;
  }
}

// File: REMIX_FILE_SYNC/DigitalMediaSaleBase.sol

pragma solidity 0.4.25;







/**
 * Base class that manages the underlying functions of a Digital Media Sale,
 * most importantly the escrow of digital tokens.
 *
 * Manages ensuring that only approved addresses interact with this contract.
 *
 */
contract DigitalMediaSaleBase is ERC721Holder, Pausable, OBOControl, WithdrawFundsControl {
    using SafeMath for uint256;

     // Mapping of token contract address to bool indicated approval.
    mapping (address => bool) public approvedTokenContracts;

    /**
     * Adds a new token contract address to be approved to be called.
     */
    function addApprovedTokenContract(address _tokenContractAddress) 
            public onlyOwner {
        approvedTokenContracts[_tokenContractAddress] = true;
    }

    /**
     * Remove an approved token contract address from the list of approved addresses.
     */
    function removeApprovedTokenContract(address _tokenContractAddress) 
            public onlyOwner {            
        delete approvedTokenContracts[_tokenContractAddress];
    }

    /**
     * Checks that a particular token contract address is a valid address.
     */
    function _isValidTokenContract(address _tokenContractAddress) 
            internal view returns (bool) {
        return approvedTokenContracts[_tokenContractAddress];
    }

    /**
     * Returns an ERC721 instance of a token contract address.  Throws otherwise.
     * Only valid and approved token contracts are allowed to be interacted with.
     */
    function _getTokenContract(address _tokenContractAddress) internal view returns (ERC721Safe) {
        require(_isValidTokenContract(_tokenContractAddress));
        return ERC721Safe(_tokenContractAddress);
    }

    /**
     * Checks with the ERC-721 token contract that the _claimant actually owns the token.
     */
    function _owns(address _claimant, uint256 _tokenId, address _tokenContractAddress) internal view returns (bool) {
        ERC721Safe tokenContract = _getTokenContract(_tokenContractAddress);
        return (tokenContract.ownerOf(_tokenId) == _claimant);
    }

    /**
     * Checks with the ERC-721 token contract the owner of the a token
     */
    function _ownerOf(uint256 _tokenId, address _tokenContractAddress) internal view returns (address) {
        ERC721Safe tokenContract = _getTokenContract(_tokenContractAddress);
        return tokenContract.ownerOf(_tokenId);
    }

    /**
     * Checks to ensure that the token owner has approved the escrow contract 
     */
    function _approvedForEscrow(address _seller, uint256 _tokenId, address _tokenContractAddress) internal view returns (bool) {
        ERC721Safe tokenContract = _getTokenContract(_tokenContractAddress);
        return (tokenContract.isApprovedForAll(_seller, this) || 
                tokenContract.getApproved(_tokenId) == address(this));
    }

    /**
     * Escrows an ERC-721 token from the seller to this contract.  Assumes that the escrow contract
     * is already approved to make the transfer, otherwise it will fail.
     */
    function _escrow(address _seller, uint256 _tokenId, address _tokenContractAddress) internal {
        // it will throw if transfer fails
        ERC721Safe tokenContract = _getTokenContract(_tokenContractAddress);
        tokenContract.safeTransferFrom(_seller, this, _tokenId);
    }

    /**
     * Transfer an ERC-721 token from escrow to the buyer.  This is to be called after a purchase is
     * completed.
     */
    function _transfer(address _receiver, uint256 _tokenId, address _tokenContractAddress) internal {
        // it will throw if transfer fails
        ERC721Safe tokenContract = _getTokenContract(_tokenContractAddress);
        tokenContract.safeTransferFrom(this, _receiver, _tokenId);
    }

    /**
     * Method to check whether this is an escrow contract
     */
    function isEscrowContract() public pure returns(bool) {
        return true;
    }

    /**
     * Withdraws all the funds to a specified non-zero address
     */
    function withdrawFunds(address _withdrawAddress) public onlyOwner {
        require(isApprovedWithdrawAddress(_withdrawAddress));
        _withdrawAddress.transfer(address(this).balance);
    }
}

// File: REMIX_FILE_SYNC/DigitalMediaCore.sol

pragma solidity 0.4.25;





/**
 * This is the main driver contract that is used to control and run the service. Funds 
 * are managed through this function, underlying contracts are also updated through 
 * this contract.
 *
 * This class also exposes a set of creation methods that are allowed to be created
 * by an approved token creator, on behalf of a particular address.  This is meant
 * to simply the creation flow for MakersToken users that aren't familiar with 
 * the blockchain.  The ERC721 tokens that are created are still fully compliant, 
 * although it is possible for a malicious token creator to mint unwanted tokens 
 * on behalf of a creator.  Worst case, the creator can burn those tokens.
 */
contract DigitalMediaCore is DigitalMediaToken {
    using SafeMath for uint32;

    // List of approved token creators (on behalf of the owner)
    mapping (address => bool) public approvedTokenCreators;

    // Mapping from owner to operator accounts.
    mapping (address => mapping (address => bool)) internal oboOperatorApprovals;

    // Mapping of all disabled OBO operators.
    mapping (address => bool) public disabledOboOperators;

    // OboApproveAll Event
    event OboApprovalForAll(
        address _owner, 
        address _operator, 
        bool _approved);

    // Fired when disbaling obo capability.
    event OboDisabledForAll(address _operator);

    constructor (
        string _tokenName, 
        string _tokenSymbol, 
        uint256 _tokenIdStartingCounter, 
        address _dmsAddress,
        address _crsAddress)
            public DigitalMediaToken(
                _tokenName, 
                _tokenSymbol,
                _tokenIdStartingCounter) {
        paused = true;
        setDigitalMediaStoreAddress(_dmsAddress);
        setCreatorRegistryStore(_crsAddress);
    }

    /**
     * Retrieves a Digital Media object.
     */
    function getDigitalMedia(uint256 _id) 
            external 
            view 
            returns (
            uint256 id,
            uint32 totalSupply,
            uint32 printIndex,
            uint256 collectionId,
            address creator,
            string metadataPath) {

        DigitalMedia memory digitalMedia = _getDigitalMedia(_id);
        require(digitalMedia.creator != address(0), "DigitalMedia not found.");
        id = _id;
        totalSupply = digitalMedia.totalSupply;
        printIndex = digitalMedia.printIndex;
        collectionId = digitalMedia.collectionId;
        creator = digitalMedia.creator;
        metadataPath = digitalMedia.metadataPath;
    }

    /**
     * Retrieves a collection.
     */
    function getCollection(uint256 _id) 
            external 
            view 
            returns (
            uint256 id,
            address creator,
            string metadataPath) {
        DigitalMediaCollection memory digitalMediaCollection = _getCollection(_id);
        require(digitalMediaCollection.creator != address(0), "Collection not found.");
        id = _id;
        creator = digitalMediaCollection.creator;
        metadataPath = digitalMediaCollection.metadataPath;
    }

    /**
     * Retrieves a Digital Media Release (i.e a token)
     */
    function getDigitalMediaRelease(uint256 _id) 
            external 
            view 
            returns (
            uint256 id,
            uint32 printEdition,
            uint256 digitalMediaId) {
        require(exists(_id));
        DigitalMediaRelease storage digitalMediaRelease = tokenIdToDigitalMediaRelease[_id];
        id = _id;
        printEdition = digitalMediaRelease.printEdition;
        digitalMediaId = digitalMediaRelease.digitalMediaId;
    }

    /**
     * Creates a new collection.
     *
     * No creations of any kind are allowed when the contract is paused.
     */
    function createCollection(string _metadataPath) 
            external 
            whenNotPaused {
        _createCollection(msg.sender, _metadataPath);
    }

    /**
     * Creates a new digital media object.
     */
    function createDigitalMedia(uint32 _totalSupply, uint256 _collectionId, string _metadataPath) 
            external 
            whenNotPaused {
        _createDigitalMedia(msg.sender, _totalSupply, _collectionId, _metadataPath);
    }

    /**
     * Creates a new digital media object and mints it's first digital media release token.
     *
     * No creations of any kind are allowed when the contract is paused.
     */
    function createDigitalMediaAndReleases(
                uint32 _totalSupply,
                uint256 _collectionId,
                string _metadataPath,
                uint32 _numReleases)
            external 
            whenNotPaused {
        uint256 digitalMediaId = _createDigitalMedia(msg.sender, _totalSupply, _collectionId, _metadataPath);
        _createDigitalMediaReleases(msg.sender, digitalMediaId, _numReleases);
    }

    /**
     * Creates a new collection, a new digital media object within it and mints a new
     * digital media release token.
     *
     * No creations of any kind are allowed when the contract is paused.
     */
    function createDigitalMediaAndReleasesInNewCollection(
                uint32 _totalSupply, 
                string _digitalMediaMetadataPath,
                string _collectionMetadataPath,
                uint32 _numReleases)
            external 
            whenNotPaused {
        uint256 collectionId = _createCollection(msg.sender, _collectionMetadataPath);
        uint256 digitalMediaId = _createDigitalMedia(msg.sender, _totalSupply, collectionId, _digitalMediaMetadataPath);
        _createDigitalMediaReleases(msg.sender, digitalMediaId, _numReleases);
    }

    /**
     * Creates a new digital media release (token) for a given digital media id.
     *
     * No creations of any kind are allowed when the contract is paused.
     */
    function createDigitalMediaReleases(uint256 _digitalMediaId, uint32 _numReleases) 
            external 
            whenNotPaused {
        _createDigitalMediaReleases(msg.sender, _digitalMediaId, _numReleases);
    }

    /**
     * Deletes a token / digital media release. Doesn't modify the current print index
     * and total to be printed. Although dangerous, the owner of a token should always 
     * be able to burn a token they own.
     *
     * Only the owner of the token or accounts approved by the owner can burn this token.
     */
    function burnToken(uint256 _tokenId) external {
        _burnToken(_tokenId, msg.sender);
    }

    /* Support ERC721 burn method */
    function burn(uint256 tokenId) public {
        _burnToken(tokenId, msg.sender);
    }

    /**
     * Ends the production run of a digital media.  Afterwards no more tokens
     * will be allowed to be printed for this digital media.  Used when a creator
     * makes a mistake and wishes to burn and recreate their digital media.
     * 
     * When a contract is paused we do not allow new tokens to be created, 
     * so stopping the production of a token doesn't have much purpose.
     */
    function burnDigitalMedia(uint256 _digitalMediaId) external whenNotPaused {
        _burnDigitalMedia(_digitalMediaId, msg.sender);
    }

    /**
     * Resets the approval rights for a given tokenId.
     */
    function resetApproval(uint256 _tokenId) external {
        clearApproval(msg.sender, _tokenId);
    }

    /**
     * Changes the creator for the current sender, in the event we 
     * need to be able to mint new tokens from an existing digital media 
     * print production. When changing creator, the old creator will
     * no longer be able to mint tokens.
     *
     * A creator may need to be changed:
     * 1. If we want to allow a creator to take control over their token minting (i.e go decentralized)
     * 2. If we want to re-issue private keys due to a compromise.  For this reason, we can call this function
     * when the contract is paused.
     * @param _creator the creator address
     * @param _newCreator the new creator address
     */
    function changeCreator(address _creator, address _newCreator) external {
        _changeCreator(msg.sender, _creator, _newCreator);
    }

    /**********************************************************************/
    /**Calls that are allowed to be called by approved creator addresses **/ 
    /**********************************************************************/
    
    /**
     * Add a new approved token creator.
     *
     * Only the owner of this contract can update approved Obo accounts.
     */
    function addApprovedTokenCreator(address _creatorAddress) external onlyOwner {
        require(disabledOboOperators[_creatorAddress] != true, "Address disabled.");
        approvedTokenCreators[_creatorAddress] = true;
    }

    /**
     * Removes an approved token creator.
     *
     * Only the owner of this contract can update approved Obo accounts.
     */
    function removeApprovedTokenCreator(address _creatorAddress) external onlyOwner {
        delete approvedTokenCreators[_creatorAddress];
    }

    /**
    * @dev Modifier to make the approved creation calls only callable by approved token creators
    */
    modifier isApprovedCreator() {
        require(
            (approvedTokenCreators[msg.sender] == true && 
             disabledOboOperators[msg.sender] != true), 
            "Unapproved OBO address.");
        _;
    }

    /**
     * Only the owner address can set a special obo approval list.
     * When issuing OBO management accounts, we should give approvals through
     * this method only so that we can very easily reset it's approval in
     * the event of a disaster scenario.
     *
     * Only the owner themselves is allowed to give OboApproveAll access.
     */
    function setOboApprovalForAll(address _to, bool _approved) public {
        require(_to != msg.sender, "Approval address is same as approver.");
        require(approvedTokenCreators[_to], "Unrecognized OBO address.");
        require(disabledOboOperators[_to] != true, "Approval address is disabled.");
        oboOperatorApprovals[msg.sender][_to] = _approved;
        emit OboApprovalForAll(msg.sender, _to, _approved);
    }

    /**
     * Only called in a disaster scenario if the account has been compromised.  
     * There's no turning back from this and the oboAddress will no longer be 
     * able to be given approval rights or perform obo functions.  
     * 
     * Only the owner of this contract is allowed to disable an Obo address.
     *
     */
    function disableOboAddress(address _oboAddress) public onlyOwner {
        require(approvedTokenCreators[_oboAddress], "Unrecognized OBO address.");
        disabledOboOperators[_oboAddress] = true;
        delete approvedTokenCreators[_oboAddress];
        emit OboDisabledForAll(_oboAddress);
    }

    /**
     * Override the isApprovalForAll to check for a special oboApproval list.  Reason for this
     * is that we can can easily remove obo operators if they every become compromised.
     */
    function isApprovedForAll(address _owner, address _operator) public view returns (bool) {
        if (disabledOboOperators[_operator] == true) {
            return false;
        } else if (isOperatorApprovedForCustodialAccount(_operator, _owner) == true) {
            return true;
        } else if (oboOperatorApprovals[_owner][_operator]) {
            return true;
        } else {
            return super.isApprovedForAll(_owner, _operator);
        }
    }

    /**
     * Creates a new digital media object and mints it's digital media release tokens.
     * Called on behalf of the _owner. Pass count to mint `n` number of tokens.
     *
     * Only approved creators are allowed to create Obo.
     *
     * No creations of any kind are allowed when the contract is paused.
     */
    function oboCreateDigitalMediaAndReleases(
                address _owner,
                uint32 _totalSupply, 
                uint256 _collectionId, 
                string _metadataPath,
                uint32 _numReleases)
            external 
            whenNotPaused
            isApprovedCreator {
        uint256 digitalMediaId = _createDigitalMedia(_owner, _totalSupply, _collectionId, _metadataPath);
        _createDigitalMediaReleases(_owner, digitalMediaId, _numReleases);
    }

    /**
     * Creates a new collection, a new digital media object within it and mints a new
     * digital media release token.
     * Called on behalf of the _owner.
     *
     * Only approved creators are allowed to create Obo.
     *
     * No creations of any kind are allowed when the contract is paused.
     */
    function oboCreateDigitalMediaAndReleasesInNewCollection(
                address _owner,
                uint32 _totalSupply, 
                string _digitalMediaMetadataPath,
                string _collectionMetadataPath,
                uint32 _numReleases)
            external 
            whenNotPaused
            isApprovedCreator {
        uint256 collectionId = _createCollection(_owner, _collectionMetadataPath);
        uint256 digitalMediaId = _createDigitalMedia(_owner, _totalSupply, collectionId, _digitalMediaMetadataPath);
        _createDigitalMediaReleases(_owner, digitalMediaId, _numReleases);
    }

    /**
     * Creates multiple digital media releases (tokens) for a given digital media id.
     * Called on behalf of the _owner.
     *
     * Only approved creators are allowed to create Obo.
     *
     * No creations of any kind are allowed when the contract is paused.
     */
    function oboCreateDigitalMediaReleases(
                address _owner,
                uint256 _digitalMediaId,
                uint32 _numReleases) 
            external 
            whenNotPaused
            isApprovedCreator {
        _createDigitalMediaReleases(_owner, _digitalMediaId, _numReleases);
    }

}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"currentStartingDigitalMediaId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_metadataPath","type":"string"}],"name":"createCollection","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_totalSupply","type":"uint32"},{"name":"_digitalMediaMetadataPath","type":"string"},{"name":"_collectionMetadataPath","type":"string"},{"name":"_numReleases","type":"uint32"}],"name":"oboCreateDigitalMediaAndReleasesInNewCollection","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"singleCreatorAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentDigitalMediaStore","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_digitalMediaId","type":"uint256"}],"name":"burnDigitalMedia","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenIdToDigitalMediaRelease","outputs":[{"name":"printEdition","type":"uint32"},{"name":"digitalMediaId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_creatorAddress","type":"address"}],"name":"removeApprovedTokenCreator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"approvedCreators","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getDigitalMedia","outputs":[{"name":"id","type":"uint256"},{"name":"totalSupply","type":"uint32"},{"name":"printIndex","type":"uint32"},{"name":"collectionId","type":"uint256"},{"name":"creator","type":"address"},{"name":"metadataPath","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getCollection","outputs":[{"name":"id","type":"uint256"},{"name":"creator","type":"address"},{"name":"metadataPath","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_creator","type":"address"},{"name":"_newCreator","type":"address"}],"name":"changeCreator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_totalSupply","type":"uint32"},{"name":"_collectionId","type":"uint256"},{"name":"_metadataPath","type":"string"}],"name":"createDigitalMedia","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_totalSupply","type":"uint32"},{"name":"_collectionId","type":"uint256"},{"name":"_metadataPath","type":"string"},{"name":"_numReleases","type":"uint32"}],"name":"oboCreateDigitalMediaAndReleases","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_approved","type":"bool"}],"name":"setOboApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"burnToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_digitalMediaId","type":"uint256"},{"name":"_numReleases","type":"uint32"}],"name":"createDigitalMediaReleases","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getDigitalMediaRelease","outputs":[{"name":"id","type":"uint256"},{"name":"printEdition","type":"uint32"},{"name":"digitalMediaId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_totalSupply","type":"uint32"},{"name":"_digitalMediaMetadataPath","type":"string"},{"name":"_collectionMetadataPath","type":"string"},{"name":"_numReleases","type":"uint32"}],"name":"createDigitalMediaAndReleasesInNewCollection","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_dmsAddress","type":"address"}],"name":"setV1DigitalMediaStoreAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_oboAddress","type":"address"}],"name":"disableOboAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"v1DigitalMediaStore","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCreatorAddress","type":"address"}],"name":"changeSingleCreator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_digitalMediaId","type":"uint256"},{"name":"_numReleases","type":"uint32"}],"name":"oboCreateDigitalMediaReleases","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"creatorRegistryStore","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"resetApproval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"approvedTokenCreators","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"disabledOboOperators","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_totalSupply","type":"uint32"},{"name":"_collectionId","type":"uint256"},{"name":"_metadataPath","type":"string"},{"name":"_numReleases","type":"uint32"}],"name":"createDigitalMediaAndReleases","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_creatorAddress","type":"address"}],"name":"addApprovedTokenCreator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_tokenName","type":"string"},{"name":"_tokenSymbol","type":"string"},{"name":"_tokenIdStartingCounter","type":"uint256"},{"name":"_dmsAddress","type":"address"},{"name":"_crsAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_owner","type":"address"},{"indexed":false,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"OboApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_operator","type":"address"}],"name":"OboDisabledForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"printEdition","type":"uint32"},{"indexed":false,"name":"tokenURI","type":"string"},{"indexed":false,"name":"digitalMediaId","type":"uint256"}],"name":"DigitalMediaReleaseCreateEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"storeContractAddress","type":"address"},{"indexed":false,"name":"creator","type":"address"},{"indexed":false,"name":"totalSupply","type":"uint32"},{"indexed":false,"name":"printIndex","type":"uint32"},{"indexed":false,"name":"collectionId","type":"uint256"},{"indexed":false,"name":"metadataPath","type":"string"}],"name":"DigitalMediaCreateEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"storeContractAddress","type":"address"},{"indexed":false,"name":"creator","type":"address"},{"indexed":false,"name":"metadataPath","type":"string"}],"name":"DigitalMediaCollectionCreateEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"caller","type":"address"},{"indexed":false,"name":"storeContractAddress","type":"address"}],"name":"DigitalMediaBurnEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"owner","type":"address"}],"name":"DigitalMediaReleaseBurnEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"digitalMediaId","type":"uint256"},{"indexed":false,"name":"printEdition","type":"uint32"}],"name":"UpdateDigitalMediaPrintIndexEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"creator","type":"address"},{"indexed":false,"name":"newCreator","type":"address"}],"name":"ChangedCreator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousCreatorAddress","type":"address"},{"indexed":true,"name":"newCreatorAddress","type":"address"}],"name":"SingleCreatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

60806040526000805460a060020a60ff02191681556013553480156200002457600080fd5b5060405162004769380380620047698339810160409081528151602080840151928401516060850151608086015160008054600160a060020a0319163317905593860180519096959095019491939092909186918691869184918491620000919160099185019062000577565b508051620000a790600a90602084019062000577565b50505060135550506000805460a060020a60ff02191674010000000000000000000000000000000000000000179055620000ea8264010000000062000109810204565b620000fe8164010000000062000335810204565b50505050506200061c565b600081905080600160a060020a0316636c669f256040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156200016657600080fd5b505af11580156200017b573d6000803e3d6000fd5b505050506040513d60208110156200019257600080fd5b50516002146200020357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e636f72726563742076657273696f6e2e0000000000000000000000000000604482015290519081900360640190fd5b60028054600160a060020a031916600160a060020a038381169190911791829055604080517fa60800b80000000000000000000000000000000000000000000000000000000081529051929091169163a60800b89160048082019260009290919082900301818387803b1580156200027a57600080fd5b505af11580156200028f573d6000803e3d6000fd5b50505050600260009054906101000a9004600160a060020a0316600160a060020a031663b9905d116040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156200030057600080fd5b505af115801562000315573d6000803e3d6000fd5b505050506040513d60208110156200032c57600080fd5b50516003555050565b600081905080600160a060020a0316630d8e6e2c6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156200039257600080fd5b505af1158015620003a7573d6000803e3d6000fd5b505050506040513d6020811015620003be57600080fd5b5051600114620003cd57600080fd5b604080517f617070726f76656443726561746f725265676973747279000000000000000000815281519081900360170181207fc20a03820000000000000000000000000000000000000000000000000000000082529151600160a060020a0384169163c20a038291600480830192600092919082900301818387803b1580156200045657600080fd5b505af11580156200046b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156200049557600080fd5b810190808051640100000000811115620004ae57600080fd5b82016020810184811115620004c257600080fd5b8151640100000000811182820187101715620004dd57600080fd5b50509291905050506040518082805190602001908083835b60208310620005165780518252601f199092019160209182019101620004f5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019161415156200055457600080fd5b60048054600160a060020a031916600160a060020a039290921691909117905550565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620005ba57805160ff1916838001178555620005ea565b82800160010185558215620005ea579182015b82811115620005ea578251825591602001919060010190620005cd565b50620005f8929150620005fc565b5090565b6200061991905b80821115620005f8576000815560010162000603565b90565b61413d806200062c6000396000f3006080604052600436106102635763ffffffff60e060020a6000350416630154788d811461026857806301ffc9a71461028f578063059dfe13146102c557806306a186d1146102e757806306fdde0314610333578063081812fc146103bd578063095ea7b3146103f1578063147ca2af1461041557806318160ddd1461042a5780631b284e751461043f57806323077f581461045457806323b872dd1461046c5780632f745c59146104965780633db57cbe146104ba5780633f4ba83a146104f257806342842e0e1461050757806342966c68146105315780634751ae99146105495780634f558e791461056a5780634f6ccce714610582578063552324671461059a57806355df4275146105bb5780635a1f3c28146106985780635c975abb146107485780635cf09fee1461075d578063603417fb146107845780636352211e146107b25780636ee17a78146107ca57806370a082311461080d578063774f99d01461082e5780637b47ec1a146105315780637fb08c9b146108545780638456cb59146108755780638a603bdf1461088a5780638b40e8aa146108c55780638da5cb5b1461090257806391c607881461091757806392b8bde11461093857806395d89b4114610959578063a0f01e081461096e578063a22cb46514610983578063a7df572c146109a9578063b36f0faa146109ca578063b39ba60a146109f7578063b88d4fde14610a0c578063c87b56dd14610a7b578063cf8dae0514610a93578063d70f575f14610aab578063e158386d14610acc578063e985e9c514610aed578063eca211e314610b14578063f2fde38b14610b49578063fafa8a4b14610b6a575b600080fd5b34801561027457600080fd5b5061027d610b8b565b60408051918252519081900360200190f35b34801561029b57600080fd5b506102b1600160e060020a031960043516610b91565b604080519115158252519081900360200190f35b3480156102d157600080fd5b506102e56004803560248101910135610d6d565b005b3480156102f357600080fd5b506102e5600160a060020a0360048035919091169063ffffffff602480358216926044358083019390820135926064359081019201359060843516610dc3565b34801561033f57600080fd5b50610348610efc565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561038257818101518382015260200161036a565b50505050905090810190601f1680156103af5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103c957600080fd5b506103d5600435610f93565b60408051600160a060020a039092168252519081900360200190f35b3480156103fd57600080fd5b506102e5600160a060020a0360043516602435610fae565b34801561042157600080fd5b506103d5611092565b34801561043657600080fd5b5061027d6110a1565b34801561044b57600080fd5b506103d56110a7565b34801561046057600080fd5b506102e56004356110b6565b34801561047857600080fd5b506102e5600160a060020a03600435811690602435166044356110da565b3480156104a257600080fd5b5061027d600160a060020a0360043516602435611189565b3480156104c657600080fd5b506104d26004356111d7565b6040805163ffffffff909316835260208301919091528051918290030190f35b3480156104fe57600080fd5b506102e56111f9565b34801561051357600080fd5b506102e5600160a060020a036004358116906024351660443561126f565b34801561053d57600080fd5b506102e56004356112a7565b34801561055557600080fd5b506102e5600160a060020a03600435166112b1565b34801561057657600080fd5b506102b16004356112e9565b34801561058e57600080fd5b5061027d600435611306565b3480156105a657600080fd5b506103d5600160a060020a036004351661133b565b3480156105c757600080fd5b506105d3600435611356565b604051808781526020018663ffffffff1663ffffffff1681526020018563ffffffff1663ffffffff16815260200184815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610658578181015183820152602001610640565b50505050905090810190601f1680156106855780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b3480156106a457600080fd5b506106b0600435611406565b6040518084815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561070b5781810151838201526020016106f3565b50505050905090810190601f1680156107385780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b34801561075457600080fd5b506102b1611499565b34801561076957600080fd5b506102e5600160a060020a03600435811690602435166114a9565b34801561079057600080fd5b506102e56004803563ffffffff169060248035916044359182019101356114b8565b3480156107be57600080fd5b506103d5600435611512565b3480156107d657600080fd5b506102e560048035600160a060020a0316906024803563ffffffff9081169260443592606435908101929101359060843516611536565b34801561081957600080fd5b5061027d600160a060020a036004351661162f565b34801561083a57600080fd5b506102e5600160a060020a03600435166024351515611662565b34801561086057600080fd5b506102e560043563ffffffff60243516611846565b34801561088157600080fd5b506102e5611868565b34801561089657600080fd5b506108a26004356118e3565b6040805193845263ffffffff909216602084015282820152519081900360600190f35b3480156108d157600080fd5b506102e56004803563ffffffff90811691602480358082019390830135926044359283019201359060643516611925565b34801561090e57600080fd5b506103d56119ce565b34801561092357600080fd5b506102e5600160a060020a03600435166119dd565b34801561094457600080fd5b506102e5600160a060020a0360043516611bac565b34801561096557600080fd5b50610348611ca2565b34801561097a57600080fd5b506103d5611d03565b34801561098f57600080fd5b506102e5600160a060020a03600435166024351515611d12565b3480156109b557600080fd5b506102e5600160a060020a0360043516611d96565b3480156109d657600080fd5b506102e5600160a060020a036004351660243563ffffffff60443516611e83565b348015610a0357600080fd5b506103d5611f34565b348015610a1857600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526102e594600160a060020a038135811695602480359092169560443595369560849401918190840183828082843750949750611f439650505050505050565b348015610a8757600080fd5b50610348600435611f7b565b348015610a9f57600080fd5b506102e5600435612030565b348015610ab757600080fd5b506102b1600160a060020a036004351661203a565b348015610ad857600080fd5b506102b1600160a060020a036004351661204f565b348015610af957600080fd5b506102b1600160a060020a0360043581169060243516612064565b348015610b2057600080fd5b506102e563ffffffff6004803582169160248035926044359182019291013590606435166120f5565b348015610b5557600080fd5b506102e5600160a060020a0360043516612156565b348015610b7657600080fd5b506102e5600160a060020a03600435166121dd565b60035481565b604080517f737570706f727473496e7465726661636528627974657334290000000000000081529051908190036019019020600090600160e060020a031983811691161480610d655750604080517f736166655472616e7366657246726f6d28616464726573732c6164647265737381527f2c75696e74323536290000000000000000000000000000000000000000000000602082015281519081900360290181207f617070726f766528616464726573732c75696e74323536290000000000000000825282519182900360180182207f6f776e65724f662875696e743235362900000000000000000000000000000000835283519283900360100183207f62616c616e63654f662861646472657373290000000000000000000000000000845284519384900360120184207f746f74616c537570706c792829000000000000000000000000000000000000008552855194859003600d0185207f73796d626f6c2829000000000000000000000000000000000000000000000000865286519586900360080186207f6e616d65282900000000000000000000000000000000000000000000000000008752965195869003600601909520600160e060020a0319898116919097189095181818181891909116145b90505b919050565b60005460a060020a900460ff1615610d8457600080fd5b610dbe3383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375061228e945050505050565b505050565b60008054819060a060020a900460ff1615610ddd57600080fd5b3360009081526014602052604090205460ff1615156001148015610e1657503360009081526016602052604090205460ff161515600114155b1515610e6c576040805160e560020a62461bcd02815260206004820152601760248201527f556e617070726f766564204f424f20616464726573732e000000000000000000604482015290519081900360640190fd5b610ea68986868080601f0160208091040260200160405190810160405280939291908181526020018383808284375061228e945050505050565b9150610ee48989848a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843750612466945050505050565b9050610ef189828561270d565b505050505050505050565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f885780601f10610f5d57610100808354040283529160200191610f88565b820191906000526020600020905b815481529060010190602001808311610f6b57829003601f168201915b505050505090505b90565b600090815260066020526040902054600160a060020a031690565b6000610fb982611512565b9050600160a060020a038381169082161415610fd457600080fd5b33600160a060020a0382161480610ff05750610ff08133612064565b1515610ffb57600080fd5b600061100683610f93565b600160a060020a03161415806110245750600160a060020a03831615155b15610dbe576000828152600660209081526040918290208054600160a060020a031916600160a060020a03878116918217909255835186815293519093918516927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a3505050565b601054600160a060020a031681565b600d5490565b600254600160a060020a031681565b60005460a060020a900460ff16156110cd57600080fd5b6110d78133612bcf565b50565b806110e53382612cf9565b15156110f057600080fd5b600160a060020a038416151561110557600080fd5b600160a060020a038316151561111a57600080fd5b6111248483612d58565b61112e8483612df8565b6111388383612f31565b82600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b60006111948361162f565b821061119f57600080fd5b600160a060020a0383166000908152600b602052604090208054839081106111c357fe5b906000526020600020015490505b92915050565b6011602052600090815260409020805460019091015463ffffffff9091169082565b600054600160a060020a0316331461121057600080fd5b60005460a060020a900460ff16151561122857600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a1565b8061127a3382612cf9565b151561128557600080fd5b6112a18484846020604051908101604052806000815250611f43565b50505050565b6110d78133612f7a565b600054600160a060020a031633146112c857600080fd5b600160a060020a03166000908152601460205260409020805460ff19169055565b600090815260056020526040902054600160a060020a0316151590565b60006113106110a1565b821061131b57600080fd5b600d80548390811061132957fe5b90600052602060002001549050919050565b601260205260009081526040902054600160a060020a031681565b60008060008060006060611368613f93565b611371886130c1565b6080810151909150600160a060020a031615156113d8576040805160e560020a62461bcd02815260206004820152601760248201527f4469676974616c4d65646961206e6f7420666f756e642e000000000000000000604482015290519081900360640190fd5b602081015160408201516060830151608084015160a0909401519a9b929a9199509750919550909350915050565b6000806060611413613fdf565b61141c85613257565b6020810151909150600160a060020a03161515611483576040805160e560020a62461bcd02815260206004820152601560248201527f436f6c6c656374696f6e206e6f7420666f756e642e0000000000000000000000604482015290519081900360640190fd5b6020810151604090910151949590949350915050565b60005460a060020a900460ff1681565b6114b43383836133c5565b5050565b60005460a060020a900460ff16156114cf57600080fd5b61150b33858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843750612466945050505050565b5050505050565b600081815260056020526040812054600160a060020a03168015156111d157600080fd5b6000805460a060020a900460ff161561154e57600080fd5b3360009081526014602052604090205460ff161515600114801561158757503360009081526016602052604090205460ff161515600114155b15156115dd576040805160e560020a62461bcd02815260206004820152601760248201527f556e617070726f766564204f424f20616464726573732e000000000000000000604482015290519081900360640190fd5b61161987878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750612466945050505050565b905061162687828461270d565b50505050505050565b6000600160a060020a038216151561164657600080fd5b50600160a060020a031660009081526007602052604090205490565b600160a060020a0382163314156116e9576040805160e560020a62461bcd02815260206004820152602560248201527f417070726f76616c20616464726573732069732073616d65206173206170707260448201527f6f7665722e000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03821660009081526014602052604090205460ff16151561175b576040805160e560020a62461bcd02815260206004820152601960248201527f556e7265636f676e697a6564204f424f20616464726573732e00000000000000604482015290519081900360640190fd5b600160a060020a03821660009081526016602052604090205460ff161515600114156117d1576040805160e560020a62461bcd02815260206004820152601d60248201527f417070726f76616c20616464726573732069732064697361626c65642e000000604482015290519081900360640190fd5b336000818152601560209081526040808320600160a060020a03871680855290835292819020805486151560ff19909116811790915581519485529184019290925282820152517f017e8a478826a4348bfb695968246edfab885f8a76b03279cf4630ac073945c99181900360600190a15050565b60005460a060020a900460ff161561185d57600080fd5b6114b433838361270d565b600054600160a060020a0316331461187f57600080fd5b60005460a060020a900460ff161561189657600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a1565b6000806000806118f2856112e9565b15156118fd57600080fd5b50505060008281526011602052604090208054600190910154929363ffffffff909116929150565b60008054819060a060020a900460ff161561193f57600080fd5b6119793386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375061228e945050505050565b91506119b73389848a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843750612466945050505050565b90506119c433828561270d565b5050505050505050565b600054600160a060020a031681565b60008054600160a060020a031633146119f557600080fd5b600154600160a060020a031615611a56576040805160e560020a62461bcd02815260206004820152601b60248201527f5631206d656469612073746f726520616c7265616479207365742e0000000000604482015290519081900360640190fd5b81905080600160a060020a0316636c669f256040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611a9757600080fd5b505af1158015611aab573d6000803e3d6000fd5b505050506040513d6020811015611ac157600080fd5b5051600114611b1a576040805160e560020a62461bcd02815260206004820152601260248201527f496e636f72726563742076657273696f6e2e0000000000000000000000000000604482015290519081900360640190fd5b60018054600160a060020a031916600160a060020a038381169190911791829055604080517fa60800b80000000000000000000000000000000000000000000000000000000081529051929091169163a60800b89160048082019260009290919082900301818387803b158015611b9057600080fd5b505af1158015611ba4573d6000803e3d6000fd5b505050505050565b600054600160a060020a03163314611bc357600080fd5b600160a060020a03811660009081526014602052604090205460ff161515611c35576040805160e560020a62461bcd02815260206004820152601960248201527f556e7265636f676e697a6564204f424f20616464726573732e00000000000000604482015290519081900360640190fd5b600160a060020a0381166000818152601660209081526040808320805460ff1990811660011790915560148352928190208054909316909255815192835290517ffd0e0c743dbdd84ef4e7c513db9b7e085970164787288791343fda28575652dd9281900390910190a150565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f885780601f10610f5d57610100808354040283529160200191610f88565b600154600160a060020a031681565b600160a060020a038216331415611d2857600080fd5b336000818152600860209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b600160a060020a0381161515611dab57600080fd5b601054600160a060020a03163314611e33576040805160e560020a62461bcd02815260206004820152602660248201527f4e6f7420617070726f76656420746f206368616e67652073696e676c6520637260448201527f6561746f722e0000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60108054600160a060020a031916600160a060020a0383811691821792839055604051919216907f384c948063df3740539b4b000658c1a22348e7f18c87f808085662e461e48e7190600090a350565b60005460a060020a900460ff1615611e9a57600080fd5b3360009081526014602052604090205460ff1615156001148015611ed357503360009081526016602052604090205460ff161515600114155b1515611f29576040805160e560020a62461bcd02815260206004820152601760248201527f556e617070726f766564204f424f20616464726573732e000000000000000000604482015290519081900360640190fd5b610dbe83838361270d565b600454600160a060020a031681565b81611f4e3382612cf9565b1515611f5957600080fd5b611f648585856110da565b611f708585858561361d565b151561150b57600080fd5b6060611f86826112e9565b1515611f9157600080fd5b6000828152600f602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156120245780601f10611ff957610100808354040283529160200191612024565b820191906000526020600020905b81548152906001019060200180831161200757829003601f168201915b50505050509050919050565b6110d73382612d58565b60146020526000908152604090205460ff1681565b60166020526000908152604090205460ff1681565b600160a060020a03811660009081526016602052604081205460ff16151560011415612092575060006111d1565b61209c8284613770565b1515600114156120ae575060016111d1565b600160a060020a0380841660009081526015602090815260408083209386168352929052205460ff16156120e4575060016111d1565b6120ee8383613831565b90506111d1565b6000805460a060020a900460ff161561210d57600080fd5b61214933878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750612466945050505050565b9050611ba433828461270d565b600054600160a060020a0316331461216d57600080fd5b600160a060020a038116151561218257600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360008054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a031633146121f457600080fd5b600160a060020a03811660009081526016602052604090205460ff1615156001141561226a576040805160e560020a62461bcd02815260206004820152601160248201527f416464726573732064697361626c65642e000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03166000908152601460205260409020805460ff19166001179055565b600254604080517fb577fd73000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830190815260248301938452855160448401528551600095869593169363b577fd73938993899390926064019060208501908083838c5b838110156123145781810151838201526020016122fc565b50505050905090810190601f1680156123415780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b15801561236157600080fd5b505af1158015612375573d6000803e3d6000fd5b505050506040513d602081101561238b57600080fd5b505160025460408051838152600160a060020a0392831660208281018290529389169282019290925260806060820181815288519183019190915287519495507f01e2312dcdafe7cd3f82579d8c121fdb930d46ef2eb231953a521ac62093e2779486948a938a939092909160a08401919085019080838360005b8381101561241e578181015183820152602001612406565b50505050905090810190601f16801561244b5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a18091505b5092915050565b600080612473848761385f565b15156124ee576040805160e560020a62461bcd028152602060048201526024808201527f43726561746f7220666f7220636f6c6c656374696f6e206e6f7420617070726f60448201527f7665642e00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6002546040517f09242ba2000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830190815260006024840181905263ffffffff8a1660448501526064840189905260a060848501908152885160a4860152885193909516946309242ba2948c9492938c938c938c93909160c49091019060208501908083838b5b8381101561259657818101518382015260200161257e565b50505050905090810190601f1680156125c35780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b1580156125e657600080fd5b505af11580156125fa573d6000803e3d6000fd5b505050506040513d602081101561261057600080fd5b505160025460408051838152600160a060020a039283166020828101829052938b169282019290925263ffffffff8916606082015260006080820181905260a0820189905260e060c0830181815289519184019190915288519596507f794c5cd70604d9d8dc2cbca1f8be65f167e4147b6512541d41e8e410594098a09587958d948d94938d938d93610100840191908501908083838a5b838110156126c05781810151838201526020016126a8565b50505050905090810190601f1680156126ed5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a18091505b50949350505050565b612715613f93565b60006060600080612724613ffe565b600063ffffffff881681106127a9576040805160e560020a62461bcd02815260206004820152603260248201527f4661696c6564207072696e742065646974696f6e2e20204372656174696f6e2060448201527f636f756e74206d757374206265203e20302e0000000000000000000000000000606482015290519081900360840190fd5b61271063ffffffff89161061282e576040805160e560020a62461bcd02815260206004820152602960248201527f43616e6e6f74207072696e74206d6f7265207468616e2031304b20746f6b656e60448201527f73206174206f6e63650000000000000000000000000000000000000000000000606482015290519081900360840190fd5b612837896130c1565b96508660400151955061284e87608001518b61388e565b15156128a4576040805160e560020a62461bcd02815260206004820152601560248201527f43726561746f72206e6f7420617070726f7665642e0000000000000000000000604482015290519081900360640190fd5b6128ad8a6138e9565b1515612929576040805160e560020a62461bcd02815260206004820152602a60248201527f43726561746f72206d757374206d617463682073696e676c652063726561746f60448201527f7220616464726573732e00000000000000000000000000000000000000000000606482015290519081900360840190fd5b866020015163ffffffff1686890163ffffffff1611151515612995576040805160e560020a62461bcd02815260206004820152601660248201527f546f74616c20737570706c792065786365656465642e00000000000000000000604482015290519081900360640190fd5b6129d86040805190810160405280600c81526020017f697066733a2f2f697066732f00000000000000000000000000000000000000008152508860a00151613999565b9450600093505b8763ffffffff168463ffffffff161015612b7757838660010101925060408051908101604052808463ffffffff1681526020018a8152509150612a20613ae8565b9050816011600083815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff160217905550602082015181600101559050507f775f53e4c75ce0c74e611f7f0bb660e4cd647e0522ef0f8aefd4ecef373c5df9818b85888d6040518086815260200185600160a060020a0316600160a060020a031681526020018463ffffffff1663ffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015612b03578181015183820152602001612aeb565b50505050905090810190601f168015612b305780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a1612b4b8a82613b04565b612b558186613b53565b601354612b6990600163ffffffff613b8616565b6013556001909301926129df565b612b818789613b93565b604080518a815263ffffffff888b0116602082015281517f12d99f5e49ef761c52953e4f9a109827fc3540292ba88c10d309fef470685259929181900390910190a150505050505050505050565b612bd7613f93565b600080612be3856130c1565b9250612bf383608001518561388e565b80612c075750612c07836080015185612064565b1515612c83576040805160e560020a62461bcd02815260206004820152603060248201527f4661696c6564206469676974616c206d65646961206275726e2e202043616c6c60448201527f6572206e6f7420617070726f7665642e00000000000000000000000000000000606482015290519081900360840190fd5b82604001518360200151039150612c9a8383613b93565b8251612ca590613c56565b60408051878152600160a060020a03808816602083015283168183015290519192507f327ecc068f1b41267f69376098f6a50da487e4a4d762d53c01197d6a2f294b3e919081900360600190a15050505050565b600080612d0583611512565b905080600160a060020a031684600160a060020a03161480612d40575083600160a060020a0316612d3584610f93565b600160a060020a0316145b80612d505750612d508185612064565b949350505050565b81600160a060020a0316612d6b82611512565b600160a060020a031614612d7e57600080fd5b600081815260066020526040902054600160a060020a0316156114b45760008181526006602090815260408083208054600160a060020a031916905580518481529051600160a060020a038616927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35050565b6000806000612e078585613cb5565b6000848152600c6020908152604080832054600160a060020a0389168452600b90925290912054909350612e4290600163ffffffff613d3e16565b600160a060020a0386166000908152600b6020526040902080549193509083908110612e6a57fe5b9060005260206000200154905080600b600087600160a060020a0316600160a060020a0316815260200190815260200160002084815481101515612eaa57fe5b6000918252602080832090910192909255600160a060020a0387168152600b90915260408120805484908110612edc57fe5b6000918252602080832090910192909255600160a060020a0387168152600b90915260409020805490612f13906000198301614015565b506000938452600c6020526040808520859055908452909220555050565b6000612f3d8383613d50565b50600160a060020a039091166000908152600b6020908152604080832080546001810182559084528284208101859055938352600c909152902055565b6000612f8583611512565b905080600160a060020a031682600160a060020a03161480612fc0575081600160a060020a0316612fb584610f93565b600160a060020a0316145b80612fd05750612fd08183612064565b151561304c576040805160e560020a62461bcd02815260206004820152602b60248201527f4661696c656420746f6b656e206275726e2e202043616c6c6572206973206e6f60448201527f7420617070726f7665642e000000000000000000000000000000000000000000606482015290519081900360840190fd5b6130568184613dd4565b6000838152601160209081526040808320805463ffffffff19168155600101929092558151858152600160a060020a0384169181019190915281517f1e8df141f42ed659a8fe7e7c5966cbdf2d240d0c45f4c30cbe02526c618075ef929181900390910190a1505050565b6130c9613f93565b6000806000806000606060006130dd613f93565b600154600160a060020a031615156130f457600080fd5b600254600160a060020a0316151561310b57600080fd5b6131148a613c56565b915081600160a060020a03166355df42758b6040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b15801561315f57600080fd5b505af1158015613173573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260c081101561319c57600080fd5b8151602083015160408401516060850151608086015160a087018051959794969395929491938201926401000000008111156131d757600080fd5b820160208101848111156131ea57600080fd5b815164010000000081118282018710171561320457600080fd5b50506040805160c081018252998a5263ffffffff98891660208b0152979096169688019690965250506060850191909152600160a060020a0316608084015260a0830152509a9950505050505050505050565b61325f613fdf565b600080606061326c613fdf565b600154600160a060020a0316151561328357600080fd5b600254600160a060020a0316151561329a57600080fd5b600254604080517f5a1f3c28000000000000000000000000000000000000000000000000000000008152600481018990529051600160a060020a0390921691635a1f3c289160248082019260009290919082900301818387803b15801561330057600080fd5b505af1158015613314573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052606081101561333d57600080fd5b815160208301516040840180519294919382019264010000000081111561336357600080fd5b8201602081018481111561337657600080fd5b815164010000000081118282018710171561339057600080fd5b505060408051606081018252968752600160a060020a0395909516602087015293850193909352509198975050505050505050565b600160a060020a038083166000908152601260205260409020548116908416158015906133fa5750600160a060020a03831615155b1515613476576040805160e560020a62461bcd02815260206004820152602660248201527f43726561746f72206d7573742062652076616c6964206e6f6e2030783020616460448201527f64726573732e0000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b82600160a060020a031684600160a060020a031614806134a7575080600160a060020a031684600160a060020a0316145b15156134fd576040805160e560020a62461bcd02815260206004820152601460248201527f556e617574686f72697a65642063616c6c65722e000000000000000000000000604482015290519081900360640190fd5b600160a060020a038116151561354057600160a060020a0384811660009081526012602052604090208054600160a060020a0319169184169190911790556135d2565b600160a060020a03848116908216146135a3576040805160e560020a62461bcd02815260206004820152601460248201527f556e617574686f72697a65642063616c6c65722e000000000000000000000000604482015290519081900360640190fd5b600160a060020a0383811660009081526012602052604090208054600160a060020a0319169184169190911790555b60408051600160a060020a0380861682528416602082015281517fde6cfdf21fe76bcb45258138e27bcd332b76941b24d226b5da8dc5f9cd531c3e929181900390910190a150505050565b60008061363285600160a060020a0316613ece565b15156136415760019150612704565b84600160a060020a031663f0b9e5ba8786866040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156136c05781810151838201526020016136a8565b50505050905090810190601f1680156136ed5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561370e57600080fd5b505af1158015613722573d6000803e3d6000fd5b505050506040513d602081101561373857600080fd5b5051600160e060020a0319167ff0b9e5ba00000000000000000000000000000000000000000000000000000000149695505050505050565b600454600090600160a060020a0316151561378a57600080fd5b60048054604080517f67d6a7dc000000000000000000000000000000000000000000000000000000008152600160a060020a03878116948201949094528584166024820152905192909116916367d6a7dc916044808201926020929091908290030181600087803b1580156137fe57600080fd5b505af1158015613812573d6000803e3d6000fd5b505050506040513d602081101561382857600080fd5b50519392505050565b600160a060020a03918216600090815260086020908152604080832093909416825291909152205460ff1690565b6000613869613fdf565b831515613879576001915061245f565b61388284613257565b9050612d508160200151845b600160a060020a0380831660009081526012602052604081205490911680156138cd5782600160a060020a031681600160a060020a031614915061245f565b82600160a060020a031684600160a060020a031614915061245f565b6000600160a060020a0382161515613971576040805160e560020a62461bcd02815260206004820152602660248201527f3078302063726561746f722061646472657373657320617265206e6f7420616c60448201527f6c6f7765642e0000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b601054600160a060020a03161580610d65575050601054600160a060020a0391821691161490565b606080606080606060008088955087945084518651016040519080825280601f01601f1916602001820160405280156139dc578160200160208202803883390190505b50935083925060009150600090505b8551811015613a61578581815181101515613a0257fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613a2957fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001016139eb565b5060005b8451811015613adb578481815181101515613a7c57fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613aa357fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101613a65565b5090979650505050505050565b601354600090613aff90600163ffffffff613b8616565b905090565b613b0e8282613ed6565b600d80546000838152600e60205260408120829055600182018355919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5015550565b613b5c826112e9565b1515613b6757600080fd5b6000828152600f602090815260409091208251610dbe92840190614039565b818101828110156111d157fe5b600154600090600160a060020a03161515613bad57600080fd5b600254600160a060020a03161515613bc457600080fd5b8251613bcf90613c56565b8351604080517f5160a124000000000000000000000000000000000000000000000000000000008152600481019290925263ffffffff8516602483015251919250600160a060020a03831691635160a1249160448082019260009290919082900301818387803b158015613c4257600080fd5b505af1158015611626573d6000803e3d6000fd5b600154600090600160a060020a03161515613c7057600080fd5b600254600160a060020a03161515613c8757600080fd5b600354821015613ca35750600154600160a060020a0316610d68565b50600254600160a060020a0316610d68565b81600160a060020a0316613cc882611512565b600160a060020a031614613cdb57600080fd5b600160a060020a038216600090815260076020526040902054613d0590600163ffffffff613d3e16565b600160a060020a039092166000908152600760209081526040808320949094559181526005909152208054600160a060020a0319169055565b600082821115613d4a57fe5b50900390565b600081815260056020526040902054600160a060020a031615613d7257600080fd5b60008181526005602090815260408083208054600160a060020a031916600160a060020a03871690811790915583526007909152902054613db4906001613b86565b600160a060020a0390921660009081526007602052604090209190915550565b6000806000613de38585613f3a565b6000848152600f60205260409020546002600019610100600184161502019091160415613e21576000848152600f60205260408120613e21916140b7565b6000848152600e6020526040902054600d54909350613e4790600163ffffffff613d3e16565b9150600d82815481101515613e5857fe5b9060005260206000200154905080600d84815481101515613e7557fe5b6000918252602082200191909155600d805484908110613e9157fe5b600091825260209091200155600d805490613eb0906000198301614015565b506000938452600e6020526040808520859055908452909220555050565b6000903b1190565b600160a060020a0382161515613eeb57600080fd5b613ef58282612f31565b604080518281529051600160a060020a038416916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b613f448282612d58565b613f4e8282612df8565b604080518281529051600091600160a060020a038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60c06040519081016040528060008152602001600063ffffffff168152602001600063ffffffff168152602001600081526020016000600160a060020a03168152602001606081525090565b6040805160608181018352600080835260208301529181019190915290565b604080518082019091526000808252602082015290565b815481835581811115610dbe57600083815260209020610dbe9181019083016140f7565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061407a57805160ff19168380011785556140a7565b828001600101855582156140a7579182015b828111156140a757825182559160200191906001019061408c565b506140b39291506140f7565b5090565b50805460018160011615610100020316600290046000825580601f106140dd57506110d7565b601f0160209004906000526020600020908101906110d791905b610f9091905b808211156140b357600081556001016140fd5600a165627a7a7230582005b6a9bc6212f43a161375a16f4ef7010dc257764383f56d321350b5e4e03b4f002900000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e75479ba035175a251179919080bc7bd4e700f6e000000000000000000000000a6ec692942dc8c590693dc2a1cba5a7413de851f000000000000000000000000000000000000000000000000000000000000000d4d616b657273546f6b656e56320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d4b543200000000000000000000000000000000000000000000000000000000

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

00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e75479ba035175a251179919080bc7bd4e700f6e000000000000000000000000a6ec692942dc8c590693dc2a1cba5a7413de851f000000000000000000000000000000000000000000000000000000000000000d4d616b657273546f6b656e56320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d4b543200000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _tokenName (string): MakersTokenV2
Arg [1] : _tokenSymbol (string): MKT2
Arg [2] : _tokenIdStartingCounter (uint256): 0
Arg [3] : _dmsAddress (address): 0xE75479Ba035175A251179919080Bc7BD4E700f6e
Arg [4] : _crsAddress (address): 0xA6ec692942dc8C590693dC2A1cBa5a7413De851f

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 000000000000000000000000e75479ba035175a251179919080bc7bd4e700f6e
Arg [4] : 000000000000000000000000a6ec692942dc8c590693dc2a1cba5a7413de851f
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [6] : 4d616b657273546f6b656e563200000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 4d4b543200000000000000000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

65332:13529:0:-;;;;;;;;;-1:-1:-1;;;65332:13529:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7961:44;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7961:44:0;;;;;;;;;;;;;;;;;;;;57379:195;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57379:195:0;-1:-1:-1;;;;;;57379:195:0;;;;;;;;;;;;;;;;;;;;;;;68519:162;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68519:162:0;;;;;;;;;;;;;;77600:635;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;77600:635:0;-1:-1:-1;;;;;77600:635:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33788:70;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33788:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;33788:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24894:113;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;24894:113:0;;;;;;;;;-1:-1:-1;;;;;24894:113:0;;;;;;;;;;;;;;24294:364;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;24294:364:0;-1:-1:-1;;;;;24294:364:0;;;;;;;14493:35;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14493:35:0;;;;35069:89;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35069:89:0;;;;7896:58;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7896:58:0;;;;71858:139;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;71858:139:0;;;;;26408:325;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;26408:325:0;-1:-1:-1;;;;;26408:325:0;;;;;;;;;;;;34741:180;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;34741:180:0;-1:-1:-1;;;;;34741:180:0;;;;;;;48360:76;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;48360:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6768:95;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6768:95:0;;;;27362:235;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;27362:235:0;-1:-1:-1;;;;;27362:235:0;;;;;;;;;;;;71346:88;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;71346:88:0;;;;;73772:144;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;73772:144:0;-1:-1:-1;;;;;73772:144:0;;;;;23721:143;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;23721:143:0;;;;;35495;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;35495:143:0;;;;;48595:52;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;48595:52:0;-1:-1:-1;;;;;48595:52:0;;;;;66545:709;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;66545:709:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66545:709:0;-1:-1:-1;;;;;66545:709:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;66545:709:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67312:504;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;67312:504:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;67312:504:0;-1:-1:-1;;;;;67312:504:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;67312:504:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6147:26;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6147:26:0;;;;72864:139;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;72864:139:0;-1:-1:-1;;;;;72864:139:0;;;;;;;;;;68751:239;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68751:239:0;;;;;;;;;;;;;;;;;;;;;23368:168;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;23368:168:0;;;;;76757:505;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;76757:505:0;;;;-1:-1:-1;;;;;76757:505:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;23003:145;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;23003:145:0;-1:-1:-1;;;;;23003:145:0;;;;;74638:434;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;74638:434:0;-1:-1:-1;;;;;74638:434:0;;;;;;;;;70637:222;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;70637:222:0;;;;;;;;;6588:93;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6588:93:0;;;;67898:479;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;67898:479:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69867:580;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;69867:580:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5034:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5034:20:0;;;;9220:498;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9220:498:0;-1:-1:-1;;;;;9220:498:0;;;;;75424:305;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;75424:305:0;-1:-1:-1;;;;;75424:305:0;;;;;33962:74;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33962:74:0;;;;7761:53;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7761:53:0;;;;25300:209;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;25300:209:0;-1:-1:-1;;;;;25300:209:0;;;;;;;;;15781:350;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;15781:350:0;-1:-1:-1;;;;;15781:350:0;;;;;78536:320;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;78536:320:0;-1:-1:-1;;;;;78536:320:0;;;;;;;;;;;10816:60;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10816:60:0;;;;28298:314;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;28298:314:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28298:314:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28298:314:0;;-1:-1:-1;28298:314:0;;-1:-1:-1;;;;;;;28298:314:0;34236:136;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;34236:136:0;;;;;72079:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;72079:104:0;;;;;65485:54;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;65485:54:0;-1:-1:-1;;;;;65485:54:0;;;;;65729:53;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;65729:53:0;-1:-1:-1;;;;;65729:53:0;;;;;75940:474;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;75940:474:0;-1:-1:-1;;;;;75940:474:0;;;;;;;;;;69191:444;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;69191:444:0;;;;;;;;;;;;;;;;;;;;;;;;;;;5654:178;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5654:178:0;-1:-1:-1;;;;;5654:178:0;;;;;73394:227;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;73394:227:0;-1:-1:-1;;;;;73394:227:0;;;;;7961:44;;;;:::o;57379:195::-;39240:38;;;;;;;;;;;;;;;;57450:4;;-1:-1:-1;;;;;;57476:41:0;;;;;;;57475:90;;-1:-1:-1;39640:54:0;;;;;;;;;;;;;;;;;;;;;39583:37;;;;;;;;;;;;;39534:29;;;;;;;;;;;;;39483:31;;;;;;;;;;;;;39437:26;;;;;;;;;;;;;39396:21;;;;;;;;;;;;;39357:19;;;;;;;;;;;;;;-1:-1:-1;;;;;;57523:41:0;;;39350:68;;;;:114;;;:165;:214;:271;:345;57523:41;;;;;57475:90;57467:99;;57379:195;;;;:::o;68519:162::-;6323:6;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;68629:44;68647:10;68659:13;;68629:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68629:17:0;;-1:-1:-1;;;;;68629:44:0:i;:::-;;68519:162;;:::o;77600:635::-;77960:20;6323:6;;77960:20;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;74124:10;74102:33;;;;:21;:33;;;;;;;;:41;;:33;:41;:100;;;;-1:-1:-1;74183:10:0;74162:32;;;;:20;:32;;;;;;;;:40;;:32;:40;;74102:100;74079:166;;;;;;;-1:-1:-1;;;;;74079:166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;77983:50;78001:6;78009:23;;77983:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77983:17:0;;-1:-1:-1;;;;;77983:50:0:i;:::-;77960:73;;78069:82;78089:6;78097:12;78111;78125:25;;78069:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78069:19:0;;-1:-1:-1;;;;;78069:82:0:i;:::-;78044:107;;78162:65;78190:6;78198:14;78214:12;78162:27;:65::i;:::-;77600:635;;;;;;;;;:::o;33788:70::-;33847:5;33840:12;;;;;;;;-1:-1:-1;;33840:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33825:6;;33840:12;;33847:5;;33840:12;;33847:5;33840:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33788:70;;:::o;24894:113::-;24954:7;24977:24;;;:14;:24;;;;;;-1:-1:-1;;;;;24977:24:0;;24894:113::o;24294:364::-;24356:13;24372:17;24380:8;24372:7;:17::i;:::-;24356:33;-1:-1:-1;;;;;;24404:12:0;;;;;;;;24396:21;;;;;;24432:10;-1:-1:-1;;;;;24432:19:0;;;;:58;;;24455:35;24472:5;24479:10;24455:16;:35::i;:::-;24424:67;;;;;;;;24537:1;24504:21;24516:8;24504:11;:21::i;:::-;-1:-1:-1;;;;;24504:35:0;;;:56;;;-1:-1:-1;;;;;;24543:17:0;;;;24504:56;24500:153;;;24571:24;;;;:14;:24;;;;;;;;;:30;;-1:-1:-1;;;;;;24571:30:0;-1:-1:-1;;;;;24571:30:0;;;;;;;;;24615;;;;;;;24571;;24615;;;;;;;;;;;;24294:364;;;:::o;14493:35::-;;;-1:-1:-1;;;;;14493:35:0;;:::o;35069:89::-;35136:9;:16;35069:89;:::o;7896:58::-;;;-1:-1:-1;;;;;7896:58:0;;:::o;71858:139::-;6323:6;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;71943:46;71961:15;71978:10;71943:17;:46::i;:::-;71858:139;:::o;26408:325::-;26495:8;22750:39;22768:10;22780:8;22750:17;:39::i;:::-;22742:48;;;;;;;;-1:-1:-1;;;;;26520:19:0;;;;26512:28;;;;;;-1:-1:-1;;;;;26555:17:0;;;;26547:26;;;;;;26582:30;26596:5;26603:8;26582:13;:30::i;:::-;26619:32;26635:5;26642:8;26619:15;:32::i;:::-;26658:25;26669:3;26674:8;26658:10;:25::i;:::-;26713:3;-1:-1:-1;;;;;26697:30:0;26706:5;-1:-1:-1;;;;;26697:30:0;;26718:8;26697:30;;;;;;;;;;;;;;;;;;26408:325;;;;:::o;34741:180::-;34823:7;34856:17;34866:6;34856:9;:17::i;:::-;34847:26;;34839:35;;;;;;-1:-1:-1;;;;;34888:19:0;;;;;;:11;:19;;;;;:27;;34908:6;;34888:27;;;;;;;;;;;;;;34881:34;;34741:180;;;;;:::o;48360:76::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;6768:95::-;5467:5;;-1:-1:-1;;;;;5467:5:0;5453:10;:19;5445:28;;;;;;6483:6;;-1:-1:-1;;;6483:6:0;;;;6475:15;;;;;;;;6831:5;6822:14;;-1:-1:-1;;6822:14:0;;;6848:9;;;;6831:5;6848:9;6768:95::o;27362:235::-;27483:8;22750:39;22768:10;22780:8;22750:17;:39::i;:::-;22742:48;;;;;;;;27549:42;27566:5;27573:3;27578:8;27549:42;;;;;;;;;;;;;:16;:42::i;:::-;27362:235;;;;:::o;71346:88::-;71395:31;71406:7;71415:10;71395;:31::i;73772:144::-;5467:5;;-1:-1:-1;;;;;5467:5:0;5453:10;:19;5445:28;;;;;;-1:-1:-1;;;;;73870:38:0;;;;;:21;:38;;;;;73863:45;;-1:-1:-1;;73863:45:0;;;73772:144::o;23721:143::-;23776:4;23805:20;;;:10;:20;;;;;;-1:-1:-1;;;;;23805:20:0;23839:19;;;23721:143::o;35495:::-;35554:7;35587:13;:11;:13::i;:::-;35578:22;;35570:31;;;;;;35615:9;:17;;35625:6;;35615:17;;;;;;;;;;;;;;35608:24;;35495:143;;;:::o;48595:52::-;;;;;;;;;;;;-1:-1:-1;;;;;48595:52:0;;:::o;66545:709::-;66662:10;66687:18;66720:17;66752:20;66787:15;66817:19;66851:32;;:::i;:::-;66886:21;66903:3;66886:16;:21::i;:::-;66926:20;;;;66851:56;;-1:-1:-1;;;;;;66926:34:0;;;66918:70;;;;;-1:-1:-1;;;;;66918:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;67032:24;;;;67080:23;;;;67129:25;;;;67175:20;;;;67221:25;;;;;67004:3;;67032:24;;67080:23;;-1:-1:-1;67129:25:0;-1:-1:-1;67175:20:0;;-1:-1:-1;67221:25:0;;-1:-1:-1;66545:709:0;-1:-1:-1;;66545:709:0:o;67312:504::-;67427:10;67452:15;67482:19;67514:52;;:::i;:::-;67569:19;67584:3;67569:14;:19::i;:::-;67607:30;;;;67514:74;;-1:-1:-1;;;;;;67607:44:0;;;67599:78;;;;;-1:-1:-1;;;;;67599:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;67717:30;;;;67773:35;;;;;67693:3;;67717:30;;67773:35;-1:-1:-1;67312:504:0;-1:-1:-1;;67312:504:0:o;6147:26::-;;;-1:-1:-1;;;6147:26:0;;;;;:::o;72864:139::-;72946:49;72961:10;72973:8;72983:11;72946:14;:49::i;:::-;72864:139;;:::o;68751:239::-;6323:6;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;68907:75;68927:10;68939:12;68953:13;68968;;68907:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68907:19:0;;-1:-1:-1;;;;;68907:75:0:i;:::-;;68751:239;;;;:::o;23368:168::-;23424:7;23456:20;;;:10;:20;;;;;;-1:-1:-1;;;;;23456:20:0;23491:19;;;23483:28;;;;;76757:505;77082:22;6323:6;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;74124:10;74102:33;;;;:21;:33;;;;;;;;:41;;:33;:41;:100;;;;-1:-1:-1;74183:10:0;74162:32;;;;:20;:32;;;;;;;;:40;;:32;:40;;74102:100;74079:166;;;;;;;-1:-1:-1;;;;;74079:166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;77107:71;77127:6;77135:12;77149:13;77164;;77107:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77107:19:0;;-1:-1:-1;;;;;77107:71:0:i;:::-;77082:96;;77189:65;77217:6;77225:14;77241:12;77189:27;:65::i;:::-;76757:505;;;;;;;:::o;23003:145::-;23059:7;-1:-1:-1;;;;;23083:20:0;;;;23075:29;;;;;;-1:-1:-1;;;;;;23118:24:0;;;;;:16;:24;;;;;;;23003:145::o;74638:434::-;-1:-1:-1;;;;;74723:17:0;;74730:10;74723:17;;74715:67;;;;;-1:-1:-1;;;;;74715:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;74801:26:0;;;;;;:21;:26;;;;;;;;74793:64;;;;;;;-1:-1:-1;;;;;74793:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;74876:25:0;;;;;;:20;:25;;;;;;;;:33;;:25;:33;;74868:75;;;;;-1:-1:-1;;;;;74868:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;74975:10;74954:32;;;;:20;:32;;;;;;;;-1:-1:-1;;;;;74954:37:0;;;;;;;;;;;;:49;;;;;-1:-1:-1;;74954:49:0;;;;;;;;75019:45;;;;;;;;;;;;;;;;;;;;;;;;;;74638:434;;:::o;70637:222::-;6323:6;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;70781:70;70809:10;70821:15;70838:12;70781:27;:70::i;6588:93::-;5467:5;;-1:-1:-1;;;;;5467:5:0;5453:10;:19;5445:28;;;;;;6323:6;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;6643:6;:13;;-1:-1:-1;;6643:13:0;-1:-1:-1;;;6643:13:0;;;6668:7;;;;6643:6;6668:7;6588:93::o;67898:479::-;68022:10;68047:19;68081:22;68147:47;68124:11;68131:3;68124:6;:11::i;:::-;68116:20;;;;;;;;-1:-1:-1;;;68197:33:0;;;;:28;:33;;;;;68275:32;;;68335:34;;;;68226:3;;68275:32;;;;;68335:34;-1:-1:-1;67898:479:0:o;69867:580::-;70160:20;6323:6;;70160:20;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;70183:54;70201:10;70213:23;;70183:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70183:17:0;;-1:-1:-1;;;;;70183:54:0:i;:::-;70160:77;;70273:86;70293:10;70305:12;70319;70333:25;;70273:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70273:19:0;;-1:-1:-1;;;;;70273:86:0:i;:::-;70248:111;;70370:69;70398:10;70410:14;70426:12;70370:27;:69::i;:::-;69867:580;;;;;;;;:::o;5034:20::-;;;-1:-1:-1;;;;;5034:20:0;;:::o;9220:498::-;9392:53;5467:5;;-1:-1:-1;;;;;5467:5:0;5453:10;:19;5445:28;;;;;;9324:19;;-1:-1:-1;;;;;9324:19:0;9316:33;9308:73;;;;;-1:-1:-1;;;;;9308:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;9475:11;9392:95;;9506:26;-1:-1:-1;;;;;9506:54:0;;:56;;;;;-1:-1:-1;;;9506:56:0;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9506:56:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9506:56:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9506:56:0;9566:1;9506:61;9498:92;;;;;-1:-1:-1;;;;;9498:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;9601:19;:48;;-1:-1:-1;;;;;;9601:48:0;-1:-1:-1;;;;;9601:48:0;;;;;;;;;;;9660:50;;;;;;;;:19;;;;;:48;;:50;;;;;-1:-1:-1;;9660:50:0;;;;;;;;-1:-1:-1;9660:19:0;:50;;;5:2:-1;;;;30:1;27;20:12;5:2;9660:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9660:50:0;;;;9220:498;;:::o;75424:305::-;5467:5;;-1:-1:-1;;;;;5467:5:0;5453:10;:19;5445:28;;;;;;-1:-1:-1;;;;;75508:34:0;;;;;;:21;:34;;;;;;;;75500:72;;;;;;;-1:-1:-1;;;;;75500:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;75583:33:0;;;;;;:20;:33;;;;;;;;:40;;-1:-1:-1;;75583:40:0;;;75619:4;75583:40;;;;75641:21;:34;;;;;;75634:41;;;;;;;;75691:30;;;;;;;;;;;;;;;;;75424:305;:::o;33962:74::-;34023:7;34016:14;;;;;;;;-1:-1:-1;;34016:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34001:6;;34016:14;;34023:7;;34016:14;;34023:7;34016:14;;;;;;;;;;;;;;;;;;;;;;;;7761:53;;;-1:-1:-1;;;;;7761:53:0;;:::o;25300:209::-;-1:-1:-1;;;;;25378:17:0;;25385:10;25378:17;;25370:26;;;;;;25421:10;25403:29;;;;:17;:29;;;;;;;;-1:-1:-1;;;;;25403:34:0;;;;;;;;;;;;:46;;-1:-1:-1;;25403:46:0;;;;;;;;;;25461:42;;;;;;;25403:34;;25421:10;25461:42;;;;;;;;;;;25300:209;;:::o;15781:350::-;-1:-1:-1;;;;;15864:32:0;;;;15856:41;;;;;;15930:20;;-1:-1:-1;;;;;15930:20:0;15916:10;:34;15908:85;;;;;-1:-1:-1;;;;;15908:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16004:20;:41;;-1:-1:-1;;;;;;16004:41:0;-1:-1:-1;;;;;16004:41:0;;;;;;;;;;16061:62;;16004:41;;16082:20;;16061:62;;-1:-1:-1;;16061:62:0;15781:350;:::o;78536:320::-;6323:6;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;74124:10;74102:33;;;;:21;:33;;;;;;;;:41;;:33;:41;:100;;;;-1:-1:-1;74183:10:0;74162:32;;;;:20;:32;;;;;;;;:40;;:32;:40;;74102:100;74079:166;;;;;;;-1:-1:-1;;;;;74079:166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;78782:66;78810:6;78818:15;78835:12;78782:27;:66::i;10816:60::-;;;-1:-1:-1;;;;;10816:60:0;;:::o;28298:314::-;28437:8;22750:39;22768:10;22780:8;22750:17;:39::i;:::-;22742:48;;;;;;;;28457:34;28470:5;28477:3;28482:8;28457:12;:34::i;:::-;28552:53;28577:5;28584:3;28589:8;28599:5;28552:24;:53::i;:::-;28544:62;;;;;;;34236:136;34293:6;34316:16;34323:8;34316:6;:16::i;:::-;34308:25;;;;;;;;34347:19;;;;:9;:19;;;;;;;;;34340:26;;;;;;-1:-1:-1;;34340:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34347:19;;34340:26;;34347:19;34340:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34236:136;;;:::o;72079:104::-;72140:35;72154:10;72166:8;72140:13;:35::i;65485:54::-;;;;;;;;;;;;;;;:::o;65729:53::-;;;;;;;;;;;;;;;:::o;75940:474::-;-1:-1:-1;;;;;76043:31:0;;76022:4;76043:31;;;:20;:31;;;;;;;;:39;;:31;:39;76039:368;;;-1:-1:-1;76106:5:0;76099:12;;76039:368;76133:56;76171:9;76182:6;76133:37;:56::i;:::-;:64;;76193:4;76133:64;76129:278;;;-1:-1:-1;76221:4:0;76214:11;;76129:278;-1:-1:-1;;;;;76247:28:0;;;;;;;:20;:28;;;;;;;;:39;;;;;;;;;;;;76243:164;;;-1:-1:-1;76310:4:0;76303:11;;76243:164;76354:41;76377:6;76385:9;76354:22;:41::i;:::-;76347:48;;;;69191:444;69447:22;6323:6;;-1:-1:-1;;;6323:6:0;;;;6322:7;6314:16;;;;;;69472:75;69492:10;69504:12;69518:13;69533;;69472:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;69472:19:0;;-1:-1:-1;;;;;69472:75:0:i;:::-;69447:100;;69558:69;69586:10;69598:14;69614:12;69558:27;:69::i;5654:178::-;5467:5;;-1:-1:-1;;;;;5467:5:0;5453:10;:19;5445:28;;;;;;-1:-1:-1;;;;;5731:22:0;;;;5723:31;;;;;;5787:5;;;5766:37;;-1:-1:-1;;;;;5766:37:0;;;;5787:5;;;5766:37;;;5810:5;:16;;-1:-1:-1;;;;;;5810:16:0;-1:-1:-1;;;;;5810:16:0;;;;;;;;;;5654:178::o;73394:227::-;5467:5;;-1:-1:-1;;;;;5467:5:0;5453:10;:19;5445:28;;;;;;-1:-1:-1;;;;;73490:37:0;;;;;;:20;:37;;;;;;;;:45;;:37;:45;;73482:75;;;;;-1:-1:-1;;;;;73482:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;73568:38:0;;;;;:21;:38;;;;;:45;;-1:-1:-1;;73568:45:0;73609:4;73568:45;;;73394:227::o;52091:481::-;52255:24;;:93;;;;;;-1:-1:-1;;;;;52255:93:0;;;;;;;;;;;;;;;;;;;;;;;52212:4;;;;52255:24;;;:41;;52311:8;;52334:13;;52255:93;;;;;;;;;;;;52212:4;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;52255:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52255:93:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52255:93:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52255:93:0;52452:24;;52366:163;;;;;;-1:-1:-1;;;;;52452:24:0;;;52255:93;52366:163;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52255:93;;-1:-1:-1;52366:163:0;;52255:93;;52492:8;;52515:13;;52366:163;;;;;;;;;;;;;;;52452:24;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;52366:163:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52549:15;52542:22;;52091:481;;;;;;:::o;49329:776::-;49496:4;49621:25;49523:44;49543:13;49558:8;49523:19;:44::i;:::-;49515:93;;;;;;;-1:-1:-1;;;;;49515:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49649:24;;:167;;;;;-1:-1:-1;;;;;49649:167:0;;;;;;;;;:24;:167;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:24;;;;;:43;;49707:8;;49649:24;;49747:12;;49774:13;;49802;;49649:167;;;;;;;;;;;;;;:24;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;49649:167:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49649:167:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49649:167:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49649:167:0;49912:24;;49834:226;;;;;;-1:-1:-1;;;;;49912:24:0;;;49649:167;49834:226;;;;;;;;;;;;;;;;;;;;;;;49912:24;49834:226;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49649:167;;-1:-1:-1;49834:226:0;;49649:167;;49952:8;;49975:12;;49912:24;50018:13;;50046;;49912:24;49834:226;;;;;;;;;;49912:24;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;49834:226:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50080:17;50073:24;;49329:776;;;;;;;;:::o;52849:1986::-;53146:33;;:::i;:::-;53226:24;53592:22;53700:8;53744:22;53809:47;;:::i;:::-;54010:32;52991:10;;;;-1:-1:-1;52983:73:0;;;;;-1:-1:-1;;;;;52983:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53084:5;53075:14;;;;53067:68;;;;;-1:-1:-1;;;;;53067:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53182:33;53199:15;53182:16;:33::i;:::-;53146:69;;53253:13;:24;;;53226:51;;53296:52;53318:13;:21;;;53341:6;53296:21;:52::i;:::-;53288:86;;;;;;;-1:-1:-1;;;;;53288:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53393:30;53416:6;53393:22;:30::i;:::-;53385:85;;;;;;;-1:-1:-1;;;;;53385:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53519:13;:25;;;53489:55;;53498:17;53489:6;:26;:55;;;;53481:90;;;;;;;-1:-1:-1;;;;;53481:90:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53617:65;;;;;;;;;;;;;;;;;;;53655:13;:26;;;53617:21;:65::i;:::-;53592:90;;53709:1;53700:10;;53695:973;53716:6;53712:10;;:1;:10;;;53695:973;;;53793:1;53769:17;53789:1;53769:21;:25;53744:50;;53859:134;;;;;;;;;53912:15;53859:134;;;;;;53962:15;53859:134;;;53809:184;;54045:17;:15;:17::i;:::-;54010:52;;54134:20;54077:28;:54;54106:24;54077:54;;;;;;;;;;;:77;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54184:208;54233:24;54276:6;54301:15;54335:8;54362:15;54184:208;;;;;;;;;-1:-1:-1;;;;;54184:208:0;-1:-1:-1;;;;;54184:208:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;54184:208:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54499:39;54505:6;54513:24;54499:5;:39::i;:::-;54553:48;54566:24;54592:8;54553:12;:48::i;:::-;54633:14;;:21;;54652:1;54633:21;:18;:21;:::i;:::-;54616:14;:38;53724:3;;;;;53695:973;;;54678:55;54711:13;54726:6;54678:32;:55::i;:::-;54749:78;;;;;;;54800:26;;;54749:78;;;;;;;;;;;;;;;;;;52849:1986;;;;;;;;;;:::o;51110:737::-;51199:33;;:::i;:::-;51494:16;51645:37;51235:33;51252:15;51235:16;:33::i;:::-;51199:69;;51287:53;51309:13;:21;;;51332:7;51287:21;:53::i;:::-;:123;;;;51362:48;51379:13;:21;;;51402:7;51362:16;:48::i;:::-;51279:202;;;;;;;-1:-1:-1;;;;;51279:202:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51541:13;:24;;;51513:13;:25;;;:52;51494:71;;51576:58;51609:13;51624:9;51576:32;:58::i;:::-;51715:16;;51693:39;;:21;:39::i;:::-;51749:90;;;;;;-1:-1:-1;;;;;51749:90:0;;;;;;;;;;;;;;;51645:88;;-1:-1:-1;51749:90:0;;;;;;;;;;51110:737;;;;;:::o;28968:243::-;29054:4;29067:13;29083:17;29091:8;29083:7;:17::i;:::-;29067:33;;29126:5;-1:-1:-1;;;;;29114:17:0;:8;-1:-1:-1;;;;;29114:17:0;;:54;;;;29160:8;-1:-1:-1;;;;;29135:33:0;:21;29147:8;29135:11;:21::i;:::-;-1:-1:-1;;;;;29135:33:0;;29114:54;:91;;;;29172:33;29189:5;29196:8;29172:16;:33::i;:::-;29107:98;28968:243;-1:-1:-1;;;;28968:243:0:o;30311:271::-;30413:6;-1:-1:-1;;;;;30392:27:0;:17;30400:8;30392:7;:17::i;:::-;-1:-1:-1;;;;;30392:27:0;;30384:36;;;;;;30467:1;30431:24;;;:14;:24;;;;;;-1:-1:-1;;;;;30431:24:0;:38;30427:150;;30515:1;30480:24;;;:14;:24;;;;;;;;:37;;-1:-1:-1;;;;;;30480:37:0;;;30531:38;;;;;;;-1:-1:-1;;;;;30531:38:0;;;;;;;;;;;30311:271;;:::o;36796:872::-;36917:18;36971:22;37035:17;36870:38;36892:5;36899:8;36870:21;:38::i;:::-;36938:26;;;;:16;:26;;;;;;;;;-1:-1:-1;;;;;36996:18:0;;;;:11;:18;;;;;;:25;36938:26;;-1:-1:-1;36996:32:0;;37026:1;36996:32;:29;:32;:::i;:::-;-1:-1:-1;;;;;37055:18:0;;;;;;:11;:18;;;;;:34;;36971:57;;-1:-1:-1;37055:18:0;36971:57;;37055:34;;;;;;;;;;;;;;37035:54;;37131:9;37098:11;:18;37110:5;-1:-1:-1;;;;;37098:18:0;-1:-1:-1;;;;;37098:18:0;;;;;;;;;;;;37117:10;37098:30;;;;;;;;;;;;;;;;;;;;;:42;;;;-1:-1:-1;;;;;37147:18:0;;;;:11;:18;;;;;;:34;;37166:14;;37147:34;;;;;;;;;;;;;;;;;:38;;;;-1:-1:-1;;;;;37551:18:0;;;;:11;:18;;;;;;:27;;;;;-1:-1:-1;;37551:27:0;;;:::i;:::-;-1:-1:-1;37614:1:0;37585:26;;;:16;:26;;;;;;:30;;;37622:27;;;;;;:40;-1:-1:-1;;36796:872:0:o;36279:231::-;36384:14;36346:31;36363:3;36368:8;36346:16;:31::i;:::-;-1:-1:-1;;;;;;36401:16:0;;;;;;;:11;:16;;;;;;;;:23;;39:1:-1;23:18;;45:23;;36431:31:0;;;;;;;;;;;36469:26;;;:16;:26;;;;;:35;36279:231::o;50290:474::-;50365:13;50381:17;50389:8;50381:7;:17::i;:::-;50365:33;;50428:5;-1:-1:-1;;;;;50417:16:0;:7;-1:-1:-1;;;;;50417:16:0;;:70;;;;50480:7;-1:-1:-1;;;;;50455:32:0;:21;50467:8;50455:11;:21::i;:::-;-1:-1:-1;;;;;50455:32:0;;50417:70;:124;;;;50509:32;50526:5;50533:7;50509:16;:32::i;:::-;50409:197;;;;;;;-1:-1:-1;;;;;50409:197:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50617:22;50623:5;50630:8;50617:5;:22::i;:::-;50657:38;;;;:28;:38;;;;;;;;50650:45;;-1:-1:-1;;50650:45:0;;;;;;;;;50711;;;;;-1:-1:-1;;;;;50711:45:0;;;;;;;;;;;;;;;;;;;;;;50290:474;;;:::o;12445:846::-;12582:12;;:::i;:::-;12607:10;12628:18;12657:17;12685:20;12716:15;12742:26;12779:45;12983:32;;:::i;:::-;8137:19;;-1:-1:-1;;;;;8137:19:0;:33;;8129:42;;;;;;8190:24;;-1:-1:-1;;;;;8190:24:0;:38;;8182:47;;;;;;12827:26;12849:3;12827:21;:26::i;:::-;12779:74;;12933:18;-1:-1:-1;;;;;12933:34:0;;12968:3;12933:39;;;;;-1:-1:-1;;;12933:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12933:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12933:39:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;12933:39:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:3;5:12;;2:2;;;30:1;27;20:12;2:2;12933:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20:11:-1;12:20;;9:2;;;45:1;42;35:12;9:2;64:21;;126:4;117:14;;142:31;;;139:2;;;186:1;183;176:12;139:2;218:10;;268:11;251:29;;293:43;;;290:58;-1:-1;239:118;236:2;;;370:1;367;360:12;236:2;-1:-1;;13018:235:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;13018:235:0;;;;;;;-1:-1:-1;;;;;13018:235:0;;;;;;;;;-1:-1:-1;13018:235:0;12445:846;-1:-1:-1;;;;;;;;;;12445:846:0:o;11826:545::-;11961:22;;:::i;:::-;11996:10;12017:15;12043:26;12164:40;;:::i;:::-;8137:19;;-1:-1:-1;;;;;8137:19:0;:33;;8129:42;;;;;;8190:24;;-1:-1:-1;;;;;8190:24:0;:38;;8182:47;;;;;;12110:24;;:43;;;;;;;;;;;;;;-1:-1:-1;;;;;12110:24:0;;;;:38;;:43;;;;;:24;;:43;;;;;;;;:24;;:43;;;5:2:-1;;;;30:1;27;20:12;5:2;12110:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12110:43:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;12110:43:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;12110:43:0;;;;;;;;;;;;;;;;;;20:11:-1;12:20;;9:2;;;45:1;42;35:12;9:2;64:21;;126:4;117:14;;142:31;;;139:2;;;186:1;183;176:12;139:2;218:10;;268:11;251:29;;293:43;;;290:58;-1:-1;239:118;236:2;;;370:1;367;360:12;236:2;-1:-1;;12207:128:0;;;;;;;;;;;-1:-1:-1;;;;;12207:128:0;;;;;;;;;;;;;;;-1:-1:-1;12207:128:0;;11826:545;-1:-1:-1;;;;;;;;11826:545:0:o;56586:673::-;-1:-1:-1;;;;;56712:26:0;;;56686:23;56712:26;;;:16;:26;;;;;;;;;56757:21;;;;;;:47;;-1:-1:-1;;;;;;56782:22:0;;;;56757:47;56749:98;;;;;;;-1:-1:-1;;;;;56749:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56877:8;-1:-1:-1;;;;;56866:19:0;:7;-1:-1:-1;;;;;56866:19:0;;:49;;;;56900:15;-1:-1:-1;;;;;56889:26:0;:7;-1:-1:-1;;;;;56889:26:0;;56866:49;56858:82;;;;;;;-1:-1:-1;;;;;56858:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56955:29:0;;;56951:248;;;-1:-1:-1;;;;;57001:25:0;;;;;;;:16;:25;;;;;:39;;-1:-1:-1;;;;;;57001:39:0;;;;;;;;;;56951:248;;;-1:-1:-1;;;;;57081:26:0;;;;;;;57073:59;;;;;-1:-1:-1;;;;;57073:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57147:26:0;;;;;;;:16;:26;;;;;:40;;-1:-1:-1;;;;;;57147:40:0;;;;;;;;;;56951:248;57214:37;;;-1:-1:-1;;;;;57214:37:0;;;;;;;;;;;;;;;;;;;;;;;;56586:673;;;;:::o;32086:342::-;32232:4;32305:13;32253:16;:3;-1:-1:-1;;;;;32253:14:0;;:16::i;:::-;32252:17;32248:51;;;32287:4;32280:11;;;;32248:51;32336:3;-1:-1:-1;;;;;32321:36:0;;32358:5;32365:8;32375:5;32321:60;;;;;-1:-1:-1;;;32321:60:0;;;;;;;-1:-1:-1;;;;;32321:60:0;-1:-1:-1;;;;;32321:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;32321:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32321:60:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32321:60:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32321:60:0;-1:-1:-1;;;;;;32396:25:0;32406:15;32396:25;;;-1:-1:-1;;;;;;32086:342:0:o;13788:267::-;11700:20;;13932:4;;-1:-1:-1;;;;;11700:20:0;:34;;11692:43;;;;;;13956:20;;;:91;;;;;;-1:-1:-1;;;;;13956:91:0;;;;;;;;;;;;;;;;;;;:20;;;;;:58;;:91;;;;;;;;;;;;;;;:20;;:91;;;5:2:-1;;;;30:1;27;20:12;5:2;13956:91:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;13956:91:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13956:91:0;;13788:267;-1:-1:-1;;;13788:267:0:o;25826:144::-;-1:-1:-1;;;;;25928:25:0;;;25908:4;25928:25;;;:17;:25;;;;;;;;:36;;;;;;;;;;;;;;;25826:144::o;55652:375::-;55786:4;55878:40;;:::i;:::-;55807:18;;55803:63;;;55850:4;55843:11;;;;55803:63;55921:29;55936:13;55921:14;:29::i;:::-;55878:72;;55968:51;55990:10;:18;;;56010:8;55117:372;-1:-1:-1;;;;;55291:26:0;;;55248:4;55291:26;;;:16;:26;;;;;;55248:4;;55291:26;55332:29;;55328:154;;55404:7;-1:-1:-1;;;;;55385:26:0;:15;-1:-1:-1;;;;;55385:26:0;;55378:33;;;;55328:154;55463:7;-1:-1:-1;;;;;55451:19:0;:8;-1:-1:-1;;;;;55451:19:0;;55444:26;;;;15333:280;15413:4;-1:-1:-1;;;;;15438:29:0;;;;15430:80;;;;;-1:-1:-1;;;;;15430:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15528:20;;-1:-1:-1;;;;;15528:20:0;:34;;:77;;-1:-1:-1;;15566:20:0;;-1:-1:-1;;;;;15566:39:0;;;:20;;:39;;15333:280::o;45705:439::-;45769:6;45788:16;45827;45866;45931;45970:6;45996;45813:2;45788:28;;45852:2;45827:28;;45909:3;:10;45896:3;:10;:23;45885:35;;;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;45885:35:0;;45866:54;;45956:2;45931:28;;45979:1;45970:10;;46005:1;45996:10;;45991:55;46012:3;:10;46008:1;:14;45991:55;;;46040:3;46044:1;46040:6;;;;;;;;;;;;;;;-1:-1:-1;;;46040:6:0;;-1:-1:-1;;;46040:6:0;46029:3;46033;;;;;;46029:8;;;;;;;;;;;;;;:17;;;;;;;;;;-1:-1:-1;46024:3:0;;45991:55;;;-1:-1:-1;46066:1:0;46057:50;46073:3;:10;46069:1;:14;46057:50;;;46101:3;46105:1;46101:6;;;;;;;;;;;;;;;-1:-1:-1;;;46101:6:0;;-1:-1:-1;;;46101:6:0;46090:3;46094;;;;;;46090:8;;;;;;;;;;;;;;:17;;;;;;;;;;-1:-1:-1;46085:3:0;;46057:50;;;-1:-1:-1;46132:3:0;;45705:439;-1:-1:-1;;;;;;;45705:439:0:o;56085:106::-;56161:14;;56134:7;;56161:21;;56180:1;56161:21;:18;:21;:::i;:::-;56154:28;;56085:106;:::o;37942:177::-;38004:26;38016:3;38021:8;38004:11;:26::i;:::-;38066:9;:16;;38039:24;;;;:14;:24;;;;;:43;;;39:1:-1;23:18;;45:23;;38089:24:0;;;;;;;-1:-1:-1;37942:177:0:o;35876:133::-;35953:16;35960:8;35953:6;:16::i;:::-;35945:25;;;;;;;;35977:19;;;;:9;:19;;;;;;;;:26;;;;;;;;:::i;1128:127::-;1208:5;;;1227:6;;;;1220:14;;;13397:313;8137:19;;13544:45;;-1:-1:-1;;;;;8137:19:0;:33;;8129:42;;;;;;8190:24;;-1:-1:-1;;;;;8190:24:0;:38;;8182:47;;;;;;13614:6;;13592:29;;:21;:29::i;:::-;13683:6;;13632:70;;;;;;;;;;;;;;;;;;;;;13544:77;;-1:-1:-1;;;;;;13632:50:0;;;;;:70;;;;;13683:6;;13632:70;;;;;;;;13683:6;13632:50;:70;;;5:2:-1;;;;30:1;27;20:12;5:2;13632:70:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;9875:369:0;8137:19;;10028:26;;-1:-1:-1;;;;;8137:19:0;:33;;8129:42;;;;;;8190:24;;-1:-1:-1;;;;;8190:24:0;:38;;8182:47;;;;;;10089:29;;10071:15;:47;10067:170;;;-1:-1:-1;10142:19:0;;-1:-1:-1;;;;;10142:19:0;10135:26;;10067:170;-1:-1:-1;10201:24:0;;-1:-1:-1;;;;;10201:24:0;10194:31;;31346:218;31449:5;-1:-1:-1;;;;;31428:26:0;:17;31436:8;31428:7;:17::i;:::-;-1:-1:-1;;;;;31428:26:0;;31420:35;;;;;;-1:-1:-1;;;;;31488:23:0;;;;;;:16;:23;;;;;;:30;;31516:1;31488:30;:27;:30;:::i;:::-;-1:-1:-1;;;;;31462:23:0;;;;;;;:16;:23;;;;;;;;:56;;;;31525:20;;;:10;:20;;;;:33;;-1:-1:-1;;;;;;31525:33:0;;;31346:218::o;948:113::-;1006:7;1029:6;;;;1022:14;;;;-1:-1:-1;1050:5:0;;;948:113::o;30852:208::-;30959:1;30927:20;;;:10;:20;;;;;;-1:-1:-1;;;;;30927:20:0;:34;30919:43;;;;;;30969:20;;;;:10;:20;;;;;;;;:26;;-1:-1:-1;;;;;;30969:26:0;-1:-1:-1;;;;;30969:26:0;;;;;;;;31026:21;;:16;:21;;;;;;:28;;-1:-1:-1;31026:25:0;:28::i;:::-;-1:-1:-1;;;;;31002:21:0;;;;;;;:16;:21;;;;;:52;;;;-1:-1:-1;30852:208:0:o;38364:604::-;38625:18;38677:22;38732:17;38429:29;38441:6;38449:8;38429:11;:29::i;:::-;38509:19;;;;:9;:19;;;;;38503:33;;-1:-1:-1;;38503:33:0;;;;;;;;;;;:38;38499:87;;38559:19;;;;:9;:19;;;;;38552:26;;;:::i;:::-;38646:24;;;;:14;:24;;;;;;38702:9;:16;38646:24;;-1:-1:-1;38702:23:0;;38723:1;38702:23;:20;:23;:::i;:::-;38677:48;;38752:9;38762:14;38752:25;;;;;;;;;;;;;;;;;;38732:45;;38810:9;38786;38796:10;38786:21;;;;;;;;;;;;;;;;;;:33;;;;38826:9;:25;;38836:14;;38826:25;;;;;;;;;;;;;;;:29;38864:9;:18;;;;;-1:-1:-1;;38864:18:0;;;:::i;:::-;-1:-1:-1;38916:1:0;38889:24;;;:14;:24;;;;;;:28;;;38924:25;;;;;;:38;-1:-1:-1;;38364:604:0:o;20627:578::-;20684:4;21107:17;;21191:8;;20627:578::o;29473:173::-;-1:-1:-1;;;;;29543:17:0;;;;29535:26;;;;;;29568:25;29579:3;29584:8;29568:10;:25::i;:::-;29605:35;;;;;;;;-1:-1:-1;;;;;29605:35:0;;;29622:1;;29605:35;;;;;;;;;29473:173;;:::o;29844:192::-;29909:31;29923:6;29931:8;29909:13;:31::i;:::-;29947:33;29963:6;29971:8;29947:15;:33::i;:::-;29992:38;;;;;;;;30017:1;;-1:-1:-1;;;;;29992:38:0;;;;;;;;;;;;29844:192;;:::o;65332:13529::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65332:13529:0;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;65332:13529:0;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;65332:13529:0;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65332:13529:0;;;-1:-1:-1;65332:13529:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://05b6a9bc6212f43a161375a16f4ef7010dc257764383f56d321350b5e4e03b4f

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.