ETH Price: $3,344.52 (-0.92%)

Token

BEING_AND_NOTHINGNESS (|Ψ>)
 

Overview

Max Total Supply

0 |Ψ>

Holders

1

Total Transfers

-

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

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:
BEING_AND_NOTHINGNESS

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 22 : BEING_AND_NOTHINGNESS.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

// @author: white lights (whitelights.eth)

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@manifoldxyz/libraries-solidity/contracts/access/AdminControl.sol";
import "./ITokenURISupplier.sol";
import "./ABISupplier.sol";
import "./AsciiArtSupplier.sol";
import "./SSTORE2.sol";
import "./ERC721SuperpositionToken.sol";
import "./IERC7572.sol";

/////////////////////////////////////////////////////////////////////////
//                                                                     //
//     ╟▌█╨▌█N███████████████████████████████████▀███▌   ████████████  //
//     ╠▌ΦM▀  ╟█████████▌█Å█████████████████████▌▐███M  ▐███▌██╝█████  //
//         ╙▓▄▓██████████████████████████████▓██▌"███▌  J█████╣▌▀████  //
//         "╬████████████████████████████████▌███_████▄  ╫███████▌╠▀▀  //
//           `╚███████████████████████████████Ö███▌▀███▌  ▀█████▀████  //
//                ▀████████"╙╫████████████▌█████╟▀███████▌  ▀████████  //
//                 ╫███████▄ ╙█████████Ñ██▌└████▀█▌┴▀███████▄▄ ╜▀▀▀▀█  //
//     ▄▄╓_I~_    ▄███████████████████"████ └████╨███ ╙▀████████████▀  //
//    ██▀╜   ╛   ████████████████████ ╟██Ñ█▌  ██╣█_╜███ └▀████▀██████  //
//  ~╛          █████████████████████ ▐██▌╫██  █▌╟█▄└████▄ ▀█████████  //
//             ██████████████████████▌ ▀██▌▀██_ █▄╝██_▀█████_ ╙▀▀▀▀▀╜  //
//            ╓██████████████████████╬█_╜███╬███┘██▄▀██╬▀▀█████▄_      //
//           ╓█████████████████████████╬▀W▄║▀████▀╨██████████▀███████  //
//          █████████████████████████████╫███▓████╬████╫█████████╬╠▄▄  //
//          █████████████████████████████╫▄▄▓╫╫███████████▄▀▀████████  //
//           └╜▀▀▀╜╙╙▀█████████████████████████████████▀██████▌╠▀▀▀▀╙  //
//                    ███████████████████████████████████╠█████▀█████  //
//                   ███████████████████████████████████▌╫▄▀█████████  //
//                   └▀▀█████████████ being ██████████▌██ ██└▀███████  //
//                      ██████ & ████████████████████████ ╟██▄ ╙▀████  //
//                     ▐██████████████████████████████▌██▌ █████▄_ ┘▀  //
//                          ╜█████████████████████████╫███  █████████  //
//               ness     ████████████████████████▌████▌   ▀██████     //
//         nothing           ███████████████████████████████▄    ╙▀▀█  //
//                          ╟█████████████████████████▄████████▄_      //
//                           ███████████████████████████╟████████████  //
//                            ▀███████▀███▀▀▀██████████████████▀▀████  //
//                                              ▀█████████████▀ █████  //
//                                                 ╙▀████████" ██████  //
//                                                     ╫████▌ ███████  //
//                                                     ████▌▌ ███╫███  //
//                                                   ╓██████╫ ╙███▓██  //
//       |Ψ> = 1/√2|0> + 1/√2|1                    ▄█████████▀▄╜█████  //
//                                               ▄███████╟████▄▀█▄▀▀▀  //
//                                            ▄▓█████▌╟██▄╠██████╬▀▀█  //
//                                  _▄▄,▄▄▀╧╫╝███████▌ ███  ▀████████  //
//                                                                     //
/////////////////////////////////////////////////////////////////////////

contract BEING_AND_NOTHINGNESS is ERC721SuperpositionToken, ABISupplier, AsciiArtSupplier, IERC7572 {
  ITokenURISupplier public renderer = ITokenURISupplier(0x0000000000000000000000000000000000000000);
  address private artistStatementPointer;

  constructor() ERC721SuperpositionToken(
    "BEING_AND_NOTHINGNESS",
    "|\u03A8>"
  ) {}

  function supportsInterface(bytes4 interfaceId) public view override(ERC721SuperpositionToken, ABISupplier, AsciiArtSupplier) returns (bool) {
    return super.supportsInterface(interfaceId);
  }

  function setRenderer(address addr) public adminRequired {
    renderer = ITokenURISupplier(addr);
  }

  /**
   * @dev See {IERC721Metadata-tokenURI}.
   * @notice What exactly do you own when the token is
   *         in a superposition of being and nothingness?
   */
  function tokenURI(uint256 tokenId) public view override returns (string memory) {
    require(exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
    return renderer.tokenURI(tokenId);
  }

  /**
   * @notice Returns the ERC7572 contract URI for this contract, modified to
   *         include the ASCII art of this contract as a URI as well.
   * @return The data:application/json;utf8, URI
   * @dev    See {IERC7572-contractURI}.
   */
  function contractURI() public view returns (string memory) {
      string memory json = string.concat(
        '{"name": "being and nothingness","asciiArtURI":"',
        this.asciiArtURI(),
        '"}'
      );
      return string.concat("data:application/json;utf8,", json);
  }

  /**
   * @notice Returns the ASCII art of this contract as a Data URI
   *         for long-term storage on-chain
   * @return The data:text/plain;charset=utf-8;base64, URI
   * @dev    See {IAsciiSupplier-asciiUri}.
   */
  function asciiArtURI() public pure override returns (string memory) {
    return "data:text/plain;charset=utf-8;base64,Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLw0KLy8gICAgIOKVn+KWjOKWiOKVqOKWjOKWiE7ilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojiloDilojilojilojilowgICDilojilojilojilojilojilojilojilojilojilojilojiloggIC8vDQovLyAgICAg4pWg4paMzqZN4paAICDilZ/ilojilojilojilojilojilojilojilojilojilozilojDheKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWjOKWkOKWiOKWiOKWiE0gIOKWkOKWiOKWiOKWiOKWjOKWiOKWiOKVneKWiOKWiOKWiOKWiOKWiCAgLy8NCi8vICAgICAgICAg4pWZ4paT4paE4paT4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paT4paI4paI4paMIuKWiOKWiOKWiOKWjCAgSuKWiOKWiOKWiOKWiOKWiOKVo+KWjOKWgOKWiOKWiOKWiOKWiCAgLy8NCi8vICAgICAgICAgIuKVrOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWjOKWiOKWiOKWiF/ilojilojilojilojiloQgIOKVq+KWiOKWiOKWiOKWiOKWiOKWiOKWiOKWjOKVoOKWgOKWgCAgLy8NCi8vICAgICAgICAgICBg4pWa4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paIw5bilojilojilojiloziloDilojilojilojilowgIOKWgOKWiOKWiOKWiOKWiOKWiOKWgOKWiOKWiOKWiOKWiCAgLy8NCi8vICAgICAgICAgICAgICAgIOKWgOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiCLilZnilavilojilojilojilojilojilojilojilojilojilojilojilojilozilojilojilojilojilojilZ/iloDilojilojilojilojilojilojilojilowgIOKWgOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiCAgLy8NCi8vICAgICAgICAgICAgICAgICDilavilojilojilojilojilojilojilojiloQg4pWZ4paI4paI4paI4paI4paI4paI4paI4paI4paIw5HilojilojilozilJTilojilojilojilojiloDilojilozilLTiloDilojilojilojilojilojilojilojiloTiloQg4pWc4paA4paA4paA4paA4paIICAvLw0KLy8gICAgIOKWhOKWhOKVk19Jfl8gICAg4paE4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paIIuKWiOKWiOKWiOKWiCDilJTilojilojilojilojilajilojilojilogg4pWZ4paA4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paAICAvLw0KLy8gICAg4paI4paI4paA4pWcICAg4pWbICAg4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paIIOKVn+KWiOKWiMOR4paI4paMICDilojilojilaPilohf4pWc4paI4paI4paIIOKUlOKWgOKWiOKWiOKWiOKWiOKWgOKWiOKWiOKWiOKWiOKWiOKWiCAgLy8NCi8vICB+4pWbICAgICAgICAgIOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiCDilpDilojilojilozilavilojiloggIOKWiOKWjOKVn+KWiOKWhOKUlOKWiOKWiOKWiOKWiOKWhCDiloDilojilojilojilojilojilojilojilojiloggIC8vDQovLyAgICAgICAgICAgICDilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilowg4paA4paI4paI4paM4paA4paI4paIXyDilojiloTilZ3ilojilohf4paA4paI4paI4paI4paI4paIXyDilZniloDiloDiloDiloDiloDilZwgIC8vDQovLyAgICAgICAgICAgIOKVk+KWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKVrOKWiF/ilZzilojilojilojilazilojilojilojilJjilojilojiloTiloDilojilojilaziloDiloDilojilojilojilojilojiloRfICAgICAgLy8NCi8vICAgICAgICAgICDilZPilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilaziloBX4paE4pWR4paA4paI4paI4paI4paI4paA4pWo4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paA4paI4paI4paI4paI4paI4paI4paIICAvLw0KLy8gICAgICAgICAg4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4pWr4paI4paI4paI4paT4paI4paI4paI4paI4pWs4paI4paI4paI4paI4pWr4paI4paI4paI4paI4paI4paI4paI4paI4paI4pWs4pWg4paE4paEICAvLw0KLy8gICAgICAgICAg4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4pWr4paE4paE4paT4pWr4pWr4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paE4paA4paA4paI4paI4paI4paI4paI4paI4paI4paIICAvLw0KLy8gICAgICAgICAgIOKUlOKVnOKWgOKWgOKWgOKVnOKVmeKVmeKWgOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWgOKWiOKWiOKWiOKWiOKWiOKWiOKWjOKVoOKWgOKWgOKWgOKWgOKVmSAgLy8NCi8vICAgICAgICAgICAgICAgICAgICDilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilaDilojilojilojilojilojiloDilojilojilojilojiloggIC8vDQovLyAgICAgICAgICAgICAgICAgICDilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilozilaviloTiloDilojilojilojilojilojilojilojilojiloggIC8vDQovLyAgICAgICAgICAgICAgICAgICDilJTiloDiloDilojilojilojilojilojilojilojilojilojilojilojilojiloggYmVpbmcg4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paM4paI4paIIOKWiOKWiOKUlOKWgOKWiOKWiOKWiOKWiOKWiOKWiOKWiCAgLy8NCi8vICAgICAgICAgICAgICAgICAgICAgIOKWiOKWiOKWiOKWiOKWiOKWiCAmIOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiCDilZ/ilojilojiloQg4pWZ4paA4paI4paI4paI4paIICAvLw0KLy8gICAgICAgICAgICAgICAgICAgICDilpDilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilozilojilojilowg4paI4paI4paI4paI4paI4paEXyDilJjiloAgIC8vDQovLyAgICAgICAgICAgICAgICAgICAgICAgICAg4pWc4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4pWr4paI4paI4paIICDilojilojilojilojilojilojilojilojiloggIC8vDQovLyAgICAgICAgICAgICAgIG5lc3MgICAgIOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWjOKWiOKWiOKWiOKWiOKWjCAgIOKWgOKWiOKWiOKWiOKWiOKWiOKWiCAgICAgLy8NCi8vICAgICAgICAgbm90aGluZyAgICAgICAgICAg4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paEICAgIOKVmeKWgOKWgOKWiCAgLy8NCi8vICAgICAgICAgICAgICAgICAgICAgICAgICDilZ/ilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojilojiloTilojilojilojilojilojilojilojilojiloRfICAgICAgLy8NCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAg4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4pWf4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paIICAvLw0KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAg4paA4paI4paI4paI4paI4paI4paI4paI4paA4paI4paI4paI4paA4paA4paA4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paA4paA4paI4paI4paI4paIICAvLw0KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4paA4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paI4paAIOKWiOKWiOKWiOKWiOKWiCAgLy8NCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKVmeKWgOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiCIg4paI4paI4paI4paI4paI4paIICAvLw0KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKVq+KWiOKWiOKWiOKWiOKWjCDilojilojilojilojilojilojiloggIC8vDQovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4paI4paI4paI4paI4paM4paMIOKWiOKWiOKWiOKVq+KWiOKWiOKWiCAgLy8NCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pWT4paI4paI4paI4paI4paI4paI4pWrIOKVmeKWiOKWiOKWiOKWk+KWiOKWiCAgLy8NCi8vICAgICAgIHzOqD4gPSAxL+KImjJ8MD4gKyAxL+KImjJ8MSAgICAgICAgICAgICAgICAgICAg4paE4paI4paI4paI4paI4paI4paI4paI4paI4paI4paA4paE4pWc4paI4paI4paI4paI4paIICAvLw0KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWhOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKVn+KWiOKWiOKWiOKWiOKWhOKWgOKWiOKWhOKWgOKWgOKWgCAgLy8NCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDiloTilpPilojilojilojilojilojilozilZ/ilojilojiloTilaDilojilojilojilojilojilojilaziloDiloDiloggIC8vDQovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBf4paE4paELOKWhOKWhOKWgOKVp+KVq+KVneKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWjCDilojilojiloggIOKWgOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiCAgLy8NCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8NCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8=";
  }

  /**
   * @notice Sets the ABI JSON string for this contract
   * @param _abiString The new ABI JSON string
   * @dev see {IABISupplier-setABIString}
   */
  function setABIString(string memory _abiString) public adminRequired {
    abiStoragePointer = SSTORE2.write(bytes(_abiString));
  }
}

File 2 of 22 : AdminControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IAdminControl.sol";

abstract contract AdminControl is Ownable, IAdminControl, ERC165 {
    using EnumerableSet for EnumerableSet.AddressSet;

    // Track registered admins
    EnumerableSet.AddressSet private _admins;

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

    /**
     * @dev Only allows approved admins to call the specified function
     */
    modifier adminRequired() {
        require(owner() == msg.sender || _admins.contains(msg.sender), "AdminControl: Must be owner or admin");
        _;
    }   

    /**
     * @dev See {IAdminControl-getAdmins}.
     */
    function getAdmins() external view override returns (address[] memory admins) {
        admins = new address[](_admins.length());
        for (uint i = 0; i < _admins.length(); i++) {
            admins[i] = _admins.at(i);
        }
        return admins;
    }

    /**
     * @dev See {IAdminControl-approveAdmin}.
     */
    function approveAdmin(address admin) external override onlyOwner {
        if (!_admins.contains(admin)) {
            emit AdminApproved(admin, msg.sender);
            _admins.add(admin);
        }
    }

    /**
     * @dev See {IAdminControl-revokeAdmin}.
     */
    function revokeAdmin(address admin) external override onlyOwner {
        if (_admins.contains(admin)) {
            emit AdminRevoked(admin, msg.sender);
            _admins.remove(admin);
        }
    }

    /**
     * @dev See {IAdminControl-isAdmin}.
     */
    function isAdmin(address admin) public override view returns (bool) {
        return (owner() == admin || _admins.contains(admin));
    }

}

File 3 of 22 : IAdminControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * @dev Interface for admin control
 */
interface IAdminControl is IERC165 {

    event AdminApproved(address indexed account, address indexed sender);
    event AdminRevoked(address indexed account, address indexed sender);

    /**
     * @dev gets address of all admins
     */
    function getAdmins() external view returns (address[] memory);

    /**
     * @dev add an admin.  Can only be called by contract owner.
     */
    function approveAdmin(address admin) external;

    /**
     * @dev remove an admin.  Can only be called by contract owner.
     */
    function revokeAdmin(address admin) external;

    /**
     * @dev checks whether or not given address is an admin
     * Returns True if they are
     */
    function isAdmin(address admin) external view returns (bool);

}

File 4 of 22 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

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

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 5 of 22 : ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (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 overridden 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 || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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);

        _afterTokenTransfer(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);

        _afterTokenTransfer(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 from incorrect owner");
        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);

        _afterTokenTransfer(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 {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

File 6 of 22 : ERC721Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Burnable.sol)

pragma solidity ^0.8.0;

import "../ERC721.sol";
import "../../../utils/Context.sol";

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

File 7 of 22 : 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 8 of 22 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (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`.
     *
     * 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;

    /**
     * @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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @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);
}

File 9 of 22 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (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 `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 10 of 22 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 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 11 of 22 : 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 12 of 22 : 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 13 of 22 : 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 14 of 22 : 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 15 of 22 : EnumerableSet.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/EnumerableSet.sol)

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

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

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

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

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

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

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}

File 16 of 22 : ABISupplier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "./SSTORE2.sol";

interface IABISupplier is IERC165 {
  function abiString() external view returns (string memory);
}

contract ABISupplier is IABISupplier, ERC165 {
  address internal abiStoragePointer;

  function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
    return interfaceId == type(IABISupplier).interfaceId || super.supportsInterface(interfaceId);
  }

  /**
   * @notice Returns the ABI of this contract as a JSON string, for aliens who come to earth.
   *         How else will they know how to interact with this program?
   * @return The ABI JSON string
   * @dev see {IABISupplier-abiString}
   */
  function abiString() public view returns (string memory) {
    if (abiStoragePointer != address(0)) {
      bytes memory b = SSTORE2.read(abiStoragePointer);
      return string(b);
    }
    return "";
  }
}

File 17 of 22 : AsciiArtSupplier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "./SSTORE2.sol";

interface IAsciiArtSupplier is IERC165 {
  function asciiArtURI() external view returns (string memory);
}

contract AsciiArtSupplier is ERC165, IAsciiArtSupplier {
  address internal asciiArtStoragePointer;

  function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
    return interfaceId == type(IAsciiArtSupplier).interfaceId || super.supportsInterface(interfaceId);
  }

  function asciiArtURI() public virtual view returns (string memory) {
    if (asciiArtStoragePointer != address(0)) {
      bytes memory b = SSTORE2.read(asciiArtStoragePointer);
      return string(b);
    }
    return "";
  }
}

File 18 of 22 : Bytecode.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


library Bytecode {
  error InvalidCodeAtRange(uint256 _size, uint256 _start, uint256 _end);

  /**
    @notice Generate a creation code that results on a contract with `_code` as bytecode
    @param _code The returning value of the resulting `creationCode`
    @return creationCode (constructor) for new contract
  */
  function creationCodeFor(bytes memory _code) internal pure returns (bytes memory) {
    /*
      0x00    0x63         0x63XXXXXX  PUSH4 _code.length  size
      0x01    0x80         0x80        DUP1                size size
      0x02    0x60         0x600e      PUSH1 14            14 size size
      0x03    0x60         0x6000      PUSH1 00            0 14 size size
      0x04    0x39         0x39        CODECOPY            size
      0x05    0x60         0x6000      PUSH1 00            0 size
      0x06    0xf3         0xf3        RETURN
      <CODE>
    */

    return abi.encodePacked(
      hex"63",
      uint32(_code.length),
      hex"80_60_0E_60_00_39_60_00_F3",
      _code
    );
  }

  /**
    @notice Returns the size of the code on a given address
    @param _addr Address that may or may not contain code
    @return size of the code on the given `_addr`
  */
  function codeSize(address _addr) internal view returns (uint256 size) {
    assembly { size := extcodesize(_addr) }
  }

  /**
    @notice Returns the code of a given address
    @dev It will fail if `_end < _start`
    @param _addr Address that may or may not contain code
    @param _start number of bytes of code to skip on read
    @param _end index before which to end extraction
    @return oCode read from `_addr` deployed bytecode

    Forked from: https://gist.github.com/KardanovIR/fe98661df9338c842b4a30306d507fbd
  */
  function codeAt(address _addr, uint256 _start, uint256 _end) internal view returns (bytes memory oCode) {
    uint256 csize = codeSize(_addr);
    if (csize == 0) return bytes("");

    if (_start > csize) return bytes("");
    if (_end < _start) revert InvalidCodeAtRange(csize, _start, _end);

    unchecked {
      uint256 reqSize = _end - _start;
      uint256 maxSize = csize - _start;

      uint256 size = maxSize < reqSize ? maxSize : reqSize;

      assembly {
        // allocate output byte array - this could also be done without assembly
        // by using o_code = new bytes(size)
        oCode := mload(0x40)
        // new "memory end" including padding
        mstore(0x40, add(oCode, and(add(add(size, 0x20), 0x1f), not(0x1f))))
        // store length in memory
        mstore(oCode, size)
        // actually retrieve the code, this needs assembly
        extcodecopy(_addr, add(oCode, 0x20), _start, size)
      }
    }
  }
}

File 19 of 22 : ERC721SuperpositionToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@manifoldxyz/libraries-solidity/contracts/access/AdminControl.sol";

/**
 * @title ERC721SuperpositionToken
 * @dev ERC721 token that sits in a superposition of existance. The token's
 * data either exists or does not for only the moment that qubitState or
 * exists is read from. At all other times it is in a superposition of both
 * existing and not existing.
 */
abstract contract ERC721SuperpositionToken is ERC721Burnable, AdminControl {
  bool public engaged = false;

  constructor(string memory name, string memory symbol) ERC721(name, symbol) {
    _safeMint(msg.sender, 1);
  }

  function supportsInterface(bytes4 interfaceId) public virtual view override(ERC721, AdminControl) returns (bool) {
    return super.supportsInterface(interfaceId);
  }

  /**
   * @return represents |0> or |1>
   * @dev    pseudo-impossible to indefinitely predict the state of the qubit.
   *         an attacker would need to always control the last four validators
   *         of an epoch. in each of the four slots they could then choose to
   *         sign or not, giving them 2^4 possible total random values to pick
   *         from. this is equivalent to one bit of influence over only
   *         prevrandao. an expensive sisyphean task to say the least.
   *
   */
  function qubitState() public view returns (bool) {
    return !engaged || ((uint256(
      keccak256(abi.encodePacked(block.number, block.prevrandao, block.timestamp))
    )) % 2 == 1);
  }

  /**
   * @dev Returns whether the token exists, according to the state of a qubit
   *      defined by wave function qubitState() combined with the token's
   *      default existence in the ERC721 contract.
   * @param tokenId uint256 ID of the token to query
   * @return bool whether the token exists
   */
  function exists(uint256 tokenId) internal view returns (bool) {
    return _exists(tokenId) && qubitState() == true;
  }

  function engage() public adminRequired {
    engaged = true;
  }
}

File 20 of 22 : IERC7572.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

interface IERC7572 {
  function contractURI() external view returns (string memory);

  event ContractURIUpdated();
}

File 21 of 22 : ITokenURISupplier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface ITokenURISupplier is IERC165 {
  function tokenURI(uint256 id) external view returns (string memory);
}

contract TokenURISupplier is ITokenURISupplier {
  function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
    return interfaceId == type(ITokenURISupplier).interfaceId;
  }

  function tokenURI(uint256 id) virtual external view returns (string memory) {
    return string(abi.encodePacked(id));
  }
}

File 22 of 22 : SSTORE2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./Bytecode.sol";

/**
  @title A key-value storage with auto-generated keys for storing chunks of data with a lower write & read cost.
  @author Agustin Aguilar <[email protected]>

  Readme: https://github.com/0xsequence/sstore2#readme
*/
library SSTORE2 {
  error WriteError();

  /**
    @notice Stores `_data` and returns `pointer` as key for later retrieval
    @dev The pointer is a contract address with `_data` as code
    @param _data to be written
    @return pointer Pointer to the written `_data`
  */
  function write(bytes memory _data) internal returns (address pointer) {
    // Append 00 to _data so contract can't be called
    // Build init code
    bytes memory code = Bytecode.creationCodeFor(
      abi.encodePacked(
        hex'00',
        _data
      )
    );

    // Deploy contract using create
    assembly { pointer := create(0, add(code, 32), mload(code)) }

    // Address MUST be non-zero
    if (pointer == address(0)) revert WriteError();
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @return data read from `_pointer` contract
  */
  function read(address _pointer) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, 1, type(uint256).max);
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @param _start number of bytes to skip
    @return data read from `_pointer` contract
  */
  function read(address _pointer, uint256 _start) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, _start + 1, type(uint256).max);
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @param _start number of bytes to skip
    @param _end index before which to end extraction
    @return data read from `_pointer` contract
  */
  function read(address _pointer, uint256 _start, uint256 _end) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, _start + 1, _end + 1);
  }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_size","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"InvalidCodeAtRange","type":"error"},{"inputs":[],"name":"WriteError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[],"name":"ContractURIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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":"abiString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"approveAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asciiArtURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"engage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"engaged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAdmins","outputs":[{"internalType":"address[]","name":"admins","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"isAdmin","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":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"qubitState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renderer","outputs":[{"internalType":"contract ITokenURISupplier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"revokeAdmin","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":"string","name":"_abiString","type":"string"}],"name":"setABIString","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":"address","name":"addr","type":"address"}],"name":"setRenderer","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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60808060405234620001ec576200001660c0604052565b601581527f4245494e475f414e445f4e4f5448494e474e455353000000000000000000000060a0526040516200004c8162000204565b60048152633e67541f60e11b6020808301919091525f8054336001600160a01b0319821681178355929492916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a38051926001600160401b038411620001e657600191620000d485620000ce855462000260565b6200029b565b602091601f86116001146200015b575093806200010c9262000114965f926200014f575b50508160011b915f199060031b1c19161790565b905562000349565b6200012460ff1960095416600955565b6200012f3362000432565b600b80546001600160a01b0319169055604051613a1590816200080a8239f35b015190505f80620000f8565b60015f529190601f1986167fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6935f905b828210620001ce575050918493918762000114989410620001b5575b505050811b01905562000349565b01515f1960f88460031b161c191690555f8080620001a7565b8087869782949787015181550196019401906200018b565b620001f0565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b604081019081106001600160401b03821117620001e657604052565b602081019081106001600160401b03821117620001e657604052565b601f909101601f19168101906001600160401b03821190821017620001e657604052565b90600182811c9216801562000290575b60208310146200027c57565b634e487b7160e01b5f52602260045260245ffd5b91607f169162000270565b90601f8211620002a9575050565b60019160015f5260205f20906020601f840160051c83019310620002e9575b601f0160051c01905b818110620002de57505050565b5f81558201620002d1565b9091508190620002c8565b601f811162000301575050565b60025f5260205f20906020601f840160051c830193106200033e575b601f0160051c01905b81811062000332575050565b5f815560010162000326565b90915081906200031d565b80519091906001600160401b038111620001e65762000375816200036f60025462000260565b620002f4565b602080601f8311600114620003ad57508190620003a893945f926200014f5750508160011b915f199060031b1c19161790565b600255565b60025f52601f198316949091907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace925f905b8782106200041957505083600195961062000400575b505050811b01600255565b01515f1960f88460031b161c191690555f8080620003f5565b80600185968294968601518155019501930190620003df565b60405190620004418262000220565b5f82526001600160a01b0391818316918215620005385760015f81905260036020527fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054c5462000536956200053095916200049d911615620005d2565b6001600160a01b0383165f908152600460205260409020620004c081546200061f565b905560015f5260036020527fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054c80546001600160a01b0319166001600160a01b0385161790555f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a46200070d565b6200057c565b565b606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b156200058457565b60405162461bcd60e51b815260206004820152603260248201525f805160206200421f83398151915260448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608490fd5b15620005da57565b60405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606490fd5b90600182018092116200062e57565b634e487b7160e01b5f52601160045260245ffd5b90816020910312620001ec57516001600160e01b031981168103620001ec5790565b9092919260018060a01b031681526020925f602083015260016040830152608060608301528051908160808401525f5b828110620006b657505060a09293505f838284010152601f8019910116010190565b81810186015184820160a00152850162000694565b3d1562000708573d906001600160401b038211620001e65760405191620006fd601f8201601f1916602001846200023c565b82523d5f602084013e565b606090565b803b15620008025760206040518092815f816200073a630a85bd0160e11b98898352336004840162000664565b03926001600160a01b03165af15f9181620007ca575b50620007bc5762000760620006cb565b80519081620007b75760405162461bcd60e51b815260206004820152603260248201525f805160206200421f83398151915260448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608490fd5b602001fd5b6001600160e01b0319161490565b620007f291925060203d602011620007fa575b620007e981836200023c565b81019062000642565b905f62000750565b503d620007dd565b505060019056fe60806040526004361015610011575f80fd5b5f3560e01c806301ffc9a7146101f457806306fdde03146101ef578063081812fc146101ea578063095ea7b3146101e557806323b872dd146101e057806324d7806c146101db5780632d345670146101d65780632edd8b4d146101d157806331ae450b146101cc57806342842e0e146101c757806342966c68146101c25780634a166f68146101bd57806356d3163d146101b85780635eb6c10e146101b35780636352211e146101ae5780636c1a0188146101a95780636d73e669146101a457806370a082311461019f578063715018a61461019a5780638ada6b0f146101955780638da5cb5b1461019057806395d89b411461018b578063a22cb46514610186578063b88d4fde14610181578063be93c3871461017c578063c87b56dd14610177578063e8a3d48514610172578063e985e9c51461016d578063f2fde38b146101685763f674e1a714610163575f80fd5b612e48565b612db3565b612d57565b612c84565b612b6b565b612b47565b612ae7565b6129ff565b61293e565b612917565b6128ef565b612894565b6127f4565b612776565b610bec565b610bce565b610a76565b61093a565b6108de565b6107d6565b6107af565b610717565b6106b1565b610634565b6105d9565b6105b0565b61048f565b610433565b610332565b61020f565b6001600160e01b031981160361020b57565b5f80fd5b3461020b57602036600319011261020b5761025d60043561022f816101f9565b63ffffffff60e01b16630d83403160e31b8114908115610261575b5060405190151581529081906020820190565b0390f35b63f674e1a760e01b81149150811561027b575b505f61024a565b632a9f3abf60e11b811491508115610295575b505f610274565b6380ac58cd60e01b8114915081156102c7575b81156102b6575b505f61028e565b6301ffc9a760e01b1490505f6102af565b635b5e139f60e01b811491506102a8565b5f5b8381106102e95750505f910152565b81810151838201526020016102da565b90602091610312815180928185528580860191016102d8565b601f01601f1916010190565b90602061032f9281815201906102f9565b90565b3461020b575f36600319011261020b576040515f60018054908160011c9160018116918215610429575b6020916020851084146104155784875260208701939081156103f6575060011461039d575b61025d8661039181880382610a02565b6040519182918261031e565b60015f90815294509192917fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b8386106103e557505050910190506103918261025d5f610381565b8054858701529482019481016103ca565b60ff1916845250505090151560051b0190506103918261025d5f610381565b634e487b7160e01b5f52602260045260245ffd5b92607f169261035c565b3461020b57602036600319011261020b576020610451600435612e77565b6040516001600160a01b039091168152f35b600435906001600160a01b038216820361020b57565b602435906001600160a01b038216820361020b57565b3461020b57604036600319011261020b576104a8610463565b6024356104b4816130ae565b916001600160a01b03808416908216811461052c576104e6936104e19133149081156104e8575b50612f07565b613303565b005b6001600160a01b03165f908152600660205260409020610526915061051f9033905b9060018060a01b03165f5260205260405f2090565b5460ff1690565b5f6104db565b60405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608490fd5b606090600319011261020b576001600160a01b0390600435828116810361020b5791602435908116810361020b579060443590565b3461020b576104e66105c13661057b565b916105d46105cf8433613365565b612f79565b6134db565b3461020b57602036600319011261020b5760206105f4610463565b5f546001600160a01b0391821691168114908115610618575b506040519015158152f35b61062e91505f52600860205260405f2054151590565b5f61060d565b3461020b57602036600319011261020b5761064d610463565b5f546001600160a01b0391906106669083163314612fdf565b1661067c815f52600860205260405f2054151590565b61068257005b6104e69033817f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d55f80a3613732565b3461020b575f36600319011261020b57602060ff600954166040519015158152f35b60209060206040818301928281528551809452019301915f5b8281106106fa575050505090565b83516001600160a01b0316855293810193928101926001016106ec565b3461020b575f36600319011261020b576007546107338161302a565b906107416040519283610a02565b80825261074d8161302a565b602090601f190136848301375f5b828110610770576040518061025d86826106d3565b610779816136a5565b91905485518210156107aa5760039290921b9190911c6001600160a01b0316600582901b850183015260010161075b565b613042565b3461020b576104e66107c03661057b565b90604051926107ce846109c4565b5f8452613125565b3461020b57602036600319011261020b576004356107f48133613365565b1561088057610802816130ae565b61080b826132b0565b6001600160a01b03165f81815260046020526040902080549091905f19810190811161087b575f92558282526003602052604082206bffffffffffffffffffffffff60a01b81541690557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a4005b6134ab565b60405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b6064820152608490fd5b3461020b575f36600319011261020b575f546001600160a01b03163314801561091a575b61090b90613056565b6009805460ff19166001179055005b5061090b610933335f52600860205260405f2054151590565b9050610902565b3461020b57602036600319011261020b57610953610463565b5f546001600160a01b039190821633148015610990575b61097390613056565b166bffffffffffffffffffffffff60a01b600b541617600b555f80f35b506109736109a9335f52600860205260405f2054151590565b905061096a565b634e487b7160e01b5f52604160045260245ffd5b6020810190811067ffffffffffffffff8211176109e057604052565b6109b0565b611f20810190811067ffffffffffffffff8211176109e057604052565b90601f8019910116810190811067ffffffffffffffff8211176109e057604052565b67ffffffffffffffff81116109e057601f01601f191660200190565b929192610a4c82610a24565b91610a5a6040519384610a02565b82948184528183011161020b578281602093845f960137010152565b3461020b57602036600319011261020b5760043567ffffffffffffffff811161020b573660238201121561020b57610ab8903690602481600401359101610a40565b5f546001600160a01b039190821633148015610bae575b610ad890613056565b610b59610b69602e604051610b1460218260208101975f8952610b0481518092602086860191016102d8565b8101036001810184520182610a02565b8051946040519485926020840197606360f81b895263ffffffff60e01b9060e01b1660218501526880600e6000396000f360b81b6025850152518092858501906102d8565b810103600e810184520182610a02565b51905ff090811615610b9c5760098054610100600160a81b03191660089290921b610100600160a81b0316919091179055005b60405163046a55db60e11b8152600490fd5b50610ad8610bc7335f52600860205260405f2054151590565b9050610acf565b3461020b57602036600319011261020b5760206104516004356130ae565b3461020b575f36600319011261020b5761025d604051610c0b816109e5565b611ef181527f646174613a746578742f706c61696e3b636861727365743d7574662d383b626160208201527f736536342c4c7938764c7938764c7938764c7938764c7938764c7938764c793860408201527f764c7938764c7938764c7938764c7938764c7938764c7938764c7938764c79388060608301528060808301527f764c7938764c77304b4c7938674943416749434167494341674943416749434160a08301527f67494341674943416749434167494341674943416749434167494341674943418060c08401528060e08401527f6749434167494341764c77304b4c79386749434167494f4b566e2b4b576a4f4b6101008401527f57694f4b56714f4b576a4f4b57694537696c6f6a696c6f6a696c6f6a696c6f6a6101208401527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a8061014085015280610160850152806101808501527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f446101a08501527f696c6f6a696c6f6a696c6f6a696c6f7767494344696c6f6a696c6f6a696c6f6a6101c0850152806101e08501527f696c6f67674943387644516f764c79416749434167347057673470614d7a715a6102008501527f4e34706141494344696c5a2f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a6102208501527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f7a696c6f6a4468654b57694f4b6102408501527f57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b9081610260860152816102808601527f57694f4b57694f4b57694f4b57694f4b576a4f4b576b4f4b57694f4b57694f4b6102a08601527f5769453067494f4b576b4f4b57694f4b57694f4b57694f4b576a4f4b57694f4b6102c08601527f57694f4b566e654b57694f4b57694f4b57694f4b57694f4b57694341674c79386102e08601527f4e436938764943416749434167494341673470575a34706154347061453470616103008601527f54347061493470614934706149347061493470614934706149347061493470616103208601527f49347061493470614934706149347061493470614934706149347061493470619081610340870152816103608701527f49347061493470614934706149347061493470614934706149347061543470616103808701527f49347061493470614d49754b57694f4b57694f4b57694f4b576a43416753754b6103a08701527f57694f4b57694f4b57694f4b57694f4b57694f4b566f2b4b576a4f4b57674f4b6103c08701527f57694f4b57694f4b57694f4b57694341674c79384e43693876494341674943416103e08701527f674943416749754b56724f4b57694f4b57694f4b57694f4b57694f4b57694f4b6104008701528261042087015282610440870152826104608701527f57694f4b57694f4b57694f4b576a4f4b57694f4b57694f4b5769462f696c6f6a6104808701527f696c6f6a696c6f6a696c6f6a696c6f5167494f4b56712b4b57694f4b57694f4b6104a08701527f57694f4b57694f4b57694f4b57694f4b57694f4b576a4f4b566f4f4b57674f4b806104c08801527f57674341674c79384e43693876494341674943416749434167494342673470576104e08801527f613470614934706149347061493470614934706149347061493470614934706161050088015282610520880152826105408801527f49347061493470614934706149347061493470614934706149347061497735626105608801527f696c6f6a696c6f6a696c6f6a696c6f7a696c6f44696c6f6a696c6f6a696c6f6a6105808801527f696c6f7767494f4b57674f4b57694f4b57694f4b57694f4b57694f4b57694f4b6105a08801527f57674f4b57694f4b57694f4b57694f4b57694341674c79384e436938764943416105c08801527f6749434167494341674943416749434167494f4b57674f4b57694f4b57694f4b6105e08801527f57694f4b57694f4b57694f4b57694f4b57694f4b5769434c696c5a6e696c6176610600880152816106208801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f7a696c6f6a696c6f6a696c6f6a6106408801527f696c6f6a696c6f6a696c5a2f696c6f44696c6f6a696c6f6a696c6f6a696c6f6a6106608801527f696c6f6a696c6f6a696c6f6a696c6f7767494f4b57674f4b57694f4b57694f4b6106808801527f57694f4b57694f4b57694f4b57694f4b57694f4b57694341674c79384e4369386106a08801527f764943416749434167494341674943416749434167494344696c6176696c6f6a6106c08801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f51673470576106e08801527f5a347061493470614934706149347061493470614934706149347061493470616107008801527f4934706149773548696c6f6a696c6f6a696c6f7a696c4a54696c6f6a696c6f6a6107208801527f696c6f6a696c6f6a696c6f44696c6f6a696c6f7a696c4c54696c6f44696c6f6a6107408801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f54696c6f516107608801527f67347057633470614134706141347061413470614134706149494341764c77306107808801527f4b4c79386749434167494f4b57684f4b57684f4b566b31394a666c38674943416107a08801527f67347061453470614934706149347061493470614934706149347061493470616107c0880152826107e08801527f493470614934706149347061493470614949754b57694f4b57694f4b57694f4b6108008801527f57694344696c4a54696c6f6a696c6f6a696c6f6a696c6f6a696c616a696c6f6a6108208801527f696c6f6a696c6f67673470575a34706141347061493470614934706149347061610840880152826108608801527f4934706141494341764c77304b4c7938674943416734706149347061493470616108808801527f41347057634943416734705762494341673470614934706149347061493470616108a0880152826108c0880152826108e08801527f49494f4b566e2b4b57694f4b57694d4f52347061493470614d494344696c6f6a6109008801527f696c6f6a696c6150696c6f686634705763347061493470614934706149494f4b6109208801527f556c4f4b57674f4b57694f4b57694f4b57694f4b57694f4b57674f4b57694f4b6109408801527f57694f4b57694f4b57694f4b57694f4b57694341674c79384e436938764943426109608801527f2b34705762494341674943416749434167494f4b57694f4b57694f4b57694f4b610980880152836109a0880152836109c08801527f57694f4b57694344696c7044696c6f6a696c6f6a696c6f7a696c6176696c6f6a6109e08801527f696c6f6767494f4b57694f4b576a4f4b566e2b4b57694f4b57684f4b556c4f4b610a008801527f57694f4b57694f4b57694f4b57694f4b57684344696c6f44696c6f6a696c6f6a610a208801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6767494338610a408801527f7644516f764c794167494341674943416749434167494344696c6f6a696c6f6a610a6088015281610a8088015281610aa08801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f77673470614134706149347061610ac08801527f493470614d347061413470614934706149587944696c6f6a696c6f54696c5a33610ae08801527f696c6f6a696c6f68663470614134706149347061493470614934706149347061610b008801527f49587944696c5a6e696c6f44696c6f44696c6f44696c6f44696c6f44696c5a77610b208801527f674943387644516f764c794167494341674943416749434167494f4b566b2b4b610b4088015283610b6088015283610b808801527f57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b56724f4b5769462f610ba08801527f696c5a7a696c6f6a696c6f6a696c6f6a696c617a696c6f6a696c6f6a696c6f6a610bc08801527f696c4a6a696c6f6a696c6f6a696c6f54696c6f44696c6f6a696c6f6a696c617a610be08801527f696c6f44696c6f44696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f52610c008801527f6649434167494341674c79384e43693876494341674943416749434167494344610c208801527f696c5a50696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a610c4088015281610c6088015281610c808801527f696c6f6a696c6f6a696c617a696c6f4258347061453470575234706141347061610ca08801527f49347061493470614934706149347061413470576f3470614934706149347061610cc088015282610ce08801527f4134706149347061493470614934706149347061493470614934706149494341610d008801527f764c77304b4c7938674943416749434167494341673470614934706149347061610d2088015282610d4088015282610d6088015282610d808801527f4934706149347061493470577234706149347061493470614934706154347061610da08801527f4934706149347061493470614934705773347061493470614934706149347061610dc08801527f4934705772347061493470614934706149347061493470614934706149347061610de08801527f49347061493470614934705773347057673470614534706145494341764c7730610e008801527f4b4c793867494341674943416749434167347061493470614934706149347061610e2088015282610e4088015282610e6088015282610e808801527f4934706149347057723470614534706145347061543470577234705772347061610ea088015282610ec08801527f4934706149347061493470614534706141347061413470614934706149347061610ee08801527f493470614934706149347061493470614934706149494341764c77304b4c7938610f008801527f67494341674943416749434167494f4b556c4f4b566e4f4b57674f4b57674f4b610f208801527f57674f4b566e4f4b566d654b566d654b57674f4b57694f4b57694f4b57694f4b610f4088015283610f6088015283610f8088015283610fa08801527f57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b57674f4b57694f4b610fc0880152610fe08701527f57674f4b57674f4b57674f4b566d5341674c79384e43693876494341674943416110008701527f6749434167494341674943416749434167494344696c6f6a696c6f6a696c6f6a80611020880152816110408801528161106088015281611080880152816110a08801527f696c6144696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f44696c6f6a6110c08801527f696c6f6a696c6f6a696c6f6a696c6f67674943387644516f764c7941674943416110e0880152611100870152806111208701528061114087015280611160870152806111808701527f696c6f7a696c6176696c6f54696c6f44696c6f6a696c6f6a696c6f6a696c6f6a6111a08701527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f67674943387644516f764c794190816111c08801527f674943416749434167494341674943416749434167494344696c4a54696c6f446111e08801527f696c6f44696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a6112008801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6767596d5670626d636112208801527f67347061493470614934706149347061493470614934706149347061493470616112408801527f4934706149347061493470614d3470614934706149494f4b57694f4b57694f4b6112608801527f556c4f4b57674f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b6112808801527f57694341674c79384e436938764943416749434167494341674943416749434193846112a08901527f674943416749434167494f4b57694f4b57694f4b57694f4b57694f4b57694f4b6112c08901527f576943416d494f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b6112e089015280611300890152806113208901527f57694f4b57694344696c5a2f696c6f6a696c6f6a696c6f51673470575a3470616113408901527f4134706149347061493470614934706149494341764c77304b4c7938674943416113608901527f674943416749434167494341674943416749434167494344696c7044696c6f6a611380890152816113a0890152816113c0890152816113e08901527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f7a696c6f6a696c6f6a6114008901527f696c6f77673470614934706149347061493470614934706149347061455879446114208901527f696c4a6a696c6f41674943387644516f764c79416749434167494341674943416114408901527f674943416749434167494341674943416749434167347057633470614934706161146089015283611480890152836114a08901527f493470614934706149347061493470614934706149347061493470614934705792836114c08a01527f72347061493470614934706149494344696c6f6a696c6f6a696c6f6a696c6f6a6114e08a01526115008901527f67494341674943416749434167494341674947356c63334d6749434167494f4b61152089015280611540890152806115608901526115808801527f576a4f4b57694f4b57694f4b57694f4b57694f4b576a434167494f4b57674f4b6115a08801527f57694f4b57694f4b57694f4b57694f4b57694f4b5769434167494341674c79386115c08801527f4e43693876494341674943416749434167626d393061476c755a7941674943416115e08801527f67494341674943416734706149347061493470614934706149347061493470616116008801528261162088015282611640880152826116608801527f49347061493470614549434167494f4b566d654b57674f4b57674f4b576943416116808801527f674c79384e4369387649434167494341674943416749434167494341674943416116a08801527f674943416749434167494344696c5a2f696c6f6a696c6f6a696c6f6a696c6f6a6116c0880152806116e08801526117008701527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f54696c6f6a696c6f6a6117208701527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f52664943416117408701527f67494341674c79384e43693876494341674943416749434167494341674943416117608701527f6749434167494341674943416749434167347061493470614934706149347061611780870152816117a0870152816117c08701526117e08601527f66347061493470614934706149347061493470614934706149347061493470616118008601527f4934706149347061493470614934706149494341764c77304b4c793867494341611820860152826118408601527f67347061413470614934706149347061493470614934706149347061493470616118608601527f4934706141347061493470614934706149347061413470614134706141347061611880860152806118a0860152806118c08601527f49347061493470614134706141347061493470614934706149347061494943416118e08601527f764c77304b4c7938674943416749434167494341674943416749434167494341611900860152826119208601527f67494341673470614134706149347061493470614934706149347061493470616119408601526119608501527f41494f4b57694f4b57694f4b57694f4b57694f4b57694341674c79384e4369386119808501527f76494341674943416749434167494341674943416749434167494341674943416119a0850152816119c08501527f67494f4b566d654b57674f4b57694f4b57694f4b57694f4b57694f4b57694f4b6119e08501527f57694f4b57694f4b576943496734706149347061493470614934706149347061611a008501527f4934706149494341764c77304b4c793867494341674943416749434167494341611a2085015281611a408501527f674943416749434167494341674943416749434167494f4b56712b4b57694f4b611a608501527f57694f4b57694f4b57694f4b576a4344696c6f6a696c6f6a696c6f6a696c6f6a611a808501527f696c6f6a696c6f6a696c6f67674943387644516f764c79416749434167494341611aa085015281611ac08501527f6749434167494341674943416749434167494341674943416749434167347061611ae08501527f493470614934706149347061493470614d3470614d494f4b57694f4b57694f4b611b008501527f57694f4b56712b4b57694f4b57694f4b57694341674c79384e43693876494341611b2085015281611b4085015281611b608501527f6734705754347061493470614934706149347061493470614934706149347057611b808501527f72494f4b566d654b57694f4b57694f4b57694f4b576b2b4b57694f4b57694341611ba08501527f674c79384e43693876494341674943416749487a4f71443467505341784c2b4b611bc08501527f496d6a4a384d4434674b7941784c2b4b496d6a4a384d53416749434167494341611be08501527f6749434167494341674943416749434167347061453470614934706149347061611c008501527f4934706149347061493470614934706149347061493470614934706141347061611c208501527f45347057633470614934706149347061493470614934706149494341764c7730611c408501527f4b4c793867494341674943416749434167494341674943416749434167494341611c6085015281611c808501527f67494f4b57684f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b611ca08501527f57694f4b566e2b4b57694f4b57694f4b57694f4b57694f4b57684f4b57674f4b611cc08501527f57694f4b57684f4b57674f4b57674f4b57674341674c79384e43693876494341611ce085015281611d008501527f674943416749434167494341674943416749434167494344696c6f54696c7050611d208501527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f7a696c5a2f696c6f6a611d408501527f696c6f6a696c6f54696c6144696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a611d608501527f696c6f6a696c617a696c6f44696c6f44696c6f67674943387644516f764c7941611d8085015281611da08501527f6749434167494341674943426634706145347061454c4f4b57684f4b57684f4b611dc08501527f57674f4b56702b4b56712b4b566e654b57694f4b57694f4b57694f4b57694f4b611de08501527f57694f4b57694f4b57694f4b576a4344696c6f6a696c6f6a696c6f6767494f4b611e008501527f57674f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b611e20850152611e4084015280611e60840152611e808301527f6749434167494341674c79384e436938764c7938764c7938764c7938764c7938611ea083015280611ec0830152611ee082015270764c7938764c7938764c7938764c79383d60781b611f008201526040519182918261031e565b3461020b57602036600319011261020b5761278f610463565b5f546001600160a01b0391906127a89083163314612fdf565b166127be815f52600860205260405f2054151590565b156127c557005b6104e69033817f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb15f80a36137dd565b3461020b57602036600319011261020b576001600160a01b03612815610463565b16801561283c575f52600460205261025d60405f2054604051918291829190602083019252565b60405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608490fd5b3461020b575f36600319011261020b575f80546001600160a01b038116906128bd338314612fdf565b6001600160a01b03191682557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461020b575f36600319011261020b57600b546040516001600160a01b039091168152602090f35b3461020b575f36600319011261020b575f546040516001600160a01b039091168152602090f35b3461020b575f36600319011261020b576040515f60025460018160011c91600181169182156129f5575b6020916020851084146104155784875260208701939081156103f6575060011461299c5761025d8661039181880382610a02565b60025f90815294509192917f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace5b8386106129e457505050910190506103918261025d5f610381565b8054858701529482019481016129c9565b92607f1692612968565b3461020b57604036600319011261020b57612a18610463565b602435801515810361020b576001600160a01b03821691338314612aa25781612a5f612a7092335f52600660205260405f209060018060a01b03165f5260205260405f2090565b9060ff801983541691151516179055565b604051901515815233907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190602090a3005b60405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606490fd5b3461020b57608036600319011261020b57612b00610463565b612b08610479565b6064359167ffffffffffffffff831161020b573660238401121561020b57612b3d6104e6933690602481600401359101610a40565b9160443591613125565b3461020b575f36600319011261020b576020612b6161316d565b6040519015158152f35b3461020b57602036600319011261020b576004355f818152600360205260409020546001600160a01b0316151580612c71575b15612c1457600b5460405163c87b56dd60e01b815260048101929092525f90829060249082906001600160a01b03165afa8015612c0f5761025d915f91612bed575b506040519182918261031e565b612c0991503d805f833e612c018183610a02565b8101906131c0565b5f612be0565b61321f565b60405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608490fd5b506001612c7c61316d565b151514612b9e565b3461020b575f36600319011261020b57604051630d83403160e31b81525f81600481305afa908115612c0f5761025d91610391915f91612d3d575b50612d38605260405180937f7b226e616d65223a20226265696e6720616e64206e6f7468696e676e6573732260208301526f161130b9b1b4b4a0b93a2aa924911d1160811b6040830152612d1d8151809260206050860191016102d8565b810161227d60f01b6050820152036032810184520182610a02565b61322a565b612d5191503d805f833e612c018183610a02565b5f612cbf565b3461020b57604036600319011261020b57602060ff612da7612d77610463565b612d7f610479565b6001600160a01b039182165f9081526006865260408082209290931681526020919091522090565b54166040519015158152f35b3461020b57602036600319011261020b57612dcc610463565b5f546001600160a01b0390612de49082163314612fdf565b811615612df4576104e69061360c565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b3461020b575f36600319011261020b5761025d612e63613280565b6040519182916020835260208301906102f9565b5f818152600360205260409020546001600160a01b031615612ead575f908152600560205260409020546001600160a01b031690565b60405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608490fd5b15612f0e57565b60405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608490fd5b15612f8057565b60405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6044820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b6064820152608490fd5b15612fe657565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b67ffffffffffffffff81116109e05760051b60200190565b634e487b7160e01b5f52603260045260245ffd5b1561305d57565b60405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608490fd5b5f908152600360205260409020546001600160a01b031680156130ce5790565b60405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608490fd5b906131499392916131396105cf8433613365565b6131448383836134db565b6138c8565b1561315057565b60405162461bcd60e51b81528061316960048201613652565b0390fd5b60ff6009541615801561317d5790565b506040516020810143815244604083015242606083015260608252608082019082821067ffffffffffffffff8311176109e0576001928392604052519020161490565b60208183031261020b5780519067ffffffffffffffff821161020b570181601f8201121561020b5780516131f381610a24565b926132016040519485610a02565b8184526020828401011161020b5761032f91602080850191016102d8565b6040513d5f823e3d90fd5b9061327e603b60405180947f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c0000000000602083015261326e81518092602086860191016102d8565b810103601b810185520183610a02565b565b60095460081c6001600160a01b0316806132a757506040516132a1816109c4565b5f815290565b61032f9061398a565b5f81815260056020526040812080546001600160a01b03191690556001600160a01b036132dc836130ae565b167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258280a4565b5f82815260056020526040902080546001600160a01b0319166001600160a01b0383161790556001600160a01b038061333b846130ae565b169116907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4565b5f828152600360205260409020546001600160a01b0316156133f95761338a826130ae565b9160018060a01b03908183169282851684149485156133c9575b505083156133b3575b50505090565b6133bf91929350612e77565b16145f80806133ad565b6001600160a01b03165f90815260066020526040902091945060ff916133ef919061050a565b5416925f806133a4565b60405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608490fd5b1561345a57565b60405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b634e487b7160e01b5f52601160045260245ffd5b5f1981019190821161087b57565b906001820180921161087b57565b906134e5836130ae565b6001600160a01b0383811692909182168390036135b95761353361359392821694613511861515613453565b61351a876132b0565b6001600160a01b03165f90815260046020526040902090565b61353d81546134bf565b90556001600160a01b0381165f90815260046020526040902061356081546134cd565b9055613574855f52600360205260405f2090565b80546001600160a01b0319166001600160a01b03909216919091179055565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4565b60405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608490fd5b5f80546001600160a01b039283166001600160a01b03198216811783559216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3565b60809060208152603260208201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60608201520190565b6007548110156107aa5760075f527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68801905f90565b600754801561371e575f19810190808210156107aa577fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6875f91600783520155600755565b634e487b7160e01b5f52603160045260245ffd5b5f8181526008602052604090205480156137d7575f19918183019180831161087b5760075493840193841161087b578383613788945f960361378e575b50505061377a6136da565b5f52600860205260405f2090565b55600190565b61377a6137b6916137ae6137a46137ce956136a5565b90549060031b1c90565b9283916136a5565b90919082549060031b91821b915f19901b1916179055565b555f808061376f565b50505f90565b805f52600860205260405f2054155f1461384e57600754680100000000000000008110156109e05760018101806007558110156107aa5781907fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880155600754905f52600860205260405f2055600190565b505f90565b9081602091031261020b575161032f816101f9565b6001600160a01b03918216815291166020820152604081019190915260806060820181905261032f929101906102f9565b3d156138c3573d906138aa82610a24565b916138b86040519384610a02565b82523d5f602084013e565b606090565b92909190823b15613981576138fa926020925f604051809681958294630a85bd0160e11b9a8b85523360048601613868565b03926001600160a01b03165af15f9181613950575b506139425761391c613899565b8051908161393d5760405162461bcd60e51b81528061316960048201613652565b602001fd5b6001600160e01b0319161490565b61397391925060203d60201161397a575b61396b8183610a02565b810190613853565b905f61390f565b503d613961565b50505050600190565b90813b80156139d057806001116139d0575f1901600119808210156139c957505b600160405193601f19603f840116850160405282855260208501903c565b90506139ab565b5090506040516132a1816109c456fea264697066735822122067afa4573c71340dec850dcb0ef5662094861132321935afe536e45ce9c2432d64736f6c634300081800334552433732313a207472616e7366657220746f206e6f6e204552433732315265

Deployed Bytecode

0x60806040526004361015610011575f80fd5b5f3560e01c806301ffc9a7146101f457806306fdde03146101ef578063081812fc146101ea578063095ea7b3146101e557806323b872dd146101e057806324d7806c146101db5780632d345670146101d65780632edd8b4d146101d157806331ae450b146101cc57806342842e0e146101c757806342966c68146101c25780634a166f68146101bd57806356d3163d146101b85780635eb6c10e146101b35780636352211e146101ae5780636c1a0188146101a95780636d73e669146101a457806370a082311461019f578063715018a61461019a5780638ada6b0f146101955780638da5cb5b1461019057806395d89b411461018b578063a22cb46514610186578063b88d4fde14610181578063be93c3871461017c578063c87b56dd14610177578063e8a3d48514610172578063e985e9c51461016d578063f2fde38b146101685763f674e1a714610163575f80fd5b612e48565b612db3565b612d57565b612c84565b612b6b565b612b47565b612ae7565b6129ff565b61293e565b612917565b6128ef565b612894565b6127f4565b612776565b610bec565b610bce565b610a76565b61093a565b6108de565b6107d6565b6107af565b610717565b6106b1565b610634565b6105d9565b6105b0565b61048f565b610433565b610332565b61020f565b6001600160e01b031981160361020b57565b5f80fd5b3461020b57602036600319011261020b5761025d60043561022f816101f9565b63ffffffff60e01b16630d83403160e31b8114908115610261575b5060405190151581529081906020820190565b0390f35b63f674e1a760e01b81149150811561027b575b505f61024a565b632a9f3abf60e11b811491508115610295575b505f610274565b6380ac58cd60e01b8114915081156102c7575b81156102b6575b505f61028e565b6301ffc9a760e01b1490505f6102af565b635b5e139f60e01b811491506102a8565b5f5b8381106102e95750505f910152565b81810151838201526020016102da565b90602091610312815180928185528580860191016102d8565b601f01601f1916010190565b90602061032f9281815201906102f9565b90565b3461020b575f36600319011261020b576040515f60018054908160011c9160018116918215610429575b6020916020851084146104155784875260208701939081156103f6575060011461039d575b61025d8661039181880382610a02565b6040519182918261031e565b60015f90815294509192917fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b8386106103e557505050910190506103918261025d5f610381565b8054858701529482019481016103ca565b60ff1916845250505090151560051b0190506103918261025d5f610381565b634e487b7160e01b5f52602260045260245ffd5b92607f169261035c565b3461020b57602036600319011261020b576020610451600435612e77565b6040516001600160a01b039091168152f35b600435906001600160a01b038216820361020b57565b602435906001600160a01b038216820361020b57565b3461020b57604036600319011261020b576104a8610463565b6024356104b4816130ae565b916001600160a01b03808416908216811461052c576104e6936104e19133149081156104e8575b50612f07565b613303565b005b6001600160a01b03165f908152600660205260409020610526915061051f9033905b9060018060a01b03165f5260205260405f2090565b5460ff1690565b5f6104db565b60405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608490fd5b606090600319011261020b576001600160a01b0390600435828116810361020b5791602435908116810361020b579060443590565b3461020b576104e66105c13661057b565b916105d46105cf8433613365565b612f79565b6134db565b3461020b57602036600319011261020b5760206105f4610463565b5f546001600160a01b0391821691168114908115610618575b506040519015158152f35b61062e91505f52600860205260405f2054151590565b5f61060d565b3461020b57602036600319011261020b5761064d610463565b5f546001600160a01b0391906106669083163314612fdf565b1661067c815f52600860205260405f2054151590565b61068257005b6104e69033817f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d55f80a3613732565b3461020b575f36600319011261020b57602060ff600954166040519015158152f35b60209060206040818301928281528551809452019301915f5b8281106106fa575050505090565b83516001600160a01b0316855293810193928101926001016106ec565b3461020b575f36600319011261020b576007546107338161302a565b906107416040519283610a02565b80825261074d8161302a565b602090601f190136848301375f5b828110610770576040518061025d86826106d3565b610779816136a5565b91905485518210156107aa5760039290921b9190911c6001600160a01b0316600582901b850183015260010161075b565b613042565b3461020b576104e66107c03661057b565b90604051926107ce846109c4565b5f8452613125565b3461020b57602036600319011261020b576004356107f48133613365565b1561088057610802816130ae565b61080b826132b0565b6001600160a01b03165f81815260046020526040902080549091905f19810190811161087b575f92558282526003602052604082206bffffffffffffffffffffffff60a01b81541690557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a4005b6134ab565b60405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b6064820152608490fd5b3461020b575f36600319011261020b575f546001600160a01b03163314801561091a575b61090b90613056565b6009805460ff19166001179055005b5061090b610933335f52600860205260405f2054151590565b9050610902565b3461020b57602036600319011261020b57610953610463565b5f546001600160a01b039190821633148015610990575b61097390613056565b166bffffffffffffffffffffffff60a01b600b541617600b555f80f35b506109736109a9335f52600860205260405f2054151590565b905061096a565b634e487b7160e01b5f52604160045260245ffd5b6020810190811067ffffffffffffffff8211176109e057604052565b6109b0565b611f20810190811067ffffffffffffffff8211176109e057604052565b90601f8019910116810190811067ffffffffffffffff8211176109e057604052565b67ffffffffffffffff81116109e057601f01601f191660200190565b929192610a4c82610a24565b91610a5a6040519384610a02565b82948184528183011161020b578281602093845f960137010152565b3461020b57602036600319011261020b5760043567ffffffffffffffff811161020b573660238201121561020b57610ab8903690602481600401359101610a40565b5f546001600160a01b039190821633148015610bae575b610ad890613056565b610b59610b69602e604051610b1460218260208101975f8952610b0481518092602086860191016102d8565b8101036001810184520182610a02565b8051946040519485926020840197606360f81b895263ffffffff60e01b9060e01b1660218501526880600e6000396000f360b81b6025850152518092858501906102d8565b810103600e810184520182610a02565b51905ff090811615610b9c5760098054610100600160a81b03191660089290921b610100600160a81b0316919091179055005b60405163046a55db60e11b8152600490fd5b50610ad8610bc7335f52600860205260405f2054151590565b9050610acf565b3461020b57602036600319011261020b5760206104516004356130ae565b3461020b575f36600319011261020b5761025d604051610c0b816109e5565b611ef181527f646174613a746578742f706c61696e3b636861727365743d7574662d383b626160208201527f736536342c4c7938764c7938764c7938764c7938764c7938764c7938764c793860408201527f764c7938764c7938764c7938764c7938764c7938764c7938764c7938764c79388060608301528060808301527f764c7938764c77304b4c7938674943416749434167494341674943416749434160a08301527f67494341674943416749434167494341674943416749434167494341674943418060c08401528060e08401527f6749434167494341764c77304b4c79386749434167494f4b566e2b4b576a4f4b6101008401527f57694f4b56714f4b576a4f4b57694537696c6f6a696c6f6a696c6f6a696c6f6a6101208401527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a8061014085015280610160850152806101808501527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f446101a08501527f696c6f6a696c6f6a696c6f6a696c6f7767494344696c6f6a696c6f6a696c6f6a6101c0850152806101e08501527f696c6f67674943387644516f764c79416749434167347057673470614d7a715a6102008501527f4e34706141494344696c5a2f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a6102208501527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f7a696c6f6a4468654b57694f4b6102408501527f57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b9081610260860152816102808601527f57694f4b57694f4b57694f4b57694f4b576a4f4b576b4f4b57694f4b57694f4b6102a08601527f5769453067494f4b576b4f4b57694f4b57694f4b57694f4b576a4f4b57694f4b6102c08601527f57694f4b566e654b57694f4b57694f4b57694f4b57694f4b57694341674c79386102e08601527f4e436938764943416749434167494341673470575a34706154347061453470616103008601527f54347061493470614934706149347061493470614934706149347061493470616103208601527f49347061493470614934706149347061493470614934706149347061493470619081610340870152816103608701527f49347061493470614934706149347061493470614934706149347061543470616103808701527f49347061493470614d49754b57694f4b57694f4b57694f4b576a43416753754b6103a08701527f57694f4b57694f4b57694f4b57694f4b57694f4b566f2b4b576a4f4b57674f4b6103c08701527f57694f4b57694f4b57694f4b57694341674c79384e43693876494341674943416103e08701527f674943416749754b56724f4b57694f4b57694f4b57694f4b57694f4b57694f4b6104008701528261042087015282610440870152826104608701527f57694f4b57694f4b57694f4b576a4f4b57694f4b57694f4b5769462f696c6f6a6104808701527f696c6f6a696c6f6a696c6f6a696c6f5167494f4b56712b4b57694f4b57694f4b6104a08701527f57694f4b57694f4b57694f4b57694f4b57694f4b576a4f4b566f4f4b57674f4b806104c08801527f57674341674c79384e43693876494341674943416749434167494342673470576104e08801527f613470614934706149347061493470614934706149347061493470614934706161050088015282610520880152826105408801527f49347061493470614934706149347061493470614934706149347061497735626105608801527f696c6f6a696c6f6a696c6f6a696c6f7a696c6f44696c6f6a696c6f6a696c6f6a6105808801527f696c6f7767494f4b57674f4b57694f4b57694f4b57694f4b57694f4b57694f4b6105a08801527f57674f4b57694f4b57694f4b57694f4b57694341674c79384e436938764943416105c08801527f6749434167494341674943416749434167494f4b57674f4b57694f4b57694f4b6105e08801527f57694f4b57694f4b57694f4b57694f4b57694f4b5769434c696c5a6e696c6176610600880152816106208801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f7a696c6f6a696c6f6a696c6f6a6106408801527f696c6f6a696c6f6a696c5a2f696c6f44696c6f6a696c6f6a696c6f6a696c6f6a6106608801527f696c6f6a696c6f6a696c6f6a696c6f7767494f4b57674f4b57694f4b57694f4b6106808801527f57694f4b57694f4b57694f4b57694f4b57694f4b57694341674c79384e4369386106a08801527f764943416749434167494341674943416749434167494344696c6176696c6f6a6106c08801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f51673470576106e08801527f5a347061493470614934706149347061493470614934706149347061493470616107008801527f4934706149773548696c6f6a696c6f6a696c6f7a696c4a54696c6f6a696c6f6a6107208801527f696c6f6a696c6f6a696c6f44696c6f6a696c6f7a696c4c54696c6f44696c6f6a6107408801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f54696c6f516107608801527f67347057633470614134706141347061413470614134706149494341764c77306107808801527f4b4c79386749434167494f4b57684f4b57684f4b566b31394a666c38674943416107a08801527f67347061453470614934706149347061493470614934706149347061493470616107c0880152826107e08801527f493470614934706149347061493470614949754b57694f4b57694f4b57694f4b6108008801527f57694344696c4a54696c6f6a696c6f6a696c6f6a696c6f6a696c616a696c6f6a6108208801527f696c6f6a696c6f67673470575a34706141347061493470614934706149347061610840880152826108608801527f4934706141494341764c77304b4c7938674943416734706149347061493470616108808801527f41347057634943416734705762494341673470614934706149347061493470616108a0880152826108c0880152826108e08801527f49494f4b566e2b4b57694f4b57694d4f52347061493470614d494344696c6f6a6109008801527f696c6f6a696c6150696c6f686634705763347061493470614934706149494f4b6109208801527f556c4f4b57674f4b57694f4b57694f4b57694f4b57694f4b57674f4b57694f4b6109408801527f57694f4b57694f4b57694f4b57694f4b57694341674c79384e436938764943426109608801527f2b34705762494341674943416749434167494f4b57694f4b57694f4b57694f4b610980880152836109a0880152836109c08801527f57694f4b57694344696c7044696c6f6a696c6f6a696c6f7a696c6176696c6f6a6109e08801527f696c6f6767494f4b57694f4b576a4f4b566e2b4b57694f4b57684f4b556c4f4b610a008801527f57694f4b57694f4b57694f4b57694f4b57684344696c6f44696c6f6a696c6f6a610a208801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6767494338610a408801527f7644516f764c794167494341674943416749434167494344696c6f6a696c6f6a610a6088015281610a8088015281610aa08801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f77673470614134706149347061610ac08801527f493470614d347061413470614934706149587944696c6f6a696c6f54696c5a33610ae08801527f696c6f6a696c6f68663470614134706149347061493470614934706149347061610b008801527f49587944696c5a6e696c6f44696c6f44696c6f44696c6f44696c6f44696c5a77610b208801527f674943387644516f764c794167494341674943416749434167494f4b566b2b4b610b4088015283610b6088015283610b808801527f57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b56724f4b5769462f610ba08801527f696c5a7a696c6f6a696c6f6a696c6f6a696c617a696c6f6a696c6f6a696c6f6a610bc08801527f696c4a6a696c6f6a696c6f6a696c6f54696c6f44696c6f6a696c6f6a696c617a610be08801527f696c6f44696c6f44696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f52610c008801527f6649434167494341674c79384e43693876494341674943416749434167494344610c208801527f696c5a50696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a610c4088015281610c6088015281610c808801527f696c6f6a696c6f6a696c617a696c6f4258347061453470575234706141347061610ca08801527f49347061493470614934706149347061413470576f3470614934706149347061610cc088015282610ce08801527f4134706149347061493470614934706149347061493470614934706149494341610d008801527f764c77304b4c7938674943416749434167494341673470614934706149347061610d2088015282610d4088015282610d6088015282610d808801527f4934706149347061493470577234706149347061493470614934706154347061610da08801527f4934706149347061493470614934705773347061493470614934706149347061610dc08801527f4934705772347061493470614934706149347061493470614934706149347061610de08801527f49347061493470614934705773347057673470614534706145494341764c7730610e008801527f4b4c793867494341674943416749434167347061493470614934706149347061610e2088015282610e4088015282610e6088015282610e808801527f4934706149347057723470614534706145347061543470577234705772347061610ea088015282610ec08801527f4934706149347061493470614534706141347061413470614934706149347061610ee08801527f493470614934706149347061493470614934706149494341764c77304b4c7938610f008801527f67494341674943416749434167494f4b556c4f4b566e4f4b57674f4b57674f4b610f208801527f57674f4b566e4f4b566d654b566d654b57674f4b57694f4b57694f4b57694f4b610f4088015283610f6088015283610f8088015283610fa08801527f57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b57674f4b57694f4b610fc0880152610fe08701527f57674f4b57674f4b57674f4b566d5341674c79384e43693876494341674943416110008701527f6749434167494341674943416749434167494344696c6f6a696c6f6a696c6f6a80611020880152816110408801528161106088015281611080880152816110a08801527f696c6144696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f44696c6f6a6110c08801527f696c6f6a696c6f6a696c6f6a696c6f67674943387644516f764c7941674943416110e0880152611100870152806111208701528061114087015280611160870152806111808701527f696c6f7a696c6176696c6f54696c6f44696c6f6a696c6f6a696c6f6a696c6f6a6111a08701527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f67674943387644516f764c794190816111c08801527f674943416749434167494341674943416749434167494344696c4a54696c6f446111e08801527f696c6f44696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a6112008801527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6767596d5670626d636112208801527f67347061493470614934706149347061493470614934706149347061493470616112408801527f4934706149347061493470614d3470614934706149494f4b57694f4b57694f4b6112608801527f556c4f4b57674f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b6112808801527f57694341674c79384e436938764943416749434167494341674943416749434193846112a08901527f674943416749434167494f4b57694f4b57694f4b57694f4b57694f4b57694f4b6112c08901527f576943416d494f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b6112e089015280611300890152806113208901527f57694f4b57694344696c5a2f696c6f6a696c6f6a696c6f51673470575a3470616113408901527f4134706149347061493470614934706149494341764c77304b4c7938674943416113608901527f674943416749434167494341674943416749434167494344696c7044696c6f6a611380890152816113a0890152816113c0890152816113e08901527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f7a696c6f6a696c6f6a6114008901527f696c6f77673470614934706149347061493470614934706149347061455879446114208901527f696c4a6a696c6f41674943387644516f764c79416749434167494341674943416114408901527f674943416749434167494341674943416749434167347057633470614934706161146089015283611480890152836114a08901527f493470614934706149347061493470614934706149347061493470614934705792836114c08a01527f72347061493470614934706149494344696c6f6a696c6f6a696c6f6a696c6f6a6114e08a01526115008901527f67494341674943416749434167494341674947356c63334d6749434167494f4b61152089015280611540890152806115608901526115808801527f576a4f4b57694f4b57694f4b57694f4b57694f4b576a434167494f4b57674f4b6115a08801527f57694f4b57694f4b57694f4b57694f4b57694f4b5769434167494341674c79386115c08801527f4e43693876494341674943416749434167626d393061476c755a7941674943416115e08801527f67494341674943416734706149347061493470614934706149347061493470616116008801528261162088015282611640880152826116608801527f49347061493470614549434167494f4b566d654b57674f4b57674f4b576943416116808801527f674c79384e4369387649434167494341674943416749434167494341674943416116a08801527f674943416749434167494344696c5a2f696c6f6a696c6f6a696c6f6a696c6f6a6116c0880152806116e08801526117008701527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f54696c6f6a696c6f6a6117208701527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f52664943416117408701527f67494341674c79384e43693876494341674943416749434167494341674943416117608701527f6749434167494341674943416749434167347061493470614934706149347061611780870152816117a0870152816117c08701526117e08601527f66347061493470614934706149347061493470614934706149347061493470616118008601527f4934706149347061493470614934706149494341764c77304b4c793867494341611820860152826118408601527f67347061413470614934706149347061493470614934706149347061493470616118608601527f4934706141347061493470614934706149347061413470614134706141347061611880860152806118a0860152806118c08601527f49347061493470614134706141347061493470614934706149347061494943416118e08601527f764c77304b4c7938674943416749434167494341674943416749434167494341611900860152826119208601527f67494341673470614134706149347061493470614934706149347061493470616119408601526119608501527f41494f4b57694f4b57694f4b57694f4b57694f4b57694341674c79384e4369386119808501527f76494341674943416749434167494341674943416749434167494341674943416119a0850152816119c08501527f67494f4b566d654b57674f4b57694f4b57694f4b57694f4b57694f4b57694f4b6119e08501527f57694f4b57694f4b576943496734706149347061493470614934706149347061611a008501527f4934706149494341764c77304b4c793867494341674943416749434167494341611a2085015281611a408501527f674943416749434167494341674943416749434167494f4b56712b4b57694f4b611a608501527f57694f4b57694f4b57694f4b576a4344696c6f6a696c6f6a696c6f6a696c6f6a611a808501527f696c6f6a696c6f6a696c6f67674943387644516f764c79416749434167494341611aa085015281611ac08501527f6749434167494341674943416749434167494341674943416749434167347061611ae08501527f493470614934706149347061493470614d3470614d494f4b57694f4b57694f4b611b008501527f57694f4b56712b4b57694f4b57694f4b57694341674c79384e43693876494341611b2085015281611b4085015281611b608501527f6734705754347061493470614934706149347061493470614934706149347057611b808501527f72494f4b566d654b57694f4b57694f4b57694f4b576b2b4b57694f4b57694341611ba08501527f674c79384e43693876494341674943416749487a4f71443467505341784c2b4b611bc08501527f496d6a4a384d4434674b7941784c2b4b496d6a4a384d53416749434167494341611be08501527f6749434167494341674943416749434167347061453470614934706149347061611c008501527f4934706149347061493470614934706149347061493470614934706141347061611c208501527f45347057633470614934706149347061493470614934706149494341764c7730611c408501527f4b4c793867494341674943416749434167494341674943416749434167494341611c6085015281611c808501527f67494f4b57684f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b611ca08501527f57694f4b566e2b4b57694f4b57694f4b57694f4b57694f4b57684f4b57674f4b611cc08501527f57694f4b57684f4b57674f4b57674f4b57674341674c79384e43693876494341611ce085015281611d008501527f674943416749434167494341674943416749434167494344696c6f54696c7050611d208501527f696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a696c6f7a696c5a2f696c6f6a611d408501527f696c6f6a696c6f54696c6144696c6f6a696c6f6a696c6f6a696c6f6a696c6f6a611d608501527f696c6f6a696c617a696c6f44696c6f44696c6f67674943387644516f764c7941611d8085015281611da08501527f6749434167494341674943426634706145347061454c4f4b57684f4b57684f4b611dc08501527f57674f4b56702b4b56712b4b566e654b57694f4b57694f4b57694f4b57694f4b611de08501527f57694f4b57694f4b57694f4b576a4344696c6f6a696c6f6a696c6f6767494f4b611e008501527f57674f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b57694f4b611e20850152611e4084015280611e60840152611e808301527f6749434167494341674c79384e436938764c7938764c7938764c7938764c7938611ea083015280611ec0830152611ee082015270764c7938764c7938764c7938764c79383d60781b611f008201526040519182918261031e565b3461020b57602036600319011261020b5761278f610463565b5f546001600160a01b0391906127a89083163314612fdf565b166127be815f52600860205260405f2054151590565b156127c557005b6104e69033817f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb15f80a36137dd565b3461020b57602036600319011261020b576001600160a01b03612815610463565b16801561283c575f52600460205261025d60405f2054604051918291829190602083019252565b60405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608490fd5b3461020b575f36600319011261020b575f80546001600160a01b038116906128bd338314612fdf565b6001600160a01b03191682557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461020b575f36600319011261020b57600b546040516001600160a01b039091168152602090f35b3461020b575f36600319011261020b575f546040516001600160a01b039091168152602090f35b3461020b575f36600319011261020b576040515f60025460018160011c91600181169182156129f5575b6020916020851084146104155784875260208701939081156103f6575060011461299c5761025d8661039181880382610a02565b60025f90815294509192917f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace5b8386106129e457505050910190506103918261025d5f610381565b8054858701529482019481016129c9565b92607f1692612968565b3461020b57604036600319011261020b57612a18610463565b602435801515810361020b576001600160a01b03821691338314612aa25781612a5f612a7092335f52600660205260405f209060018060a01b03165f5260205260405f2090565b9060ff801983541691151516179055565b604051901515815233907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190602090a3005b60405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606490fd5b3461020b57608036600319011261020b57612b00610463565b612b08610479565b6064359167ffffffffffffffff831161020b573660238401121561020b57612b3d6104e6933690602481600401359101610a40565b9160443591613125565b3461020b575f36600319011261020b576020612b6161316d565b6040519015158152f35b3461020b57602036600319011261020b576004355f818152600360205260409020546001600160a01b0316151580612c71575b15612c1457600b5460405163c87b56dd60e01b815260048101929092525f90829060249082906001600160a01b03165afa8015612c0f5761025d915f91612bed575b506040519182918261031e565b612c0991503d805f833e612c018183610a02565b8101906131c0565b5f612be0565b61321f565b60405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608490fd5b506001612c7c61316d565b151514612b9e565b3461020b575f36600319011261020b57604051630d83403160e31b81525f81600481305afa908115612c0f5761025d91610391915f91612d3d575b50612d38605260405180937f7b226e616d65223a20226265696e6720616e64206e6f7468696e676e6573732260208301526f161130b9b1b4b4a0b93a2aa924911d1160811b6040830152612d1d8151809260206050860191016102d8565b810161227d60f01b6050820152036032810184520182610a02565b61322a565b612d5191503d805f833e612c018183610a02565b5f612cbf565b3461020b57604036600319011261020b57602060ff612da7612d77610463565b612d7f610479565b6001600160a01b039182165f9081526006865260408082209290931681526020919091522090565b54166040519015158152f35b3461020b57602036600319011261020b57612dcc610463565b5f546001600160a01b0390612de49082163314612fdf565b811615612df4576104e69061360c565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b3461020b575f36600319011261020b5761025d612e63613280565b6040519182916020835260208301906102f9565b5f818152600360205260409020546001600160a01b031615612ead575f908152600560205260409020546001600160a01b031690565b60405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608490fd5b15612f0e57565b60405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608490fd5b15612f8057565b60405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6044820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b6064820152608490fd5b15612fe657565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b67ffffffffffffffff81116109e05760051b60200190565b634e487b7160e01b5f52603260045260245ffd5b1561305d57565b60405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608490fd5b5f908152600360205260409020546001600160a01b031680156130ce5790565b60405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608490fd5b906131499392916131396105cf8433613365565b6131448383836134db565b6138c8565b1561315057565b60405162461bcd60e51b81528061316960048201613652565b0390fd5b60ff6009541615801561317d5790565b506040516020810143815244604083015242606083015260608252608082019082821067ffffffffffffffff8311176109e0576001928392604052519020161490565b60208183031261020b5780519067ffffffffffffffff821161020b570181601f8201121561020b5780516131f381610a24565b926132016040519485610a02565b8184526020828401011161020b5761032f91602080850191016102d8565b6040513d5f823e3d90fd5b9061327e603b60405180947f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c0000000000602083015261326e81518092602086860191016102d8565b810103601b810185520183610a02565b565b60095460081c6001600160a01b0316806132a757506040516132a1816109c4565b5f815290565b61032f9061398a565b5f81815260056020526040812080546001600160a01b03191690556001600160a01b036132dc836130ae565b167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258280a4565b5f82815260056020526040902080546001600160a01b0319166001600160a01b0383161790556001600160a01b038061333b846130ae565b169116907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4565b5f828152600360205260409020546001600160a01b0316156133f95761338a826130ae565b9160018060a01b03908183169282851684149485156133c9575b505083156133b3575b50505090565b6133bf91929350612e77565b16145f80806133ad565b6001600160a01b03165f90815260066020526040902091945060ff916133ef919061050a565b5416925f806133a4565b60405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608490fd5b1561345a57565b60405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b634e487b7160e01b5f52601160045260245ffd5b5f1981019190821161087b57565b906001820180921161087b57565b906134e5836130ae565b6001600160a01b0383811692909182168390036135b95761353361359392821694613511861515613453565b61351a876132b0565b6001600160a01b03165f90815260046020526040902090565b61353d81546134bf565b90556001600160a01b0381165f90815260046020526040902061356081546134cd565b9055613574855f52600360205260405f2090565b80546001600160a01b0319166001600160a01b03909216919091179055565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4565b60405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608490fd5b5f80546001600160a01b039283166001600160a01b03198216811783559216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3565b60809060208152603260208201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60608201520190565b6007548110156107aa5760075f527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68801905f90565b600754801561371e575f19810190808210156107aa577fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6875f91600783520155600755565b634e487b7160e01b5f52603160045260245ffd5b5f8181526008602052604090205480156137d7575f19918183019180831161087b5760075493840193841161087b578383613788945f960361378e575b50505061377a6136da565b5f52600860205260405f2090565b55600190565b61377a6137b6916137ae6137a46137ce956136a5565b90549060031b1c90565b9283916136a5565b90919082549060031b91821b915f19901b1916179055565b555f808061376f565b50505f90565b805f52600860205260405f2054155f1461384e57600754680100000000000000008110156109e05760018101806007558110156107aa5781907fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880155600754905f52600860205260405f2055600190565b505f90565b9081602091031261020b575161032f816101f9565b6001600160a01b03918216815291166020820152604081019190915260806060820181905261032f929101906102f9565b3d156138c3573d906138aa82610a24565b916138b86040519384610a02565b82523d5f602084013e565b606090565b92909190823b15613981576138fa926020925f604051809681958294630a85bd0160e11b9a8b85523360048601613868565b03926001600160a01b03165af15f9181613950575b506139425761391c613899565b8051908161393d5760405162461bcd60e51b81528061316960048201613652565b602001fd5b6001600160e01b0319161490565b61397391925060203d60201161397a575b61396b8183610a02565b810190613853565b905f61390f565b503d613961565b50505050600190565b90813b80156139d057806001116139d0575f1901600119808210156139c957505b600160405193601f19603f840116850160405282855260208501903c565b90506139ab565b5090506040516132a1816109c456fea264697066735822122067afa4573c71340dec850dcb0ef5662094861132321935afe536e45ce9c2432d64736f6c63430008180033

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.