ETH Price: $3,580.67 (-3.08%)

Token

QuiddMintablesAtari (QMA)
 

Overview

Max Total Supply

0 QMA

Holders

2,136

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3 QMA
0x74AA2E6dCed35279ED2512d45C11dEBF2d1e4ADb
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
QuiddMintables

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 21 : QuiddMintables.sol
pragma solidity ^0.8.4;

import './QuiddMintablesBase.sol';
import './roles/AdminRole.sol';
import './roles/MinterRole.sol';
import './roles/UnminterRole.sol';
import './royalties/ERC2981/ERC2981TokenIDMask.sol';
import './token_id/TokenIDMaskRestrictor.sol';

// Generic contract for any Ethereum Mainnet contract with no central directory contract
contract QuiddMintables is QuiddMintablesBase, TokenIDMaskRestrictor, ERC2981TokenIDMask, AccessControl {
  bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
  bytes32 public constant UNMINTER_ROLE = keccak256("UNMINTER_ROLE");

  // Base URI
  string private _theBaseURI;
  
  // Sets the base URI for all tokens managed by the contract
  constructor(
	      string memory _name,
	      string memory _symbol,
	      string memory baseURI_,
	      uint256[] memory _allowedMasks,
	      uint256[] memory _allowedValues,
	      uint256 _basisPoints,
	      address _payee)
      QuiddMintablesBase(_name, _symbol)
      TokenIDMaskRestrictor(_allowedMasks, _allowedValues)
      ERC2981TokenIDMask(_basisPoints, _payee) {
    _setBaseURI(baseURI_);
    _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
    _setupRole(MINTER_ROLE, _msgSender());
    _setupRole(UNMINTER_ROLE, _msgSender());
  }
  
  /**
   * @dev See {IERC721Metadata-tokenURI}.
   */
  function _baseURI() internal view virtual override returns (string memory) {
      return _theBaseURI;
  }
  
  /**
   * @dev Internal function to set the base URI for all token IDs. It is
   * automatically added as a prefix to the value returned in {tokenURI},
   * or to the token ID if {tokenURI} is empty.
   */
  function _setBaseURI(string memory baseURI_) internal virtual {
    _theBaseURI = baseURI_;
  }
    
  /**
   * @dev Mints a token to an address with a tokenURI. Less gas than safeMint, but should only be called for user wallets as _to.
   * @param _to address of the future owner of the token
   * @param _tokenId the ID of the print as registered with Quidd
   */
  function mint(address _to, uint256 _tokenId) public override {
      require(hasRole(MINTER_ROLE, _msgSender()), "Not a Minter");
      require(_tokenIDAllowed(_tokenId), "Token ID not allowed");
      super.mint(_to, _tokenId);
  }
  
  /**
   * @dev Safe Mints a token to an address with a tokenURI.
   * @param _to address of the future owner of the token
   * @param _tokenId the ID of the print as registered with Quidd
   * TODO: Implement custom indexing of tokens to save gas
   */
  function safeMint(address _to, uint256 _tokenId) public override {
      require(hasRole(MINTER_ROLE, _msgSender()), "Not a Minter");
      require(_tokenIDAllowed(_tokenId), "Token ID not allowed");
      super.safeMint(_to, _tokenId);
  }
  
  /**
   * @dev Moves token ownership to the contract address, making it unminted
   * @param _tokenId the Token ID, formatted according to the QuiddTokenID standard
   *
   * TODO: Make unmint an interface!
   */
  function unmint(uint256 _tokenId) public override {
      require(hasRole(UNMINTER_ROLE, _msgSender()), "Not an Unminter");
      super.unmint(_tokenId);
  }
  
  // TokenIDMaskRestrictor functions
  
  /**
   * @dev Adds an entry to the allowed token IDs
   * @param mask the bitwise mask to define which parameters to match on the token id
   * @param value the value to match on the token id
   */
  function addAllowedTokenIDConfiguration(
					  uint256 mask,
					  uint256 value
					  )
      public
  {
      require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Not an Admin");
      _addAllowedTokenIDConfiguration(mask, value);
  }
  
  /**
   * @dev Resets the configurations of token IDs permitted for minting
   * @param masks The list of bitwise mask to define which parameters to match on the token id
   * @param values The list of values to match on the token id
   */
  function setAllowedTokenIDConfigurations(
					   uint256[] memory masks,
					   uint256[] memory values
					   )
      public
  {
      require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Not an Admin");
      _setAllowedTokenIDConfigurations(masks, values);
  }
  
  /**
   * @dev Returns the full list of allowed token ID configurations
   * @return The complete list of AllowedTokenIDConfig elements
   */
  function getAllowedTokenIDConfigurations()
      public
      view
      returns (AllowedTokenIDConfig[] memory)
  {
      return _getAllowedTokenIDConfigurations();
  }
  
  // ERC2981TokenIDMask functions

  /**
   * @dev Sets default token royalties
   * @param basisPoints the royalty percent in basis points (using 2 decimals: 10000 = 100, 0 = 0)
   * @param payee recipient of the royalties
   */
  function setDefaultRoyalties(
			       uint256 basisPoints,
			       address payee
			       )
    public
  {
    require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Not an Admin");
    _setDefaultRoyalties(basisPoints, payee);
  }

  /**
   * @dev Adds an entry to the royalties configuration array
   * @param mask the bitwise mask to define which parameters to match on the token id
   * @param value the value to match on the token id
   * @param basisPoints the royalty percent in basis points (using 2 decimals: 10000 = 100, 0 = 0)
   * @param payee recipient of the royalties
   */
  function addRoyaltyConfiguration(
				   uint256 mask,
				   uint256 value,
				   uint256 basisPoints,
				   address payee
				   )
    public
  {
    require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Not an Admin");
    _addRoyaltyConfiguration(mask, value, basisPoints, payee);
  }

  /**
   * @dev Resets the configurations 
   * @param masks The list of bitwise mask to define which parameters to match on the token id
   * @param values The list of values to match on the token id
   * @param basisPoints The list of royalty percents in basis points (using 2 decimals: 10000 = 100, 0 = 0)
   * @param payees The list of recipients of the royalties
   */
  function setRoyaltyConfigurations(
				    uint256[] memory masks,
				    uint256[] memory values,
				    uint256[] memory basisPoints,
				    address[] memory payees
				    )
    public
  {
    require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Not an Admin");
    _setRoyaltyConfigurations(masks, values, basisPoints, payees);
  }
  
  /**
   * @dev Returns the default royalty configuration
   * @return The PaymentInfo struct representing the default royalty configuration
   */
  function getRoyaltyConfigurations()
    public
    view
    returns (RoyaltiesConfig[] memory)
  {
    return _getRoyaltyConfigurations();
  }

  /**
   * @dev Returns the full list of custom royalty configurations, default not included
   * @return The complete list of RoyaltiesConfig elements
   */
  function getDefaultRoyalties()
    public
    view
    returns (PaymentInfo memory)
  {
    return _getDefaultRoyalties();
  }
  
  /**
   * @inheritdoc ERC165
   */
  function supportsInterface(bytes4 interfaceId)
      public
      view
      virtual
      override(QuiddMintablesBase, ERC2981TokenIDMask, AccessControl)
      returns (bool)
  {
      return QuiddMintablesBase.supportsInterface(interfaceId) ||
	  ERC2981TokenIDMask.supportsInterface(interfaceId) ||
	  AccessControl.supportsInterface(interfaceId);
  }
}

File 2 of 21 : QuiddMintablesBase.sol
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "hardhat/console.sol";
import './token_id/QuiddTokenIDv0.sol';


// This is the abstract parent contract for Quidd NFTs that use the standard Quidd token format
abstract contract QuiddMintablesBase is ERC721 {
    using QuiddTokenIDv0 for uint256;
    
    
    /**
     * The constructor does not set the baseURI, but rather leaves that up to subclasses
     * The owner of the contract will automatically be set up with Admin and Minter roles
     */
    constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {
    }
    
    /**
     * @dev Plain Mints a token to an address with a tokenURI.
     * @param _to address of the future owner of the token
     * @param _tokenId the ID of the print as registered with Quidd
     * TODO: Implement custom indexing of tokens to save gas
     */
    function mint(address _to, uint256 _tokenId) public virtual {
	bool notNew = _exists(_tokenId);
	if (notNew) {
	    address owner = ownerOf(_tokenId);
	    require(owner == address(this), "Already minted");
	    
	    // Print was unminted. Transfer to new owner, with possibly new tokenId
	    // TODO: This means the count of tokens might be off
	    _transfer(address(this), _to, _tokenId);
	} else {
	    // First time minting
	    _mint(_to, _tokenId);
	}
	
    }
    
    /**
     * @dev Safe Mints a token to an address with a tokenURI.
     * @param _to address of the future owner of the token
     * @param _tokenId the ID of the print as registered with Quidd
     */
    function safeMint(address _to, uint256 _tokenId) public virtual {
	bool notNew = _exists(_tokenId);
	if (notNew) {
	    address owner = ownerOf(_tokenId);
	    require(owner == address(this), "Already minted");
	    
	    // Print was unminted. Transfer to new owner, with possibly new tokenId
	    // TODO: This means the count of tokens might be off
	    _safeTransfer(address(this), _to, _tokenId, "");
	} else {
	    // First time minting
	    _safeMint(_to, _tokenId);
	}
	
    }
    
    /**
     * @dev Moves token ownership to the contract address, making it unminted
     * @param _tokenId the Token ID, formatted according to the QuiddTokenID standard
     *
     * TODO: Make unmint an interface!
     */
    function unmint(uint256 _tokenId) public virtual {
	address owner = ownerOf(_tokenId);
	require(owner != address(this), "Already unminted");
	_transfer(owner, address(this), _tokenId);
    }
    
    // The following functions are overrides required by Solidity.
    
    /**
     * @inheritdoc ERC165
     */
    function supportsInterface(bytes4 interfaceId)
	public
	view
	virtual
	override(ERC721)
	returns (bool)
    {
	//console.log("IERC721:");
	//console.logBytes4(type(IERC721).interfaceId);
	return super.supportsInterface(interfaceId);
    }
}


contract TestQuiddMintablesBase is QuiddMintablesBase {
    constructor(string memory _name, string memory _symbol) QuiddMintablesBase(_name, _symbol) {
    }

    function mint(address _to, uint256 _tokenId) public override {
	super.mint(_to, _tokenId);
    }

    function safeMint(address _to, uint256 _tokenId) public override {
	super.safeMint(_to, _tokenId);
    }    

    function unmint(uint256 _tokenId) public override {
	super.unmint(_tokenId);
    }
}

File 3 of 21 : AdminRole.sol
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/access/AccessControl.sol";

/**
 * @dev Contract module which add functions for the default admin role defined by Access Control
 * By default, the account that deploys the contract will be assigned the Admin role.
 * Accounts can be added or removed with the functions defined below.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyAdmin`, which can be applied to your functions to restrict their use to admins.
 */
abstract contract AdminRole is AccessControl {

  /**
     * Modifier to make a function callable only by accounts with the admin role.
     */
    modifier onlyAdmin() {
        require(isAdmin(_msgSender()), "Not an Admin");
        _;
    }

    /**
     * Constructor.
     */
    constructor() {
      _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
    }

    /**
     * Validates whether or not the given account has been granted the admin role.
     * @param account The account to validate.
     * @return True if the account has been granted the admin role, false otherwise.
     */
    function isAdmin(address account) public view returns (bool) {
        return hasRole(DEFAULT_ADMIN_ROLE, account);
    }

    /**
     * Grants the admin role to a non-admin.
     * @param account The account to grant the admin role to.
     */
    function addAdmin(address account) public onlyAdmin {
        require(!isAdmin(account), "Already an Admin");
        grantRole(DEFAULT_ADMIN_ROLE, account);
    }

    /**
     * Removes the granted admin role.
     */
    function removeAdmin() public onlyAdmin {
        renounceRole(DEFAULT_ADMIN_ROLE, _msgSender());
    }
}

File 4 of 21 : MinterRole.sol
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/access/AccessControl.sol";

/**
 * @dev Contract module which creates a Minter role, to which more than one
 * address can be assigned, to grant limited access to minting actions
 *
 * By default, the account that deploys the contract will be assigned the Minter role. 
 * Accounts can be added or removed with the functions defined below.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyMinter`, which can be applied to your functions to restrict their use to
 * minters.
 */
abstract contract MinterRole is AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
 
    /**
     * Modifier to make a function callable only by accounts with the minter role.
     */
    modifier onlyMinter() {
        require(isMinter(_msgSender()), "Not a Minter");
        _;
    }

    /**
     * Constructor.
     */
    constructor() {
        _setupRole(MINTER_ROLE, _msgSender());
    }

    /**
     * Validates whether or not the given account has been granted the minter role.
     * @param account The account to validate.
     * @return True if the account has been granted the minter role, false otherwise.
     */
    function isMinter(address account) public view returns (bool) {
        return hasRole(MINTER_ROLE, account);
    }

    /**
     * Grants the minter role to a non-minter.
     * @param account The account to grant the minter role to.
     */
    function addMinter(address account) public onlyMinter {
        require(!isMinter(account), "Already a Minter");
        grantRole(MINTER_ROLE, account);
    }

    /**
     * Removes the granted minter role.
     */
    function removeMinter() public onlyMinter {
        renounceRole(MINTER_ROLE, _msgSender());
    }
}

File 5 of 21 : UnminterRole.sol
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/access/AccessControl.sol";

/**
 * @dev Contract module which creates an Unminter role, to which more than one
 * address can be assigned, to grant limited access to the unmint function
 * (and any related activities)
 *
 * By default, the account that deploys the contract will be assigned the Unminter role. 
 * Accounts can be added or removed with the functions defined below.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyMinter`, which can be applied to your functions to restrict their use to
 * minters.
 */
abstract contract UnminterRole is AccessControl {
    bytes32 public constant UNMINTER_ROLE = keccak256("UNMINTER_ROLE");
 
    /**
     * Modifier to make a function callable only by accounts with the minter role.
     */
    modifier onlyUnminter() {
        require(isUnminter(_msgSender()), "Not an Unminter");
        _;
    }

    /**
     * Constructor.
     */
    constructor() {
        _setupRole(UNMINTER_ROLE, _msgSender());
    }

    /**
     * Validates whether or not the given account has been granted the unminter role.
     * @param account The account to validate.
     * @return True if the account has been granted the minter role, false otherwise.
     */
    function isUnminter(address account) public view returns (bool) {
        return hasRole(UNMINTER_ROLE, account);
    }

    /**
     * Grants the unminter role to a non-unminter.
     * @param account The account to grant the unminter role to.
     */
    function addUnminter(address account) public onlyUnminter {
        require(!isUnminter(account), "Already an Unminter");
        grantRole(UNMINTER_ROLE, account);
    }

    /**
     * Removes the granted unminter role.
     */
    function removeUnminter() public onlyUnminter {
        renounceRole(UNMINTER_ROLE, _msgSender());
    }
}

File 6 of 21 : ERC2981TokenIDMask.sol
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import '../../token_id/QuiddTokenIDv0.sol';
import './IERC2981.sol';

/**
 * @dev This abstract contract provides for configuration and calculation of royalties 
 * based on NFT data stored in the Token ID, according to the QuiddTokenIDv0 format.
 *
 * This implementation specifically uses a bitwise mask over the token ID to check for a match,
 * which works something like the example below (this is simplification just for illustration):
 * 110000011000 - Mask
 * 100000010000 - Match value
 * 10XXXXX10XXX - What the Token ID must look like in bits
 * 100110010110 - Token ID (match)
 * 101111010111 - Token ID (match)
 * 110110010110 - Token ID (not a match)
 *
 * This is done by doing a bitwise AND of the mask and the Token ID, then seeing if the result exactly matches the match value
 *
 * In practice, this means that distinct royalties can be configured for single attributes, or for multiple attributes ANDed together. E.g.
 * - Publisher ID = 120
 * - Set ID = 98293
 * - Product Type = Figure
 * - Item Type = Award
 * - Edition = 1
 * - Publisher ID = 120 and Product Type = Figure and Item Type = Award
 * - Edition = 1 and Number = 1
 * 
 * Not supported:
 * - Publisher ID = 120 or Item Type = Award (this could be supported with 2 separate entries)
 * - Print Number < 10
 * - Set ID != 2398
 * - Total Count = 1000 (this data isn’t stored in the Token ID)
 *
 * To reduce complexity and gas costs, the ordering of masks is FILO. 
 * Newer configurations are assumed to more likely to be used. This also allows an old configurations to be replaced without having to delete the previous entry.
 * As a best practice, more specific rules should be added after more general ones, since the algorithm returns the first match.
 *
 * Order of specificity (more specific to less) (in general - specific cases may vary):
 * - Print ID
 * - Shiny ID
 * - Print Number
 * - Quidd ID
 * - Set ID
 * - Channel ID
 * - Publisher ID
 * - Product Type
 * - Item Type
 * - Edition
 * - Token ID Version
 *
 * Note that ANDing two categories makes for a more specific rule (e.g. Channel ID AND Product Type)
 * Note also that due to hierarchical structure, it would be redundant to AND any of the following:
 * - Publisher ID -> Channel ID -> Set ID -> Quidd ID -> Shiny ID
 */
abstract contract ERC2981TokenIDMask is ERC165, IERC2981 {
  using QuiddTokenIDv0 for uint256;

  struct PaymentInfo {
    uint24 basisPoints;
    address payee;
  }

  struct RoyaltiesConfig {
    uint256 mask;
    uint256 value;
    PaymentInfo info;
  }
    
  PaymentInfo public _defaultRoyalties;
  RoyaltiesConfig[] public _royaltyConfigs;
  
  /**
   * The constructor does not set the baseURI, but rather leaves that up to subclasses
   */
  constructor(uint256 _basisPoints, address _payee) {
    _setDefaultRoyalties(_basisPoints, _payee);
  }

  /**
   * @inheritdoc IERC2981
   */
  function royaltyInfo(uint256 tokenId, uint256 value)
    external
    view
    override
    returns (address payee, uint256 royaltyAmount)
  {
    PaymentInfo memory royalties = _defaultRoyalties;
    RoyaltiesConfig memory config;

    // Find proper mask
    if (_royaltyConfigs.length > 0) {
      for (int i = int(_royaltyConfigs.length - 1); i >= 0; i--) {
        config = _royaltyConfigs[uint(i)];
	if ((tokenId & config.mask) == config.value) {
	  royalties = config.info;
	  break;
	}
      }
    }
    
    payee = royalties.payee;
    royaltyAmount = (value * royalties.basisPoints) / 10000;
  }

  /**
   * @dev Sets default token royalties
   * @param basisPoints the royalty percent in basis points (using 2 decimals: 10000 = 100, 0 = 0) - maximum 2000 (20%) allowed
   * @param payee recipient of the royalties
   */
  function _setDefaultRoyalties(
			       uint256 basisPoints,
			       address payee
			    )
    internal
  {
    require(basisPoints <= 2000, "Invalid royalty");
    require(payee != address(0), "Invalid payee");
    _defaultRoyalties = PaymentInfo(uint24(basisPoints), payee);
  }

  /**
   * @dev Adds an entry to the royalties configuration array
   * @param mask the bitwise mask to define which parameters to match on the token id
   * @param value the value to match on the token id
   * @param basisPoints the royalty percent in basis points (using 2 decimals: 10000 = 100, 0 = 0)
   * @param payee recipient of the royalties
   */
  function _addRoyaltyConfiguration(
			       uint256 mask,
			       uint256 value,
			       uint256 basisPoints,
			       address payee
			    )
    internal
  {
    _validateRoyaltyConfiguration(mask, value, basisPoints, payee);
    _royaltyConfigs.push(RoyaltiesConfig(
				mask,
				value,
				PaymentInfo(uint24(basisPoints), payee)
				));
  }

  /**
   * @dev Validates the data supplied for a royalty configuration
   * @param mask the bitwise mask to define which parameters to match on the token id
   * @param value the value to match on the token id
   * @param basisPoints the royalty percent in basis points (using 2 decimals: 10000 = 100, 0 = 0)
   * @param payee recipient of the royalties
   */
  function _validateRoyaltyConfiguration(
			       uint256 mask,
			       uint256 value,
			       uint256 basisPoints,
			       address payee
			    )
    internal
    pure
  {
    require(mask > 0, "Invalid mask");
    require(value <= mask, "Value incompatible with mask");
    require(basisPoints <= 2000, "Invalid royalty");
    require(payee != address(0), "Invalid payee");
  }
  
  /**
   * @dev Resets the configurations 
   * @param masks The list of bitwise mask to define which parameters to match on the token id
   * @param values The list of values to match on the token id
   * @param basisPoints The list of royalty percents in basis points (using 2 decimals: 10000 = 100, 0 = 0)
   * @param payees The list of recipients of the royalties
   */
  function _setRoyaltyConfigurations(
			       uint256[] memory masks,
			       uint256[] memory values,
			       uint256[] memory basisPoints,
			       address[] memory payees
			    )
    internal
  {
    require(masks.length == values.length, "Royalty masks don't match values");
    require(masks.length == basisPoints.length, "Royalty masks don't match basis points");
    require(masks.length == payees.length, "Royalty masks don't match payees");

    delete _royaltyConfigs;
    for (uint i=0; i < masks.length; i++) {
      _addRoyaltyConfiguration(masks[i], values[i], basisPoints[i], payees[i]);
    }
  }

  /**
   * @dev Returns the default royalty configuration
   * @return The PaymentInfo struct representing the default royalty configuration
   */
  function _getDefaultRoyalties()
    public
    view
    returns (PaymentInfo memory)
  {
    return _defaultRoyalties;
  }

  /**
   * @dev Returns the full list of custom royalty configurations, default not included
   * @return The complete list of RoyaltiesConfig elements
   */
  function _getRoyaltyConfigurations()
    internal
    view
    returns (RoyaltiesConfig[] memory) {
    return _royaltyConfigs;
  }

  /**
   * @inheritdoc ERC165
   */
  function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override
    returns (bool)
  {
    return
      interfaceId == type(IERC2981).interfaceId ||
      super.supportsInterface(interfaceId);
  }
  
}


contract TestERC2981TokenIDMask is ERC2981TokenIDMask {
  constructor(uint256 _basisPoints, address _payee) ERC2981TokenIDMask(_basisPoints, _payee) {
  }

  function setDefaultRoyalties(
			       uint256 basisPoints,
			       address payee
			       )
    public
  {
    _setDefaultRoyalties(basisPoints, payee);
  }

  function addRoyaltyConfiguration(
				   uint256 mask,
				   uint256 value,
				   uint256 basisPoints,
				   address payee
				   )
    public
  {
    _addRoyaltyConfiguration(mask, value, basisPoints, payee);
  }

  function setRoyaltyConfigurations(
				    uint256[] memory masks,
				    uint256[] memory values,
				    uint256[] memory basisPoints,
				    address[] memory payees
				    )
    public
  {
    _setRoyaltyConfigurations(masks, values, basisPoints, payees);
  }
  
  function getRoyaltyConfigurations()
    public
    view
    returns (RoyaltiesConfig[] memory)
  {
    return _getRoyaltyConfigurations();
  }

  function getDefaultRoyalties()
    public
    view
    returns (PaymentInfo memory)
  {
    return _getDefaultRoyalties();
  }
}

File 7 of 21 : TokenIDMaskRestrictor.sol
pragma solidity ^0.8.4;

import './QuiddTokenIDv0.sol';

/**
 * @dev This abstract contract adds a constraint for Quidd Mintables regarding which items can be minted to the contract
 * based on NFT data stored in the Token ID, according to the QuiddTokenIDv0 format.
 *
 * This implementation specifically uses a bitwise mask over the token ID to check for a match,
 * which works something like the example below (this is a simplification just for illustration):
 * 110000011000 - Mask
 * 100000010000 - Match value
 * 10XXXXX10XXX - What the Token ID must look like in bits
 * 100110010110 - Token ID (match)
 * 101111010111 - Token ID (match)
 * 110110010110 - Token ID (not a match)
 *
 * This is done by doing a bitwise AND of the mask and the Token ID, then seeing if the result exactly matches the match value
 *
 * Only token IDs that match one of the masks can be minted to the contract.
 * Match rules can be configured for single attributes, or for multiple attributes ANDed together. E.g.
 * - Publisher ID = 120
 * - Set ID = 98293
 * - Product Type = Figure
 * - Item Type = Award
 * - Edition = 1
 * - Publisher ID = 120 and Product Type = Figure and Item Type = Award
 * - Edition = 1 and Number = 1
 * 
 * Not supported:
 * - Publisher ID = 120 or Item Type = Award (this could be supported with 2 separate entries)
 * - Print Number < 10
 * - Set ID != 2398
 * - Total Count = 1000 (this data isn’t stored in the Token ID)
 *
 * Note that due to hierarchical structure, it would be redundant to AND any of the following:
 * - Publisher ID -> Channel ID -> Set ID -> Quidd ID -> Shiny ID
 */
abstract contract TokenIDMaskRestrictor {
  using QuiddTokenIDv0 for uint256;

  struct AllowedTokenIDConfig {
    uint256 mask;
    uint256 value;
  }
    
  AllowedTokenIDConfig[] public _allowedTokenIDConfigs;
  
  /**
   * The constructor does not 
   */
  constructor(
	      uint256[] memory masks,
	      uint256[] memory values
	      )
      {
	  _setAllowedTokenIDConfigurations(masks, values);
      }
  
  /**
   * @dev Utility method to check if the contract should allow the token ID to be minted to this contract. Should be called by the mint/safemint methods.
   * @param tokenId the token id to be verified against the allow configurations
   */
  function _tokenIDAllowed(uint256 tokenId)
      internal
      view
      returns (bool)
  {
      // Find proper mask
      if (_allowedTokenIDConfigs.length > 0) {
	  for (uint i = 0; i < _allowedTokenIDConfigs.length; i++) {
	      AllowedTokenIDConfig memory config = _allowedTokenIDConfigs[i];
	      if ((tokenId & config.mask) == config.value) {
		  return true;
	      }
	  }
      } else {
	  return true;
      }    
      return false;
  }
  
  /**
   * @dev Adds an entry to the allowed token IDs
   * @param mask the bitwise mask to define which parameters to match on the token id
   * @param value the value to match on the token id
   */
  function _addAllowedTokenIDConfiguration(
				    uint256 mask,
				    uint256 value
				    )
      internal
  {
      require(_allowedTokenIDConfigs.length < 100, "Reached max configurations");
      _validateAllowedTokenIDConfiguration(mask, value);
      _allowedTokenIDConfigs.push(AllowedTokenIDConfig(
						       mask,
						       value
						       ));
  }

  /**
   * @dev Validates the data supplied for a token ID mask configuration
   * @param mask the bitwise mask to define which parameters to match on the token id
   * @param value the value to match on the token id
   */
  function _validateAllowedTokenIDConfiguration(
						uint256 mask,
						uint256 value
						)
      internal
      pure
  {
      require(mask > 0, "Mask can't be zero");
      require(value <= mask, "Value incompatible with mask");
  }
  
  /**
   * @dev Resets the configurations 
   * @param masks The list of bitwise mask to define which parameters to match on the token id
   * @param values The list of values to match on the token id
   */
  function _setAllowedTokenIDConfigurations(
				     uint256[] memory masks,
				     uint256[] memory values
				     )
      internal
  {
      require(masks.length == values.length, "Masks don't match values");
      require(masks.length <= 100, "Too many configurations");
      
      delete _allowedTokenIDConfigs;
      for (uint i=0; i < masks.length; i++) {
	  _addAllowedTokenIDConfiguration(masks[i], values[i]);
      }
  }
  
  /**
   * @dev Returns the full list of allowed token ID configurations
   * @return The complete list of AllowedTokenIDConfig elements
   */
  function _getAllowedTokenIDConfigurations()
    internal
    view
    returns (AllowedTokenIDConfig[] memory) {
    return _allowedTokenIDConfigs;
  }
}


contract TestTokenIDMaskRestrictor is TokenIDMaskRestrictor {
    constructor(
		uint256[] memory masks,
		uint256[] memory values
		)
	TokenIDMaskRestrictor(masks, values) {
    }
    
    function addAllowedTokenIDConfiguration(
					    uint256 mask,
					    uint256 value
					    )
	public
    {
	_addAllowedTokenIDConfiguration(mask, value);
    }

    function setAllowedTokenIDConfigurations(
				      uint256[] memory masks,
				      uint256[] memory values
				      )
	public
    {
	_setAllowedTokenIDConfigurations(masks, values);
    }
    
    function getAllowedTokenIDConfigurations()
	public
	view
	returns (AllowedTokenIDConfig[] memory)
    {
	return _getAllowedTokenIDConfigurations();
    }

    function tokenIDAllowed(uint256 tokenId)
	public
	view
	returns (bool)
    {
	return _tokenIDAllowed(tokenId);
    }
}

File 8 of 21 : ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

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

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

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

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

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

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

        _balances[to] += 1;
        _owners[tokenId] = to;

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

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

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

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

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

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

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

File 9 of 21 : console.sol
// SPDX-License-Identifier: MIT
pragma solidity >= 0.4.22 <0.9.0;

library console {
	address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);

	function _sendLogPayload(bytes memory payload) private view {
		uint256 payloadLength = payload.length;
		address consoleAddress = CONSOLE_ADDRESS;
		assembly {
			let payloadStart := add(payload, 32)
			let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
		}
	}

	function log() internal view {
		_sendLogPayload(abi.encodeWithSignature("log()"));
	}

	function logInt(int p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(int)", p0));
	}

	function logUint(uint p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
	}

	function logString(string memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
	}

	function logBool(bool p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
	}

	function logAddress(address p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
	}

	function logBytes(bytes memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
	}

	function logBytes1(bytes1 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
	}

	function logBytes2(bytes2 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
	}

	function logBytes3(bytes3 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
	}

	function logBytes4(bytes4 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
	}

	function logBytes5(bytes5 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
	}

	function logBytes6(bytes6 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
	}

	function logBytes7(bytes7 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
	}

	function logBytes8(bytes8 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
	}

	function logBytes9(bytes9 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
	}

	function logBytes10(bytes10 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
	}

	function logBytes11(bytes11 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
	}

	function logBytes12(bytes12 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
	}

	function logBytes13(bytes13 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
	}

	function logBytes14(bytes14 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
	}

	function logBytes15(bytes15 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
	}

	function logBytes16(bytes16 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
	}

	function logBytes17(bytes17 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
	}

	function logBytes18(bytes18 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
	}

	function logBytes19(bytes19 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
	}

	function logBytes20(bytes20 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
	}

	function logBytes21(bytes21 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
	}

	function logBytes22(bytes22 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
	}

	function logBytes23(bytes23 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
	}

	function logBytes24(bytes24 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
	}

	function logBytes25(bytes25 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
	}

	function logBytes26(bytes26 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
	}

	function logBytes27(bytes27 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
	}

	function logBytes28(bytes28 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
	}

	function logBytes29(bytes29 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
	}

	function logBytes30(bytes30 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
	}

	function logBytes31(bytes31 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
	}

	function logBytes32(bytes32 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
	}

	function log(uint p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
	}

	function log(string memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
	}

	function log(bool p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
	}

	function log(address p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
	}

	function log(uint p0, uint p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1));
	}

	function log(uint p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1));
	}

	function log(uint p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1));
	}

	function log(uint p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1));
	}

	function log(string memory p0, uint p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1));
	}

	function log(string memory p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
	}

	function log(string memory p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
	}

	function log(string memory p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
	}

	function log(bool p0, uint p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1));
	}

	function log(bool p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
	}

	function log(bool p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
	}

	function log(bool p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
	}

	function log(address p0, uint p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1));
	}

	function log(address p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
	}

	function log(address p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
	}

	function log(address p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
	}

	function log(uint p0, uint p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2));
	}

	function log(uint p0, uint p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2));
	}

	function log(uint p0, uint p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2));
	}

	function log(uint p0, uint p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2));
	}

	function log(uint p0, string memory p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2));
	}

	function log(uint p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2));
	}

	function log(uint p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2));
	}

	function log(uint p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2));
	}

	function log(uint p0, bool p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2));
	}

	function log(uint p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2));
	}

	function log(uint p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2));
	}

	function log(uint p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2));
	}

	function log(uint p0, address p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2));
	}

	function log(uint p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2));
	}

	function log(uint p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2));
	}

	function log(uint p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2));
	}

	function log(string memory p0, uint p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2));
	}

	function log(string memory p0, uint p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2));
	}

	function log(string memory p0, uint p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2));
	}

	function log(string memory p0, uint p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
	}

	function log(string memory p0, address p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2));
	}

	function log(string memory p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
	}

	function log(string memory p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
	}

	function log(string memory p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
	}

	function log(bool p0, uint p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2));
	}

	function log(bool p0, uint p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2));
	}

	function log(bool p0, uint p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2));
	}

	function log(bool p0, uint p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
	}

	function log(bool p0, bool p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2));
	}

	function log(bool p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
	}

	function log(bool p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
	}

	function log(bool p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
	}

	function log(bool p0, address p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2));
	}

	function log(bool p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
	}

	function log(bool p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
	}

	function log(bool p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
	}

	function log(address p0, uint p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2));
	}

	function log(address p0, uint p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2));
	}

	function log(address p0, uint p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2));
	}

	function log(address p0, uint p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2));
	}

	function log(address p0, string memory p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2));
	}

	function log(address p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
	}

	function log(address p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
	}

	function log(address p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
	}

	function log(address p0, bool p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2));
	}

	function log(address p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
	}

	function log(address p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
	}

	function log(address p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
	}

	function log(address p0, address p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2));
	}

	function log(address p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
	}

	function log(address p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
	}

	function log(address p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
	}

	function log(uint p0, uint p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
	}

}

File 10 of 21 : QuiddTokenIDv0.sol
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/utils/Strings.sol";

// Extracts Quidd data from a standard Quidd Token ID
/*
 * The standard Quidd Mintable token ID is a uint256 encoded with several bits of unique print data.
 * From leftmost bit to right:
 * Bits 1-16:    Publisher ID (supports up to 65,535 publishers)
 * Bits 17-32:   Channel ID (supports up to 65,535 channels)
 * Bits 33-64:   Set ID
 * Bits 64-96:   Quidd ID
 * Bits 97-98:   Item (Set) type: 0 = Standard, 1 = Award, 2 = Collector's Edition
 * Bits 99-100:  Product type: 1 = Sticker, 2 = Card, 3 = 3D Figure
 * Bits 101-128: Shiny ID, or all 0's if not a shiny (28 bits, supports up to 268,435,456, way more than enough)
 * Bits 129-136: Edition (8 bits, supports up to 255 editions)
 * Bits 137-160: Print Number (24 bits, supports up to number 16,777,215)
 * Bits 161-192: Token Version (32 bits starting at 0, but probably only the rightmost bits will be used)
 * Bits 193-256: Print ID (uint64)
 */
library QuiddTokenIDv0 {
  function publisherId(uint256 self) internal pure returns (uint16) {
    return uint16(self >> 240);
  }  

  function channelId(uint256 self) internal pure returns (uint16) {
    return uint16(self >> 224);
  }  

  function setId(uint256 self) internal pure returns (uint32) {
    return uint32(self >> 192);
  }  

  function quiddId(uint256 self) internal pure returns (uint32) {
    return uint32(self >> 160);

  }  

  function itemType(uint256 self) internal pure returns (uint8) {
    uint256 shifty = self;
    shifty = shifty << 96;
    shifty = shifty >> 254;
    return uint8(shifty);
  }

  function productType(uint256 self) internal pure returns (uint8) {
    uint256 shifty = self;
    shifty = shifty << 98;
    shifty = shifty >> 254;
    return uint8(shifty);
  }

  function shinyId(uint256 self) internal pure returns (uint32) {
    uint256 shifty = self;
    shifty = shifty << 100;
    shifty = shifty >> 228;
    return uint32(shifty);
  }

  function edition(uint256 self) internal pure returns (uint8) {
    return uint8(self >> 120);
  }

  function printNumber(uint256 self) internal pure returns (uint24) {
    return uint24(self >> 96);
  }

  function tokenVersion(uint256 self) internal pure returns (uint32) {
    return uint32(self >> 64);
  }

  function printId(uint256 self) internal pure returns (uint64) {
    return uint64(self);
  }

  /*
  function uintToByteStr(uint256 self) internal pure returns (string memory) {
    uint256 shifty = self;
    string memory str;
    for (uint i = 0; i < 32; i++) {
      uint r = shifty % 256;
      shifty = shifty / 256;
      str = string(bytes.concat("[", bytes(Strings.toString(r)), "] ", bytes(str)));
    }
    return str;
  }
  */
}


contract TestQuiddTokenIDv0 {
  using QuiddTokenIDv0 for uint256;
  
  function getPublisherId(uint256 tid) public pure returns (uint16) {
    return tid.publisherId();
  }  
  
  function getChannelId(uint256 tid) public pure returns (uint16) {
    return tid.channelId();
  }  
  
  function getSetId(uint256 tid) public pure returns (uint32) {
    return tid.setId();
  }  
  
  function getQuiddId(uint256 tid) public pure returns (uint32) {
    return tid.quiddId();
  }  
  
  function getItemType(uint256 tid) public pure returns (uint8) {
    return tid.itemType();
  }  
  
  function getProductType(uint256 tid) public pure returns (uint8) {
    return tid.productType();
  }  
  
  function getShinyId(uint256 tid) public pure returns (uint32) {
    return tid.shinyId();
  }  
  
  function getEdition(uint256 tid) public pure returns (uint8) {
    return tid.edition();
  }  
  
  function getPrintNumber(uint256 tid) public pure returns (uint24) {
    return tid.printNumber();
  }  
  
  function getTokenVersion(uint256 tid) public pure returns (uint32) {
    return tid.tokenVersion();
  }  
  
  function getPrintId(uint256 tid) public pure returns (uint64) {
    return tid.printId();
  }  
}

File 11 of 21 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 12 of 21 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 13 of 21 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

File 14 of 21 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

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

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

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 15 of 21 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 16 of 21 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

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

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

File 17 of 21 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 18 of 21 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 19 of 21 : AccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)

pragma solidity ^0.8.0;

import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 20 of 21 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 21 of 21 : IERC2981.sol
pragma solidity ^0.8.4;

/// @title IERC2981
/// @dev Interface for the ERC2981 - Token Royalty standard
interface IERC2981 {
    /// @notice Called with the sale price to determine how much royalty
    //          is owed and to whom.
    /// @param _tokenId - the NFT asset queried for royalty information
    /// @param _value - the sale price of the NFT asset specified by _tokenId
    /// @return _receiver - address of who should be sent the royalty payment
    /// @return _royaltyAmount - the royalty payment amount for value sale price
    function royaltyInfo(uint256 _tokenId, uint256 _value)
        external
        view
        returns (address _receiver, uint256 _royaltyAmount);
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"baseURI_","type":"string"},{"internalType":"uint256[]","name":"_allowedMasks","type":"uint256[]"},{"internalType":"uint256[]","name":"_allowedValues","type":"uint256[]"},{"internalType":"uint256","name":"_basisPoints","type":"uint256"},{"internalType":"address","name":"_payee","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNMINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_allowedTokenIDConfigs","outputs":[{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_defaultRoyalties","outputs":[{"internalType":"uint24","name":"basisPoints","type":"uint24"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_getDefaultRoyalties","outputs":[{"components":[{"internalType":"uint24","name":"basisPoints","type":"uint24"},{"internalType":"address","name":"payee","type":"address"}],"internalType":"struct ERC2981TokenIDMask.PaymentInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_royaltyConfigs","outputs":[{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"components":[{"internalType":"uint24","name":"basisPoints","type":"uint24"},{"internalType":"address","name":"payee","type":"address"}],"internalType":"struct ERC2981TokenIDMask.PaymentInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"addAllowedTokenIDConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"basisPoints","type":"uint256"},{"internalType":"address","name":"payee","type":"address"}],"name":"addRoyaltyConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedTokenIDConfigurations","outputs":[{"components":[{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct TokenIDMaskRestrictor.AllowedTokenIDConfig[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDefaultRoyalties","outputs":[{"components":[{"internalType":"uint24","name":"basisPoints","type":"uint24"},{"internalType":"address","name":"payee","type":"address"}],"internalType":"struct ERC2981TokenIDMask.PaymentInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRoyaltyConfigurations","outputs":[{"components":[{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"components":[{"internalType":"uint24","name":"basisPoints","type":"uint24"},{"internalType":"address","name":"payee","type":"address"}],"internalType":"struct ERC2981TokenIDMask.PaymentInfo","name":"info","type":"tuple"}],"internalType":"struct ERC2981TokenIDMask.RoyaltiesConfig[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"payee","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"masks","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"setAllowedTokenIDConfigurations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"basisPoints","type":"uint256"},{"internalType":"address","name":"payee","type":"address"}],"name":"setDefaultRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"masks","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"uint256[]","name":"basisPoints","type":"uint256[]"},{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setRoyaltyConfigurations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"unmint","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162006bb238038062006bb283398181016040528101906200003791906200093b565b818185858a8a8181816000908051906020019062000057929190620006fa565b50806001908051906020019062000070929190620006fa565b50505050506200008782826200016160201b60201c565b50506200009b8282620002bc60201b60201c565b5050620000ae856200041c60201b60201c565b620000d26000801b620000c66200043860201b60201c565b6200044060201b60201c565b620001137f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6620001076200043860201b60201c565b6200044060201b60201c565b620001547fc47c7929930c7f2bb9db31476e47def40882b518b18186f92b9e275b3dae4d18620001486200043860201b60201c565b6200044060201b60201c565b5050505050505062001022565b8051825114620001a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200019f9062000bfe565b60405180910390fd5b606482511115620001f0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001e79062000bba565b60405180910390fd5b600660006200020091906200078b565b60005b8251811015620002b757620002a18382815181106200024b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518383815181106200028d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516200045660201b60201c565b8080620002ae9062000de3565b91505062000203565b505050565b6107d082111562000304576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002fb9062000c20565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141562000377576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200036e9062000b76565b60405180910390fd5b60405180604001604052808362ffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815250600760008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050505050565b80600a908051906020019062000434929190620006fa565b5050565b600033905090565b6200045282826200050d60201b60201c565b5050565b606460068054905010620004a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004989062000b98565b60405180910390fd5b620004b38282620005ff60201b60201c565b60066040518060400160405280848152602001838152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550505050565b6200051f82826200068f60201b60201c565b620005fb5760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620005a06200043860201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000821162000645576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200063c9062000c42565b60405180910390fd5b818111156200068b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006829062000bdc565b60405180910390fd5b5050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b828054620007089062000d77565b90600052602060002090601f0160209004810192826200072c576000855562000778565b82601f106200074757805160ff191683800117855562000778565b8280016001018555821562000778579182015b82811115620007775782518255916020019190600101906200075a565b5b509050620007879190620007b1565b5090565b5080546000825560020290600052602060002090810190620007ae9190620007d0565b50565b5b80821115620007cc576000816000905550600101620007b2565b5090565b5b80821115620007f557600080820160009055600182016000905550600201620007d1565b5090565b6000620008106200080a8462000c8d565b62000c64565b905080838252602082019050828560208602820111156200083057600080fd5b60005b8581101562000864578162000849888262000924565b84526020840193506020830192505060018101905062000833565b5050509392505050565b6000620008856200087f8462000cbc565b62000c64565b9050828152602081018484840111156200089e57600080fd5b620008ab84828562000d41565b509392505050565b600081519050620008c48162000fee565b92915050565b600082601f830112620008dc57600080fd5b8151620008ee848260208601620007f9565b91505092915050565b600082601f8301126200090957600080fd5b81516200091b8482602086016200086e565b91505092915050565b600081519050620009358162001008565b92915050565b600080600080600080600060e0888a0312156200095757600080fd5b600088015167ffffffffffffffff8111156200097257600080fd5b620009808a828b01620008f7565b975050602088015167ffffffffffffffff8111156200099e57600080fd5b620009ac8a828b01620008f7565b965050604088015167ffffffffffffffff811115620009ca57600080fd5b620009d88a828b01620008f7565b955050606088015167ffffffffffffffff811115620009f657600080fd5b62000a048a828b01620008ca565b945050608088015167ffffffffffffffff81111562000a2257600080fd5b62000a308a828b01620008ca565b93505060a062000a438a828b0162000924565b92505060c062000a568a828b01620008b3565b91505092959891949750929550565b600062000a74600d8362000cf2565b915062000a818262000ecf565b602082019050919050565b600062000a9b601a8362000cf2565b915062000aa88262000ef8565b602082019050919050565b600062000ac260178362000cf2565b915062000acf8262000f21565b602082019050919050565b600062000ae9601c8362000cf2565b915062000af68262000f4a565b602082019050919050565b600062000b1060188362000cf2565b915062000b1d8262000f73565b602082019050919050565b600062000b37600f8362000cf2565b915062000b448262000f9c565b602082019050919050565b600062000b5e60128362000cf2565b915062000b6b8262000fc5565b602082019050919050565b6000602082019050818103600083015262000b918162000a65565b9050919050565b6000602082019050818103600083015262000bb38162000a8c565b9050919050565b6000602082019050818103600083015262000bd58162000ab3565b9050919050565b6000602082019050818103600083015262000bf78162000ada565b9050919050565b6000602082019050818103600083015262000c198162000b01565b9050919050565b6000602082019050818103600083015262000c3b8162000b28565b9050919050565b6000602082019050818103600083015262000c5d8162000b4f565b9050919050565b600062000c7062000c83565b905062000c7e828262000dad565b919050565b6000604051905090565b600067ffffffffffffffff82111562000cab5762000caa62000e8f565b5b602082029050602081019050919050565b600067ffffffffffffffff82111562000cda5762000cd962000e8f565b5b62000ce58262000ebe565b9050602081019050919050565b600082825260208201905092915050565b600062000d108262000d17565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b8381101562000d6157808201518184015260208101905062000d44565b8381111562000d71576000848401525b50505050565b6000600282049050600182168062000d9057607f821691505b6020821081141562000da75762000da662000e60565b5b50919050565b62000db88262000ebe565b810181811067ffffffffffffffff8211171562000dda5762000dd962000e8f565b5b80604052505050565b600062000df08262000d37565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141562000e265762000e2562000e31565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f496e76616c696420706179656500000000000000000000000000000000000000600082015250565b7f52656163686564206d617820636f6e66696775726174696f6e73000000000000600082015250565b7f546f6f206d616e7920636f6e66696775726174696f6e73000000000000000000600082015250565b7f56616c756520696e636f6d70617469626c652077697468206d61736b00000000600082015250565b7f4d61736b7320646f6e2774206d617463682076616c7565730000000000000000600082015250565b7f496e76616c696420726f79616c74790000000000000000000000000000000000600082015250565b7f4d61736b2063616e2774206265207a65726f0000000000000000000000000000600082015250565b62000ff98162000d03565b81146200100557600080fd5b50565b620010138162000d37565b81146200101f57600080fd5b50565b615b8080620010326000396000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c806366e8fbf311610130578063a217fddf116100b8578063d547741f1161007c578063d547741f14610689578063dbd0cba0146106a5578063dd3202e2146106c3578063e985e9c5146106df578063faac63151461070f57610227565b8063a217fddf146105e5578063a22cb46514610603578063b88d4fde1461061f578063c87b56dd1461063b578063d53913931461066b57610227565b8063725b093a116100ff578063725b093a146105415780638de036d01461055d57806391d148541461057b57806395d89b41146105ab578063a1448194146105c957610227565b806366e8fbf3146104a65780636704c624146104c45780636dfcb19b146104e057806370a082311461051157610227565b8063326e886d116101b357806342842e0e1161018257806342842e0e146103f057806343ab7ec31461040c57806344f79eb91461043e5780636352211e1461045a57806364e779b11461048a57610227565b8063326e886d1461037d57806336568abe1461039c57806340c10f19146103b85780634189fe9f146103d457610227565b80630c2b190c116101fa5780630c2b190c146102c657806323b872dd146102e4578063248a9ca3146103005780632a55205a146103305780632f2ff15d1461036157610227565b806301ffc9a71461022c57806306fdde031461025c578063081812fc1461027a578063095ea7b3146102aa575b600080fd5b61024660048036038101906102419190613e82565b61072d565b60405161025391906148a9565b60405180910390f35b61026461075f565b60405161027191906148df565b60405180910390f35b610294600480360381019061028f9190613ed4565b6107f1565b6040516102a191906147d5565b60405180910390f35b6102c460048036038101906102bf9190613cb2565b610876565b005b6102ce61098e565b6040516102db91906148c4565b60405180910390f35b6102fe60048036038101906102f99190613bac565b6109b2565b005b61031a60048036038101906103159190613e1d565b610a12565b60405161032791906148c4565b60405180910390f35b61034a60048036038101906103459190613f39565b610a32565b60405161035892919061483c565b60405180910390f35b61037b60048036038101906103769190613e46565b610c51565b005b610385610c7a565b604051610393929190614d3c565b60405180910390f35b6103b660048036038101906103b19190613e46565b610cbb565b005b6103d260048036038101906103cd9190613cb2565b610d3e565b005b6103ee60048036038101906103e99190613cee565b610e04565b005b61040a60048036038101906104059190613bac565b610e65565b005b61042660048036038101906104219190613ed4565b610e85565b60405161043593929190614da9565b60405180910390f35b61045860048036038101906104539190613d5a565b610f42565b005b610474600480360381019061046f9190613ed4565b610fa7565b60405161048191906147d5565b60405180910390f35b6104a4600480360381019061049f9190613ed4565b611059565b005b6104ae6110d5565b6040516104bb9190614887565b60405180910390f35b6104de60048036038101906104d99190613f39565b6110e4565b005b6104fa60048036038101906104f59190613ed4565b611145565b604051610508929190614d80565b60405180910390f35b61052b60048036038101906105269190613b47565b611179565b6040516105389190614d65565b60405180910390f35b61055b60048036038101906105569190613efd565b611231565b005b610565611292565b6040516105729190614d21565b60405180910390f35b61059560048036038101906105909190613e46565b6112a7565b6040516105a291906148a9565b60405180910390f35b6105b3611312565b6040516105c091906148df565b60405180910390f35b6105e360048036038101906105de9190613cb2565b6113a4565b005b6105ed61146a565b6040516105fa91906148c4565b60405180910390f35b61061d60048036038101906106189190613c76565b611471565b005b61063960048036038101906106349190613bfb565b611487565b005b61065560048036038101906106509190613ed4565b6114e9565b60405161066291906148df565b60405180910390f35b610673611590565b60405161068091906148c4565b60405180910390f35b6106a3600480360381019061069e9190613e46565b6115b4565b005b6106ad6115dd565b6040516106ba9190614d21565b60405180910390f35b6106dd60048036038101906106d89190613f75565b611670565b005b6106f960048036038101906106f49190613b70565b6116d5565b60405161070691906148a9565b60405180910390f35b610717611769565b6040516107249190614865565b60405180910390f35b600061073882611778565b8061074857506107478261178a565b5b80610758575061075782611804565b5b9050919050565b60606000805461076e906151a4565b80601f016020809104026020016040519081016040528092919081815260200182805461079a906151a4565b80156107e75780601f106107bc576101008083540402835291602001916107e7565b820191906000526020600020905b8154815290600101906020018083116107ca57829003601f168201915b5050505050905090565b60006107fc8261187e565b61083b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083290614b21565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061088182610fa7565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156108f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e990614ba1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109116118ea565b73ffffffffffffffffffffffffffffffffffffffff161480610940575061093f8161093a6118ea565b6116d5565b5b61097f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097690614a81565b60405180910390fd5b61098983836118f2565b505050565b7fc47c7929930c7f2bb9db31476e47def40882b518b18186f92b9e275b3dae4d1881565b6109c36109bd6118ea565b826119ab565b610a02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f990614bc1565b60405180910390fd5b610a0d838383611a89565b505050565b600060096000838152602001908152602001600020600101549050919050565b600080600060076040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050610ac76137ff565b60006008805490501115610c1d5760006001600880549050610ae99190615024565b90505b60008112610c1b5760088181548110610b2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282016040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152505091508160200151826000015188161415610c085781604001519250610c1b565b8080610c1390615131565b915050610aec565b505b81602001519350612710826000015162ffffff1686610c3c9190614fca565b610c469190614f99565b925050509250929050565b610c5a82610a12565b610c6b81610c666118ea565b611ce5565b610c758383611d82565b505050565b60078060000160009054906101000a900462ffffff16908060000160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b610cc36118ea565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2790614ce1565b60405180910390fd5b610d3a8282611e63565b5050565b610d6f7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d6a6118ea565b6112a7565b610dae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da590614961565b60405180910390fd5b610db781611f45565b610df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ded90614c81565b60405180910390fd5b610e008282612019565b5050565b610e186000801b610e136118ea565b6112a7565b610e57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4e90614c21565b60405180910390fd5b610e6182826120c8565b5050565b610e8083838360405180602001604052806000815250611487565b505050565b60088181548110610e9557600080fd5b9060005260206000209060030201600091509050806000015490806001015490806002016040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050905083565b610f566000801b610f516118ea565b6112a7565b610f95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8c90614c21565b60405180910390fd5b610fa18484848461220d565b50505050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611050576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104790614ac1565b60405180910390fd5b80915050919050565b61108a7fc47c7929930c7f2bb9db31476e47def40882b518b18186f92b9e275b3dae4d186110856118ea565b6112a7565b6110c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c090614a01565b60405180910390fd5b6110d281612419565b50565b60606110df6124a4565b905090565b6110f86000801b6110f36118ea565b6112a7565b611137576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112e90614c21565b60405180910390fd5b61114182826125a4565b5050565b6006818154811061115557600080fd5b90600052602060002090600202016000915090508060000154908060010154905082565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e190614aa1565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6112456000801b6112406118ea565b6112a7565b611284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127b90614c21565b60405180910390fd5b61128e8282612650565b5050565b61129a613826565b6112a26115dd565b905090565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060018054611321906151a4565b80601f016020809104026020016040519081016040528092919081815260200182805461134d906151a4565b801561139a5780601f1061136f5761010080835404028352916020019161139a565b820191906000526020600020905b81548152906001019060200180831161137d57829003601f168201915b5050505050905090565b6113d57f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66113d06118ea565b6112a7565b611414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140b90614961565b60405180910390fd5b61141d81611f45565b61145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145390614c81565b60405180910390fd5b61146682826127aa565b5050565b6000801b81565b61148361147c6118ea565b8383612869565b5050565b6114986114926118ea565b836119ab565b6114d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ce90614bc1565b60405180910390fd5b6114e3848484846129d6565b50505050565b60606114f48261187e565b611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161152a90614b61565b60405180910390fd5b600061153d612a32565b9050600081511161155d5760405180602001604052806000815250611588565b8061156784612ac4565b604051602001611578929190614777565b6040516020818303038152906040525b915050919050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6115bd82610a12565b6115ce816115c96118ea565b611ce5565b6115d88383611e63565b505050565b6115e5613826565b60076040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050905090565b6116846000801b61167f6118ea565b6112a7565b6116c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ba90614c21565b60405180910390fd5b6116cf84848484612c71565b50505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060611773612d85565b905090565b600061178382612df8565b9050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806117fd57506117fc82611778565b5b9050919050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061187757506118768261178a565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661196583610fa7565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006119b68261187e565b6119f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ec90614a61565b60405180910390fd5b6000611a0083610fa7565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611a6f57508373ffffffffffffffffffffffffffffffffffffffff16611a57846107f1565b73ffffffffffffffffffffffffffffffffffffffff16145b80611a805750611a7f81856116d5565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611aa982610fa7565b73ffffffffffffffffffffffffffffffffffffffff1614611aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af690614b41565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b66906149c1565b60405180910390fd5b611b7a838383612eda565b611b856000826118f2565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611bd59190615024565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611c2c9190614f43565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b611cef82826112a7565b611d7e57611d148173ffffffffffffffffffffffffffffffffffffffff166014612edf565b611d228360001c6020612edf565b604051602001611d3392919061479b565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7591906148df565b60405180910390fd5b5050565b611d8c82826112a7565b611e5f5760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611e046118ea565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b611e6d82826112a7565b15611f415760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611ee66118ea565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b60008060068054905011156120065760005b60068054905081101561200057600060068281548110611fa0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505090508060200151816000015185161415611fec57600192505050612014565b508080611ff890615207565b915050611f57565b5061200f565b60019050612014565b600090505b919050565b60006120248261187e565b905080156120b857600061203783610fa7565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209e90614921565b60405180910390fd5b6120b2308585611a89565b506120c3565b6120c283836131d9565b5b505050565b805182511461210c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210390614c41565b60405180910390fd5b606482511115612151576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214890614be1565b60405180910390fd5b6006600061215f919061385b565b60005b8251811015612208576121f58382815181106121a7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518383815181106121e8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516125a4565b808061220090615207565b915050612162565b505050565b8251845114612251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224890614ae1565b60405180910390fd5b8151845114612295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228c90614a41565b60405180910390fd5b80518451146122d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d090614cc1565b60405180910390fd5b600860006122e7919061387f565b60005b8451811015612412576123ff85828151811061232f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110612370577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518584815181106123b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518585815181106123f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151612c71565b808061240a90615207565b9150506122ea565b5050505050565b600061242482610fa7565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612495576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248c90614ca1565b60405180910390fd5b6124a0813084611a89565b5050565b60606008805480602002602001604051908101604052809291908181526020016000905b8282101561259b57838290600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282016040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081525050815260200190600101906124c8565b50505050905090565b6064600680549050106125ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e390614b81565b60405180910390fd5b6125f682826133a7565b60066040518060400160405280848152602001838152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550505050565b6107d0821115612695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268c90614c61565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612705576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126fc90614a21565b60405180910390fd5b60405180604001604052808362ffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815250600760008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050505050565b60006127b58261187e565b905080156128595760006127c883610fa7565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282f90614921565b60405180910390fd5b612853308585604051806020016040528060008152506129d6565b50612864565b6128638383613431565b5b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156128d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128cf906149e1565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516129c991906148a9565b60405180910390a3505050565b6129e1848484611a89565b6129ed8484848461344f565b612a2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a2390614981565b60405180910390fd5b50505050565b6060600a8054612a41906151a4565b80601f0160208091040260200160405190810160405280929190818152602001828054612a6d906151a4565b8015612aba5780601f10612a8f57610100808354040283529160200191612aba565b820191906000526020600020905b815481529060010190602001808311612a9d57829003601f168201915b5050505050905090565b60606000821415612b0c576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612c6c565b600082905060005b60008214612b3e578080612b2790615207565b915050600a82612b379190614f99565b9150612b14565b60008167ffffffffffffffff811115612b80577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612bb25781602001600182028036833780820191505090505b5090505b60008514612c6557600182612bcb9190615024565b9150600a85612bda9190615250565b6030612be69190614f43565b60f81b818381518110612c22577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612c5e9190614f99565b9450612bb6565b8093505050505b919050565b612c7d848484846135e6565b6008604051806060016040528086815260200185815260200160405180604001604052808662ffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152508152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001556020820151816001015560408201518160020160008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050505050565b60606006805480602002602001604051908101604052809291908181526020016000905b82821015612def57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190612da9565b50505050905090565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612ec357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612ed35750612ed282613727565b5b9050919050565b505050565b606060006002836002612ef29190614fca565b612efc9190614f43565b67ffffffffffffffff811115612f3b577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612f6d5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612fcb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613055577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026130959190614fca565b61309f9190614f43565b90505b600181111561318b577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110613107577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b828281518110613144577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806131849061517a565b90506130a2565b50600084146131cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131c690614901565b60405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324090614b01565b60405180910390fd5b6132528161187e565b15613292576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613289906149a1565b60405180910390fd5b61329e60008383612eda565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546132ee9190614f43565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600082116133ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133e190614d01565b60405180910390fd5b8181111561342d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161342490614c01565b60405180910390fd5b5050565b61344b828260405180602001604052806000815250613791565b5050565b60006134708473ffffffffffffffffffffffffffffffffffffffff166137ec565b156135d9578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026134996118ea565b8786866040518563ffffffff1660e01b81526004016134bb94939291906147f0565b602060405180830381600087803b1580156134d557600080fd5b505af192505050801561350657506040513d601f19601f820116820180604052508101906135039190613eab565b60015b613589573d8060008114613536576040519150601f19603f3d011682016040523d82523d6000602084013e61353b565b606091505b50600081511415613581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161357890614981565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506135de565b600190505b949350505050565b60008411613629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161362090614941565b60405180910390fd5b8383111561366c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161366390614c01565b60405180910390fd5b6107d08211156136b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136a890614c61565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161371890614a21565b60405180910390fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61379b83836131d9565b6137a8600084848461344f565b6137e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137de90614981565b60405180910390fd5b505050565b600080823b905060008111915050919050565b60405180606001604052806000815260200160008152602001613820613826565b81525090565b6040518060400160405280600062ffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b508054600082556002029060005260206000209081019061387c91906138a3565b50565b50805460008255600302906000526020600020908101906138a091906138ca565b50565b5b808211156138c6576000808201600090556001820160009055506002016138a4565b5090565b5b8082111561393157600080820160009055600182016000905560028201600080820160006101000a81549062ffffff02191690556000820160036101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050506003016138cb565b5090565b600061394861394384614e05565b614de0565b9050808382526020820190508285602086028201111561396757600080fd5b60005b85811015613997578161397d8882613a4b565b84526020840193506020830192505060018101905061396a565b5050509392505050565b60006139b46139af84614e31565b614de0565b905080838252602082019050828560208602820111156139d357600080fd5b60005b85811015613a0357816139e98882613b32565b8452602084019350602083019250506001810190506139d6565b5050509392505050565b6000613a20613a1b84614e5d565b614de0565b905082815260208101848484011115613a3857600080fd5b613a438482856150ef565b509392505050565b600081359050613a5a81615ad7565b92915050565b600082601f830112613a7157600080fd5b8135613a81848260208601613935565b91505092915050565b600082601f830112613a9b57600080fd5b8135613aab8482602086016139a1565b91505092915050565b600081359050613ac381615aee565b92915050565b600081359050613ad881615b05565b92915050565b600081359050613aed81615b1c565b92915050565b600081519050613b0281615b1c565b92915050565b600082601f830112613b1957600080fd5b8135613b29848260208601613a0d565b91505092915050565b600081359050613b4181615b33565b92915050565b600060208284031215613b5957600080fd5b6000613b6784828501613a4b565b91505092915050565b60008060408385031215613b8357600080fd5b6000613b9185828601613a4b565b9250506020613ba285828601613a4b565b9150509250929050565b600080600060608486031215613bc157600080fd5b6000613bcf86828701613a4b565b9350506020613be086828701613a4b565b9250506040613bf186828701613b32565b9150509250925092565b60008060008060808587031215613c1157600080fd5b6000613c1f87828801613a4b565b9450506020613c3087828801613a4b565b9350506040613c4187828801613b32565b925050606085013567ffffffffffffffff811115613c5e57600080fd5b613c6a87828801613b08565b91505092959194509250565b60008060408385031215613c8957600080fd5b6000613c9785828601613a4b565b9250506020613ca885828601613ab4565b9150509250929050565b60008060408385031215613cc557600080fd5b6000613cd385828601613a4b565b9250506020613ce485828601613b32565b9150509250929050565b60008060408385031215613d0157600080fd5b600083013567ffffffffffffffff811115613d1b57600080fd5b613d2785828601613a8a565b925050602083013567ffffffffffffffff811115613d4457600080fd5b613d5085828601613a8a565b9150509250929050565b60008060008060808587031215613d7057600080fd5b600085013567ffffffffffffffff811115613d8a57600080fd5b613d9687828801613a8a565b945050602085013567ffffffffffffffff811115613db357600080fd5b613dbf87828801613a8a565b935050604085013567ffffffffffffffff811115613ddc57600080fd5b613de887828801613a8a565b925050606085013567ffffffffffffffff811115613e0557600080fd5b613e1187828801613a60565b91505092959194509250565b600060208284031215613e2f57600080fd5b6000613e3d84828501613ac9565b91505092915050565b60008060408385031215613e5957600080fd5b6000613e6785828601613ac9565b9250506020613e7885828601613a4b565b9150509250929050565b600060208284031215613e9457600080fd5b6000613ea284828501613ade565b91505092915050565b600060208284031215613ebd57600080fd5b6000613ecb84828501613af3565b91505092915050565b600060208284031215613ee657600080fd5b6000613ef484828501613b32565b91505092915050565b60008060408385031215613f1057600080fd5b6000613f1e85828601613b32565b9250506020613f2f85828601613a4b565b9150509250929050565b60008060408385031215613f4c57600080fd5b6000613f5a85828601613b32565b9250506020613f6b85828601613b32565b9150509250929050565b60008060008060808587031215613f8b57600080fd5b6000613f9987828801613b32565b9450506020613faa87828801613b32565b9350506040613fbb87828801613b32565b9250506060613fcc87828801613a4b565b91505092959194509250565b6000613fe4838361466c565b60408301905092915050565b6000613ffc83836146f9565b60808301905092915050565b61401181615058565b82525050565b61402081615058565b82525050565b600061403182614eae565b61403b8185614ef4565b935061404683614e8e565b8060005b8381101561407757815161405e8882613fd8565b975061406983614eda565b92505060018101905061404a565b5085935050505092915050565b600061408f82614eb9565b6140998185614f05565b93506140a483614e9e565b8060005b838110156140d55781516140bc8882613ff0565b97506140c783614ee7565b9250506001810190506140a8565b5085935050505092915050565b6140eb8161506a565b82525050565b6140fa81615076565b82525050565b600061410b82614ec4565b6141158185614f16565b93506141258185602086016150fe565b61412e8161533d565b840191505092915050565b600061414482614ecf565b61414e8185614f27565b935061415e8185602086016150fe565b6141678161533d565b840191505092915050565b600061417d82614ecf565b6141878185614f38565b93506141978185602086016150fe565b80840191505092915050565b60006141b0602083614f27565b91506141bb8261534e565b602082019050919050565b60006141d3600e83614f27565b91506141de82615377565b602082019050919050565b60006141f6600c83614f27565b9150614201826153a0565b602082019050919050565b6000614219600c83614f27565b9150614224826153c9565b602082019050919050565b600061423c603283614f27565b9150614247826153f2565b604082019050919050565b600061425f601c83614f27565b915061426a82615441565b602082019050919050565b6000614282602483614f27565b915061428d8261546a565b604082019050919050565b60006142a5601983614f27565b91506142b0826154b9565b602082019050919050565b60006142c8600f83614f27565b91506142d3826154e2565b602082019050919050565b60006142eb600d83614f27565b91506142f68261550b565b602082019050919050565b600061430e602683614f27565b915061431982615534565b604082019050919050565b6000614331602c83614f27565b915061433c82615583565b604082019050919050565b6000614354603883614f27565b915061435f826155d2565b604082019050919050565b6000614377602a83614f27565b915061438282615621565b604082019050919050565b600061439a602983614f27565b91506143a582615670565b604082019050919050565b60006143bd602083614f27565b91506143c8826156bf565b602082019050919050565b60006143e0602083614f27565b91506143eb826156e8565b602082019050919050565b6000614403602c83614f27565b915061440e82615711565b604082019050919050565b6000614426602983614f27565b915061443182615760565b604082019050919050565b6000614449602f83614f27565b9150614454826157af565b604082019050919050565b600061446c601a83614f27565b9150614477826157fe565b602082019050919050565b600061448f602183614f27565b915061449a82615827565b604082019050919050565b60006144b2603183614f27565b91506144bd82615876565b604082019050919050565b60006144d5601783614f27565b91506144e0826158c5565b602082019050919050565b60006144f8601c83614f27565b9150614503826158ee565b602082019050919050565b600061451b600c83614f27565b915061452682615917565b602082019050919050565b600061453e601883614f27565b915061454982615940565b602082019050919050565b6000614561601783614f38565b915061456c82615969565b601782019050919050565b6000614584600f83614f27565b915061458f82615992565b602082019050919050565b60006145a7601483614f27565b91506145b2826159bb565b602082019050919050565b60006145ca601083614f27565b91506145d5826159e4565b602082019050919050565b60006145ed602083614f27565b91506145f882615a0d565b602082019050919050565b6000614610601183614f38565b915061461b82615a36565b601182019050919050565b6000614633602f83614f27565b915061463e82615a5f565b604082019050919050565b6000614656601283614f27565b915061466182615aae565b602082019050919050565b6040820160008201516146826000850182614759565b5060208201516146956020850182614759565b50505050565b6040820160008201516146b1600085018261473b565b5060208201516146c46020850182614008565b50505050565b6040820160008201516146e0600085018261473b565b5060208201516146f36020850182614008565b50505050565b60808201600082015161470f6000850182614759565b5060208201516147226020850182614759565b506040820151614735604085018261469b565b50505050565b614744816150d6565b82525050565b614753816150d6565b82525050565b614762816150e5565b82525050565b614771816150e5565b82525050565b60006147838285614172565b915061478f8284614172565b91508190509392505050565b60006147a682614554565b91506147b28285614172565b91506147bd82614603565b91506147c98284614172565b91508190509392505050565b60006020820190506147ea6000830184614017565b92915050565b60006080820190506148056000830187614017565b6148126020830186614017565b61481f6040830185614768565b81810360608301526148318184614100565b905095945050505050565b60006040820190506148516000830185614017565b61485e6020830184614768565b9392505050565b6000602082019050818103600083015261487f8184614026565b905092915050565b600060208201905081810360008301526148a18184614084565b905092915050565b60006020820190506148be60008301846140e2565b92915050565b60006020820190506148d960008301846140f1565b92915050565b600060208201905081810360008301526148f98184614139565b905092915050565b6000602082019050818103600083015261491a816141a3565b9050919050565b6000602082019050818103600083015261493a816141c6565b9050919050565b6000602082019050818103600083015261495a816141e9565b9050919050565b6000602082019050818103600083015261497a8161420c565b9050919050565b6000602082019050818103600083015261499a8161422f565b9050919050565b600060208201905081810360008301526149ba81614252565b9050919050565b600060208201905081810360008301526149da81614275565b9050919050565b600060208201905081810360008301526149fa81614298565b9050919050565b60006020820190508181036000830152614a1a816142bb565b9050919050565b60006020820190508181036000830152614a3a816142de565b9050919050565b60006020820190508181036000830152614a5a81614301565b9050919050565b60006020820190508181036000830152614a7a81614324565b9050919050565b60006020820190508181036000830152614a9a81614347565b9050919050565b60006020820190508181036000830152614aba8161436a565b9050919050565b60006020820190508181036000830152614ada8161438d565b9050919050565b60006020820190508181036000830152614afa816143b0565b9050919050565b60006020820190508181036000830152614b1a816143d3565b9050919050565b60006020820190508181036000830152614b3a816143f6565b9050919050565b60006020820190508181036000830152614b5a81614419565b9050919050565b60006020820190508181036000830152614b7a8161443c565b9050919050565b60006020820190508181036000830152614b9a8161445f565b9050919050565b60006020820190508181036000830152614bba81614482565b9050919050565b60006020820190508181036000830152614bda816144a5565b9050919050565b60006020820190508181036000830152614bfa816144c8565b9050919050565b60006020820190508181036000830152614c1a816144eb565b9050919050565b60006020820190508181036000830152614c3a8161450e565b9050919050565b60006020820190508181036000830152614c5a81614531565b9050919050565b60006020820190508181036000830152614c7a81614577565b9050919050565b60006020820190508181036000830152614c9a8161459a565b9050919050565b60006020820190508181036000830152614cba816145bd565b9050919050565b60006020820190508181036000830152614cda816145e0565b9050919050565b60006020820190508181036000830152614cfa81614626565b9050919050565b60006020820190508181036000830152614d1a81614649565b9050919050565b6000604082019050614d3660008301846146ca565b92915050565b6000604082019050614d51600083018561474a565b614d5e6020830184614017565b9392505050565b6000602082019050614d7a6000830184614768565b92915050565b6000604082019050614d956000830185614768565b614da26020830184614768565b9392505050565b6000608082019050614dbe6000830186614768565b614dcb6020830185614768565b614dd860408301846146ca565b949350505050565b6000614dea614dfb565b9050614df682826151d6565b919050565b6000604051905090565b600067ffffffffffffffff821115614e2057614e1f61530e565b5b602082029050602081019050919050565b600067ffffffffffffffff821115614e4c57614e4b61530e565b5b602082029050602081019050919050565b600067ffffffffffffffff821115614e7857614e7761530e565b5b614e818261533d565b9050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614f4e826150e5565b9150614f59836150e5565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614f8e57614f8d615281565b5b828201905092915050565b6000614fa4826150e5565b9150614faf836150e5565b925082614fbf57614fbe6152b0565b5b828204905092915050565b6000614fd5826150e5565b9150614fe0836150e5565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561501957615018615281565b5b828202905092915050565b600061502f826150e5565b915061503a836150e5565b92508282101561504d5761504c615281565b5b828203905092915050565b6000615063826150b6565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561511c578082015181840152602081019050615101565b8381111561512b576000848401525b50505050565b600061513c826150ac565b91507f800000000000000000000000000000000000000000000000000000000000000082141561516f5761516e615281565b5b600182039050919050565b6000615185826150e5565b9150600082141561519957615198615281565b5b600182039050919050565b600060028204905060018216806151bc57607f821691505b602082108114156151d0576151cf6152df565b5b50919050565b6151df8261533d565b810181811067ffffffffffffffff821117156151fe576151fd61530e565b5b80604052505050565b6000615212826150e5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561524557615244615281565b5b600182019050919050565b600061525b826150e5565b9150615266836150e5565b925082615276576152756152b0565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f416c7265616479206d696e746564000000000000000000000000000000000000600082015250565b7f496e76616c6964206d61736b0000000000000000000000000000000000000000600082015250565b7f4e6f742061204d696e7465720000000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4e6f7420616e20556e6d696e7465720000000000000000000000000000000000600082015250565b7f496e76616c696420706179656500000000000000000000000000000000000000600082015250565b7f526f79616c7479206d61736b7320646f6e2774206d617463682062617369732060008201527f706f696e74730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f526f79616c7479206d61736b7320646f6e2774206d617463682076616c756573600082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f52656163686564206d617820636f6e66696775726174696f6e73000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f546f6f206d616e7920636f6e66696775726174696f6e73000000000000000000600082015250565b7f56616c756520696e636f6d70617469626c652077697468206d61736b00000000600082015250565b7f4e6f7420616e2041646d696e0000000000000000000000000000000000000000600082015250565b7f4d61736b7320646f6e2774206d617463682076616c7565730000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f496e76616c696420726f79616c74790000000000000000000000000000000000600082015250565b7f546f6b656e204944206e6f7420616c6c6f776564000000000000000000000000600082015250565b7f416c726561647920756e6d696e74656400000000000000000000000000000000600082015250565b7f526f79616c7479206d61736b7320646f6e2774206d6174636820706179656573600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f4d61736b2063616e2774206265207a65726f0000000000000000000000000000600082015250565b615ae081615058565b8114615aeb57600080fd5b50565b615af78161506a565b8114615b0257600080fd5b50565b615b0e81615076565b8114615b1957600080fd5b50565b615b2581615080565b8114615b3057600080fd5b50565b615b3c816150e5565b8114615b4757600080fd5b5056fea2646970667358221220a122a2c813c4b29bbf618f87d7db0d73e907e93c7c04220ff9e9430b717b584964736f6c6343000804003300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000003520074f2f32007f4b401c09deab5994233ab909000000000000000000000000000000000000000000000000000000000000001351756964644d696e7461626c65734174617269000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003514d410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003468747470733a2f2f6170692d70726f642e6f6e71756964642e636f6d2f7072696e74732f6d696e7465642f6d657461646174612f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100e0000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102275760003560e01c806366e8fbf311610130578063a217fddf116100b8578063d547741f1161007c578063d547741f14610689578063dbd0cba0146106a5578063dd3202e2146106c3578063e985e9c5146106df578063faac63151461070f57610227565b8063a217fddf146105e5578063a22cb46514610603578063b88d4fde1461061f578063c87b56dd1461063b578063d53913931461066b57610227565b8063725b093a116100ff578063725b093a146105415780638de036d01461055d57806391d148541461057b57806395d89b41146105ab578063a1448194146105c957610227565b806366e8fbf3146104a65780636704c624146104c45780636dfcb19b146104e057806370a082311461051157610227565b8063326e886d116101b357806342842e0e1161018257806342842e0e146103f057806343ab7ec31461040c57806344f79eb91461043e5780636352211e1461045a57806364e779b11461048a57610227565b8063326e886d1461037d57806336568abe1461039c57806340c10f19146103b85780634189fe9f146103d457610227565b80630c2b190c116101fa5780630c2b190c146102c657806323b872dd146102e4578063248a9ca3146103005780632a55205a146103305780632f2ff15d1461036157610227565b806301ffc9a71461022c57806306fdde031461025c578063081812fc1461027a578063095ea7b3146102aa575b600080fd5b61024660048036038101906102419190613e82565b61072d565b60405161025391906148a9565b60405180910390f35b61026461075f565b60405161027191906148df565b60405180910390f35b610294600480360381019061028f9190613ed4565b6107f1565b6040516102a191906147d5565b60405180910390f35b6102c460048036038101906102bf9190613cb2565b610876565b005b6102ce61098e565b6040516102db91906148c4565b60405180910390f35b6102fe60048036038101906102f99190613bac565b6109b2565b005b61031a60048036038101906103159190613e1d565b610a12565b60405161032791906148c4565b60405180910390f35b61034a60048036038101906103459190613f39565b610a32565b60405161035892919061483c565b60405180910390f35b61037b60048036038101906103769190613e46565b610c51565b005b610385610c7a565b604051610393929190614d3c565b60405180910390f35b6103b660048036038101906103b19190613e46565b610cbb565b005b6103d260048036038101906103cd9190613cb2565b610d3e565b005b6103ee60048036038101906103e99190613cee565b610e04565b005b61040a60048036038101906104059190613bac565b610e65565b005b61042660048036038101906104219190613ed4565b610e85565b60405161043593929190614da9565b60405180910390f35b61045860048036038101906104539190613d5a565b610f42565b005b610474600480360381019061046f9190613ed4565b610fa7565b60405161048191906147d5565b60405180910390f35b6104a4600480360381019061049f9190613ed4565b611059565b005b6104ae6110d5565b6040516104bb9190614887565b60405180910390f35b6104de60048036038101906104d99190613f39565b6110e4565b005b6104fa60048036038101906104f59190613ed4565b611145565b604051610508929190614d80565b60405180910390f35b61052b60048036038101906105269190613b47565b611179565b6040516105389190614d65565b60405180910390f35b61055b60048036038101906105569190613efd565b611231565b005b610565611292565b6040516105729190614d21565b60405180910390f35b61059560048036038101906105909190613e46565b6112a7565b6040516105a291906148a9565b60405180910390f35b6105b3611312565b6040516105c091906148df565b60405180910390f35b6105e360048036038101906105de9190613cb2565b6113a4565b005b6105ed61146a565b6040516105fa91906148c4565b60405180910390f35b61061d60048036038101906106189190613c76565b611471565b005b61063960048036038101906106349190613bfb565b611487565b005b61065560048036038101906106509190613ed4565b6114e9565b60405161066291906148df565b60405180910390f35b610673611590565b60405161068091906148c4565b60405180910390f35b6106a3600480360381019061069e9190613e46565b6115b4565b005b6106ad6115dd565b6040516106ba9190614d21565b60405180910390f35b6106dd60048036038101906106d89190613f75565b611670565b005b6106f960048036038101906106f49190613b70565b6116d5565b60405161070691906148a9565b60405180910390f35b610717611769565b6040516107249190614865565b60405180910390f35b600061073882611778565b8061074857506107478261178a565b5b80610758575061075782611804565b5b9050919050565b60606000805461076e906151a4565b80601f016020809104026020016040519081016040528092919081815260200182805461079a906151a4565b80156107e75780601f106107bc576101008083540402835291602001916107e7565b820191906000526020600020905b8154815290600101906020018083116107ca57829003601f168201915b5050505050905090565b60006107fc8261187e565b61083b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083290614b21565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061088182610fa7565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156108f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e990614ba1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109116118ea565b73ffffffffffffffffffffffffffffffffffffffff161480610940575061093f8161093a6118ea565b6116d5565b5b61097f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097690614a81565b60405180910390fd5b61098983836118f2565b505050565b7fc47c7929930c7f2bb9db31476e47def40882b518b18186f92b9e275b3dae4d1881565b6109c36109bd6118ea565b826119ab565b610a02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f990614bc1565b60405180910390fd5b610a0d838383611a89565b505050565b600060096000838152602001908152602001600020600101549050919050565b600080600060076040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050610ac76137ff565b60006008805490501115610c1d5760006001600880549050610ae99190615024565b90505b60008112610c1b5760088181548110610b2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282016040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152505091508160200151826000015188161415610c085781604001519250610c1b565b8080610c1390615131565b915050610aec565b505b81602001519350612710826000015162ffffff1686610c3c9190614fca565b610c469190614f99565b925050509250929050565b610c5a82610a12565b610c6b81610c666118ea565b611ce5565b610c758383611d82565b505050565b60078060000160009054906101000a900462ffffff16908060000160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b610cc36118ea565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2790614ce1565b60405180910390fd5b610d3a8282611e63565b5050565b610d6f7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d6a6118ea565b6112a7565b610dae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da590614961565b60405180910390fd5b610db781611f45565b610df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ded90614c81565b60405180910390fd5b610e008282612019565b5050565b610e186000801b610e136118ea565b6112a7565b610e57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4e90614c21565b60405180910390fd5b610e6182826120c8565b5050565b610e8083838360405180602001604052806000815250611487565b505050565b60088181548110610e9557600080fd5b9060005260206000209060030201600091509050806000015490806001015490806002016040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050905083565b610f566000801b610f516118ea565b6112a7565b610f95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8c90614c21565b60405180910390fd5b610fa18484848461220d565b50505050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611050576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104790614ac1565b60405180910390fd5b80915050919050565b61108a7fc47c7929930c7f2bb9db31476e47def40882b518b18186f92b9e275b3dae4d186110856118ea565b6112a7565b6110c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c090614a01565b60405180910390fd5b6110d281612419565b50565b60606110df6124a4565b905090565b6110f86000801b6110f36118ea565b6112a7565b611137576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112e90614c21565b60405180910390fd5b61114182826125a4565b5050565b6006818154811061115557600080fd5b90600052602060002090600202016000915090508060000154908060010154905082565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e190614aa1565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6112456000801b6112406118ea565b6112a7565b611284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127b90614c21565b60405180910390fd5b61128e8282612650565b5050565b61129a613826565b6112a26115dd565b905090565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060018054611321906151a4565b80601f016020809104026020016040519081016040528092919081815260200182805461134d906151a4565b801561139a5780601f1061136f5761010080835404028352916020019161139a565b820191906000526020600020905b81548152906001019060200180831161137d57829003601f168201915b5050505050905090565b6113d57f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66113d06118ea565b6112a7565b611414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140b90614961565b60405180910390fd5b61141d81611f45565b61145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145390614c81565b60405180910390fd5b61146682826127aa565b5050565b6000801b81565b61148361147c6118ea565b8383612869565b5050565b6114986114926118ea565b836119ab565b6114d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ce90614bc1565b60405180910390fd5b6114e3848484846129d6565b50505050565b60606114f48261187e565b611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161152a90614b61565b60405180910390fd5b600061153d612a32565b9050600081511161155d5760405180602001604052806000815250611588565b8061156784612ac4565b604051602001611578929190614777565b6040516020818303038152906040525b915050919050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6115bd82610a12565b6115ce816115c96118ea565b611ce5565b6115d88383611e63565b505050565b6115e5613826565b60076040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050905090565b6116846000801b61167f6118ea565b6112a7565b6116c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ba90614c21565b60405180910390fd5b6116cf84848484612c71565b50505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060611773612d85565b905090565b600061178382612df8565b9050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806117fd57506117fc82611778565b5b9050919050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061187757506118768261178a565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661196583610fa7565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006119b68261187e565b6119f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ec90614a61565b60405180910390fd5b6000611a0083610fa7565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611a6f57508373ffffffffffffffffffffffffffffffffffffffff16611a57846107f1565b73ffffffffffffffffffffffffffffffffffffffff16145b80611a805750611a7f81856116d5565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611aa982610fa7565b73ffffffffffffffffffffffffffffffffffffffff1614611aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af690614b41565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b66906149c1565b60405180910390fd5b611b7a838383612eda565b611b856000826118f2565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611bd59190615024565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611c2c9190614f43565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b611cef82826112a7565b611d7e57611d148173ffffffffffffffffffffffffffffffffffffffff166014612edf565b611d228360001c6020612edf565b604051602001611d3392919061479b565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7591906148df565b60405180910390fd5b5050565b611d8c82826112a7565b611e5f5760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611e046118ea565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b611e6d82826112a7565b15611f415760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611ee66118ea565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b60008060068054905011156120065760005b60068054905081101561200057600060068281548110611fa0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505090508060200151816000015185161415611fec57600192505050612014565b508080611ff890615207565b915050611f57565b5061200f565b60019050612014565b600090505b919050565b60006120248261187e565b905080156120b857600061203783610fa7565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209e90614921565b60405180910390fd5b6120b2308585611a89565b506120c3565b6120c283836131d9565b5b505050565b805182511461210c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210390614c41565b60405180910390fd5b606482511115612151576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214890614be1565b60405180910390fd5b6006600061215f919061385b565b60005b8251811015612208576121f58382815181106121a7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518383815181106121e8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516125a4565b808061220090615207565b915050612162565b505050565b8251845114612251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224890614ae1565b60405180910390fd5b8151845114612295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228c90614a41565b60405180910390fd5b80518451146122d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d090614cc1565b60405180910390fd5b600860006122e7919061387f565b60005b8451811015612412576123ff85828151811061232f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110612370577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518584815181106123b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518585815181106123f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151612c71565b808061240a90615207565b9150506122ea565b5050505050565b600061242482610fa7565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612495576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248c90614ca1565b60405180910390fd5b6124a0813084611a89565b5050565b60606008805480602002602001604051908101604052809291908181526020016000905b8282101561259b57838290600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282016040518060400160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081525050815260200190600101906124c8565b50505050905090565b6064600680549050106125ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e390614b81565b60405180910390fd5b6125f682826133a7565b60066040518060400160405280848152602001838152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550505050565b6107d0821115612695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268c90614c61565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612705576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126fc90614a21565b60405180910390fd5b60405180604001604052808362ffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815250600760008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050505050565b60006127b58261187e565b905080156128595760006127c883610fa7565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282f90614921565b60405180910390fd5b612853308585604051806020016040528060008152506129d6565b50612864565b6128638383613431565b5b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156128d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128cf906149e1565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516129c991906148a9565b60405180910390a3505050565b6129e1848484611a89565b6129ed8484848461344f565b612a2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a2390614981565b60405180910390fd5b50505050565b6060600a8054612a41906151a4565b80601f0160208091040260200160405190810160405280929190818152602001828054612a6d906151a4565b8015612aba5780601f10612a8f57610100808354040283529160200191612aba565b820191906000526020600020905b815481529060010190602001808311612a9d57829003601f168201915b5050505050905090565b60606000821415612b0c576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612c6c565b600082905060005b60008214612b3e578080612b2790615207565b915050600a82612b379190614f99565b9150612b14565b60008167ffffffffffffffff811115612b80577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612bb25781602001600182028036833780820191505090505b5090505b60008514612c6557600182612bcb9190615024565b9150600a85612bda9190615250565b6030612be69190614f43565b60f81b818381518110612c22577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612c5e9190614f99565b9450612bb6565b8093505050505b919050565b612c7d848484846135e6565b6008604051806060016040528086815260200185815260200160405180604001604052808662ffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152508152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001556020820151816001015560408201518160020160008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050505050565b60606006805480602002602001604051908101604052809291908181526020016000905b82821015612def57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190612da9565b50505050905090565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612ec357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612ed35750612ed282613727565b5b9050919050565b505050565b606060006002836002612ef29190614fca565b612efc9190614f43565b67ffffffffffffffff811115612f3b577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612f6d5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612fcb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613055577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026130959190614fca565b61309f9190614f43565b90505b600181111561318b577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110613107577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b828281518110613144577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806131849061517a565b90506130a2565b50600084146131cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131c690614901565b60405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324090614b01565b60405180910390fd5b6132528161187e565b15613292576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613289906149a1565b60405180910390fd5b61329e60008383612eda565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546132ee9190614f43565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600082116133ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133e190614d01565b60405180910390fd5b8181111561342d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161342490614c01565b60405180910390fd5b5050565b61344b828260405180602001604052806000815250613791565b5050565b60006134708473ffffffffffffffffffffffffffffffffffffffff166137ec565b156135d9578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026134996118ea565b8786866040518563ffffffff1660e01b81526004016134bb94939291906147f0565b602060405180830381600087803b1580156134d557600080fd5b505af192505050801561350657506040513d601f19601f820116820180604052508101906135039190613eab565b60015b613589573d8060008114613536576040519150601f19603f3d011682016040523d82523d6000602084013e61353b565b606091505b50600081511415613581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161357890614981565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506135de565b600190505b949350505050565b60008411613629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161362090614941565b60405180910390fd5b8383111561366c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161366390614c01565b60405180910390fd5b6107d08211156136b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136a890614c61565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161371890614a21565b60405180910390fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61379b83836131d9565b6137a8600084848461344f565b6137e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137de90614981565b60405180910390fd5b505050565b600080823b905060008111915050919050565b60405180606001604052806000815260200160008152602001613820613826565b81525090565b6040518060400160405280600062ffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b508054600082556002029060005260206000209081019061387c91906138a3565b50565b50805460008255600302906000526020600020908101906138a091906138ca565b50565b5b808211156138c6576000808201600090556001820160009055506002016138a4565b5090565b5b8082111561393157600080820160009055600182016000905560028201600080820160006101000a81549062ffffff02191690556000820160036101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050506003016138cb565b5090565b600061394861394384614e05565b614de0565b9050808382526020820190508285602086028201111561396757600080fd5b60005b85811015613997578161397d8882613a4b565b84526020840193506020830192505060018101905061396a565b5050509392505050565b60006139b46139af84614e31565b614de0565b905080838252602082019050828560208602820111156139d357600080fd5b60005b85811015613a0357816139e98882613b32565b8452602084019350602083019250506001810190506139d6565b5050509392505050565b6000613a20613a1b84614e5d565b614de0565b905082815260208101848484011115613a3857600080fd5b613a438482856150ef565b509392505050565b600081359050613a5a81615ad7565b92915050565b600082601f830112613a7157600080fd5b8135613a81848260208601613935565b91505092915050565b600082601f830112613a9b57600080fd5b8135613aab8482602086016139a1565b91505092915050565b600081359050613ac381615aee565b92915050565b600081359050613ad881615b05565b92915050565b600081359050613aed81615b1c565b92915050565b600081519050613b0281615b1c565b92915050565b600082601f830112613b1957600080fd5b8135613b29848260208601613a0d565b91505092915050565b600081359050613b4181615b33565b92915050565b600060208284031215613b5957600080fd5b6000613b6784828501613a4b565b91505092915050565b60008060408385031215613b8357600080fd5b6000613b9185828601613a4b565b9250506020613ba285828601613a4b565b9150509250929050565b600080600060608486031215613bc157600080fd5b6000613bcf86828701613a4b565b9350506020613be086828701613a4b565b9250506040613bf186828701613b32565b9150509250925092565b60008060008060808587031215613c1157600080fd5b6000613c1f87828801613a4b565b9450506020613c3087828801613a4b565b9350506040613c4187828801613b32565b925050606085013567ffffffffffffffff811115613c5e57600080fd5b613c6a87828801613b08565b91505092959194509250565b60008060408385031215613c8957600080fd5b6000613c9785828601613a4b565b9250506020613ca885828601613ab4565b9150509250929050565b60008060408385031215613cc557600080fd5b6000613cd385828601613a4b565b9250506020613ce485828601613b32565b9150509250929050565b60008060408385031215613d0157600080fd5b600083013567ffffffffffffffff811115613d1b57600080fd5b613d2785828601613a8a565b925050602083013567ffffffffffffffff811115613d4457600080fd5b613d5085828601613a8a565b9150509250929050565b60008060008060808587031215613d7057600080fd5b600085013567ffffffffffffffff811115613d8a57600080fd5b613d9687828801613a8a565b945050602085013567ffffffffffffffff811115613db357600080fd5b613dbf87828801613a8a565b935050604085013567ffffffffffffffff811115613ddc57600080fd5b613de887828801613a8a565b925050606085013567ffffffffffffffff811115613e0557600080fd5b613e1187828801613a60565b91505092959194509250565b600060208284031215613e2f57600080fd5b6000613e3d84828501613ac9565b91505092915050565b60008060408385031215613e5957600080fd5b6000613e6785828601613ac9565b9250506020613e7885828601613a4b565b9150509250929050565b600060208284031215613e9457600080fd5b6000613ea284828501613ade565b91505092915050565b600060208284031215613ebd57600080fd5b6000613ecb84828501613af3565b91505092915050565b600060208284031215613ee657600080fd5b6000613ef484828501613b32565b91505092915050565b60008060408385031215613f1057600080fd5b6000613f1e85828601613b32565b9250506020613f2f85828601613a4b565b9150509250929050565b60008060408385031215613f4c57600080fd5b6000613f5a85828601613b32565b9250506020613f6b85828601613b32565b9150509250929050565b60008060008060808587031215613f8b57600080fd5b6000613f9987828801613b32565b9450506020613faa87828801613b32565b9350506040613fbb87828801613b32565b9250506060613fcc87828801613a4b565b91505092959194509250565b6000613fe4838361466c565b60408301905092915050565b6000613ffc83836146f9565b60808301905092915050565b61401181615058565b82525050565b61402081615058565b82525050565b600061403182614eae565b61403b8185614ef4565b935061404683614e8e565b8060005b8381101561407757815161405e8882613fd8565b975061406983614eda565b92505060018101905061404a565b5085935050505092915050565b600061408f82614eb9565b6140998185614f05565b93506140a483614e9e565b8060005b838110156140d55781516140bc8882613ff0565b97506140c783614ee7565b9250506001810190506140a8565b5085935050505092915050565b6140eb8161506a565b82525050565b6140fa81615076565b82525050565b600061410b82614ec4565b6141158185614f16565b93506141258185602086016150fe565b61412e8161533d565b840191505092915050565b600061414482614ecf565b61414e8185614f27565b935061415e8185602086016150fe565b6141678161533d565b840191505092915050565b600061417d82614ecf565b6141878185614f38565b93506141978185602086016150fe565b80840191505092915050565b60006141b0602083614f27565b91506141bb8261534e565b602082019050919050565b60006141d3600e83614f27565b91506141de82615377565b602082019050919050565b60006141f6600c83614f27565b9150614201826153a0565b602082019050919050565b6000614219600c83614f27565b9150614224826153c9565b602082019050919050565b600061423c603283614f27565b9150614247826153f2565b604082019050919050565b600061425f601c83614f27565b915061426a82615441565b602082019050919050565b6000614282602483614f27565b915061428d8261546a565b604082019050919050565b60006142a5601983614f27565b91506142b0826154b9565b602082019050919050565b60006142c8600f83614f27565b91506142d3826154e2565b602082019050919050565b60006142eb600d83614f27565b91506142f68261550b565b602082019050919050565b600061430e602683614f27565b915061431982615534565b604082019050919050565b6000614331602c83614f27565b915061433c82615583565b604082019050919050565b6000614354603883614f27565b915061435f826155d2565b604082019050919050565b6000614377602a83614f27565b915061438282615621565b604082019050919050565b600061439a602983614f27565b91506143a582615670565b604082019050919050565b60006143bd602083614f27565b91506143c8826156bf565b602082019050919050565b60006143e0602083614f27565b91506143eb826156e8565b602082019050919050565b6000614403602c83614f27565b915061440e82615711565b604082019050919050565b6000614426602983614f27565b915061443182615760565b604082019050919050565b6000614449602f83614f27565b9150614454826157af565b604082019050919050565b600061446c601a83614f27565b9150614477826157fe565b602082019050919050565b600061448f602183614f27565b915061449a82615827565b604082019050919050565b60006144b2603183614f27565b91506144bd82615876565b604082019050919050565b60006144d5601783614f27565b91506144e0826158c5565b602082019050919050565b60006144f8601c83614f27565b9150614503826158ee565b602082019050919050565b600061451b600c83614f27565b915061452682615917565b602082019050919050565b600061453e601883614f27565b915061454982615940565b602082019050919050565b6000614561601783614f38565b915061456c82615969565b601782019050919050565b6000614584600f83614f27565b915061458f82615992565b602082019050919050565b60006145a7601483614f27565b91506145b2826159bb565b602082019050919050565b60006145ca601083614f27565b91506145d5826159e4565b602082019050919050565b60006145ed602083614f27565b91506145f882615a0d565b602082019050919050565b6000614610601183614f38565b915061461b82615a36565b601182019050919050565b6000614633602f83614f27565b915061463e82615a5f565b604082019050919050565b6000614656601283614f27565b915061466182615aae565b602082019050919050565b6040820160008201516146826000850182614759565b5060208201516146956020850182614759565b50505050565b6040820160008201516146b1600085018261473b565b5060208201516146c46020850182614008565b50505050565b6040820160008201516146e0600085018261473b565b5060208201516146f36020850182614008565b50505050565b60808201600082015161470f6000850182614759565b5060208201516147226020850182614759565b506040820151614735604085018261469b565b50505050565b614744816150d6565b82525050565b614753816150d6565b82525050565b614762816150e5565b82525050565b614771816150e5565b82525050565b60006147838285614172565b915061478f8284614172565b91508190509392505050565b60006147a682614554565b91506147b28285614172565b91506147bd82614603565b91506147c98284614172565b91508190509392505050565b60006020820190506147ea6000830184614017565b92915050565b60006080820190506148056000830187614017565b6148126020830186614017565b61481f6040830185614768565b81810360608301526148318184614100565b905095945050505050565b60006040820190506148516000830185614017565b61485e6020830184614768565b9392505050565b6000602082019050818103600083015261487f8184614026565b905092915050565b600060208201905081810360008301526148a18184614084565b905092915050565b60006020820190506148be60008301846140e2565b92915050565b60006020820190506148d960008301846140f1565b92915050565b600060208201905081810360008301526148f98184614139565b905092915050565b6000602082019050818103600083015261491a816141a3565b9050919050565b6000602082019050818103600083015261493a816141c6565b9050919050565b6000602082019050818103600083015261495a816141e9565b9050919050565b6000602082019050818103600083015261497a8161420c565b9050919050565b6000602082019050818103600083015261499a8161422f565b9050919050565b600060208201905081810360008301526149ba81614252565b9050919050565b600060208201905081810360008301526149da81614275565b9050919050565b600060208201905081810360008301526149fa81614298565b9050919050565b60006020820190508181036000830152614a1a816142bb565b9050919050565b60006020820190508181036000830152614a3a816142de565b9050919050565b60006020820190508181036000830152614a5a81614301565b9050919050565b60006020820190508181036000830152614a7a81614324565b9050919050565b60006020820190508181036000830152614a9a81614347565b9050919050565b60006020820190508181036000830152614aba8161436a565b9050919050565b60006020820190508181036000830152614ada8161438d565b9050919050565b60006020820190508181036000830152614afa816143b0565b9050919050565b60006020820190508181036000830152614b1a816143d3565b9050919050565b60006020820190508181036000830152614b3a816143f6565b9050919050565b60006020820190508181036000830152614b5a81614419565b9050919050565b60006020820190508181036000830152614b7a8161443c565b9050919050565b60006020820190508181036000830152614b9a8161445f565b9050919050565b60006020820190508181036000830152614bba81614482565b9050919050565b60006020820190508181036000830152614bda816144a5565b9050919050565b60006020820190508181036000830152614bfa816144c8565b9050919050565b60006020820190508181036000830152614c1a816144eb565b9050919050565b60006020820190508181036000830152614c3a8161450e565b9050919050565b60006020820190508181036000830152614c5a81614531565b9050919050565b60006020820190508181036000830152614c7a81614577565b9050919050565b60006020820190508181036000830152614c9a8161459a565b9050919050565b60006020820190508181036000830152614cba816145bd565b9050919050565b60006020820190508181036000830152614cda816145e0565b9050919050565b60006020820190508181036000830152614cfa81614626565b9050919050565b60006020820190508181036000830152614d1a81614649565b9050919050565b6000604082019050614d3660008301846146ca565b92915050565b6000604082019050614d51600083018561474a565b614d5e6020830184614017565b9392505050565b6000602082019050614d7a6000830184614768565b92915050565b6000604082019050614d956000830185614768565b614da26020830184614768565b9392505050565b6000608082019050614dbe6000830186614768565b614dcb6020830185614768565b614dd860408301846146ca565b949350505050565b6000614dea614dfb565b9050614df682826151d6565b919050565b6000604051905090565b600067ffffffffffffffff821115614e2057614e1f61530e565b5b602082029050602081019050919050565b600067ffffffffffffffff821115614e4c57614e4b61530e565b5b602082029050602081019050919050565b600067ffffffffffffffff821115614e7857614e7761530e565b5b614e818261533d565b9050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614f4e826150e5565b9150614f59836150e5565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614f8e57614f8d615281565b5b828201905092915050565b6000614fa4826150e5565b9150614faf836150e5565b925082614fbf57614fbe6152b0565b5b828204905092915050565b6000614fd5826150e5565b9150614fe0836150e5565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561501957615018615281565b5b828202905092915050565b600061502f826150e5565b915061503a836150e5565b92508282101561504d5761504c615281565b5b828203905092915050565b6000615063826150b6565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561511c578082015181840152602081019050615101565b8381111561512b576000848401525b50505050565b600061513c826150ac565b91507f800000000000000000000000000000000000000000000000000000000000000082141561516f5761516e615281565b5b600182039050919050565b6000615185826150e5565b9150600082141561519957615198615281565b5b600182039050919050565b600060028204905060018216806151bc57607f821691505b602082108114156151d0576151cf6152df565b5b50919050565b6151df8261533d565b810181811067ffffffffffffffff821117156151fe576151fd61530e565b5b80604052505050565b6000615212826150e5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561524557615244615281565b5b600182019050919050565b600061525b826150e5565b9150615266836150e5565b925082615276576152756152b0565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f416c7265616479206d696e746564000000000000000000000000000000000000600082015250565b7f496e76616c6964206d61736b0000000000000000000000000000000000000000600082015250565b7f4e6f742061204d696e7465720000000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4e6f7420616e20556e6d696e7465720000000000000000000000000000000000600082015250565b7f496e76616c696420706179656500000000000000000000000000000000000000600082015250565b7f526f79616c7479206d61736b7320646f6e2774206d617463682062617369732060008201527f706f696e74730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f526f79616c7479206d61736b7320646f6e2774206d617463682076616c756573600082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f52656163686564206d617820636f6e66696775726174696f6e73000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f546f6f206d616e7920636f6e66696775726174696f6e73000000000000000000600082015250565b7f56616c756520696e636f6d70617469626c652077697468206d61736b00000000600082015250565b7f4e6f7420616e2041646d696e0000000000000000000000000000000000000000600082015250565b7f4d61736b7320646f6e2774206d617463682076616c7565730000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f496e76616c696420726f79616c74790000000000000000000000000000000000600082015250565b7f546f6b656e204944206e6f7420616c6c6f776564000000000000000000000000600082015250565b7f416c726561647920756e6d696e74656400000000000000000000000000000000600082015250565b7f526f79616c7479206d61736b7320646f6e2774206d6174636820706179656573600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f4d61736b2063616e2774206265207a65726f0000000000000000000000000000600082015250565b615ae081615058565b8114615aeb57600080fd5b50565b615af78161506a565b8114615b0257600080fd5b50565b615b0e81615076565b8114615b1957600080fd5b50565b615b2581615080565b8114615b3057600080fd5b50565b615b3c816150e5565b8114615b4757600080fd5b5056fea2646970667358221220a122a2c813c4b29bbf618f87d7db0d73e907e93c7c04220ff9e9430b717b584964736f6c63430008040033

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

00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000003520074f2f32007f4b401c09deab5994233ab909000000000000000000000000000000000000000000000000000000000000001351756964644d696e7461626c65734174617269000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003514d410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003468747470733a2f2f6170692d70726f642e6f6e71756964642e636f6d2f7072696e74732f6d696e7465642f6d657461646174612f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100e0000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): QuiddMintablesAtari
Arg [1] : _symbol (string): QMA
Arg [2] : baseURI_ (string): https://api-prod.onquidd.com/prints/minted/metadata/
Arg [3] : _allowedMasks (uint256[]): 115790322390251417039241401711187164934754157181743688420499462401711837020160
Arg [4] : _allowedValues (uint256[]): 395773742510358089826658640166413747545356392900138646619239789089546829824
Arg [5] : _basisPoints (uint256): 250
Arg [6] : _payee (address): 0x3520074f2F32007F4b401C09dEAB5994233AB909

-----Encoded View---------------
18 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000200
Arg [5] : 00000000000000000000000000000000000000000000000000000000000000fa
Arg [6] : 0000000000000000000000003520074f2f32007f4b401c09deab5994233ab909
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000013
Arg [8] : 51756964644d696e7461626c6573417461726900000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [10] : 514d410000000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000034
Arg [12] : 68747470733a2f2f6170692d70726f642e6f6e71756964642e636f6d2f707269
Arg [13] : 6e74732f6d696e7465642f6d657461646174612f000000000000000000000000
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [15] : ffff000000000000000000000000000000000000000000000000000000000000
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [17] : 00e0000000000000000000000000000000000000000000000000000000000000


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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