ETH Price: $3,351.33 (-0.92%)
Gas: 9 Gwei

Token

ForeverPunks (FPUNK)
 

Overview

Max Total Supply

10,000 FPUNK

Holders

942

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 FPUNK
0x0786c200979febac7f56849d6ea6a21cf3a31bf4
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:
ForeverPunks

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 21 : ForeverPunks.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/common/ERC2981.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {UpdatableOperatorFilterer} from "operator-filter-registry/src/UpdatableOperatorFilterer.sol";
import {RevokableDefaultOperatorFilterer} from "operator-filter-registry/src/RevokableDefaultOperatorFilterer.sol";
import "./ERC721R.sol";

contract ForeverPunks is ERC721r, ERC2981, Ownable, ReentrancyGuard, RevokableDefaultOperatorFilterer {
  using Counters for Counters.Counter;
  using Strings for uint256; //allows for uint256var.tostring()

  uint256 public MAX_MINT_PER_WALLET_SALE = 35;
  uint256 public price = 0.0088 ether;

  string private baseURI;
  bool public holdersMintEnabled = false;
  bool public whitelistMintEnabled = false;
  bool public mintEnabled = false;

  mapping(address => uint256) public users;
  mapping(address => bool) public whitelist;
  mapping(address => uint256) public holders;

  constructor() ERC721r("ForeverPunks", "FPUNK", 10_000) {
    _setDefaultRoyalty(0x57C0C7E8b0fF7c1A6ae26d6e526A6e4C45cEa3e6, 690);

    addWhitelistedAddresses();
    addHolderAddresses();
  }

  function calculatePrice(uint256 _amount) public view returns (uint256) {
    if (_amount < 10) {
      return price * _amount;
    } else if (_amount >= 10 && _amount < 30) {
      return price * (_amount - 1);
    } else {
      // 30 or more minting
      return price * (_amount - 5);
    }
  }

  function mintWhitelist(uint256 _amount) public payable {
    require(whitelistMintEnabled, "Whitelist sale is not enabled");
    require(whitelist[msg.sender] || holders[msg.sender] >= 0, "Wallet is not whitelisted");
    require(calculatePrice(_amount) <= msg.value, "Not enough ETH");

    users[msg.sender] += _amount;
    _mintRandomly(msg.sender, _amount);
  }

  function mintHolder(uint256 _amount) public {
    require(holdersMintEnabled, "Holder sale is not enabled");
    require(
      _amount <= holders[msg.sender],
      "Exceeds max mint holder limit per wallet");

    holders[msg.sender] -= _amount;
    _mintRandomly(msg.sender, _amount);
  }

  function mintSale(uint256 _amount) public payable {
    require(mintEnabled, "Sale is not enabled");
    require(calculatePrice(_amount) <= msg.value, "Not enough ETH");

    users[msg.sender] += _amount;
    _mintRandomly(msg.sender, _amount);
  }

  /// ============ INTERNAL ============
  function _mintRandomly(address to, uint256 amount) internal {
    _mintRandom(to, amount);
  }

  function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
  }

  /// ============ ONLY OWNER ============
  function setBaseURI(string calldata _newBaseURI) external onlyOwner {
    baseURI = _newBaseURI;
  }

  function toggleWhitelistSale() external onlyOwner {
    whitelistMintEnabled = !whitelistMintEnabled;
  }

  function toggleHolderSale() external onlyOwner {
    holdersMintEnabled = !holdersMintEnabled;
  }

  function togglePublicSale() external onlyOwner {
    mintEnabled = !mintEnabled;
  }

  function setMaxMintPerWalletSale(uint256 _limit) external onlyOwner {
    require(MAX_MINT_PER_WALLET_SALE != _limit, "New limit is the same as the existing one");
    MAX_MINT_PER_WALLET_SALE = _limit;
  }

  function setPrice(uint256 price_) external onlyOwner {
    price = price_;
  }

  function setRoyalty(address wallet, uint96 perc) external onlyOwner {
    _setDefaultRoyalty(wallet, perc);
  }

  function setWhitelist(address wallet, bool canMint) external onlyOwner {
    whitelist[wallet] = canMint;
  }

  function setHolder(address wallet, uint96 _amount) external onlyOwner {
    holders[wallet] = _amount;
  }

  function reserve(address to, uint256 tokenId) external onlyOwner {
    require(_ownerOf(tokenId) == address(0), "Token has been minted.");
    _mintAtIndex(to, tokenId);
  }

  function withdraw() external onlyOwner {
    (bool success, ) = msg.sender.call{value: address(this).balance}("");
    require(success, "Transfer failed.");
  }

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

  /**
   * @dev See {ERC721-_burn}. This override additionally clears the royalty information for the token.
   */
  function _burn(uint256 tokenId) internal virtual override {
    ERC721r._burn(tokenId);
    _resetTokenRoyalty(tokenId);
  }

  /// ============ OPERATOR FILTER REGISTRY ============
  function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
    super.setApprovalForAll(operator, approved);
  }

  function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) {
    super.approve(operator, tokenId);
  }

  function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
    super.transferFrom(from, to, tokenId);
  }

  function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
    super.safeTransferFrom(from, to, tokenId);
  }

  function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
  public
  override
  onlyAllowedOperator(from)
  {
    super.safeTransferFrom(from, to, tokenId, data);
  }

  function owner() public view override(UpdatableOperatorFilterer, Ownable) returns (address) {
    return Ownable.owner();
  }

  function addWhitelistedAddresses() internal {
    whitelist[0x5881513A30cec2C84D61166b258b04789a92d9e4] = true;
    whitelist[0xfeD79641f2f8AEca217a25a57bf9dA1B0cca3575] = true;
    whitelist[0x8eB514633F8fC1aEE4B405F8165f3EEb42826F6d] = true;
    whitelist[0x75671888fD4090FbE05bD130aB8999E72e21B7c0] = true;
    whitelist[0x2dAe7853C288473546BA4fEb957070f0E5e6FDd4] = true;
    whitelist[0x327b84fcA0b85f30175729C5806Bf2faea59446F] = true;
    whitelist[0x9774F8c06aDC0209f14d77aA41f1f8bBa1fF939A] = true;
    whitelist[0xF29240b873b77EC51a9B09329Ae750237eebc197] = true;
    whitelist[0xC20E05e3C514EfbBD1734e875147260b68b31c5E] = true;
    whitelist[0xA8b31BDC10585aDBFd78443584759f979F4c90ac] = true;
    whitelist[0xA5D4A2c359C958C0530E37d801e851f7b7F7D69c] = true;
    whitelist[0x1bD7730ce07ABb27F9E1Cd6fe73eC723e2a043A6] = true;
    whitelist[0x0ebe58070fF62D4df79D5363b32126EC14e73F32] = true;
    whitelist[0x0EAedcC200f7ADC3fc19AEE6d03615A7F4896047] = true;
    whitelist[0x93a324461459F9d05e254f5E2280EC954Ad37F41] = true;
    whitelist[0x92Fc22c73E0Fc9C330d65Bc35FC5a0e341E490F7] = true;
    whitelist[0x470A6671329a9DD986F1fE5Ffc03d59D3E69Fb38] = true;
    whitelist[0xe795D84c17913E9217b10621f0eA1d543EF8c604] = true;
    whitelist[0xC1e6902198bA29B5A79f11CC8Dd66692957218E0] = true;
    whitelist[0xcfb3AdAc1F63fCaE9b9c559aFd60fD2D6B52008E] = true;
    whitelist[0x899bFF3d1A3592DcbbA5Fe11ff230cb87539c5C5] = true;
    whitelist[0xa0FE4628dFFb4C9e751148cf909aECf67E3AB198] = true;
    whitelist[0xe0957DD9da46a421f06af4437dDbde19394E9cB3] = true;
    whitelist[0x8160DEeDe29fFDf6248809D2962B4a17b4f2E1BA] = true;
    whitelist[0xeaE9b59AcfBa111B7792E1a50B581F28c9c6d387] = true;
    whitelist[0xFe231A4581AE7D1420eF3a63795736b85B3F32d6] = true;
    whitelist[0xAB5f3586E0552d6dd96b54eF6ee0cC62A27628A6] = true;
    whitelist[0xAb7654552f6FA96501336854aD96C2257105c9c9] = true;
    whitelist[0x90204beACaCB2D585a8628a33BCDF23A27150c56] = true;
    whitelist[0x6B67623ff56c10d9dcFc2152425f90285fC74DDD] = true;
    whitelist[0x8450Ea347024d5b4F6bF8F0279feC174f8DC9375] = true;
    whitelist[0x76e30FA74a2387A434c613B6946D838C12393382] = true;
    whitelist[0x25B91Dcc2397CBd5e326E336faF652dAb897A882] = true;
    whitelist[0x42E0492613eb391d0f1d736D37E0DFCe66665939] = true;
    whitelist[0xCa9EFC20c129853E134f74d3c3249305bB387EFd] = true;
    whitelist[0xF40E6ef9Cfb2135f9DC3788AaAd1e4e008bA776F] = true;
    whitelist[0xBDaD4e473B1Ea1aD59Ac7034368305367BAAB0df] = true;
    whitelist[0xE920Ba2D30e812fCb02004B0253ebe168c623C66] = true;
    whitelist[0x1aBCf617CAE0a686054b95E1720b34235C3a2500] = true;
    whitelist[0xFd12EE8EE98f57d046A53D07e0B655bE5F865C4F] = true;
    whitelist[0xe1ee9E80E9CF310aef6669E8A200De68fa16258E] = true;
    whitelist[0xaf4A98251650054dEd2275dfF736cB86CbF82AeF] = true;
    whitelist[0xEE8dBE16568254450d890C1CB98180A770e82724] = true;
    whitelist[0x6113812dc9e1Ca33b18dc169f3d8bFE2Ae18ba10] = true;
    whitelist[0x525A738a85125FaA8D4e4221d58Bef1fde4a2A2d] = true;
    whitelist[0x2A8Bf5A552347012E1C82Fa3284277bf456A0Ca9] = true;
    whitelist[0xA32B7797eC0D58B8d1293Cd4b8fdD6952FF6a5d3] = true;
    whitelist[0xE537c862B36A670CAdD8d0B34f9C97a941c363F7] = true;
    whitelist[0x69392F1d58BcbD6b181FDf68f3dA89fDB7beA0e0] = true;
    whitelist[0x043C419888A9912e9d85326f326e6f89145732aF] = true;
    whitelist[0x355Ef9a820Dc10773ad66e0f01f59C14948C7921] = true;
    whitelist[0x2Bf201CA17F53CB16e66526Ac073595E206Fe656] = true;
    whitelist[0x802D6cD1650a4418D262b2C3040E4e7a6E30C563] = true;
    whitelist[0xB9013220fc3ef41E8Ac53274B463D8d595ae81c0] = true;
    whitelist[0x1Ff5fD0c5A7Fc3c74Ab2E407e23ED0855Ee20697] = true;
    whitelist[0xB886E39046561F0D3Fcf9A3057c3FAff3FbbDD1C] = true;
    whitelist[0x32F2895b0b5F00fF53EC6279F02876a6cABC3c85] = true;
    whitelist[0x33Bb477E9286ca2fFA2E4584f1a58D894A9326D2] = true;
    whitelist[0xE92f5a12D7BeC3C586C7127d64e89f5ee13d292F] = true;
    whitelist[0xe69fd96BC32B090dB80C1b2C4aB0C6B280cEd656] = true;
    whitelist[0x6358845902610dcF1aFFCbC8B8dFa89830eB7Bcf] = true;
    whitelist[0x816A4A7Db3F04a4Fe7C96bFB1692C7D8698821Ed] = true;
    whitelist[0xCbB28523892a7b0E53927569108e6281C7A26A01] = true;
    whitelist[0x2F631b5190ba4e1879E5B2Ca494c0A87914D9296] = true;
    whitelist[0xF7EfF0CF3E09809da959FA8B163239697259bAFf] = true;
    whitelist[0x3De5a1343324b8BeaE954df867563fDa750004b9] = true;
    whitelist[0x20bb3f80a00341B40f8A90A787b31D575FBC4240] = true;
    whitelist[0xBF0E8949b153DF206088a4C4534715e5219787c2] = true;
    whitelist[0x9FF1d6681508243f9C78C3e4629841BADf7C324b] = true;
    whitelist[0x6144f73C63f5683035e2417baD46374eCe916260] = true;
    whitelist[0xF6269f7Ac21fa56e2bb5B6ABdE67A7040e6F3937] = true;
    whitelist[0x8B200E05047800b0845BCc2ABE08A73AB7946e1c] = true;
    whitelist[0xa10d998F221C2deCD8209277edAad0DAf91654b0] = true;
    whitelist[0xb8a5f175D3868717C2826FA28Ab351870Ab6AB19] = true;
    whitelist[0x81A2DE75C2b324F4d330978349465097BFbB62C3] = true;
    whitelist[0x32F2895b0b5F00fF53EC6279F02876a6cABC3c85] = true;
    whitelist[0xc320E1d56521cF7Bd3D4553B5A1d3a1885298DEe] = true;
    whitelist[0x1641d72805ec0753CE1DBcF3de48E9AD2c1adACC] = true;
    whitelist[0xb78C5F9E3dce3A03d8E086BE52F0367C90eF000a] = true;
    whitelist[0x0afB2649bB2D986e48Ea28e4b4B68Cd94727cD33] = true;
    whitelist[0xFD431Cf4e3A763251f16eC64a2901F842532bb37] = true;
    whitelist[0x843F7C1561DE5a41b94A467496648BCAbad82ABb] = true;
    whitelist[0xDeFA5675CDf2c7482AcEC6A16626D14941F0ACbE] = true;
    whitelist[0xf9d056B6f6b34997e0eE0739Ee5CDAF7E9E40033] = true;
    whitelist[0x7f290cE2Acc8058Bc625870BcB262876A92394B4] = true;
    whitelist[0x8007CB96f8e2B554848EEEf264d0374997f01eF3] = true;
    whitelist[0x098b995b093140565724ED5Be5004FD8a1d0979a] = true;
    whitelist[0x811Da71B116A8FD6200256A1D579F8255cAdACB3] = true;
    whitelist[0xa2a5840165a163DB4b291Ade9B2aE5b083bFA22b] = true;
    whitelist[0x9DA3AE635d01adadA305D8F8f960b6811CcA41b7] = true;
    whitelist[0xb0ed9703eFfA36C4286D3ECb9CFa37D992f88abC] = true;
    whitelist[0x746a646dEaEDA59AeCf679813e97F659467f43BC] = true;
    whitelist[0xE52026106A3015F88774a30c1705aC325043c222] = true;
    whitelist[0x4E03C2Bf6584Ac074b017E2468349Ffd25354359] = true;
    whitelist[0xc93e979C7Ea358Cd3c26100eb14f3C13f57A2F88] = true;
    whitelist[0x5f4F59301E46Bf6f6603a8c4cF826BdaC70339d1] = true;
    whitelist[0x0DB7B02820b8826Dadebe2b0a92AC279D95ccFDD] = true;
    whitelist[0xee1401bc875aaF08e761CC9227058ad383C22B77] = true;
    whitelist[0xa3E14B0e7726C6b26e52522A4a28ac13AF40FcC6] = true;
    whitelist[0xDeDb918A4207049FAd9c0FD51e787cA1346b98AC] = true;
    whitelist[0xC80E4Af36C8759d9ff7E015EE097ba1b2Bb50752] = true;
    whitelist[0x7c2bB67A04B62b553a80d1498f4c58478677A8aa] = true;
    whitelist[0x0d5D10C539ceA9f5B7Db9412f93048deE6FD9B2e] = true;
    whitelist[0xeCAd356FA7eEEe984Cef5951ff74318C7d422b7f] = true;
    whitelist[0x4d09Da932D4983Bb8D7033C37017aC17dcAD36C4] = true;
    whitelist[0x2431aFD252f3599E27DDE47551fACe45971F045F] = true;
    whitelist[0x3e57efEf507b4db7aCFa2eE79CeCA6B19e18D106] = true;
    whitelist[0xD430dE36f41a1773A320494521a2f20Cc102781D] = true;
    whitelist[0x4536778854067CF5b63C6942e4110968A323DF23] = true;
    whitelist[0x96Ee4daeA1BBA5fCA92C51CBa5116d5BdA02A716] = true;
    whitelist[0xC20B3953f5A388bd3E62070a94246C7dCd58D64E] = true;
    whitelist[0xE174C218aca513Be78c61A46795c2D3002FA3573] = true;
    whitelist[0x369cf4a0733e24fD2158dd78C12C2f691cef078D] = true;
    whitelist[0x1a8dEF8E87903B2b852f14e8b3EEd38C575e375a] = true;
    whitelist[0x53B8e895346Bc83ea9C1F51a5010c91f892438d5] = true;
    whitelist[0xe60EF4317d4a9F0422A90617734f996A54BCb6df] = true;
    whitelist[0x02CE51592Cad04ED45d6F9D13833238d6BEa2C9d] = true;
    whitelist[0xA65e83994BC7dbdf4d29811C741D5BBf4a2FCB2d] = true;
    whitelist[0xFbD5bD432F653d611C5A942eCF18409c78FC34b6] = true;
    whitelist[0x0888Ad7d13C91A1c76EcFBa6Cd572801d5aFCeb6] = true;
    whitelist[0xA0fE83611d0971801FADd7C149A3743b3e78dfb2] = true;
    whitelist[0x1440Ae8Dca563CcE8aaC9B0D664214543bF84173] = true;
    whitelist[0xFfcd936E37AEEb7C587D4fDd982cD467480EAA01] = true;
    whitelist[0x5a9681b30F543E29Dc363b9c6Dd4a72894512192] = true;
    whitelist[0x0B1a887c3AA0316cC9e7a6683BC09A4Bb56c9e94] = true;
    whitelist[0xB6e47C3864549a961f66162DBC4a7c8CdD80B751] = true;
    whitelist[0x86Bd57Ea9bA28676036a2E80363f863B7d35d164] = true;
    whitelist[0x0247aBDB741074aff8c49351CBd8f848E922eaF2] = true;
    whitelist[0x966fE65D5e88824aC0BC5603e7fe0068Be6cc649] = true;
    whitelist[0x878a17144EC49F9eFC1E83903778c9C86e61aBdE] = true;
    whitelist[0x158b0600Da9eEfC914e89f9c4c43C4326eb3c353] = true;
    whitelist[0x9833bD1c2E629a5d2e7D5B15eBe250e8Ffa4AA96] = true;
    whitelist[0xd85Ef6A04B9270F992f9cd83AEA9380b3172E383] = true;
    whitelist[0x266efE26bC5112F1B0e85e8E2130940DFB4865eF] = true;
    whitelist[0x87038419450db8C0bbD9897Df8F8199659a43047] = true;
    whitelist[0xc3F8E3dB511e2e109A9123e966611D357847b54e] = true;
    whitelist[0xaf0A27118d9b88d867bC05a12c5964bB8388ccab] = true;
    whitelist[0x30755BF9849a20d91761df270C6823419fC5ed7a] = true;
    whitelist[0xC0d524ac24Ade60507cB59084a34463888Eb3370] = true;
    whitelist[0x4818e7c8cd65662c9272Fe2eC7F1CC2516149530] = true;
    whitelist[0x7e90ecEED693823EECd927f359CC6C816aaF53c8] = true;
    whitelist[0xA580F6DB19825990cDFE69f3D04803b7C5c81235] = true;
    whitelist[0xeA9B13b35239482BF2BC05D7CBadF5ec47a0085F] = true;
    whitelist[0xAE91CB00C413A8D6089Ba0bc8bF66fbA47A912Ea] = true;
    whitelist[0x2F631b5190ba4e1879E5B2Ca494c0A87914D9296] = true;
    whitelist[0x6b5Eee440aed19E066bBb255E236e7b4efD0f9e6] = true;
    whitelist[0xB8f3f8F25f38F5fA968fE7e624cF8E64f1Ed1BCE] = true;
    whitelist[0x0103B8C1124c2D70b9e7d81b60d20CEd79D3d9c2] = true;
    whitelist[0xe76E808b5873445d9059a51C4626992F560BeF8C] = true;
    whitelist[0x8E0AAadAeB308ef62AfBf52D53797977755907BF] = true;
    whitelist[0x4536778854067CF5b63C6942e4110968A323DF23] = true;
    whitelist[0x886039c3eABbf3613870511A72fbac74Ce25e4d5] = true;
    whitelist[0x1890E5713a9dBc98cd2146D0Dc2fe5A9a157DF92] = true;
    whitelist[0xb87Ebf06f8C99F43ecad940e4F1ACe84EECE776b] = true;
    whitelist[0xE8CC7A9e523886eF71783C6b3a8B49B421f8254d] = true;
    whitelist[0x61AB5003df44b49e115AfD9AC4e8c7Aa7D4B4A6E] = true;
    whitelist[0x830CB87bED6eB9b165Af962275550e8F32cfEd1b] = true;
    whitelist[0xF32249de62c49a8f3EF55ce564f8D4079db8564f] = true;
    whitelist[0xB2f51C8995224FF6e9a43371f25699ceBD2e5758] = true;
    whitelist[0xA022a5A072eAD080798c4E771710674406754b0e] = true;
    whitelist[0x43Ec5640E18F7384761d8817AA55d38C9a03D855] = true;
    whitelist[0x7fE0291F068BeC0cA18921756683dF8a73759fe6] = true;
    whitelist[0xE28E27239D891762024863D40A19338DA8559792] = true;
    whitelist[0x5540ec65a1Ac7eCC1EA39d81ef32192Da00439e1] = true;
    whitelist[0x7F7B584316CA0BC62dFe3e2165a45C2e40b04972] = true;
    whitelist[0x71D11243995F3003B4950E6FAEd483531F82eCA3] = true;
    whitelist[0xA8a51aB18B7cCD7474a4248Ee66E9C7E12D63A7f] = true;
    whitelist[0x36387ecCD493D4cDF6D4660D127390e0e1c55dA9] = true;
    whitelist[0xABF7FE1fB3ED2d5b14A46704824035A663acAcb0] = true;
    whitelist[0x8a5412601362654083409d6b5328fF7601822cf4] = true;
    whitelist[0x2Ac6A9338182c40fbC8C98ba522c3612Ee75b9e9] = true;
    whitelist[0x68fe4F773F50b15D396Aae30Da83Fa2f1285E5dd] = true;
    whitelist[0xb0dE71cE781c5161B41FF0A6773d7814E238A7a3] = true;
    whitelist[0xeaCb4fb49a94FdDAc3dCB7dAd5C63C3807A235Ee] = true;
    whitelist[0x08Deb89d3A895f535C8a9f865d93C146Fd7b5dA8] = true;
    whitelist[0xCD03b446d62d4df2f0A490385C920836BB9DC00d] = true;
    whitelist[0x78dac94Cc6D45c0D3100c2998b3e2753dF51BE74] = true;
    whitelist[0xfeD79641f2f8AEca217a25a57bf9dA1B0cca3575] = true;
    whitelist[0x888a02C76Dd3eabDB1bC6C381f438B4D0FA5d139] = true;
    whitelist[0xBF4Ba91Ff978559e597ae600bDeF71B8E352D47a] = true;
    whitelist[0xE52EA50aB6a3e481A555181aa01bD68150984b93] = true;
    whitelist[0x1448407b29d8e8a14785fE6496A75B5eB017c356] = true;
    whitelist[0xB90D71a2E044671DD254AB76A7F93782F8cDaBc7] = true;
    whitelist[0x7A7F7bC8737284A7523e92cA0ec018Dc7d51D3e9] = true;
    whitelist[0xf8681c75e84f1526695734FC2e0B8d57047afdF1] = true;
    whitelist[0xF7EfF0CF3E09809da959FA8B163239697259bAFf] = true;
    whitelist[0x07c08019870EdDE4dab631221C1483DEb35522Ab] = true;
    whitelist[0x246575a13ee62782e5A45436720Ba953e5Fb38Fc] = true;
    whitelist[0x727A630fC1Ba3E3e71e9e4b16Ae118526644e6FA] = true;
    whitelist[0x02380eb61a3560a34D76c0aD6f95F647Ae607922] = true;
    whitelist[0x1DDc2822e0f28AE5CF5188392FD487756CBa8b3C] = true;
    whitelist[0x2F7e7145417f3d7977f6B083F650640ddc77446b] = true;
    whitelist[0xeCf8dd1B2F532EeF1d3157B9E89Ca1dfd50fB51a] = true;
    whitelist[0x6f6C0bCD874Ec6352529Ed30AEbdeCA0b8Fc5c42] = true;
    whitelist[0x1e0754Cb0545444789411D1874c82ef1C5bb5Aec] = true;
    whitelist[0xe2e163c84e35c58cbA2E406BE079FBBDE86129A0] = true;
    whitelist[0xB32E083709588a1b3fA9C115C48051e61CBEba0a] = true;
    whitelist[0x463545d705EfE124E8bcE5d6273E3439F866527d] = true;
    whitelist[0xcc9D2aE32187D7087417EB236f552faf50A8CDf3] = true;
    whitelist[0xeeeeD7b12ceb4A81d73dA09fa915C847f7d6fCDA] = true;
    whitelist[0x38eaa9C3a73c807139F271D180fbfC23734c5661] = true;
    whitelist[0x6761BcAF2b2156C058634D9772F07374D6eDeF1d] = true;
    whitelist[0xAd188F0D79A5A1fF9c2bf506a20494cd04976545] = true;
    whitelist[0x42A2eDC109223860a19a3D0C1f1A31800505755D] = true;
    whitelist[0x605fDC424e7a6431D83aF0C9a3271Cd40877d532] = true;
    whitelist[0xb09ac06985bccdaE518F0E9cA3a0c4f335812F12] = true;
    whitelist[0x33352D8D29E293f4b379E28411337D9F80963574] = true;
    whitelist[0xe32fCd2aB4167C62328A539C70AB5878c67d327a] = true;
    whitelist[0xdeCe737bA8E9D72432Adac9C0e09c9cFDE20fd98] = true;
    whitelist[0x6db59d87046899232Ff5E89f29853B5aEa71896A] = true;
    whitelist[0xb4b6cB2789BAD42A9907493068996c358e1E5e0e] = true;
    whitelist[0xF8AF8b05323C61C6c48e4Df67f49f6CA4cEDC066] = true;
    whitelist[0xe47a92b4a21F99F145cF79BA13179757A5845ce3] = true;
    whitelist[0xc5FdaA35D33e72634aBc8C3EBbb84255a5Cd20b0] = true;
    whitelist[0xFaA10ddEf55E6C73Ac12239975580cEa755958E7] = true;
    whitelist[0x3b4e2496d5766994A87b25f99cF1d80802213172] = true;
    whitelist[0x6C89aC0F159aec29531aD2Ac57464e7788751687] = true;
    whitelist[0x412572dF27b3F0baEbCE8Ec0d138A737Db439112] = true;
    whitelist[0x2181f884b1aBDaBF6cce49687608A9779bf61A42] = true;
    whitelist[0xbD6b34a1d5db3FF53386307C6d505bB4afDC9cf4] = true;
    whitelist[0xcfa222e8C747A7BA317da66441517b4498A16b91] = true;
    whitelist[0x164b252a75AE99Cc172a2863e23790d68D8D58D3] = true;
    whitelist[0x0ACe27EbA543FCDa9412039b309A321346D395FE] = true;
    whitelist[0xAE91CB00C413A8D6089Ba0bc8bF66fbA47A912Ea] = true;
    whitelist[0xcabC8491816d5fA9F141c722FD8A08f2fd538333] = true;
    whitelist[0xf6A7Ac57755d77F90b66A7BC7C57feBadA87f24D] = true;
    whitelist[0x0907B14771F2b04c5A4643E611d23f7e988bD35D] = true;
    whitelist[0x72F711e517e8A7F67f6e44C1d5A19dBb31E96b53] = true;
    whitelist[0xA9B3E7810192733E08FC887256d0fD694644ab3e] = true;
    whitelist[0xBD16D508c99f3cFb137e38643eEaEFabde9cF1c9] = true;
    whitelist[0x008524Ae46fbB63bcd1DCB1BB766eb9eD798B1B4] = true;
    whitelist[0xa1Fbc680C30E5E1b19f5c5DAcd74fCB7645FFb57] = true;
    whitelist[0x70256b77453d6f1868741a52150DceD00D7231fF] = true;
    whitelist[0xe56B72d428c1A513f88F3d3BBAa3028F3Fe0f3F3] = true;
    whitelist[0x17476d0Ed31f81d95b5ba8960b2D0b4dE4675e64] = true;
    whitelist[0x17476d0Ed31f81d95b5ba8960b2D0b4dE4675e64] = true;
    whitelist[0x1ea39aB6f0d2113D99CC534d4E78106Be40927Ac] = true;
    whitelist[0xc4bD5d119bf3BDDDBF1D96bB65c2ea3BEFeAb212] = true;
    whitelist[0x0456728ecDe574eD1E3F5149da8Aef6772a911d3] = true;
    whitelist[0x4Bf5335C585846ED76b2E8702BdcEb9235B59F13] = true;
    whitelist[0xf8500be9E6A73C0412BCe8641634A770bd1ECa6d] = true;
    whitelist[0x962549Ab93A17F83F457B5177E7F21c59E4CF66d] = true;
    whitelist[0xBFe2F34Bc286E9e5EaC80F4BF968F91690BCDd5F] = true;
    whitelist[0x17b920Fb5dEf4395076Ca0A7f95c04454FAf9D6F] = true;
    whitelist[0xbfF29b6cfD0c6BC845D4f70BDeeb3378a4AD39BF] = true;
    whitelist[0x71157223A91189713B0B46f59815035cf2F82143] = true;
    whitelist[0x344302A1Adfd32e76177fF5a7cccbBfbF535279b] = true;
    whitelist[0x1dfd7c9f16d10fecb0A1c85654C4a0Aeaa92c137] = true;
    whitelist[0x740cf202C71BFc4DA5Cb8372E79ad88214DF1a05] = true;
    whitelist[0x05961Fc27913EfF9B11CdE8F0d6D2349e8B9a5eB] = true;
    whitelist[0x70ee76816B7ACA98F70dcd20802aF98448B9156B] = true;
    whitelist[0x0b1B848Dd5436412EcC8c0CF1E1d7dfFE92f2c25] = true;
    whitelist[0xcC9ec80aCB6ca0190A89C7825e14317eB5Cb43d9] = true;
    whitelist[0xB1258f8C92c969F7FEBC1AC266eA7ABB6249885b] = true;
    whitelist[0xb054CBe6aa8dC1b999e84DA9289C867FB580aFB2] = true;
    whitelist[0xbFc2B209406d4cA12231095de760f514E4A39559] = true;
    whitelist[0x5601b9447b984EDCFfacafD0dFA79077b755039b] = true;
    whitelist[0x6f6C0bCD874Ec6352529Ed30AEbdeCA0b8Fc5c42] = true;
    whitelist[0x00BddE1e87Ff78e1270E45C7EDE67d932B11C5Bb] = true;
    whitelist[0x00f903a27295c1BB22Cf685b9452e3183d07e5FC] = true;
    whitelist[0x724df920406dC0a47cd58EB838df5512D25fbA02] = true;
    whitelist[0x9c7Da566f9b64Fb310DA316cd00332677E736F18] = true;
    whitelist[0x5CA2dC754353C692b0dbFBFCF4574938754dEd4D] = true;
    whitelist[0xD283AC6b8dD58CDE7EdE41002219D976115Dca36] = true;
    whitelist[0xC5bc9715874C91ded9313A06baEfa1307BD72299] = true;
    whitelist[0xC76eC56Cd15A7FC2ca7d1005710c06ac6E5B28F7] = true;
    whitelist[0x14B177fE4B22199fA26C0c98Dcf0082a0125e0e2] = true;
    whitelist[0x51ecDC62FeA43E8596F82EBbE288FED29f909634] = true;
    whitelist[0x5881513A30cec2C84D61166b258b04789a92d9e4] = true;
    whitelist[0x822F2c20B49b8BDB8d62Eb11a558371049bFa951] = true;
    whitelist[0x867Eb0804eACA9FEeda8a0E1d2B9a32eEF58AF8f] = true;
    whitelist[0xf97090f5D3E0e96E1c9Cc6f07153602c2922D0E1] = true;
    whitelist[0xeedcC4D7d9ea1C9c1d1944717a1dFc73663d7D45] = true;
    whitelist[0x627eEBc2c3b21129D98D17816b8bA05aF0c9ac66] = true;
    whitelist[0xb0ed9703eFfA36C4286D3ECb9CFa37D992f88abC] = true;
    whitelist[0x3c3710bF782cf67f025AdD26C3D7Db4767C98D5F] = true;
    whitelist[0x38B29d63E93fc3D2D6670cf047E37bE1e9d84c5c] = true;
    whitelist[0x200d029F48ED9fB76A11307Ae55c8fcB2b7Aff73] = true;
    whitelist[0xE4Bb5b561D23313c89f53d80f049545f1AFD2CAF] = true;
    whitelist[0x85e8505b9C139e48a7Bb1E20cDaA9efA9379A68f] = true;
    whitelist[0xb4C95EaEA8eD720CF0d9450A5bf868711EcD06D3] = true;
    whitelist[0x9D55E92DA14498C97039867a8AaB200e7d37123f] = true;
    whitelist[0xE5463558a8241EC7bC70B202e7CB3D1465DbB124] = true;
    whitelist[0x4b15bDA13573A2d619B61065302CC6a703Bd4226] = true;
    whitelist[0x8BDdA04420f66B19194cF6a0c108291c1B8536D9] = true;
    whitelist[0xA50A9a55811d105C2d5451C688B4B74954161185] = true;
    whitelist[0x775BF864087e10FE0722F0e028c9f943d3fa62e9] = true;
    whitelist[0x0eEBbb2a7A718AFe461583d391dBa7F34cD95735] = true;
    whitelist[0xf22D096F6Fc9693B67D6B3401845A7E6FE16192a] = true;
    whitelist[0x85aA5f089EabBc67dA4b89Af5eC3140DCD3d8Cb9] = true;
    whitelist[0x3Ed483BE178d2ea17E53cCe86F19b37974d65868] = true;
    whitelist[0x0c0ffaaF6378cc0B4118F2752209a206A046d56E] = true;
    whitelist[0x945a5dbc95fDD6c0Aa873ACfc0d3CD4888E28E61] = true;
    whitelist[0xE6931F9804E194a15c9371E7A0841129f5b66FB2] = true;
    whitelist[0x69353ce89dcD43D3d8ED1AD996Be652b6f37C38e] = true;
    whitelist[0x3d66B618Dbcb3ea2001821c6844A9ad9Ca9370A8] = true;
    whitelist[0x3e72cd9D721279300121f54910E30b25de55B24f] = true;
    whitelist[0x392AfA384BcD9d884466A830DBAef17fECB43397] = true;
    whitelist[0xACF967E499F8cACd2eAc27A3cF3b956BCB748DA9] = true;
    whitelist[0x7A5EEcBef4DEC2533D81A7535A9C57B74Ef1EBD1] = true;
    whitelist[0xf52B6A3CcA0f68Ceee778547F6C4A43D423defed] = true;
    whitelist[0x99a7BEE5AaA9B3bBE1842Bfa4D563B5C7F6d100d] = true;
    whitelist[0x20d41C09Ae21132a2909f77bAEE4F39303250Dd6] = true;
    whitelist[0x4aB7ea50930b28b6A5d60879E8705faB67d36722] = true;
    whitelist[0x7d0AADcee7365FC0dD22575736F8B9F73014aeBf] = true;
    whitelist[0xb9074044b4A8d60112701Be1177d6676de43A662] = true;
    whitelist[0x207a1868C0063039461b953B811eBE84d14DA5BF] = true;
    whitelist[0x1Ff5fD0c5A7Fc3c74Ab2E407e23ED0855Ee20697] = true;
    whitelist[0x2F631b5190ba4e1879E5B2Ca494c0A87914D9296] = true;
    whitelist[0x22c3052464e684Afed272789a9108eF66606C46e] = true;
    whitelist[0xAa263edb6bb2eab2E4013bBE90e726753fCF5AF8] = true;
    whitelist[0x5E7794141088d49F95b11E0D96527d639e66392E] = true;
    whitelist[0x7c18db094612b2e43f8a3aB58dd412dF81dd3A76] = true;
    whitelist[0x75Dd1a37187773347FE7c319A3077099043Dd6B4] = true;
    whitelist[0xf9d056B6f6b34997e0eE0739Ee5CDAF7E9E40033] = true;
    whitelist[0x4c3CA732DcA1eb35CE3e68005B94103628d687f8] = true;
    whitelist[0x97C86496af9BA5478258562C370275D04474C19d] = true;
    whitelist[0xE4F7B6d11c8A25c778e70bFC8CCAfF690e017BcB] = true;
    whitelist[0x14B177fE4B22199fA26C0c98Dcf0082a0125e0e2] = true;
    whitelist[0xfF5c5df35ec7cD6Efe36a63B2bd5f4df9A7211aE] = true;
    whitelist[0x88cCcd08296F8dfA666478A7187c408f832b8E98] = true;
    whitelist[0x2F631b5190ba4e1879E5B2Ca494c0A87914D9296] = true;
    whitelist[0x9A782Ab347F19F7AB2bf8d2AbB1B968384273988] = true;
    whitelist[0xb78C5F9E3dce3A03d8E086BE52F0367C90eF000a] = true;
    whitelist[0x9937D915BFF7Bcb091C5d93Cb5F2fb757Be6554E] = true;
    whitelist[0xeAb3cfBF53AeEA4D9ddd138ed9EE379ff30dDA3f] = true;
    whitelist[0x7D31A4758267d65AE9A9Cc68700FD00279B463CA] = true;
    whitelist[0xdB5dc95BF080dd3921C2C6Aa5c30F108d55158ec] = true;
    whitelist[0x4E03C2Bf6584Ac074b017E2468349Ffd25354359] = true;
    whitelist[0x0eEBbb2a7A718AFe461583d391dBa7F34cD95735] = true;
    whitelist[0x394F290C9C89e51f150F40A565381F79396adD33] = true;
    whitelist[0xB0736A8436f4F226D63d6f0447968479C39c8F41] = true;
    whitelist[0x4d09Da932D4983Bb8D7033C37017aC17dcAD36C4] = true;
    whitelist[0x16Bd3527128aAC9061dfDe0B05fcf26B148c7cf6] = true;
    whitelist[0xF924232D18c1Fc74c47BA623633C1B643eEEb319] = true;
    whitelist[0x2F7e7145417f3d7977f6B083F650640ddc77446b] = true;
    whitelist[0xB35cFe9ea3Ae22902eef91bA5584CdaBDa7a3b59] = true;
    whitelist[0x3D2E21E911f780406471854233656C01C1b4E5ae] = true;
    whitelist[0x58d55449E4Cc7719970A27bD1Be569cd6834483F] = true;
    whitelist[0xe53455412f627aA4586CB9C33030D9D51dC3B56A] = true;
    whitelist[0x5bBA33f03671B7AEEC91cbD05Eb31776Bc05337d] = true;
    whitelist[0xF63E7E364bA2A8cE99c34563A9768B3BAfF65D1a] = true;
    whitelist[0xD6587a974C7D3ecE23Fa53d5606da6B291311F6f] = true;
    whitelist[0xa1e58D3853A938c75D1A54FEd332A5814F94FaDc] = true;
    whitelist[0xBDaD4e473B1Ea1aD59Ac7034368305367BAAB0df] = true;
    whitelist[0x6A20dFbB6F4Ee6476AeF9aCE825cC6e12c50835a] = true;
    whitelist[0xf1E07E08C90bd411FFE296140d3F886e249b94a3] = true;
    whitelist[0x06F9d88ddEf658A4491e46078FEEDB0e3c18cbF1] = true;
    whitelist[0x535EFa407b36889c3280d75E264a7d122b63539C] = true;
    whitelist[0xe7096dAf78c15bF0889230a328e3482930F3c936] = true;
    whitelist[0xDb1486005448686beDda0D52175cbE2C9a739EAd] = true;
    whitelist[0x8fe067dEaa37CECE05601223a763B9961769E6F0] = true;
    whitelist[0xA7Aa4B444A75F6Df5fcaE6E563755b14CF573728] = true;
    whitelist[0x97B68f5D84F931a144d829E17b0C97dAE0912283] = true;
    whitelist[0x76dB815a1C977124F2EcC8861c3215161d9c1a89] = true;
    whitelist[0xeAb3cfBF53AeEA4D9ddd138ed9EE379ff30dDA3f] = true;
    whitelist[0x7D07cBa0Db193A340D3466e8596c4Cfe0Dc33DE9] = true;
    whitelist[0xD20C80897Eb88cDB84664aECfeD3AB9f1051C6Df] = true;
    whitelist[0xB6354C33576069d677C73b15abc9FE20DA80Dc0a] = true;
    whitelist[0x671249ef1bDb683C37A893aff13C70eD37BdF977] = true;
    whitelist[0x4aA1F597164871347ED33B2be7bba2Db2EBE5799] = true;
    whitelist[0x8290326F3d2A01659996B0DC1638c3374b49BF65] = true;
    whitelist[0xA2427cD956602612Eb9cF36a01b6bD67ACF81A59] = true;
    whitelist[0xc3Bd7EEfC1e30E351A64F764621aecc0B9825394] = true;
    whitelist[0xa44abB19Ac28C10Dcb11454e0A1D2b91351c0B57] = true;
    whitelist[0x5A6D4C34C6A43C39aC7787AD88f0EE6e5F537740] = true;
    whitelist[0x75C8cF229D0b50c04dD264AAcc8539898cf6c9F8] = true;
    whitelist[0xD209A08E6aDb55C6F7BB74F6D0cE7444Eff47578] = true;
    whitelist[0xd2488630C14CA417cE41a0Ea801b3E11CD20cAFb] = true;
    whitelist[0xF4E115673718Bb540665Ae901f392f96996fb336] = true;
    whitelist[0x4536778854067CF5b63C6942e4110968A323DF23] = true;
    whitelist[0xEdD4BefD928C15e02D0FC3d4a2998dedb9252188] = true;
    whitelist[0xF04addc585002735C378b5e51A813513Ad8E3B64] = true;
    whitelist[0xa05f6ae479C84a404641bbBF58f2a3aD364D73fD] = true;
    whitelist[0x1304F7DfCaDc3d30bA8510E328650eCBEFBB4c1d] = true;
    whitelist[0x85a4a13f408f3D275980379A8e3Eb1Ab6f9232E9] = true;
    whitelist[0x09C406bd813364C406f183104AB2E9Cca77CDFe3] = true;
    whitelist[0x3e72cd9D721279300121f54910E30b25de55B24f] = true;
    whitelist[0x85e8505b9C139e48a7Bb1E20cDaA9efA9379A68f] = true;
    whitelist[0x5CA2dC754353C692b0dbFBFCF4574938754dEd4D] = true;
    whitelist[0xB40f05Ad72E7Bcb0d8ff05A3D6C47E9331e759be] = true;
    whitelist[0xdBfEa76bCf122B8F62EAb66e36f2f1F378ab7d9B] = true;
    whitelist[0xF22b63bFaF049C9a91e9933b962131dBdDaFc838] = true;
    whitelist[0xa0501600eD268594c6710c7531D6093c0fAd29DD] = true;
    whitelist[0xcf25A23D533F9156eAb5Dfb6c2520901b475214c] = true;
    whitelist[0x3cAc7E12dc3bae6EBe2909C82ADDb04DA4CC340b] = true;
    whitelist[0xeeB2FFA13F4eF4381647FE642eBFaD0CC1BBc467] = true;
    whitelist[0x169bfe7762F05385894b0989A8aAa7fE899524E5] = true;
    whitelist[0xcc9D3DD3F433De6c14E8881B13D4BcfE1A3E59f5] = true;
    whitelist[0x377E13c59F0aDb62de0C12b4F6eECD4E7a8d04d5] = true;
    whitelist[0x7Ef082b9a971f198f9ddE7f3c331B16a43D76EFf] = true;
    whitelist[0xbb2dC6Ca53A9D03219b10916125038e29Ae695e2] = true;
    whitelist[0x448427b62249AcC4C2d69e56D2723e21924B27ad] = true;
    whitelist[0x0B1a887c3AA0316cC9e7a6683BC09A4Bb56c9e94] = true;
    whitelist[0xe1852a39d6865BCA5922F71696E22d4065263626] = true;
    whitelist[0xA669D9B0e6b89e661Fa125DB990498fE84886bfb] = true;
    whitelist[0x48F1ef35C0E7B9921102f4b8F2AfDaeEeE62Efa8] = true;
    whitelist[0x5339026Ba61Fe0fFC2774D2c4cBb4C91c6CB5c22] = true;
    whitelist[0xd09e7Af426b05c4c4fB79632f1be6391470cC7Cb] = true;
    whitelist[0x9BF43BfD38F96F459e261f5531291CE9D3913588] = true;
    whitelist[0xF9756e4f4355228dc6f11Df58683E85303828268] = true;
    whitelist[0x75B81Ca1C61A7e59d3bdcd9d293E6f7e68ca1031] = true;
    whitelist[0x6aBfF48E92FDd073b497756089253E43d42747FC] = true;
    whitelist[0x7b17d8c2e5d8518c4D25d97e6A1EB1D0D7ee4a71] = true;
    whitelist[0x2F631b5190ba4e1879E5B2Ca494c0A87914D9296] = true;
    whitelist[0x694CD0eFDFA527233aa1d324798AcDE775812aF3] = true;
    whitelist[0x1D6FA76b3a383cb9ab4151f9AB1597BC95948A4C] = true;
    whitelist[0x13bdEf348c679FBa043b96195536A404cDd8E66f] = true;
    whitelist[0x899bFF3d1A3592DcbbA5Fe11ff230cb87539c5C5] = true;
    whitelist[0x716428E298a00937bd4F07a55c06B69019266133] = true;
    whitelist[0xe1E44529a2E9166C153993c7Fc55C39be6072b94] = true;
    whitelist[0x010349096105E83557fD8ecc2b269d2d2DBFf593] = true;
    whitelist[0x6d3C4f01Fe5C5Ce3acfdafc234bB3C610F0B088d] = true;
    whitelist[0xEdD4BefD928C15e02D0FC3d4a2998dedb9252188] = true;
    whitelist[0x26915Ac15d6B30Ca180c343E52FaF33C04f26F5a] = true;
    whitelist[0x531bf9FdC6da22aF543f579C1f733C6863f60abb] = true;
    whitelist[0xEE293E4ceb7Aec9f70387e850F5dD2d58764B4C4] = true;
    whitelist[0x2Bb456d6580f3c6BEaE4131182cF64b791202a0b] = true;
    whitelist[0x70F6Feb191F3E235aB3231740840d132800a16dB] = true;
    whitelist[0xa2d887d384a8D71faEf4F7433db3709c1b385533] = true;
    whitelist[0x0eEBbb2a7A718AFe461583d391dBa7F34cD95735] = true;
    whitelist[0x06D6f74C14ca13505220751ED21Da78c644a9144] = true;
    whitelist[0x9e0b2573059699AbB244b5bcAad8C9924f9f9422] = true;
    whitelist[0xEE08323d41cbA6C0b72f8d952da8d364bc1Ea71d] = true;
    whitelist[0xFb054de87c048fE9f9D859afE6059d023529E0d8] = true;
    whitelist[0x27aadfa8c75cEf8c3B02B63C626360649f5D2C83] = true;
    whitelist[0x5EA707f72EF17ff394d020Efdc6E5A6044872662] = true;
    whitelist[0xB970f60495B36Ac66c06f9b01e3b1520c2a2Fcd7] = true;
    whitelist[0x4eC3B52C788f58a6f273F33e4cbC38ae2cBfE6C8] = true;
    whitelist[0x78224A21316204f52C548F0de5F4aC38289D8148] = true;
    whitelist[0xfe535192BD5cD07eB2A5Cd14e9B442396F4Ff9a8] = true;
    whitelist[0x83dEcCcB466c913a6728BeFbae0C84169EE8BDdf] = true;
    whitelist[0xc56609d9bF20f92c79bD5ea83FF4b5CfF5327346] = true;
    whitelist[0x7152275089DDbc2704D31C5A7B70ffb0eFf949a7] = true;
    whitelist[0x25217b4A6138350350A2ce1f97A6B0111bbFdB56] = true;
    whitelist[0x65Ec79127a65543287A665fBaf791D9950F0ccD4] = true;
    whitelist[0xD4f0dF7005d0533768073896ef42D528172AC4Cb] = true;
    whitelist[0x2dE3BA92ff11baD1D8a7Efc40458368aBe7056a0] = true;
    whitelist[0x1234630A271A09d8cf10D2CEBC54caD1B1fb87fc] = true;
    whitelist[0x8bB59a952c3E9369f3ceE04B62c1340E0938dB7A] = true;
    whitelist[0xEC8637A34a5851308c9795F0eEA546aa71A5be21] = true;
    whitelist[0xB63c8F6F2d1bd1ec17a063c422B4282d871704e8] = true;
    whitelist[0x863e71979c2941D654124C69B905F42256F3D7ad] = true;
    whitelist[0x9254faD610D5AF7c2AF34532f41DD8c0f9C6871A] = true;
    whitelist[0x7f78369116DA61F4fDaB029745f6A86CA55Ee76d] = true;
    whitelist[0x6BeD91Db4C11a37842BbaB1A8e6A463fE09418ee] = true;
    whitelist[0x3912d7eA8140e16dAc355892653F3512C3cf3749] = true;
    whitelist[0x29e3bdd9D22Acc8218De137F3f50C733e0CaC30B] = true;
    whitelist[0x181ea61Ad520715E17eae17096BDa2F03207EC58] = true;
    whitelist[0x2594c567255FAa27b914E0B1a69bA07B473775fD] = true;
    whitelist[0xF3Bf4cADebEe8427f6fC87F4D846F21D78Efe2Dc] = true;
    whitelist[0xD43b91df4Cd2a48a6D2Ae22C91fCF44ae3877d7F] = true;
    whitelist[0xb32F3e7810b563BdDbF021679309395342f35923] = true;
    whitelist[0xaeae1a9Bb55e9c5593657010c57Af03385871CB7] = true;
    whitelist[0x07617900F0a489c66CB048933C3a043c0D0C130F] = true;
    whitelist[0x7B127A9e5bF16CCBFc1a83A65103A11aC70c72eF] = true;
    whitelist[0xb29f00014179028f0Fed2a2c96Ad9C96CD2C20e7] = true;
    whitelist[0xa2132aE11FFa79235da955aD68de9B52B291b921] = true;
    whitelist[0xCC3cEf3Ce97bF809AebaD89eaF53F05b92Cb3152] = true;
    whitelist[0x6DE6EADe4F726F94679C4695D64a5Aa81fcBbFE7] = true;
    whitelist[0xAF3c20498ff9AB190af36764428FCE9017C54758] = true;
    whitelist[0xCC68b310CDFfc3054b38843601A5F27ed9794d39] = true;
    whitelist[0x77e0292FEfDa350Eb91653c9694Ab645dF80404e] = true;
    whitelist[0x4b95F69A5375E7BB15A9e74412082DCe283Bd497] = true;
    whitelist[0xA13e7aF1B3c0446c7A331d64b35bF52D2c541F02] = true;
    whitelist[0x4245015AD786b6Af1ACed544127aF4DC8C6083fa] = true;
    whitelist[0x273689a39EB1018A5c2fedB0A9846871fF8d8050] = true;
    whitelist[0xE7921F821F86D16BF31CD3790175061a965d5270] = true;
    whitelist[0x273689a39EB1018A5c2fedB0A9846871fF8d8050] = true;
    whitelist[0xAa263edb6bb2eab2E4013bBE90e726753fCF5AF8] = true;
    whitelist[0x832A1c22272Ba7d57223f05312A7352A8F83063E] = true;
    whitelist[0x605fDC424e7a6431D83aF0C9a3271Cd40877d532] = true;
    whitelist[0xc101598AC79799585D67B0801544c260A427448B] = true;
    whitelist[0x358421FA33B71eB6f40809bc10e6C4c4Ed12e089] = true;
    whitelist[0xf85AAcA6DA3230e7b9000Db66705D329374A716f] = true;
    whitelist[0xE015938865c3e27c7cc9dE16c9c9521D316955A9] = true;
    whitelist[0x3b68B541aF74A55C5aF69c07bA5072317A4a3288] = true;
    whitelist[0x91a9692957BEECba901495E02F2AAEA991c40cee] = true;
    whitelist[0x6b2d6e1ECD4aA797d0E5009971aDD1151362Af78] = true;
    whitelist[0xa71AF61633645D9a38C9600104e025B427b1f501] = true;
    whitelist[0x593d4E0590fa8c32cE03cB3D9b9bEa6bB9Dd5201] = true;
    whitelist[0x753054Dfe7a80A0c53dEb4FFE5E06fC6C3BD566F] = true;
    whitelist[0xC49A0406771F6542c754E80790f165F6c69d33B1] = true;
    whitelist[0xE6923D4e676Dc5a1E3620790C31306EaBf38eb26] = true;
    whitelist[0xA7949B4De5F5D6D19b1b83665B75A017b0A1B265] = true;
    whitelist[0xb3D85409993310F5Cd14b7cb3e2b92bE6D0b48eb] = true;
    whitelist[0xE27116b4E637e0b700ef213743fA1bE45499899D] = true;
    whitelist[0x54deA17cA6f0a62BD482b7c0d1Cf0805E11cE648] = true;
    whitelist[0xaad08feA58A5822a076bbA2F562F4bE5E7db6f41] = true;
    whitelist[0x1c4b57AE93a298392a5D41B188AB19021B00b4cD] = true;
    whitelist[0x220d482B44F0A5048CbA7719048BdCBfD91B3c6a] = true;
    whitelist[0x6cd8488A870cEDa037260f1041a8886C8725F534] = true;
    whitelist[0xfA02f156c508DF8bC2fFd1fd34Ac7Fa4A598b6b5] = true;
    whitelist[0x69f5ab3D3129D3101fa52CCa6b74398966691f7c] = true;
    whitelist[0x67b847858EcEc3F56800d059045e8E686D5B32C6] = true;
    whitelist[0x1920dbCFDF0fd291A71BeC0b66e20Ff8674b01A7] = true;
    whitelist[0x435D4599c1A4992Dac4F8Db6f73E6b90169f6a0D] = true;
    whitelist[0x3f8F896C4E2C7ACF74B183Ecc742799C11CFB474] = true;
    whitelist[0x97AF989C937C02F763ffA0ceE07A829b4D2B6341] = true;
    whitelist[0x5394A45C1Ae75F54D14A539344263a52fAefEFb3] = true;
    whitelist[0x50F12dbffA732B3e30B0fdf7344D409547026609] = true;
    whitelist[0xd8a13d98eA4A70686b1ABa21fAb4a9a147124609] = true;
    whitelist[0xf33CcD747B1e3E4CA2d896DFA419f85b884eEB3b] = true;
    whitelist[0xAc2511B6817813411d7CC8669eeBF4C998e4320e] = true;
    whitelist[0xb77489bdf08D76e28D2884A07C2C2088dde3Ec24] = true;
    whitelist[0xf27335acd15AFA18e45585811E1be89adDBDb5B6] = true;
    whitelist[0x6D56403D5a6E1Ed520E0C99c0e8134c1e7bFd67a] = true;
    whitelist[0x51A6a7c3a80EEa15d8e8F20Df9B38A902a9e4A98] = true;
    whitelist[0xDA305Cf14AD95d13b332e3d84f639c7Fea7DAeaA] = true;
    whitelist[0x91FFe0Db1acbe42c20D0EE627AB1Ea52DE6818D8] = true;
    whitelist[0xd2a2d64690602bAd517480048dE908045AC0305B] = true;
    whitelist[0x3Bce4AA0337A20313486c49B741764430fd8423a] = true;
    whitelist[0x9dD34548F3Bc18F47E5441790810BD06C5C6fF40] = true;
    whitelist[0x0351bdb23B065c241c0B3C743Bc25F28c695477F] = true;
    whitelist[0x676f41D0B727Da0Cc8b6811700310cF5140b6F16] = true;
    whitelist[0x257FA15F9f60cB4Bfa257E6F91700570F027905E] = true;
    whitelist[0xeB94464aD93BF669DEA59461e144d6f2f3387Fb7] = true;
    whitelist[0x1DDc2822e0f28AE5CF5188392FD487756CBa8b3C] = true;
    whitelist[0xE107b4c78C55685F3A607A5eDdB4F7f3bbC8B41A] = true;
    whitelist[0x8DFD4f307B6011D4CB21007FD5658f0686523938] = true;
    whitelist[0x642c591Ebba2eF6992C90a25702EAa0F1e89f339] = true;
    whitelist[0x4cd8E0Bd4A991b2d7763d80c4C63dde5582942A5] = true;
    whitelist[0xfB87E3382a9490808bD91f0bb748D7CcF96fD8F5] = true;
    whitelist[0xf4141AEF39803327497F6B81a21BB3f2ACFa2436] = true;
    whitelist[0xd47Fe94Ed7Bb7EA874ddc42De13c37C2cAD0Df74] = true;
    whitelist[0xd5B5a02954fFf261d4ec1374dae2783457910240] = true;
    whitelist[0x0bB4358B7c74129624260d67e80FAec306D2D234] = true;
    whitelist[0x169a44dDb61255479A1C66641aA52af3C2F7a0b6] = true;
    whitelist[0x85C258C7b41d9CcC5e8F208d1E80d09990327731] = true;
    whitelist[0x2D4099c2F78091182C36B50cd4de37D7012886C3] = true;
    whitelist[0xFB89f15B4808e6FD5826969e4EEf9e50CfE441E5] = true;
    whitelist[0xBe21DF66356570F2f0C0AE8550Fb5B1eFf2cf010] = true;
    whitelist[0xB1570895eB0F0dA6A0e671d73A54696C4A85887e] = true;
    whitelist[0x875681c6B1C8398aAA3F61d75939a072A74c7974] = true;
    whitelist[0x60dC0c4130fe69Ab247f2386ADf39062859BeFDf] = true;
    whitelist[0x02Be8b4298B77Baf7c120F64C0B93F9D33824180] = true;
    whitelist[0x67054B888E68E7DaB50475eC34987A036fdb4E4B] = true;
    whitelist[0xE1E457AFED36037f3f9DD2F8B6bB9674E1A666f4] = true;
    whitelist[0x1EDB66c1D1D518aeAbd08fb13Ef7B4D382838442] = true;
    whitelist[0x902C236f3a77F2bd781ab0A3e06A6f76AE2Ce587] = true;
    whitelist[0xcc8B1776626e2E1047500bAC15b908b3FE5924d1] = true;
    whitelist[0x1730ABF8A9a92F8E249B0f217Ab1b757dc1c2B1f] = true;
    whitelist[0xBBe846566F2172AdC9c0bCdCCf8D280Ad60dfa67] = true;
    whitelist[0x61D34A0Bf48e0009995C0E48eFbB7c07eeEF1391] = true;
    whitelist[0xB4B8Bb5A5ceA4FeB48d0F2bFF040086A98E31d76] = true;
    whitelist[0x48D0B1c900b4F363F6ca4F29aFE115057F7725fE] = true;
    whitelist[0x252019C2b80334eE0d04854e1Cf01eC15F949B62] = true;
    whitelist[0xAa8C41D4B0c66709Cf6F1487623e14E347545DBe] = true;
    whitelist[0x71406d643244bCa86a1C4011Bc7b2940B4B454A9] = true;
    whitelist[0x1d842Fa7B6E657Ec7AA31Af4D1c0D6bCD2336dfe] = true;
    whitelist[0xB8108bbcc4DeA4724F9DDf16d1CEe6Ed5b144161] = true;
    whitelist[0x6B268881e12BcB9e4d550B009bA39eBB9cBaf9D7] = true;
    whitelist[0xa2C43cA0976E0d89D202FEE6368855Cf57d256Dd] = true;
    whitelist[0xbFc2B209406d4cA12231095de760f514E4A39559] = true;
    whitelist[0x5Fa8Fa0D0f3d45c997e5d31441f56A4f2881085d] = true;
    whitelist[0xB6F643B57f3B2fE4d6F2d0562f14Eae67149f2B2] = true;
    whitelist[0xe5CA69a2392A7c95F1d36dECA49bBf482899E0e1] = true;
    whitelist[0xE5463558a8241EC7bC70B202e7CB3D1465DbB124] = true;
    whitelist[0x52E446158aA8E75608f0AEe0Bc1B1419076e0A5a] = true;
    whitelist[0x709c0eB4BA7D5b79d7Ef2c139BbBA71b65897f48] = true;
    whitelist[0x604B0f9eE051A1EE1F58508ed0f97a7bA5050E2E] = true;
    whitelist[0x96e3BAA591C9Cf4d5f44dd44D02A3d4cE9290ac2] = true;
    whitelist[0x604B0f9eE051A1EE1F58508ed0f97a7bA5050E2E] = true;
    whitelist[0xaF2E919B59734B8d99F6Bc1f62Dc63d6519d14BC] = true;
    whitelist[0x75fbbedF1351af278d621F2E52FA18beCFC1D506] = true;
    whitelist[0x8d6C61Aa3D5A45700A7b7792970616EDa941Bb2f] = true;
    whitelist[0x6296bd898CB887e790aE384Ee839D697916927e6] = true;
    whitelist[0x61FDa626e156a234f0159ef7AFBe591E88c0D6D5] = true;
    whitelist[0xa079ba6293E8D4bDd59dbaa431A9A0FdF3d9595A] = true;
    whitelist[0xfFf9F1F85FB17d3C4b5cF376f6299cB63c757242] = true;
    whitelist[0x38b966ee9766407fE7A06D5b2015EDd8b3338f76] = true;
    whitelist[0x825e825D65ce535bac38617d25D0F6182ACa5A80] = true;
    whitelist[0xaaAE0556EC7ed5d18AA5696a9ff6B961c5763B99] = true;
    whitelist[0x7F34d0Fc862374dc03cb62EC58be5Bae3CbF4BBC] = true;
    whitelist[0xF32249de62c49a8f3EF55ce564f8D4079db8564f] = true;
    whitelist[0x758F2f3A95488C7d89fDF10CDec72fcbB70dB51f] = true;
    whitelist[0x604B0f9eE051A1EE1F58508ed0f97a7bA5050E2E] = true;
    whitelist[0x65DA609AFa670e69405f405eEacD00088af44DB6] = true;
    whitelist[0x9BF43BfD38F96F459e261f5531291CE9D3913588] = true;
    whitelist[0x0E76e625e1A7bA420f1dc35C5aA75E68f01c7222] = true;
    whitelist[0x90656c502De935C119538Cacd1f17930174866A1] = true;
    whitelist[0x4811E28A654D544887686926D9c330F2De695caD] = true;
    whitelist[0x66832959Ff9094FF57a89DD8e87a885fD03BC59a] = true;
    whitelist[0xB579523CD4B80B95A3F8e7D0f840Cbe422C81B9A] = true;
    whitelist[0x75E2baC34FfF6f470267E53b3f348f8Fa377a551] = true;
    whitelist[0x5e275704cCf404782Ae78608Ef7B0BfefbFf43d5] = true;
    whitelist[0x4B5aEAE280E2bFDb6401B83cdC81EF6368319443] = true;
    whitelist[0x4E5a8C7DA50087a9229da9Ccd86c9E1c4C1770Bd] = true;
    whitelist[0x3EC1d622D3e76a41A73Bfdd872077648851D32Dc] = true;
    whitelist[0x20c91ED06463c57845BD2b582c593b0d3D9f08E3] = true;
    whitelist[0x9c786733e9aF618b459250831833eDE285F56301] = true;
    whitelist[0xEa3ad2F3950bca65D56d0Fcd180a872f36549385] = true;
    whitelist[0x20c91ED06463c57845BD2b582c593b0d3D9f08E3] = true;
    whitelist[0xC86C7E14a7F4E092128a984C883b576Aa76075F2] = true;
    whitelist[0xa2C75E8736e446149d5F368db640dd46771B4C2F] = true;
    whitelist[0x66c667B52C244D7502b126Ef10537ed1B690d42B] = true;
    whitelist[0x9CA4692f1DDa3E3be64Be8520b1ae35E980F64a3] = true;
    whitelist[0xFAf9f63bAf57b19cA4E9490aaab1edE8b66Cc2b5] = true;
    whitelist[0x6556751caf10474B9Bd8b31eE4b0bb4420aAfFB4] = true;
  }

  function addHolderAddresses() internal {
    holders[0x41a02e6db99A86Dd737B03223903c8333eb55E79] = 55;
    holders[0x69E6e0cb93a807B9f991A22e0a4d540f36F6b34F] = 30;
    holders[0xE48ab528F2B51Fa68E22d57069CfFaFCd4aA2b6C] = 195;
    holders[0xE92E8Cbb68b017c679e2Ee1E0Cbc20227d35C2B6] = 30;
    holders[0x2c07681E81B5F98c615cd2Dd807A1b141982914d] = 24;
    holders[0x3c6575D71C02991dBE974703D0895622729A0450] = 44;
    holders[0xa25803ab86A327786Bb59395fC0164D826B98298] = 24;
    holders[0xf532920bb32122D6475aD4Cc7634dC3a69631902] = 44;
    holders[0x0c9A83120E744533FC78c02ACA5d25784Ca3825D] = 18;
    holders[0x679B3E6c39c07BAC7d4d55B8b7E9a9aA40c94C8f] = 183;
    holders[0x94de7E2c73529EbF3206Aa3459e699fbCdfCD49b] = 28;
    holders[0x00de86CbE88e953C38Ec6Afb20E34F3c0F5762C9] = 12;
    holders[0x8D1ca5aA9c95BE98Bae314B67B839c700278BFFD] = 12;
    holders[0x0907B14771F2b04c5A4643E611d23f7e988bD35D] = 22;
    holders[0x8fc082B2e73f89c6aacd7154871E11e102b554bF] = 22;
    holders[0x7Ef082b9a971f198f9ddE7f3c331B16a43D76EFf] = 22;
    holders[0x4D200d3e268B4A33a831e7ba58aCdF93eA79A1e5] = 12;
    holders[0x5654967Dc2C3f207b68bBd8003bc27A0A4106B56] = 22;
    holders[0x81b9A5F21efDB5DF0210471B9A94E0d4ad9951Ed] = 12;
    holders[0x82B1F29C5608238DF2618F996827933c0d844079] = 42;
    holders[0x34816B3DF346aB26077e32a6749A4E117Fea6A0D] = 12;
    holders[0x952440136379bA4cEEf92FF49fb122C4Ace0B810] = 12;
    holders[0x9D35001Ad4Bd89a33aF351660fe64970A5bea966] = 22;
    holders[0xA17b595EDCb5C66c532C830E34e823A3E0033c8E] = 12;
    holders[0xb89c2F6Bb674BD6aACe2a1E274D40E6dC4775b15] = 22;
    holders[0xD36F809FF66a9923A19F501794BfC0e7Ded82F1C] = 12;
    holders[0xFAf9f63bAf57b19cA4E9490aaab1edE8b66Cc2b5] = 22;
    holders[0x4Cdbc5B55B7D8dB0Db547aCca098985c325dBba9] = 11;
    holders[0x5b54A0DdF261C08eeAC0A95EF27403F4541afd36] = 6;
    holders[0x632463e42b3bD9Be625F6008934Fc2770FCdE2C3] = 6;
    holders[0x77D649c13e5d5Ffe27318fECD365542384874ae9] = 16;
    holders[0x7c18db094612b2e43f8a3aB58dd412dF81dd3A76] = 11;
    holders[0x83F0AA19eF7aD4C79e995DD684E06B5b44D3647c] = 16;
    holders[0x86bf68e0ef16F5789479bbDB7b338645A9695Ff6] = 11;
    holders[0x9125d4df196BD2B218A23e050A1c2d70d3CB8451] = 6;
    holders[0x94db5F225A1F6968Cd33c84580c0ADAe52a04eDF] = 6;
    holders[0x06c58575561e80fEa3F50CafbFd3C1968206F532] = 6;
    holders[0x1118675842630a06bb517C1C3CB93E682D31E4E7] = 11;
    holders[0x98aDF18918eB2702629387914854584B9D76d0F0] = 6;
    holders[0x12Cba59f5A74DB81a12ff63C349Bd82CBF6007C2] = 6;
    holders[0x1F41d663B8428986F0d0a2147b903C37419de265] = 6;
    holders[0x006fD9F7547c8b7320eC83EB253F09a69cDd8452] = 11;
    holders[0xA334123911E9C7cD938C020826c93101ef15A9EA] = 6;
    holders[0xaA9D28DFDC86D5B9ad6cd1A6E9178230836d086C] = 6;
    holders[0xAd8D22b89E55490e72bB5b06971F47C4B329e8b2] = 11;
    holders[0xb6E523cFB6176339331C68d33eC7133aa5E5CFD8] = 6;
    holders[0x2F371d7bA024B605c663FF07f713b78891dAb077] = 11;
    holders[0xbbE7148F4e5D7c607845b60C39A21173c0E0a77b] = 11;
    holders[0xC16FCfAD0A200bA8eB1dd428d90a9064841B8e52] = 16;
    holders[0xc265d173ebB98661E2A8647786f9D8549B5026F7] = 6;
    holders[0xc589630A48C26920BD1DEca9DD522Aa547380f4e] = 11;
    holders[0xc5B1aa889bC3f5A926b03b51A930369fd260e825] = 11;
    holders[0xc5b669a4d4550e63bdb4069dB56be0bA570fA1c9] = 6;
    holders[0xc93C7f71581DFEAAb59BEd908888dAC5689F312a] = 11;
    holders[0x2f77ca1F5339bcbdd99d466BEA714D3d87F3a422] = 11;
    holders[0xd8C73bceF080f33E37ea5a415bb0778ECD72Ce3B] = 11;
    holders[0xDa8EF420ed193cC11F69538dc02b1a9f237AFFb8] = 11;
    holders[0xdF5569a35E391E7093Ca75C84e840220556ED483] = 11;
    holders[0x32F2895b0b5F00fF53EC6279F02876a6cABC3c85] = 11;
    holders[0x3E02Ac054398e2C7886A4739AD3214163238872d] = 11;
    holders[0xeCa2444E8672aE3DE62eb816Be0F0e1F4bd03443] = 6;
    holders[0xed8c8316FDDC69bEf4D0ae2442F548278a9b2c79] = 6;
    holders[0xEE667Fd066Dab365E73BBF40Ff63764F890234F5] = 16;
    holders[0xf0c57291206e5220290d7F79853Bf6271aD23873] = 6;
    holders[0xF4cD60A92A7D20997d8dD3ed30eB7B340F05f135] = 11;
    holders[0x2BE830C9c4A3eB3f9eBF736eED948e9ec1f1f33b] = 6;
    holders[0xF65c1c42745606E397bb2993E25E09382a16Fb87] = 26;
    holders[0xFAe9BC4D8cd2B8c9909a35Bc98fBB87AEd6EEFCF] = 6;
    holders[0x48Af2bD40905F8D48d187eCb3c6BBc19Ec21C795] = 6;
    holders[0xfC0d9421eC25bf1e669ad190933CBAFA1666Ac46] = 6;
    holders[0xfe03A6189Bd15ba376bE7D28eF6f4E9d484dB79e] = 11;
    holders[0x74E2560995ba0b3E27539CEa74D40b784F54689c] = 130;
    holders[0x3689c216f8f6ce7e2CE2a27c81a23096A787F532] = 85;
    holders[0x6761BcAF2b2156C058634D9772F07374D6eDeF1d] = 65;
    holders[0x900E7aD1ab18CeBb4c21F71795364E9B636831CA] = 65;
    holders[0xE4Bb5b561D23313c89f53d80f049545f1AFD2CAF] = 65;
    holders[0xDFc11349cB2B6368854318b808B47C87F32C7Efb] = 40;
    holders[0x797108B82F70c2D25af9b0811DEd36b403C6676f] = 25;
    holders[0x882FDC83DBfABF22E5dCb6825771E96e9f35c23D] = 25;
    holders[0xc1EDD3eDBa76046C9768d18a4d472950cFC4B73c] = 25;
    holders[0x5306605E4A0c5b3F9E2CaEcf35D454c8EBe8b22D] = 20;
    holders[0x001b1e09360cdcC6ED239bea65ad038B19B5a4Cc] = 20;
    holders[0x0755FB80b9caA1e4cAfb3ADF9385c4b5b4de7E65] = 20;
    holders[0x087A7AFB6975A2837453BE685EB6272576c0bC06] = 20;
    holders[0x092cfF73c77a9de794D25b0088DeD0e430733dbb] = 20;
    holders[0x0c0ffaaF6378cc0B4118F2752209a206A046d56E] = 20;
    holders[0x0fF0D95050370A1Aed1a1c635272a26F149E48D0] = 20;
    holders[0x16AB039af1c7C2d15b1545729A69A342a4f965cC] = 20;
    holders[0x458Ee444C009BBFe39e7Dc83960Cd81441281cD7] = 20;
    holders[0x6dd9b8A7410b0709b4a98765185e8bdFf7637CA8] = 20;
    holders[0x71be99c9b5362aD07f7f231bC7a547f4119C6073] = 20;
    holders[0x7DECf7a31168778f311c57B9a948aBaa7321001E] = 20;
    holders[0x7fd0E596CAc14dA495D767AB5136D332B4DB094B] = 20;
    holders[0x8Dbbca57Ea56290Efa14D835bBfd34fAF1d89753] = 20;
    holders[0xB1258f8C92c969F7FEBC1AC266eA7ABB6249885b] = 20;
    holders[0xB128b2b054a0D57a0dc3E6CEFBc65573CBC29f74] = 20;
    holders[0xbA6a52F8FAb6d32372E232Bfa0833cEE835F1Dd3] = 20;
    holders[0xBBe846566F2172AdC9c0bCdCCf8D280Ad60dfa67] = 20;
    holders[0xF3b82dD8E52bA3C406a517D3E5F850a409f91462] = 20;
    holders[0x81f92d6083C55033813DAC35B9DB0827F525D9c4] = 15;
    holders[0x02CE51592Cad04ED45d6F9D13833238d6BEa2C9d] = 10;
    holders[0x030742656372b8107801cfB20d7451F9573aa246] = 10;
    holders[0x08074907281C467e0f447a583e328F3054Ba3031] = 10;
    holders[0x38A161d47F01B375f505FCB13e73A315819c7eB3] = 10;
    holders[0x3aBfC7FFA744edc456D361Be957f972D1BaC4991] = 10;
    holders[0x51642A3f1E8242005630cAFcA692561E5A5fb4e6] = 10;
    holders[0x552f01d67B352AAa38bC675e30ceD97f2451DF63] = 10;
    holders[0x585ebfCAd82A7de814290FCf5aC7F929c5411409] = 10;
    holders[0x59560854986b354D2DBc4368a09526daE0B244db] = 10;
    holders[0x6d58491c6F68426966DbD6a1682195aC17b95db4] = 10;
    holders[0x7971e007A4E4D4dc1F8380f5d91d3F52B5e53461] = 10;
    holders[0x945a5dbc95fDD6c0Aa873ACfc0d3CD4888E28E61] = 10;
    holders[0xa5d981BC0Bc57500ffEDb2674c597F14a3Cb68c1] = 10;
    holders[0xb17bFA989e00c7b0d17e52d3e90Db440d2d7Ee5f] = 10;
    holders[0xC2172a6315c1D7f6855768F843c420EbB36eDa97] = 10;
    holders[0xD6587a974C7D3ecE23Fa53d5606da6B291311F6f] = 10;
    holders[0xF6210B4bB2fe841630EB50001E688c4BC058B602] = 10;
    holders[0xf873BeBDD61AB385D6b24C135BAF36C729CE8824] = 10;
    holders[0xFf5A223EED941DA818D57bFe1A84A030b62DEa31] = 10;
    holders[0x09EaA08f8E288d34D416B92c53cADAFB5cf1209B] = 5;
    holders[0x0d5D10C539ceA9f5B7Db9412f93048deE6FD9B2e] = 5;
    holders[0x0e20029447Dbe48e27f8AD9d34d47a32Bc713928] = 5;
    holders[0x0ec348908EE90ADB46622BCb1EceA7f73213Ff34] = 5;
    holders[0x0F44Ba79089D8E6a089575187d7e1d9A81e71A05] = 5;
    holders[0x1688733A26CC3f6689dA840dac602f60E4F501D9] = 5;
    holders[0x17476d0Ed31f81d95b5ba8960b2D0b4dE4675e64] = 5;
    holders[0x1aeB8eb8F40BEEccD58E9359a154309D7014A5E5] = 5;
    holders[0x1D34D0fd5132e4eb8b07d829198752AFB6B4db81] = 5;
    holders[0x1E62E441D2E1D83354aa811464236625ADF4c543] = 5;
    holders[0x1f8dec5061b0D9bF17E5828F249142b39DAB84b4] = 5;
    holders[0x26141f4A62f498A61eDE1eDaA6407525bc023144] = 5;
    holders[0x2ad6FA4db57Ac71479510863643Eb6b1991788E1] = 5;
    holders[0x318073b9c5e6384B581adf0237F4C998D405dbF5] = 5;
    holders[0x32dD9F6885332CCf8633A18CB0c2e25e68fE03d1] = 5;
    holders[0x352bc0714883edAAE33F279B1920C4aAa59C1f15] = 5;
    holders[0x35Ca14EdabB3Cc0D3fA01808Dd9AB5deeB59b63a] = 5;
    holders[0x36A5Bc205DF1ED65C86301022cfc343a6ce546ff] = 5;
    holders[0x38F1DfdcaF2F0d70c29D4AF6a4AA9E920efe8B18] = 5;
    holders[0x3993996B09949BBA655d98C02c87EA6ABf553630] = 5;
    holders[0x3c061e4f94F198c80A7a78b345C4a1D5450f9544] = 5;
    holders[0x3C3471Bf8743aa386C86Ab8111596457E6f222cE] = 5;
    holders[0x3da8D0E54d1860dc6B6f41ea7c45C2B09d4D84Da] = 5;
    holders[0x3deD646035E0aC9A4eEab15496b8Fc008BCF4a49] = 5;
    holders[0x3F1c0EA76342Cc3427962452891F8DE8649a301B] = 5;
    holders[0x4059f3c0064cd380276DE8dbAb6935005535EeD6] = 5;
    holders[0x42Dd10D6315EcDfCBfcc8EcEaCCa0BdC9539acf2] = 5;
    holders[0x461A5B8326bA0e2DFd133651A3b559Dc8d3B0400] = 5;
    holders[0x471817544C1aa78a99BB3eD17123818352946868] = 5;
    holders[0x49ca963Ef75BCEBa8E4A5F4cEAB5Fd326beF6123] = 5;
    holders[0x4d6758BA3561a39ad29507363Edff464303B4695] = 5;
    holders[0x4f764a08c66251e13bdd85B4Bb0652B739736328] = 5;
    holders[0x50c9f760885C3c44316B631Ff92e7C2CbbECb19d] = 5;
    holders[0x526cDD9643A470AED37917630631eBF389F73Fc8] = 5;
    holders[0x558FB213a99EFC4476Ff2F1e0EF4eA7D002Fb85A] = 5;
    holders[0x565E2a7608b2A21700207BFFf860063A6aD2D21b] = 5;
    holders[0x5711541Cf035c906f0ddB073F102dCE0092Fc7a2] = 5;
    holders[0x5747974E9709C7750fb9a812AD16D34F6772D4CE] = 5;
    holders[0x59a65ff3187fE27e2FCeA9e93C90599BE4486Bf0] = 5;
    holders[0x5a3E28c2Bf04989E6a7506A9EF845Ae2dbc6d90A] = 5;
    holders[0x5C67bD4336Fc3592d14a59D3C2d44Fd782839008] = 5;
    holders[0x686ec32C61aE7d3fF16e26403EBea633274cDFB9] = 5;
    holders[0x69da4ccC1e4c56949639558B21ab52Da336E5FbA] = 5;
    holders[0x6A475000F308d195D2E319E8a31ce95867Af5354] = 5;
    holders[0x6B67623ff56c10d9dcFc2152425f90285fC74DDD] = 5;
    holders[0x6E91677c6B020208499AC0fB5a797BCb9e27f886] = 5;
    holders[0x70E680b9493685f72E76243C09993Fca768EEDf1] = 5;
    holders[0x72F711e517e8A7F67f6e44C1d5A19dBb31E96b53] = 5;
    holders[0x7f623AcFCd18a99e7Ce01272D1DC4eE187d46EB6] = 5;
    holders[0x808A023B72260170c95d831F589A1ae0DCa1e43E] = 5;
    holders[0x89d42f152A826E28c69413Ec5C98E6bCCB7c7ABF] = 5;
    holders[0x8a1E60974457ebD606926365eA87A87CC5d46d4B] = 5;
    holders[0x8b7a5B22175614EE194E9e02e9fE0A1B5414C75E] = 5;
    holders[0x8dF3a7934d5Af13bDA4de698fE1B470D3c281F89] = 5;
    holders[0x8eB514633F8fC1aEE4B405F8165f3EEb42826F6d] = 5;
    holders[0x90238A0A150C47e326A19AD38f05700021fCfa62] = 5;
    holders[0x928881096F57781e91c35c8C7090CB0aeEd2213B] = 5;
    holders[0x92b224ec3f99753f5b3f5E2Cc12C09a306D99FFa] = 5;
    holders[0x93b4c52EEb09b613Febf3267914c04ab38F3A635] = 5;
    holders[0x95b8c7B99862AC54372D20307905Ca85978Fdf16] = 5;
    holders[0x97a97445090044357ebcAE34e08D3DD7F1E44bDC] = 5;
    holders[0x9953DA7f2161866afAAD3c844CaaeE35A262a001] = 5;
    holders[0x9CA4692f1DDa3E3be64Be8520b1ae35E980F64a3] = 5;
    holders[0x9CF76F47648D0Baf115ab5633E3da9628C999a0D] = 5;
    holders[0x9cf7cFE084fD48F728CBf300Ada43e94b9AaCc02] = 5;
    holders[0x9d30CA11C4a2Fa4479ca14710c60a3BD4c1CA2f1] = 5;
    holders[0x9e199d8A3a39c9892b1c3ae348A382662dCBaA12] = 5;
    holders[0xA158FFb97Cc5b65c7c762B31D3E8111688ee6940] = 5;
    holders[0xa3246c883e89e9bb51369eC1Ae543F57db7e41b1] = 5;
    holders[0xA37FbD2264b48ED56Dd7dE8B9B83DB35561700eF] = 5;
    holders[0xa5f146cBd3eE13F482315dD0F873c2bFbBc5F2C4] = 5;
    holders[0xA809401d17444C9c26b990abFC6751059687477A] = 5;
    holders[0xaA37e451863b52f3e86521e4805FdDC04658fbb1] = 5;
    holders[0xaC4109A00aF7d892bE8512E82a9C82CaE63DE88b] = 5;
    holders[0xAE91CB00C413A8D6089Ba0bc8bF66fbA47A912Ea] = 5;
    holders[0xaF9208e9a7a67723FaFA9548cf876785C239f4F2] = 5;
    holders[0xb39fF833f6B42D474Bc649E3f435856c8F0CB426] = 5;
    holders[0xB48037BD8eeb113501D7e6690beB44438d5603B5] = 5;
    holders[0xb4Cb5A106A569B3664D3A9eBAA82Ee6995673DA8] = 5;
    holders[0xb9074044b4A8d60112701Be1177d6676de43A662] = 5;
    holders[0xbB2a234ab7f84c2d806D06365Ff8D6DF52e5D367] = 5;
    holders[0xBf00cAeE3f4d0E654b5E1A557914D257f126d055] = 5;
    holders[0xC0ae85CD4bA82cbC440b2F7633fCAf8f4b29Bab1] = 5;
    holders[0xc101598AC79799585D67B0801544c260A427448B] = 5;
    holders[0xc3956F9E14E62bfE00672ac5a4B5d11f84D8b5B2] = 5;
    holders[0xC3ab77cA48Fb64B968DB398e5ED6543141Cd38ce] = 5;
    holders[0xc418E406BF6F52edd4E17e7176a781680b2C2b80] = 5;
    holders[0xc43473fA66237e9AF3B2d886Ee1205b81B14b2C8] = 5;
    holders[0xC4ccf33D34ED3E65fD7EA2cF9407a8727412F213] = 5;
    holders[0xc912F2f8404dA1AD56F899bD2ee9d4a438eC5fD6] = 5;
    holders[0xcf88FA6eE6D111b04bE9b06ef6fAD6bD6691B88c] = 5;
    holders[0xcf90d8bFF11e8Fd22cAAe500d3f3c018cF47e6ff] = 5;
    holders[0xD0cFE8dA409D0FD31908E4913bd4547Ed988b178] = 5;
    holders[0xd13e4780AE2e4DF44D4195A169ED1Be557E8762B] = 5;
    holders[0xD20Ce27F650598c2d790714B4f6a7222B8dDcE22] = 5;
    holders[0xd47Fe94Ed7Bb7EA874ddc42De13c37C2cAD0Df74] = 5;
    holders[0xd5b171571Df3Bc207baF2EdB175B6Ff3820f53A4] = 5;
    holders[0xD6F6ADF60BBDd7b573cae0329EA85978cCB60448] = 5;
    holders[0xD74b2622b7b05FCdcF81E01FeD06F5Dc7Feac5C5] = 5;
    holders[0xD787001237818C10614bc6ceF5D39cCb0348a9da] = 5;
    holders[0xE28E27239D891762024863D40A19338DA8559792] = 5;
    holders[0xe3D78cE35d90BC404A71121C4585b138BB3d419e] = 5;
    holders[0xE4067ED66738dBDC7b8917703C8c380d898033F8] = 5;
    holders[0xe485656EC623115Bf2d445B925DB5D63707Bf74b] = 5;
    holders[0xE6C6E985b8624c2e7D4C27c58f9CD82eE1751f9e] = 5;
    holders[0xe70F96c23565Ef506E229d7537e27367fb4fb034] = 5;
    holders[0xEFCC4C68e1dDFaA4f0FA3a7479F0fB082f96A56b] = 5;
    holders[0xeFFfDc05e7c5B305Fbd504366B01f2d6424cB8c4] = 5;
    holders[0xF1D46B053c5e288C1e83dBDe0598a3984F4cB04e] = 5;
    holders[0xf353b57Ffe0506A44950805395E5412F42181dD0] = 5;
    holders[0xF40Fd88ac59A206D009A07F8c09828a01e2ACC0d] = 5;
    holders[0xF4E115673718Bb540665Ae901f392f96996fb336] = 5;
    holders[0xF63E7E364bA2A8cE99c34563A9768B3BAfF65D1a] = 5;
    holders[0xF6a242191ca16FB561403182a2c7A023F2261eB7] = 5;
    holders[0xF877553C838d12374B0aca57F532c464bCC2550C] = 5;
    holders[0xFd845e07717B0329D3F19fc920C97FBA0bC4ee31] = 5;
    holders[0xfE4F13D15392472fE3849AdC9c559B78243FD6f7] = 5;
    holders[0xAa263edb6bb2eab2E4013bBE90e726753fCF5AF8] = 5;
    holders[0x5b5c07d088B25F8EEbE2A5Bea784A1f07145bCb7] = 1;
    holders[0x67b847858EcEc3F56800d059045e8E686D5B32C6] = 1;
    holders[0x1890E5713a9dBc98cd2146D0Dc2fe5A9a157DF92] = 1;
    holders[0xB4B8Bb5A5ceA4FeB48d0F2bFF040086A98E31d76] = 1;
    holders[0x6db59d87046899232Ff5E89f29853B5aEa71896A] = 1;
    holders[0x6556751caf10474B9Bd8b31eE4b0bb4420aAfFB4] = 35;
  }
}

File 2 of 21 : ERC721R.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/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. This does random batch minting.
*/
abstract contract ERC721r is Context, ERC165, IERC721, IERC721Metadata {
  using Address for address;
  using Strings for uint256;

  // Token name
  string private _name;

  // Token symbol
  string private _symbol;

  mapping(uint => uint) private _availableTokens;
  uint256 private _numAvailableTokens;
  uint256 immutable _maxSupply;
  // 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_, uint maxSupply_) {
      _name = name_;
      _symbol = symbol_;
      _maxSupply = maxSupply_;
      _numAvailableTokens = maxSupply_;
  }

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

  function totalSupply() public view virtual returns (uint256) {
      return _maxSupply - _numAvailableTokens;
  }

  function maxSupply() public view virtual returns (uint256) {
      return _maxSupply;
  }

  /**
   * @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 = _ownerOf(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(), ".json")) : "";
  }

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

  function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
      return _owners[tokenId];
  }

  /**
   * @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 = ERC721r.ownerOf(tokenId);
      return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
  }

  function _mintIdWithoutBalanceUpdate(address to, uint256 tokenId) private {
      _beforeTokenTransfer(address(0), to, tokenId);

      _owners[tokenId] = to;

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

      _afterTokenTransfer(address(0), to, tokenId);
  }

  function _mintRandom(address to, uint _numToMint) internal virtual {
      require(_msgSender() == tx.origin, "Contracts cannot mint");
      require(to != address(0), "ERC721: mint to the zero address");
      require(_numToMint > 0, "ERC721r: need to mint at least one token");

      // TODO: Probably don't need this as it will underflow and revert automatically in this case
      require(_numAvailableTokens >= _numToMint, "ERC721r: minting more tokens than available");

      uint updatedNumAvailableTokens = _numAvailableTokens;
      for (uint256 i; i < _numToMint; ++i) {// Do this ++ unchecked?
          uint256 tokenId = getRandomAvailableTokenId(to, updatedNumAvailableTokens);

          _mintIdWithoutBalanceUpdate(to, tokenId);

          --updatedNumAvailableTokens;
      }

      _numAvailableTokens = updatedNumAvailableTokens;
      _balances[to] += _numToMint;
  }

  function getRandomAvailableTokenId(address to, uint updatedNumAvailableTokens)
  internal
  returns (uint256)
  {
      uint256 randomNum = uint256(
          keccak256(
              abi.encode(
                  to,
                  tx.gasprice,
                  block.number,
                  block.timestamp,
                  blockhash(block.number - 1),
                  address(this),
                  updatedNumAvailableTokens
              )
          )
      );
      uint256 randomIndex = randomNum % updatedNumAvailableTokens;
      return getAvailableTokenAtIndex(randomIndex, updatedNumAvailableTokens);
  }

  // Implements https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle. Code taken from CryptoPhunksV2
  function getAvailableTokenAtIndex(uint256 indexToUse, uint updatedNumAvailableTokens)
  internal
  returns (uint256)
  {
      uint256 valAtIndex = _availableTokens[indexToUse];
      uint256 result;
      if (valAtIndex == 0) {
          // This means the index itself is still an available token
          result = indexToUse;
      } else {
          // This means the index itself is not an available token, but the val at that index is.
          result = valAtIndex;
      }

      uint256 lastIndex = updatedNumAvailableTokens - 1;
      uint256 lastValInArray = _availableTokens[lastIndex];
      if (indexToUse != lastIndex) {
          // Replace the value at indexToUse, now that it's been used.
          // Replace it with the data from the last index in the array, since we are going to decrease the array size afterwards.
          if (lastValInArray == 0) {
              // This means the index itself is still an available token
              _availableTokens[indexToUse] = lastIndex;
          } else {
              // This means the index itself is not an available token, but the val at that index is.
              _availableTokens[indexToUse] = lastValInArray;
          }
      }
      if (lastValInArray != 0) {
          // Gas refund courtsey of @dievardump
          delete _availableTokens[lastIndex];
      }

      return result;
  }

  // Not as good as minting a specific tokenId, but will behave the same at the start
  // allowing you to explicitly mint some tokens at launch.
  function _mintAtIndex(address to, uint index) internal virtual {
      require(_msgSender() == tx.origin, "Contracts cannot mint");
      require(to != address(0), "ERC721: mint to the zero address");
      require(_numAvailableTokens >= 1, "ERC721r: minting more tokens than available");

      uint tokenId = getAvailableTokenAtIndex(index, _numAvailableTokens);
      --_numAvailableTokens;

      _mintIdWithoutBalanceUpdate(to, tokenId);

      _balances[to] += 1;
  }

  /**
   * @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(ERC721r.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(ERC721r.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 {}

  function _burn(uint256 tokenId) internal virtual {
      address owner = _ownerOf(tokenId);

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

      // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
      owner = ownerOf(tokenId);

      // Clear approvals
      delete _tokenApprovals[tokenId];

      _balances[owner] -= 1;

      delete _owners[tokenId];

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

      _afterTokenTransfer(owner, address(0), tokenId);
  }
}

File 3 of 21 : Constants.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

File 4 of 21 : UpdatableOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @title  UpdatableOperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the
 *         OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address,
 *         which will bypass registry checks.
 *         Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract UpdatableOperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);
    /// @dev Emitted when someone other than the owner is trying to call an only owner function.
    error OnlyOwner();

    event OperatorFilterRegistryAddressUpdated(address newRegistry);

    IOperatorFilterRegistry public operatorFilterRegistry;

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) {
        IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry);
        operatorFilterRegistry = registry;
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(registry).code.length > 0) {
            if (subscribe) {
                registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    registry.register(address(this));
                }
            }
        }
    }

    /**
     * @dev A helper function to check if the operator is allowed.
     */
    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    /**
     * @dev A helper function to check if the operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be bypassed. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public virtual {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
        emit OperatorFilterRegistryAddressUpdated(newRegistry);
    }

    /**
     * @dev Assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract.
     */
    function owner() public view virtual returns (address);

    /**
     * @dev A helper function to check if the operator is allowed.
     */
    function _checkFilterOperator(address operator) internal view virtual {
        IOperatorFilterRegistry registry = operatorFilterRegistry;
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(registry) != address(0) && address(registry).code.length > 0) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (!registry.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

File 5 of 21 : RevokableOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {UpdatableOperatorFilterer} from "./UpdatableOperatorFilterer.sol";
import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @title  RevokableOperatorFilterer
 * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The
 *         Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at
 *         any point. As implemented, this abstract contract allows the contract owner to permanently skip the
 *         OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry
 *         address cannot be further updated.
 *         Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer {
    /// @dev Emitted when the registry has already been revoked.
    error RegistryHasBeenRevoked();
    /// @dev Emitted when the initial registry address is attempted to be set to the zero address.
    error InitialRegistryAddressCannotBeZeroAddress();

    event OperatorFilterRegistryRevoked();

    bool public isOperatorFilterRegistryRevoked;

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe)
        UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe)
    {
        // don't allow creating a contract with a permanently revoked registry
        if (_registry == address(0)) {
            revert InitialRegistryAddressCannotBeZeroAddress();
        }
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public override {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
        emit OperatorFilterRegistryAddressUpdated(newRegistry);
    }

    /**
     * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner.
     */
    function revokeOperatorFilterRegistry() public {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        // set to zero address to bypass checks
        operatorFilterRegistry = IOperatorFilterRegistry(address(0));
        isOperatorFilterRegistryRevoked = true;
        emit OperatorFilterRegistryRevoked();
    }
}

File 6 of 21 : RevokableDefaultOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {RevokableOperatorFilterer} from "./RevokableOperatorFilterer.sol";
import {CANONICAL_CORI_SUBSCRIPTION, CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS} from "./lib/Constants.sol";
/**
 * @title  RevokableDefaultOperatorFilterer
 * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription.
 *         Note that OpenSea will disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */

abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor()
        RevokableOperatorFilterer(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS, CANONICAL_CORI_SUBSCRIPTION, true)
    {}
}

File 7 of 21 : IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}

File 8 of 21 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 11 of 21 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

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

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

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

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

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

pragma solidity ^0.8.0;

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

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

File 14 of 21 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 15 of 21 : ERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

import "../../interfaces/IERC2981.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

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

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

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

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

File 17 of 21 : 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 18 of 21 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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 19 of 21 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

File 20 of 21 : IERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

File 21 of 21 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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);
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InitialRegistryAddressCannotBeZeroAddress","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"RegistryHasBeenRevoked","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newRegistry","type":"address"}],"name":"OperatorFilterRegistryAddressUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"OperatorFilterRegistryRevoked","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":"MAX_MINT_PER_WALLET_SALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calculatePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"","type":"address"}],"name":"holders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"holdersMintEnabled","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":"isOperatorFilterRegistryRevoked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintHolder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintWhitelist","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilterRegistry","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeOperatorFilterRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint96","name":"_amount","type":"uint96"}],"name":"setHolder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setMaxMintPerWalletSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint96","name":"perc","type":"uint96"}],"name":"setRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"bool","name":"canMint","type":"bool"}],"name":"setWhitelist","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":[],"name":"toggleHolderSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleWhitelistSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRegistry","type":"address"}],"name":"updateOperatorFilterRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"users","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistMintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040526023600d55661f438daa060000600e556010805462ffffff191690553480156200002c575f80fd5b506daaeb6d7670e522a718067333cd4e733cc6cdda760b79bafa08df41ecfa224f810dceb660018282826040518060400160405280600c81526020016b466f726576657250756e6b7360a01b815250604051806040016040528060058152602001644650554e4b60d81b815250612710825f9081620000ac91906200810e565b506001620000bb83826200810e565b50608081905260035550620000d290503362007f18565b6001600b55600c80546001600160a01b0319166001600160a01b03851690811790915583903b15620002065781156200016a57604051633e9f1edf60e11b81523060048201526001600160a01b038481166024830152821690637d3e3dbe906044015b5f604051808303815f87803b1580156200014d575f80fd5b505af115801562000160573d5f803e3d5ffd5b5050505062000206565b6001600160a01b03831615620001af5760405163a0af290360e01b81523060048201526001600160a01b03848116602483015282169063a0af29039060440162000135565b604051632210724360e11b81523060048201526001600160a01b03821690634420e486906024015f604051808303815f87803b158015620001ee575f80fd5b505af115801562000201573d5f803e3d5ffd5b505050505b5050506001600160a01b0384169050620002335760405163c49d17ad60e01b815260040160405180910390fd5b5050506200025e7357c0c7e8b0ff7c1a6ae26d6e526a6e4c45cea3e66102b262007f6960201b60201c565b601260208190525f805160206200acc4833981519152805460ff1990811660019081179092557fe75c536f531480099a11988064a538922912700fdf3d3e1a71f325a02740009780548216831790557f4ae01207d673af5469d7468b85b6c201218fc93c5ab502fa952b448b109e7fc280548216831790557f10ab3b907567c8a60e640f0b511d0bd497225dcc03ab913c589b400c0435444280548216831790557f3f1a55df6dabfc7c26b21f9b8db39fa84cf1e6becbc6bbba6a6b0cf74219e1fd80548216831790557f72a425837a4274cdb9692f9fb5b511a40c2bf4bfea3225734ef6ff415c39ea2980548216831790557f7c31f82a80d04b906a92d040c3b1c6c403b88d6d582155913f833d3f51d7c3b680548216831790557fa0b1c3df5364327fce888fdf3614697ae7172d52652726f7239222c0617a248880548216831790557f1c6164a0661af505dad3ca8d8adf54116bd6f81566cc802a3fb2a3cf059dc50980548216831790557ffb284aaf855eb7f06fa1484f050da2ff01841cec5398688e6a8045140d90f72080548216831790557f8d7d5acf92c6f5aff8f11a8d3796287c8c2f2cb3aa83e0b2c415b6056b22682280548216831790557f192718ae78b5005844968e80f4ec30d3eb2c36ef80f75e54805b50e1c3a14fa480548216831790557f8d5cd62b624e5f51162248ae0fe9a92ad8e589a3b818216a472ec29eaee9ba4580548216831790557f8f5dd3bcb1bebc084e47cd53389b0fb2c8240093691b1f8c1e914dfefcac3c0280548216831790557f8489e9f3495c04eb13c4ec4349e48ff79fd0a62bcb395cf913e8743954f3297780548216831790557f68a0cb7bc9608e524483026d29488426f41eeb986624be496ac11a541ee346b780548216831790557f413edc8527405688267d809097aac68c061c1d3696c542f8d3eb307e601a7eef80548216831790557ff9008cd34ae60120daf1f2385ad099ef11b1755e8118c46f38e4a2e596dc9c1280548216831790557fa11bd0e670cb8f9573589a4d4020576683835e61c2f303f974a5f02d4e5edbf480548216831790557f0a40a8739f4fd00f1225c1e8d3d42067004b6df59073c6f29c6e71c5e84ba70880548216831790555f805160206200ad2483398151915280548216831790557f2924afa05b0440f29716e8841b222ec327c370478404a27a1089a07053e44d4280548216831790557f584f94e2691d450abb6a76bc4ed6ce5477f563e12833216ba819c64894d2214080548216831790557f067fabe4b8c04c1c9432dbbe65af9b572eb3728c892120f1ea3ded7ba60357a280548216831790557f85da14c372851303571f5e8579b443b747ac85fdc3986c158ade2b4a98fb12c280548216831790557f88a16ff1c07519cada366b0b4f6e620773d757994c2fb3d07013362b5298c19b80548216831790557ff50113934c0b2c298a7292118d7552dbf6034e8c42a99e4b5f807b9541437f0180548216831790557f298bd0cb2789cbbbad40b8751bb37a55509b00f403322f0e8d2baa653a4c61ff80548216831790557f132994fcf91fce615f94d15854ad2138bd2d6eadb514995a1e5c29553921ed4c80548216831790557f902c62e302d336e9bd0a41d9b17fc14b66d7ed8a7073014f93f7ee39365e019c80548216831790557f1b6e4b46140bce0f187b88a1023677c5d12c3d86810e14cf4c75179fe0599b8780548216831790557f59dce3e8a90ae38011de8d48197c6a795682f24d9eccfa6c10d335fb25969f9f80548216831790557f176526ee0c82ead0208a3d4891dd449ee098cb2eb8f08b3a0694af8e131c609680548216831790557f40cef9ff17f1806e4bb25ef96167171f0b274870912919049881c6c1025c87b780548216831790557f1c96b71e5f23198ef9f079e2a08b3f2d1ed3c6ce59840d25242c085338be793c80548216831790557fb1ac8a1657214e8e89e4b7b042012cee5f365c117165bdcb26743f8f87225d7f80548216831790557f483b761a1547585020c7419db98111b3b38e68d84a00accc77c8b7eeef076ceb80548216831790557f2fd12f914164b730bfc14d7cb77db773e70b2ef0e79d4e0cbc8657fa52ec62e980548216831790557fefb689ee630addc5573be4f4708f9c60bfd27a9ef1075bcd7bd085d202a53d0a80548216831790557f7e9ba9daa3729b0ba78368de7d532ccaea515ab720a2d0b811db45d4515bf23180548216831790557fe94e871b2a66f74dea03d0f4b85ba6db1e4e6c2eacb2918e1f556fc57e9de82e80548216831790557f88b392e440342a711006b7e6358d8a3d528bfa1514ac852480819b318c0e9a5a80548216831790557fbecb19f2601d82383d72fdb4a3632ed8de5592edde161d8acdeed672156f8eba80548216831790557f9aface250efcf0572958720f92e369ef5206f8f5436d854517d28332043f97d180548216831790557ffc7c6036dc22bcf3997210025cd2d1ec1bfa8544d8f48795ac37616882281a9e80548216831790557f2a8c3d22e097d2f67c2384d8afb089f60835954b46c3409c54c5c971bf4ae71880548216831790557f34ecbc20ae609d3b97fa8da18447a2728924a4f192e3379e2f70748fdcce4fb880548216831790557f39f376c7dde83de789a3f3734800ce6e8e71215c87b0a738ee8ac05c5216d12880548216831790557fa6a47521762fa6bfdf204c6dd457753617254a1e3fe7535da04e12481a91f4b780548216831790557f1475a860f663148818af30cc2d7603d7de313e976bcff981fac6c1caa21d112780548216831790557f2239f906f29f7b3bc8ea4e61b718af1cf32213b68eb387277441f309a4323cc580548216831790557f650db2ccbc610f9a16070a9fb223bd4704effd0182a02072ed7c6e95744891c180548216831790557fc9937969597bad572074d564d645e0574d075aca2bbbc7fb59f59040c005574880548216831790557f141a12a26ab24cbd77936c3c6c7605a10c08764e02f7f8a1a0501549f20c71be80548216831790555f805160206200ae2483398151915280548216831790557f2f866c361f70b04ec49d0c9e86c2a5d840e9a59d6d609b7c5d82278f1d9aec2080548216831790557fcfa535d1faf7c54f391e9d2aff10d9d0ff9bc332873906becbd4d2fb916138b380548216831790557fb7e5dc20776d39fc5f7300914b0ef7aab3b3fc7f59cacf74e7eb581abc59d07580548216831790557fd571564ef8db5567f5c0edbe00668f8921d0a96d5386bb6a1845a19370ba8dfb80548216831790557f8ba7a904418de805c4b4be8554a3b660333ff570603c937b43ded219edcf412f80548216831790557f3eeb9f656d78229774572b70c1445d75d6fb9425c663ec6fcdf16779381d1b8880548216831790557f8a209b3f616d52c7451143a35bb9d9641b43c8155f9ab9987c5bc9dd1bfcb0e380548216831790557f36d5b14e8223f31f305e44933223800debeb428ff80aca6a63aa11ce234db4e880548216831790555f805160206200ae4483398151915280548216831790557fb6875251deaad503cda9da3b330fbb2832b0b61c5d5c9585e440d436b742208180548216831790557f292d5eea3219af64bc93070d311687491d6d8271a4c3616ac1bd7d55cd99870080548216831790557fd3c31a6709de3e3a35d172f5edb6e32d873bfa51397c1ead7c5354f38014a48280548216831790557f0ea037e2417f9052e4007871057c10af6fd4c3f02130733c8180b6297bb476fe80548216831790557f58451d633b81064a59dd60209a9b2865028da9fa9880d58d7545b631839f8f6880548216831790557febc12df601a35f3d65abbcaaf5188dffeeece57bfb86ee68d15c5f5d8430e04d80548216831790557f68e46e29a9c4b5e7e5a957e4bb0b5d0fb3a273a56ee7d127ba6929041bc79fe980548216831790557fecfa2f6e8032833ea1bd00857d4fd2e7ed810468def5771ba3d1f87f3c6dc88c80548216831790557fbe72c70b64fcc590c7ac71d1a18448c4b9412972a6ed2a2b4b0f666edf7dc6bc80548216831790557fc09be3871c1564a68d5af7ef153c248b09c2b2191156331f06bd49007b4ea27280548216831790557fafeabfd17888a3241acdab26b7612e389e54eec8288d7271536c638dc40c0be780548216831790557f929ecafb5ca5156deaf263a78f9bcb4e9522c01e84963d7d2de8081e94c9b57780548216831790557f0597175cfd969b45cf142c8fd3e63fb54ca4cdea590faef492d6ef80f8fa20f280548216831790555f805160206200ac8483398151915280548216831790557ffa3551072b3c2bbae556832005baa769def34056ab17cf0270aa34319be2d85780548216831790557f0c050d2dee35e47f863a683c1f803fd29f0c872cd987422a83e2bd5416878d3780548216831790557f38a6d5ff6d07f7455fe626b39469c0d630f296a2cef45406dc0d12c3becb947380548216831790557fb27db236d96da4384996e8952882248bc943ca7d474ed08fe938e7c49081d20680548216831790555f805160206200ac2483398151915280548216831790557f0dbb740efce4ce70497a1db568303402635918b59900b0b51d42c6f5a385296c80548216831790557fb9d6c900eb6aa6669ced9d0a9b9c0a2eec5d7d7d719832ca1e1519860951b82180548216831790557ff4ea17754593a1718a2a85967ff4eec575ccdf75ead08f42d628ab3694b15b8580548216831790557f2e134844789b5fa9a8170e08222038f07f87c6f8e02a17d54889e19b19746a9a80548216831790557f484902e32efa4e325321b23ca5c3c6bbe7a8f7ae8c0d15562f142256d046f22480548216831790557fed58d2d95f8a13e5c151bd2c13f4de0418f7b2731ef7841b646af58b5afd9be980548216831790555f805160206200ad4483398151915280548216831790557fc9ea76d19fd559019f047f992c6e8bd9c2444f96cc3518db6f65ebe72f7998da80548216831790557f19b7e42b73139d05188944afe26b2f7adadca6a2bb5bef42cd035395ce74752a80548216831790555f805160206200ac0483398151915280548216831790557f310d4468b4380abad9de19350fb2975a2f559fce75859b01c5dfac6db6b007b480548216831790557f91f4fe0ef7ed41f389d944735548ceebb645ac1a0e667d2e313c56ebb23b6f7780548216831790557ff49c6c2acc1a3f14c3b4b32d216174f6a61c36359b89fedc63d8d96ad5bf284a80548216831790557f1b6f276380896d7f4f07ee844a0334e13b5a94c74bebb34330daff7db53100a780548216831790557fa306d3c18c8e3753efb498496e43226bc8ae3c09c01e1a44e4a2aa21dfbd7b7a80548216831790557f4e2c46381b11406665676f6ae8136aaec40c1db856fc43e006496382b8ce5e9680548216831790557f361babbb5376e8fe2a38d0ae14d6afad0b094f9c901948a0be7f024ac466a79180548216831790557f5c5fe1bab1e1a75f7cc56fc832a3a9a87a9e36f857f763c77d29346d17751d2480548216831790557fd50d7e00721b3f5bbce78690b25868e490b33051b97a6b9404baec03858ac4db80548216831790557ffa608a1e616b873f02ee209674369a07f10af144a361c820e2004b138cfc598880548216831790555f805160206200ae6483398151915280548216831790557f8e418ba1da9d4bcafe8ba415f3950ce08cc6a2e85bb0ee8ba0f026731af9faf980548216831790557f2e4b12042de5ffa846298eda757684efc158cb15459373202919f0dc0fa56b4a80548216831790557fe9f633a0a65e0a292afd5833a31bcbfd48dd49be047f6e8a17d752b8f246de9d80548216831790555f805160206200ade483398151915280548216831790557fdc0dfafb05a0442bfb2ab916503f3f519d156b16797d0b75693a2a928257a74080548216831790557fbac6e8633a7cdf92d02dfccd5c0650859423f9cb129da9d3a3b6b9c3388e9d3a80548216831790557f396b306bb4d7e5ec907e84cfd8a554d172abac772c4513734ecdcb6881c5f50e80548216831790557fab03a94dda426a36052ba4d15cf116459cab9d706000bdc0b394c452cd19989580548216831790557f9079e2ccdd665a71ffbef8130ad598941461a84fe3f09ccc34db43430c1f4b0280548216831790557f46964a924d2954150bf715c4e8f44381a11dc11dfa27d4415b8b60a6e05214f580548216831790557feefd4cb26afb2acee85bc7b7f3de83c65a43ca1aeec63fc6e60bd5b36bb7226c80548216831790557fea127846b7b387aff5b1bc5129a48777c5714b88065c9e85b7734e9c6b08020b80548216831790557ff135e4df6f7032d83172008a20dae250379377cf1c080955996563f85fb10c4180548216831790557fdd6cecaf05e60846e0e51e0f7b3b1e6a74d4f711521f86b273ec0247d8485d0680548216831790557fb0a37bd5f267f7511efb0f89d2bb12234cbdcb70f20a80d292d1f1c07737708e80548216831790557f5f1de560810a50a205dfe14468670404fa816a9019705138822707f1c3c59c8480548216831790557f1884b3f3a9dc64425d60639cbb58afeb98626efbb0bb270f3fed16997585afca80548216831790557f0cd3c535b680af1a854619332aa1d45c6ea422d5368f30b62962d6eae718d9a580548216831790557fb7df617d7b75a39372a139c1cc718b070d85d4e228a21fc28f8bbfded3e7850c80548216831790555f805160206200ae0483398151915280548216831790557f428c4cef0c796357ca88aed4132523c75595e7470053641e9f54010d52856cf080548216831790557f7cb5bb7445ae157fe7e3e16d8db338ccbf4bfd411e9d724ea4d0b4d76e4fc24e80548216831790557fd8594a8a238a16d244ce86b66cbd31ebbf372605cdc5ad0b23b2d5cb652e5cdc80548216831790557fcdbcb45d1924f9e1ceb7a67120ec090ac5fe5c12d1f23b8a3000427fef9eb80d80548216831790557f2c8ed7981e23cc42423b598c8428a14554d8ed752e8a993124c44bfe627d2cc480548216831790557f36ecdb0b69cf051a306254eb4b7901e8bedfc577da4303892e867d1a24eeebfb80548216831790557fd2befa5b54007d4eb2e39fa1b1ca63eede0e6e6d6d29b9971d87b9180ad416c080548216831790557f7367330b260941a41f4e0d73904f1f6d6fb12a3e5bf49502107dc7c690490c8880548216831790557fead9a55b3e9699f1779ca22af4c0c917d24c635f4c8154fe29d835441e1beb3e80548216831790557f1bda87fe212ee027092e89789a9f4130bd8513521e60cc9efb72b36a22f654fc80548216831790557f9609607a5dd2b0527d5cdc6051a12c5fdc67ec2aea2563cc13a02d6636bfeb3280548216831790557ff9515b38dd0a89de957ca1a39ebd513d939d414ed80ed3216c362a3e124728aa80548216831790557ff6b5c0c95d70f066962efda616a2d918de83bac47573513b73c2d4df6082c80880548216831790557f15b645ac6c22f44898ae92b7dcbdf4a8dcb357f7a2c6e35ee312483b3abd4f9180548216831790557f2c8f13b5127ec19a9a594e6316fe159437c840040d94cf9143efd4b61cb3065880548216831790557fa4187322867bc4d2109a21b627f180d81b8a9408bc62036fd0b279c029104f7180548216831790557f230a9e1bc656fdda8bc180e3d07722e0ec8d2669b7fd9f07213989b8a0f6232180548216831790557f2449de50a8b7fe5475b0739909cce30d30a38167bb28865d1a3bc095ff3418d380548216831790557f699e1bf7a7e79603fa8ffad76fd512c4d95ce6a232bba9fd729060aec6d8c2f280548216831790557fb7d7757cae5379dbb4c847ffd6b73a2f10f8eb9dd5c4e74c388e504e1367ff7280548216831790557f8dfe95cdd018b4623d7b7d3edebf6289bbf68e246eeaa47e9d1d357080da4f1680548216831790557facf1465664bb7cad64b9b6b9749251120f0a65f622f0ec580da0e944b6f01e4880548216831790557fc872f7c3503941a7a025bcc65e6082fae71d514c7899c077a1ec78edf2ee312480548216831790557fe893c690612d5aedfdb02dbbd764ec61714ff3f61dc94e95f84f50ad614902ab80548216831790557fd1136c2f479b275dda415bf3e0ddd4976dee6c66618a9a6d6a9e723b4bb5934a80548216831790557fe5c19a51edc8bc8f9f2c0cb057d9e2e187d72b3863aabf315776c94398e1868580548216831790557fc00bab8232e808aa293ad078ae77c78b25fc538faa9aa2ae6ccdb5162d8c9c9480548216831790557f726cce84406630c444a2659bef20941460d4342eeae243ca7dca4f864ac2314d80548216831790557f4fe09d34ab014270b6a07b06df994a4fe53842dbcbdb04061647e63ac270b07280548216831790557fde8caeb43fa746aaad935fc392fb191e6bef781df6aee350960316da7c5421cd80548216831790555f805160206200ada483398151915280548216831790557f2f3c12e297f26707e0c874b0c39a25e3b523b316a245ca31e3ed5e55c821c37780548216831790557fe4de0eb1378d9d59d16895a70f24b8ffaf7940420bc6bf40f015a34ff3cc1e2480548216831790557f0d7be968845e5a3033479641e5c5fa5f7f25eedbf3bad985739202232bf2162280548216831790557f4a6fbf9a6ff2171bc5906d5472319ce8e0a95654e855f6957a0280ccf16e20f180548216831790557f57599d8ac84cbe7a38f3d0262c1e94d64d7b6410007dcbed40c7baed8aadfdaf80548216831790557fdaf87966c4fc173fd31b2f09aadc09eebbdb2c7627585b12fc3462009c968d9580548216831790557ffe36b8444e3e81fe34b6f0315c46ba9738aa08cde33ebca36e6a29dd47e4e5f480548216831790557fc508bae72c2f5d7ac48d799eb6d72b10077f53321382a401378964162e7b5ed180548216831790557fbc7dae84b22d8f6885b4f1f628af8cc4d83c58e77a4d44273c293a6b00963d9380548216831790557f4c53495d51d23a08b2c21e4d4999751ed50cf7b6018d53c52aac5a531945a71280548216831790557fec216e691df94047e0077d62f6b74dde1196d02cb8e71796cde15ad18b2bd27e80548216831790557f2a51402a9af2e1c02a60496e99522e4c5860cdebbb59384e182527e1c5eb1e2b80548216831790557f3d1ee126df0d46425891ffde442a4ff43392bca2952d66477a28478d99685eeb80548216831790557f42921f39a129a6d69b6db307447372fa9ff629dbb3249e02889a520fb0e84a8b80548216831790557fa65814bebe611d96135a86d749def7933ee5f88594eb4cd70387f5bf2f004d9480548216831790557fda29da4759c00c64bfdd190dd3c105116d8c6bcda58cf64a10d85db092d9e48d80548216831790557f3928713e53b45123837476ffb7cb7f680cecfe0aec9fdefd1fe9471bb482482a80548216831790557f39fb19a74a96c16123d747a8f4cb2e6442494722fe2cae175a20daaebb485fba80548216831790557f7ee401e14b67cd85280ef94cd5cd23cf4e3e9233bb564e80136a9d8ac58e3be580548216831790557f3cde1bc5c8b03934ea43a3e6ba0aa9115670162e4df16e0a2594ce4f6ce841a180548216831790557fc824c35367d483102579d263cc39a4c32122ddd533b852acde2db0653993660f80548216831790557fc886401d0c4e91990f53ed95c9df279d1da3a373c2bcd9af8277addac4ede8d680548216831790557f9bceb8e05493e71828200874974c7c95b84513ed898ab9de521ce9f7f4f87c0180548216831790557f3ef0d3acaa7b073fc4251263b3fc6d0cc3bfb248185dc6883dd8eb5d5feb030380548216831790557f3391970490bfa4327a16c95c8ac79cc74731a03b9884d3807789cc5e79a3773880548216831790557fafa9ea9db3e951b3bcfef6a15f0934e321bf5be861090761bebc60cfc4df917f80548216831790557f59349c43008cb641dfd77275f348282065ed8f840ffb8e10a289e5556ca5c67780548216831790557f06a7be374c2fb9583cad4b977a1e1dd0331f9149fc10580cb19ec56dcce5510080548216831790557f0eebf7c3c29f96dce7db7112821176569927d3ac5e493e1875b0613c2630855580548216831790557fda1475299737f9315ce18ce713ad1456b6ac90bdc1b2c5f24953fb41cf42df6580548216831790555f805160206200aca483398151915280548216831790555f805160206200ace483398151915280548216831790557f0ad5a81be53b3eefca7b749d655abf6b7de8e032cdfe8548afcdc9023b634e5880548216831790555f805160206200ac6483398151915280548216831790557fdc8a76feadc2d9dcb03fdf000d5860170a0982e3ac4a1ad6235ac54a4f86ebe280548216831790557f2543cbb4363c4257a16d5b010067cdee4e3fbd2842f4f7f9a61111727259af8e80548216831790557f2f9e81e6acb78a4884ef30b6306b17fe05bd87fbb9d2e5e125460f8d1e95348780548216831790557ff7652464ce9568253b7cb2ce885df5af6bfb38cfe0ddeb2f8dce8cb3f4a7aadd80548216831790557facdfff0ffe68b3c632c8caa50788922de63614216103656b90ad06876a51c11180548216831790557fc7aa0613dc7485daac5a29493cbf614492ab099453068ccb291fd9664df8e63d80548216831790557f015cafa904e963d906f154d3aa3ef91992213ffd35e3b7c83c364a874c026c6380548216831790557f5988683599172647a5960741ca42387dd28ad42bdb93cf6a369e98cb8cff497e80548216831790557f23abdd3d96b243848ee39338e5ff348bc0ffa5bda643f9c9c982d5f9c6e16fb180548216831790557f1470748ad541faf514a7ef01e42b38588a9a647f0bd15aec31082e0a5816cdd080548216831790555f805160206200ad6483398151915280548216831790557f8c0908f2257ed9e7a6fa2381fa6dd754cdedd0bfd1388c262f12322e3a2c087b80548216831790557f75229037a913e3c4d64fba2e19f03fe2fee81c9dd8793e5e03ba3c588a73d5f280548216831790557f10f9ea12ad0ad227b0f70a79d69becf0280aab555e5d621baf99a66806d2d17080548216831790557fc88bc42c79b86037df3e57f42e2744457a51a2c88d0c60a685136eb2fe557a5380548216831790557fa9547badf3dfed759caac76e51d03c17d2a06032aeefb843271d532e1087e42d805482168317905573b4b6cb2789bad42a9907493068996c358e1e5e0e5f527f1b63e090229d5d380fd880ee9f887d3d248ddc08542024c6ef0a666cc12ae27e80548216831790557f9bfd724cf22d0beb1a28e5f03cf06fb1fc9a288750feaaf9b4bb6b8d372f51f780548216831790557fad2ae7590bab03e19b5b5c1e9e4a5abab79222717e8531c56c9694ddac06733180548216831790557fa48e8b3c4baa91c70ed36a4a7bbece2c672a36bb9e4de88e46d93f74a0704f1580548216831790557f26a5012274309901c9898187cafa1b42fd409c71c327228d21054a300dc45f5080548216831790557fb2f76935fc266b74c9a820dc4682f4f96b5ccf868145261547521ae173ecf22880548216831790557f23c48f791344cc90f2490bd57199d14bb5d30f40097c70f03619ef28db54d69980548216831790557fc47ccdf4f02421c233f3eb08437bb4bb5d2287e846ff72f35c57bd755655365a80548216831790557f8bc76023e8a902726663a48913a33c8b7035f2f8e7aa237df2a56301949a7d6380548216831790557fed893c13382e3372e505137dd9b965654c10dc17976193d33efe8481eed3a32c80548216831790557f525cf1ba21e09f26019273a6f586797d2262032568af8cad13cca7e0f2624a2f80548216831790557fe11047a64dc5a46006c2e702f9a642fd9bc9bcf81ccbdf795d6375dd0dcfa18680548216831790557f8b35b9b72d11315b6aee72aad618af55dba01dafa307511e8ae7763e54b19e3180548216831790557f8221eb9e05ec9f5f17fa2aeea3dac2af1f8e7a7cb8e84e7ddf625c7a94a5798e805482168317905562005cbf9291907fa2004299d44f9a162fd6bc625f366d010b6f74280d96868a3fbad226d4e61b4280548216831790557fe77497518e5cd828dfdb5bafc41940d2de2246f89fffb275d12b6fd256fbfd4680548216831790557f05bfdfa70f510ca3a449f6eb8227b386087b653c0ad873f1439a000750d7b93a80548216831790557ffdfca75e699a60c1ac1877ad71c71c9e5d9d74119780c7fbbe12070895ed5fe980548216831790557f732955df82dce0063cd7c9dfe478189bc9392ef79ab1be3052930ae03180afde80548216831790557f013b8fa16f62fed53a11adc9045b9128319bb2a0c99109399a01b57a7f57d69080548216831790557f40348547e46a16a38ddcdf2a43b934ec95de6926fcb817b912ee6803e262e5bd80548216831790557f2296ced70b2526da2bad7c9a7b5211a9d0bcb6ce1654ef5ed4283d901464a63680548216831790557fd9db9ee86130f3a7fc5c4e064f98fad0832e810bc57f61c3883d717a740d1b1680548216831790557f21efaa86ef3de713087c5f1057d5efbc5edac6f49b0289445a9700c76873885180548216831790557f3450cef040d6e335d684246b96a1eb8a63f43cd0be8ecbe0db30846221276f7b80548216831790557fd99e8c1419b4d32d8c156f33f19d7e5d1f452efd64ddf408062c81003cbdd71e80548216831790557f6561e5bec3ab0724be390d4fbcf969b79cbed4e684aa648f785b149adf55086f80548216831790557f284ea14fdf0a44c7707e574e7ff0e099a1f3b5c431db62b646f09dcbf49c77c380548216831790557f02a0b68fd31642d98546f1f250ef78f44602b1ae20b124e8ffa6a51ef918053f80548216831790557f6cfdc8d03061613ca881fa2e698dc5deedf60722092a13f3aca700e8b3a397f180548216831790557f212c1b1481d1468293fa94e0d72d0547fb6bc59fd8a915feca2c117b310c094c80548216831790557fd84a78f2e73a234778c04c20b0239b7775e780364c0a18b0e52ac7555a2ec6c980548216831790557f5d1cf1bc1e793b90a87cddaf17e024119d94c73c580c06fdc8bf2fee61aab94a80548216831790557f971841c41f1c164f017f2a26a6e06b49f7a961031dc73d736f19e18a0841d97280548216831790557fd390846d331da920a89a4641c727d2feb8d0427b09cf5f71726f01e1d614dc3180548216831790557ff6ba1d5ee34604604dba0b581b5a0cb0064efa062834beeb6c292d3765c2e5bc80548216831790557f218f44fe2c567451259aefab9100e908f42eb7cad84ece64b42f53ce38115bb380548216831790557f5365db2faccd228f13f97c7943e3dfc29c987c1c093a3f70baacd1d676662bd580548216831790557f4052675f4ea5d88ae95cc1568f133d25c0ea6c89a06f194060a0e4457176f3ee80548216831790557f968eaf61d65d83497ae814878d4590dba16ba91bc3eb4fa508ba0953feff2dc980548216831790557fb36561066677f4bdfb5bdfa0cc4faa115e51cc6b3f4eb5cd37e1e1ec4eed4dbc80548216831790557fd45448adb87794f0cf9aedd399aa07dd835264a66db137bb2e13abe758a1359d80548216831790557f4922ab70c1724ef7422c357dc7c9d6ccebc5b9e8652028c482d50f682d99836f80548216831790555f805160206200ad8483398151915280548216831790557fbfe0bb2ed5329eef2390ebf47dca763f36a0e2dea578ab004fa9d734a1092fd680548216831790555f805160206200ac6483398151915280548216831790557f1e5ca96a7e223be444a239b8141a776fe973bd0497013da1f765a8a239ba9f8980548216831790557ffb9f176bec240eb0a55ff4b0ccb903fafbc671459d6a6223c6fe03a6e113bb3980548216831790557f31af26f1f5f2064a11b938296693199a427f4cb772e55b4ba73312e6d42b104280548216831790557fa7631767aa284171014ecff522a26bd94ad5b14583731219613ea13dad39d4f680548216831790557f0867cee6357a773c760f47308b7612aef72575c00531f13178482726f18faa02805482168317815573d283ac6b8dd58cde7ede41002219d976115dca365f908152602094855260408120805484168517905560129094527f50fbcc597db0e32072b9cd9e860cea0d58d3419b04542e980c18c620e258d16780548316841790557fbc9b71e5661de3c5288eefe2cfd3332ce5644585f4acee6b2aa76d21d0aa353b80548316841790557f51860032863e2ec98e51cc66303d1371a7299fd1b0052be7cd497ea46bb3e36c80548316841790557f46abfa81ca344ee89408c40b86b0b7710b5a01abc3bc47e79af95fe30526d19f80548316841790555f805160206200acc483398151915280548316841790557f26c55c249edf93adc83c77f6d6b558268337f3e3f304e04d4bf4dcdb762c5e6580548316841790557f0a191604c1f4f42561e0247a86425965d71923afde6197a1b5445ef5dd46bdb480548316841790557ff8f40138d6802ec8c897d0460a5bc042a7fcb31c45432e87039af9c9dd8f4b1780548316841790557f0f99f2ba29734e5ad1f1b508ce8809c1738bf9a567aa5d207abb762da2bf0c7f80548316841790557f892df82172edc7b13337d8847a6b6817e2f94390910003729fa29c9ab24f1d6680548316841790555f805160206200ad4483398151915280548316841790557fd6c1c6a43887e000aa677d418d6f58ec316d4d268c1accaba667da9b8137c52980548316841790557fdde7eedd83b9c8ff3388279ec6292a43a2cb40f84056a67ad0b3d719c2085c8d80548316841790557f0a1d58ffebbf6ebbd436bf3f0debb8e6ff81a188940b68d8ec4c0c11430a528a80548316841790557fa68cb798c8b304d282e19ac45775e7ae96c7879bc6456d94b1b4b1e78a0d07ae80548316841790557f197650adc9ee61c2d4d9041d72bad3d030fa8ea43dca3bede20c7c58c7aaea4380548316841790557fb2cc79030dbbaa13e594b714c0c000aa2550d2aac5290ca392efd09f4964d1d580548316841790557ffc8b9c1132297c6c307be100ea34f6a0d57986fdee2fc308be65c77d0088136080548316841790555f805160206200ac4483398151915280548316841790557f3c306369c451c08a7787c08475d5f172fa567686a12e485bfa2c80285726188680548316841790557f2541c82c2bfc9abc071e3197ae75f701e5124f9409ddea00a1ffe5d99089140f80548316841790557fbe338f49daa283341e7c63a885aa7962d602675f0e5a79d5fbc1a900e9c22f2780548316841790557f1a8d6a694a5b0fac6de43351f345750d2cc108b6522f1a81992e0fdefe4ec54880548316841790557f78b90d01edfbcb6a2981276529387345781abcbb7590cbf08386db83db0a677180548316841790557f0874949d2425c293517b462dc78d75d65098fd12c2f2efbfc538f2715625265a80548316841790557f320c0fbbd864f846d9e4abcc33c48ab6414a762a81099ffcf414539afc73d09f80548316841790557f6198f1d845ff70886df83295130dc87aa64a2fc30bbe45e8199a4119651abafd80548316841790557f1bc77169164af09e907e7a369e51d259e00f48847c63979548d1806e02ef3fc580548316841790557f10fded4d576bc6d10f52f3a49098fa8c6a53e3c95accaff411f46959d6071a0480548316841790557fb7fb7ce14911d7dfeb8015d2c88be2291d9fb150344d18736919137ca976502380548316841790557f0badd1ee82c794a65ae356c6de21c8a65f6ea9ca3954f426b8a2ab1d24fd35fe80548316841790557fa819f5e5cda310a0e167034f047eb9b33eef11c2bd4a56e415f59d64ae4d723180548316841790557fc74ba20e531787cc73abaa8aeaad62b115b1cb3c97ac0224e7bd822551101b6980548316841790557faf2fb14fd56bd4838f27fce0a67be5753914dffe25c86950bac8c25c29fb392e80548316841790557f998888ff398a4fe0898e4b6b88b6e392bce5f38e348cf0a76ba789d22cd9ceb180548316841790557fcd31ee0882cef7d606d2506913ded726231c99ba32fe2c6acb21b37fb15d17a680548316841790557f9382144be708093b5b3cc70eb4b6e441ad503abfd0ae2b2bff9f20667ad35db380548316841790557f1befb5877d5b0a49a82709a26b6fdd2e4d41ffb9b87d051517a99bdd2954ce0480548316841790557f69af79e1b6e40f37c9462e0412769a2876742b69c1ec0b637547cbf014dd82e780548316841790557ff02303774be387acbe20f589b10db6da68e7060ab81667989081ea1e2b0f7f9780548316841790557fa832b89d9ea70d09e4874d2e0a4257244e15a45d9a6820049835fccef3b88faf80548316841790557f8c7ef17ad6396ec267d19421af85008271c70e5c904d2d7d042c4c9b4d9c3bc380548316841790557f60bbd1ec1120f58206fef7edf2d067ad4d0d6030df7d2609472920c262456be280548316841790555f805160206200ae2483398151915280548316841790555f805160206200ae4483398151915280548316841790557fa153e132859d199cde651970e3127515f1916787aeca87191e86a7001c6e7a4380548316841790555f805160206200ad0483398151915280548316841790557f68b57daef73bad50ab9822b3a510e69d3e17d36f59a6a38ee273854a29e0b6b780548316841790557fbf7dfcacefade797f2037f962cd0d0f91906b8fa7d06ac73c5d583f5fa1da7d280548316841790557f6b986739f9eda50b0f3ff3ef0fe0f2b8fee4c8dc833d6399f4148e00aab8730580548316841790555f805160206200ac2483398151915280548316841790557fe341f51a76927631bb80483b9b789dd6467fcac79296cdda65ac7bf17e5398e380548316841790557fc16c33e956125d2675e72ddee303f1c1e6aee3555b10dcec916310545b97a0c080548316841790557fae13fdd08f6468113287863bd645c0b0d39c3868094c4f9c75cc2a8d2990881880548316841790557fe68705bc893afd002a2e62082a1794c250eec86e6238c8dd6a78a77a1ac2127980548316841790557f925f8a1161f8d2f781f56e6f29f809d3a76f8c01854462131829867c748c620080548316841790557f0a833d54c39193c8d67690905fc1e488733013492623bb1657ce6149c8fc5ebb80548316841790555f805160206200ac8483398151915280548316841790557f1425642564eca84657ee18b399977c959189df962ea3cdd111a8b61abc71ebf680548316841790557fd4f48fcace08fd1320a1dd55d6eed5668ace60fc5a60f737f7cd7fcd50ef08d280548316841790557fccaa8041c16d273d6674871ed96a151058538fa7433c475eb1667557159bf85580548316841790557f92140f340ef7d03b266cf86037b210249b8e6143f4e22ff07abdf3ef12c268a780548316841790555f805160206200ac0483398151915280548316841790557f338226c8b05c32e13de6bf406282018f7cc8d4b2ac19c9a24e2213684911218880548316841790557f7eb02c14cedb9600df15de4214d1e83f20b562481b3ec73b77a9bd79679ba80780548316841790555f805160206200ae6483398151915280548316841790557f92ebf6ed77459fe0a53d9d26543d75c0e667a3768a9a46c6fb7a66ff59dbf9bb80548316841790557f969407286b6583f78094b9b1d9b78eb804535c17ded91acc4d54c7bfc9daf3e780548316841790555f805160206200ace483398151915280548316841790557fa18bdb8edfc9239e45c2d903fc8b4948dda068ddf328ad02dd9c368b2ec8fb4f80548316841790557fb62d455ea99a0e5746dd41a51687f25e00c95d0b15712782ccd14d40edda010d80548316841790557fe1e08586f6789222afe527b25fc220679ace9fd592d4e76091d38179ff3ce78480548316841790557f5069b5c60f2a89df80bb2ff6bccd824d951598c2d0dbc1908795672883f3466780548316841790557f312cb2599f50c663cfb06289ab367b7d8f7fe51b78783faea3f587928b884bde80548316841790557fd58e14c5244fa89c60522d82904e72dc21ede3f5db71e545e32273a9fba2c23080548316841790557f7d2447672eca7e2e691a836df99aa5441c6c1279f5d5332b9a91b6cf236eac4680548316841790557fbc7e74378c292ccd9301f2be95d387ad163be119d87c3d027b5bba4561d13f7b80548316841790557f483b761a1547585020c7419db98111b3b38e68d84a00accc77c8b7eeef076ceb80548316841790557f0c7eefde62b217b7914c86caf4e1674aa3e496ab9fce6a38c6a5c4968304d97080548316841790557f63800b29f0abae32794d15613bfcc2015297a0d1c0465de724628a363dd8081f80548316841790557f9d545542e208cffab14784561c0edcf02bfbb5d8c352701d0bbafc675ef5bc1380548316841790557fa6c6588328400fa7d227fa3ff902dc8e79173b3db0b4c734f7158b535d64e0b580548316841790557f52862ecc3d8b5b30dbfbd0c679f6eba79e7fbbf32d6f2527d4120d10cc0fa60880548316841790557fd01fd989fc7d70c612ee300634d5408d6f42ee4b3736d4237d43f34dcee2777180548316841790557f6710d28ddeaefc58a830950a3dafc8136fc91307b3436d1cc86fed4c3bb1375a80548316841790557fc84389b766efcb2952fad3eb0e060177f13d0166f9da1cab124cb5950ea0729b80548316841790557fc5785cc91e3e356dfa58b86d4704cbb5c018b90dc97cffe7fcf8f78891ec0d9c80548316841790557fc37178edf1915b279641620bea2a98c121b075e2691ed27ea5840188303c9ef780548316841790557f9e54a8237ae5991307f10e394657b3eecc128eaf506e05fbeb83cf800d7ee08f80548316841790557f52a653df635f055570d7b51d0b1c7120d720723334bc1a50afc994fb8e58f5cf80548316841790557fdc84a1c0ea46568d6b85493fd00e2ad4753773d152249df7490a3856b56da05180548316841790557f58d431198d12782bdb5065f654008b1b11b07b8a8aea8a2e9c367d255df6d77c80548316841790557fa4e95c6f2910485c2009207cd557866291b53ac1c9b2c6d899a7c462a9fbf32b80548316841790557f303f060a2c07bd405d15c3f83669a14eb3f124dcfef0702962f779802628115b80548316841790557fadfefed02861ac417e709b01b24356692dccb91543b1b61a27ef59df5499b71180548316841790557f14d3e9eff642cc39b2f7db1ab7dec0da2549ccbc316b9eeec43a1e8e70a15adf80548316841790557fefaf5e2d5ab713cf3e553fe1d18943f29a6b2e8ba023899780a549365f4613fd80548316841790557ff3625f355f6a27046f85ebebed5e2c851fe52ac7093801ff9cb5e5b4763dadd280548316841790557fb71c5e9464d3d3241960875d8ab687bbf3a21edca43bc4da06e911d17de688f880548316841790557fde5bde96d18fd7c7cdf87cafa2a83a44dced565a5ba6f9c9ef541bcba18ef06380548316841790557f2f6886906b8a67a970a9357972eb0e37fda45368bc8be784e01a56219e33de9080548316841790557f2b76f7ed6de6f2aeaacae3b4beae08c6cafc63753654c86ee414e365a1047e0280548316841790555f805160206200ade483398151915280548316841790557f367e726998304f89b5af4337bcfa2d88c09bef740f478f476cd571447c4efa4880548316841790557f97e0d88af6af18931633044f02bcd3ac1d9eabafece2a042d97a6b53b798428980548316841790557f07978cb747912fb26b133f194554443cfca31e17a74e88483c8839255313088580548316841790557f49a08b16f9a470ddeaefc885b46ee353deed13333689b46de91e124fbf67d36380548316841790557f8c06159577b219c2e7dd151bbccf89f654682bf9f07151768d6e60fa71a0beef80548316841790557f567690c20057dedca023a8a5409cd21b86bb26f4d0f29590b7c73f986480568b805483168417905580548216831790557fddafc322da06e4f5354ae84e5c089473c8d1f7f44d4a9cab46bf98c04b86869e80548216831790557f8ce459398d306b409fd1f30f783141ec5abbfcefe40ecfbd0ba73576a90fd73b80548216831790557f17af5816f3da593f0f454c16d40d4729b2db20f84bbf62e51b48e8dc87b085d380548216831790557ffcd6612197ced655be910d9e3baa1d4f5cbf315ad4ac0cf5895ffa6da152709680548216831790557fac5f5286879e4cd78ea5bd79f1e42c75b950552af2e4599c64b9c7d5c50dfa2780548216831790557fccaf4aad287996d01b75c36eef3d98ea4e0e6817e18053a833b7b58ca0feb83380548216831790557fa4d776f5f25fe6a8367cd89de17eb079da31987a344b41a3d07695d5429a5c9480548216831790557f616bcc794bc5b51ba9e3e6956f84e6040ca63b700781f638cfcef5d6739d887a80548216831790557fb4cfccce9b406c358ec572d44039ffba8603b6543b8579d0046cda42801984b780548216831790557feb52f79265e9b62c52b9af1979d0b5e0812494b78e037b11074fd1a2ba6a5def80548216831790557f6aa5954cf7cebd8dc8337d89665932a1f2b04b83668e7fc2c8dfda077eec0f2480548216831790557f30ca7d7600f7d7d7177092b5b81d108705a97e9c01401e44ead11ee13c3c456c80548216831790557f3713efaaadb48ec709e8f1aacbd2c2e07e0e091067edf6d942723c5c4961ceec80548216831790555f805160206200ae0483398151915280548216831790557f3f5dae91d0e0c27c4e552207de7f40264dce388f02468cc3591484f7d2e5ddec80548216831790557ff3b85d19852589123b58eb7ff3a87c55a11bdd787585dfe3f0bce9344f57db1e80548216831790557f6b24ab2f630abcd8966f64b7ea1516f4e38e48ec8d88060647ca2ec5436383f180548216831790557faf615d17cbb5809965155f64a7aabfebf7a94a03c7b10281d599097ec029780280548216831790557f1a736da4fee8ed02583077a3e121f19376a8ee110622212ecf6c900bb9f7cb4280548216831790555f805160206200adc483398151915280548216831790557f6bdd6de1d321cdf403b5343417840de43342c5d5df338e12d96a19fecc2b46a480548216831790557f24ef032306c67cd55819ca5da76b5ccd30c753fe60d64d9799d69160150319e680548216831790557f34de1fec9a938dbd67cbc7f34c9f5744d86cac4840d62a01346b88a1e622c93080548216831790557f73639074610c9912c31c78a33fc1e98ebbd1fc351af9fd3c5ccfd05185f943e680548216831790557fae340dac2c88dcdf3d1d0b7576d2e4572763f6ef830472cf693b9428f148bc7a80548216831790557f572e9fbec0349427842ce0b9d508f4312df104a79c67d207f3cffde00848d81880548216831790557f165bab5efabe1f170ce45c88ac66d68a1638368135e90c61b6d78e88b65d6dc480548216831790555f805160206200ad2483398151915280548216831790557f6078d15524eaedebf394873806f7f81a8caec86e1ab33cab03dcacd279fbe80580548216831790557e745e0de5bbf75def4e55b9d8aeca03afbb62652f4bc86096092e6ad95ae51e80548216831790557f8a6b1afb916bc243a0e914b469bbabc353d27c25ddf2c9ba1ea3257b176fe6a280548216831790557f2fedfae1b1fce23cd16e9efe6288d0354e1a0853f9c1935d51dd1e01f3e24ac080548216831790557fd281d8024ae58948d7278fefae40f546a28f64e2d33c4cf6c293a1ec8aae923080548216831790557fe1efff6f19202ea32e1e48fec32d19e614e3ca8f66ba7fc295c3535605ee19d780548216831790557fee042de7e446060fca77fc52ea32bf7c759a902ec1a71059cecb7ca95c4d5ad980548216831790557f7a8eff2bd8ce4ee8ca8eb2a3e16f6cfc7b1f73ec1984e1cb517bc3db71ef104680548216831790557fdf020915e3876c853bfecd46a9cf4df21f91fc89df0b252f275afce62d6ad4f280548216831790557f97e0dab07e719b7abe0f195ffff1b7ab75a2d6212ee9b6bfa87a9790f6c6ad3980548216831790557306d6f74c14ca13505220751ed21da78c644a914483527f94da6d457f79d0802e3356bf6058942bb97b3774c931dcc64adab4e4f357b58780548216831790557fcf4b969e6495740af9ba92cb553bd1af06ed3c954f21ca06780b96068e1f852980548216831790557ffad8fc2c5eaaad4335aee0f257654396d86900c2a0bcf16aebf7c23b27947d9180548216831790557f61259051babefc5cf35e331090988d8bc7b27fb9d379b9dc32734a46a5b9becc80548216831790557f8e4c69ac2c71e4bed9f072e1713577e12bbaf9b09a553d12acddd204f97bf7ae80548216831790557fac645b24b7cc302a0927f7ed44b13c11dbc706acbd26ac6f867064270aa3ee2480548216831790557f9969327fc46368de0aceebe30a13830766f5a562b38f809e32642aceeffde05c80548216831790557f582d4f54120b0c7d23242bd03f90ec0a778bb0af914afc667a69f18c2fe433e880548216831790557fd9d7a42191986542cdedd97512aa74c823c9a5219ec0df87f77ec7947f8d444780548216831790557f7ceb32dad85aa831c0fedb3b4ce6182aaf6ea8da9148c4f186cf21e927f3bd4e80548216831790557f78ce20bde5e505188479ac0fb6c0f8d5bca5169781dbba83c542d86609adfafc80548216831790557f2bdb284d156ed47c86aadfde086e374a682c20d9a91aeba764c64d86f3aa31ab80548216831790557f7efe52e806f3849f2c2f01fb052912bab1815c79f1ae98b7f9674bbf521e869980548216831790557fa2a4f8736cd50379263e8e5c2a63661643ebb867d9d8ad0efc59598f75875ec080548216831790557f6a65e57fc47c0721d8d7b600893b513f5a639ae7234e05f9f2e286c90637e0da80548216831790557f8c8ad04d174006098419fa220b6f7282adc86418b03dbf93226ccf28e1e54cc280548216831790557fb275f90189c4359eee75af9f6a467c9eae061340a53c503bc9e4b2a96dfc806380548216831790557fa561a4992f4c0a3b03b3c3f21c1e51e545dbe3826434bf70c5158f6b6882ac6580548216831790557f990a50feef278e8cfb9c3426b7d01fed3837b407bcee50bcdd4e8955805d64a780548216831790557f8c1da7a7c679613d576590a2313543058cc7117e77c20360df963702530eaef480548216831790557fb4da76405d48240b04b1f64b778a0897460850f7c76baf370bd1b0c1b0ea146d80548216831790557f7341b006220b2e2e217dcb5be1ab3eb107854e90dd2784858c3cf904659af44c80548216831790557f37b12e263ae6b4b45117e1b8999b0beb2384788ce6cdaf60cbd0ab62b3f4d65c80548216831790557f6d694b5e023bf1503f94939cd04acf9521a2e948fdc744409e1daf42a096337680548216831790557fe68a814ba65a944a7b6554878237d59046d0f533003819dfc830c16932af811d80548216831790557fb0e5c07adde61d55696a4959c646753fafd59ab1c03705e7f86217fd4e0a56dc80548216831790557f5c25f7e6b61a63d94115dfaa535b89d644a575561b254ec3906d8ceeb680306880548216831790557f345558bf35aa1eb06281ec0e0cc4c27d3aac222a983c9e684188381e41715d6d80548216831790557f57206d7090a3599149a96194cf96be235aed9384013d88272ce3892f3a6efae180548216831790557ffe923d2f05c74106a433b824775a1484ff5185995f4bc263f44e2501997259ed80548216831790557fe2c79e0393f1011dbf74875bb7fafff8c72f154fd382c9b90499fbd838ea11ac80548216831790557ff143ec1354090e72a9dfe7618b01c5e1a682f85c45d2823601dfa4e35df11dc180548216831790557f157ef4e7d7eddd45e222ee98d2dcc84b2eeee7d6cd1e3490f4693d75ef7500b680548216831790557f1353cd7188099dc6126aac2f3f2f6c8a3e2f47636ef04222a4c0b85e03774880805482168317905591907fd1da9035e7fad2b79743122667c8239dec9032109b3fb07544cd54313febbb8d80548416821790557fe48497a2e65e6a59830d3e174f2f1adc1420e733e378c16146fb86608d13fe5a80548416821790557e4a39afb47caa461e1e6a0038ce10dd52b7d61b9e1b7dacdaf9f09b4effdfa980548416821790557ff7af88cf1acc320186e34d921bf7adc5a864f7bc157d1e3847a6a1898c34d63880548416821790557fa05d842cbe3a2a69401469edf47c570c41beb37c80d780bd64eb40c398b0dff380548416821790557f6d75ccd091975dcd3fae87d013851d05e6579e450b7acd66e3a86a4e7437801b80548416821790557fd83b2237f561fdc62d546360ed6fe76dfc210bbc620d989fbb31a97799b8f6e580548416821790557fe607d0a16339f4e3de29efffabfcebe2ebec6ce810e1aa150ab4afa55a62e18c80548416821790557f7c349821df3b8a5d60744dd30f6e3cc3a05435edfe4f846ee565ddf7baa744b680548416821790557f33e3b5b2a5f00b756c9862aa8bcfad9aa686119fd4f0a7ecd097bdad8c8ebe8280548416821790557f1a9740efd47b2d4170fd0999528bf108ea54fd2f49064ade0ba3fc12522a42e080548416821790557fefafcc4ca203bde1394625eb9b4b41bafd447187a0441db50505d53f1d98d6de80548416821790557f50846135c5830723c05e1d8e9ba05718276a90fbb6905e695085272f8f24c65080548416821790555f805160206200ad0483398151915280548416821790557fec593c9df710e90e7a2a5cc394eb1e844dc7aad158b95c75592911d74fe602f780548416821790555f805160206200ad6483398151915280548416821790557fb8e532138d7f263301bd47b5160263bb956777ccf7423be99199e23eb674c8da8054909316811790925573358421fa33b71eb6f40809bc10e6c4c4ed12e08990527f2bc4fb7e09231b25fb8b15a53cfaebb95b2c9de90217d52f3956315661f36753805460ff8302191682151590920291909117905560126020527f378eba9b2c7ae15c388465500090ec8f5040c5a38dbe78bd17b2b439148f2734805460ff1990811660019081179092557f8dcbd9a0b86e754c13d26bd30fd6dd040bcb5b337fd0617f57a37d4a4e473eaa80548216831790557f8e5f11c4e61b1cb5e6d6a68838f25809f9e00de689b7688dc69f460e78a8bfad80548216831790557f0a59e01ed3560236d6b61978084a1280783b3a3108a7cc65afa0282cbfa59a5580548216831790557f8a803a9fd06cec4065c2345fb5d200d886a5358cf41568b3f7393d7250fa6cee80548216831790557f8b0620c0e1653df056fc1d73f94f28ee3934e204d2f05b85e512fe14e7cd9cb980548216831790557fa65d7ad861f89eddb47441fceb712af44d11c15d45f65f28541d67c7deb8ad1480548216831790557f51e31244c0db5f4ed557b84fbdf14fc8d421e4d357984e4e5efadf9f675e3cb580548216831790557f4d2462e3411b4c8bd36b79adbad217dd2f2c728b0177b59e3889b10119d7ca2180548216831790557fb6fc593c1d0696de915b492ff897a6538c74311b883eb60ab11ec469a9ccee7b80548216831790557f1578810aa9dc8f41833870b4393375435a7b2785756280c6c0b2c2dbeb9388e380548216831790557f614d5ede54d7ddb5e920970cec94e1ae9617995d0811e3209ec3a3983f118afb80548216831790557f238ba1cb0d32124a7836b1eede29637e73ccea2e281d49486343af010af413b680548216831790557fbd7a2121289a79318c830717289e71819c868dd8afd3e92865569ad1195a8bcc80548216831790557fb2e561e6d05475d05050bb238501bd17f17297283cae7e47cc09611762cd708980548216831790557f8cb979c3726c634b1789504c167e6e5bc92c13971e55f3001e9cf37c6ed0d9b380548216831790557f25ab13d3a0290da362798c332822be9e8f6a7de40fffa199e2830fbc158c57b580548216831790557f50b3140134697775850c3ac576b7277bf67d63d0d6548dc1953c7dde7a8fb06480548216831790557fd1fc121f10721bc180ab20aa691a2e67b041c775aedf66bf5a869d675f3f0d5680548216831790557f4c0daf3c5be54d3040a7a0b0e2419c503d5210864cbc915d226d4712f49de80d80548216831790557f85cb7878cd59682810dda2e98c9edbe4d01ecaed1db11f94e4f4bf1492da293b80548216831790557fc66d718269b5e6c415439710b801cd9ee27efa47154e6f8552887f284203f5f680548216831790557fd0892edb70a16a9525fef5e8410202772b314e886b646ea703378a9fb423bd5a80548216831790557f458ea298ee5be34005f5391c3921fd72baadc5bb899500b37094a3871cc83cc080548216831790557fe82debfceb6d836a2f921b35dc42405d1cf0463bab3595d3226d853308f641a180548216831790557fdeb37867861d7e082688c08e747bd4b7d43b2c4db11aab888fe0623d777e969b80548216831790557ff29a32ab3ef25776c350489e923f0c2b418c12e5be885fd0388112e173844bf580548216831790557f7b246350d12539aad89de7f2ec79462206ae55739fd0a6c58ef3574504c62a9d80548216831790557f3c501637608fda3e4c0324924c012f3f3ce4d1b4289c3f656db8963db1dd969980548216831790557ff530a3a297d81e016fb94dfd2cfbce11aee8032edfa0a3a1de9037563f368b4e80548216831790557f8ffc1c48741e3ed472e8b7c5edc35a7fb6fc4131f1d3b1283d5e4b3a248e393980548216831790557f78e8b002018e15f3eace3ad92c6d91a7b3cff53a99ce46f4d1fbb049cba80c1080548216831790557fc9807b97d0f4403df39e545a74adc9017ddb5aefe591237bde60b07961852f6580548216831790557fdc71f1b6a2e83bf1b99cba41ef125a36cf5e26861104f0a79378377ad824f8aa80548216831790557fdb723e15bd18356335e0310b73a29fed14be94d875cd9ef6fd2fcc6f95af8eef80548216831790557fc5772c0d750810ccf3eba1300d63417bb762722cda0f122f2cbafa23f2a3a56980548216831790557f5f955fbf71324d8b52f9cfff6f717d251f9441d3dbb5d620a88b1dd51dbf872580548216831790557fb2ac0971e5c83fac4a0d3a83be52047e5507090dc1b8328488b20e33bc1792bd80548216831790557fcbbc56b6ae8163e9538d0abdc8a9beeb3ebdd7ebef9d5ed1ba69a2d91313785f80548216831790557fb37073a030b2ad8d27b73b62cefc2a3a2e6fa734e6a2e0bcf1a981d5a337c95f80548216831790557ff3fd026f59eea37825bbccc922388879c5c7ddd09b768049e4a4240f2742afa680548216831790557f7f80ec89b76db982410f4a13f5246ab98009e2993d7e8024f3a700592d5016d880548216831790557f0df2a6fd6202e3a86b86d09166fb83e326ca89aeb1ef7997a2aa4b76ba30a5fa80548216831790555f805160206200aca483398151915280548216831790557f816f08135e265c9212d3df163119e38d803af571a5897775f6ec0bb79e34a49a80548216831790557f9e883fca2389ed5a041acc42b60575c635588a85674a628c53030900510b667f80548216831790557f693673264ac3a44bc6e185930d13a47c881b990dec536400075b9b37ebca406780548216831790557fb1743ea2e05d3dc1c71a446af9e4c8da0009182dc7ce1843ccbc1be404b2e7d680548216831790557f2af18bfc52fd76186e47f2f0bff95730859f27c48ad91946809e1782f23d565c80548216831790557f7be318448272b7d324a56d533ce70010807e9d36ee0a1f2dbfaf5a218a61d19a80548216831790557f044fb9167dbfefbf885f87e78d19b19070380747c2abedf5511457aee14a29b480548216831790557f4e0d946134dc2399b498b0c0b194007d7ec9d90d8d317e873cd095e84a42a50b80548216831790557f2251777f3705bfed8d266550c35bf7882ea29cd2194a14b5d89075de7cf4de1a80548216831790557f225952ee740a0067d2ee05f587fea239a6822a1ca19466b3fd88a0df88e98ee280548216831790557fd7f3e60c04d1d43f1042a8f0e09e731a214563b6159cd12bebed4ff9f0bbf3fe80548216831790557f4275e2e99ccced7744bff9be631b398e362d074d6e0c0a3ceea878c522b0286680548216831790557f4dfa7aa4999ee3cc98ab019db4a7f371808e5ffe50009fa318b56986fc820ab180548216831790557f1551586ddf75e5f14ccfcb9a41f023c58f83f59e2c0176b2d6ee13b4c879486380548216831790557f5b51ddb9e5c484123bcb91cb973097f988192cdd4c1f28a078831ce0b536d99480548216831790557ff504612d94f1f4da0fb5c24fa55c5d6799931d67bda5f6e1324471771a6d8a7380548216831790557f9efb44431887c3d279675761a45f0ce5191a4bfb05e45203d67f85611e848c4480548216831790557f861385cafb1e7c51062009b9a41057f107ea808ef15b45b7be6dc4dbfcb85a2f80548216831790557f78dd3403fbc6572577922212d35c5170d09941a88bef404f776604686bad988480548216831790557f0331f56e5d088ce845d92aa332fc036603c1ccaae36b07e6be340faf4758952880548216831790557f39bc4c7821ff168b03b17a2935c21eb7faa964093df7e502019311203aade3a880548216831790557fb140808fb0c80eb97e6176aa5da88bab8fb4258dbae285d8995e89f9b224b27680548216831790557f964cc45ec9a5c150e7f31bd594a6479a9343d9f26e1628d883c5659288d3ab1b80548216831790557fb98c599c04e0e6a897dd0ddef02cce71bba900616fe779189cd2f05c45a7094e80548216831790557fd3562d271a1e02d436f88d803cbcc9a586be95403ece784d58c3c93cc1db06ae80548216831790557f7caa51315ddca8bd6e27c5c544e58322adba5fbd400daadd554476e9e4bc2ea380548216831790557f24de1f6dbea0a760a88c8c0cc87841e028745808651d2151c2d5e9a70cb4457a80548216831790557f897f808449ff5dffe32a545a941c065b5ad39b5a7131b0e5ea3cbf5521a57bc080548216831790557f8664326e55b77df45aeacf23105618ff1742955b4dd54295e82eb12cf1d5e17e80548216831790557f212cb9fc947e459c948b1c7a2bb90715a307e01f39806197ec4b62904a11f08a80548216831790557f675465628a2622b5509b35e84e720ffcd2bd99f2a161a2d978c5240f9d0e82ef80548216831790557f1916ed9320d329671c0a475294ea4c7c882de1bedc0a5954965351453bef25be80548216831790557f679d5d5b7c4f9da9b407de7650fc68624a354704a88f1175e1637296f3a2b54080548216831790557f3a411c34c841a8465992e5f54e2780a2644cc25e4cb1c6ece21dcf179a0fa1b780548216831790557ff90573acc29afbf08714a7fba7408df23f0b300c21f421d0e5c9cbeb27c4f5ec80548216831790555f805160206200ad8483398151915280548216831790557fb8cd8d1828cc33b7b709f0132aa30b96a4123f4f8804a538b63d2f40fddb83f880548216831790557fe311bea885db23cfd12a0971f537c3941f3363c448de498d66fe24b68e2ce86280548216831790557f8a8c2ca18f707d8bb89b7a23486d674fa4a972e617f0559802d7b37199e8155c80548216831790555f805160206200ac4483398151915280548216831790557fd7b1e9eac755272f68d4e874667a69e0a229be564df90eb5992fb143f2522fc680548216831790557f8e3c6b2c5450750ae90952b1e41434fea76db1e5e894f617ef28a23a24816af980548216831790557f3c8d64976ababb8620b2810ad6211fc1340b4fa964163c4b6884dfc34e3bf45d80548216831790557fd98433aaaaa01b242c099c5212b825fb19e9aef1d31b04e3ab53b4ee1ae0375480548216831790557f4002e162165f17103c1455db9e71e07e01f8730478dd4d7e50fdfb4311880b7280548216831790557fc7ef28afcef02f1f677d7e972175a9653bca0bbeeb4e70b5024d4d1cac8f7f4780548216831790557f056f25d9cfe8151e88d298e06d9311136b4e9008d23f619107c74f7a635aed4d80548216831790557f5fadc7501a02235ffd5a5e68412f176ec8df1f174f0221d84547ee5a40c548db80548216831790557f0707d629459dec25da847f133f6b5424f7b1b78a19764a6bf22b84a6912a852e80548216831790557f63de10584bc9e7f34650613c654014656143829f7dc78ab9246aaa18d78f6dc580548216831790557f6dbdd569045cb85b8461e806fd0239218bcf0d31e7631d017af4982af607428280548216831790557f5d863292554b54a66b8080045258ade2e710c9415cd06d3e63372ee25cd1b76e80548216831790557ff6f2c14947366284757eeed33296ccce0798d9b497b3d258b9c273ca0a0b269a80548216831790557f154f7a3741f7fad6869af031ea76f7031960f09f02708201a93f268adb1dcb4180548216831790557f26474c9f87b9fe235b405f5cb306b2bf45f494d3350542f6b4012a23b80ddcc180548216831790555f805160206200ada483398151915280548216831790557f42d08f36277eb30c6e20426fd4a5f92ebceb552941e2680a38852ed129dbb60780548216831790557f63ac7362205087c08acb9eebf0a72ce6277cee6961c03c7b14522b2e495f9a0980548216831790555f805160206200adc483398151915280548216831790557f58ceb1f679141054a5988daaee9eb9df14660456e34163310b5aabe4a3a56fad80548216831790557f331d9abd55b094c778dc1eb351b0e697e7cda71cc950a4a8b1cb73d25c78f8cf80548216831790557f1463f0599e98d3e2a06a74f281a7da6b6ded1283735d80f58ead054221b8bf5380548216831790557f1a980de2c67043148e9a06c3c81a16137eb379e374396edeba6e49e0d05701c980548216831790557faace9b9e11efbfd21af9fa52d48a6c9af6d81e4223ff94af8628f0d8bacde78780548216831790557fc802f89ec93494500481b0e35c146ab185580db843c61704d9d551d1d516361780548216831790557f76e915a048b27c08a77e4b135d1863d015fe849b238562ad85c1ec1c5e19cf3c80548216831790557f53468034c5245857f86b0241d4fa0fa6df8d4bf9b3d7f511bb4f43277645a6d580548216831790557f29c36c2c95d122579d40b408c7ece81009117c2660beb637bdb2f55f7dc94d3580548216831790557ffee603fecbfad9b9de0d193b2a0d8e57b386be84db4aff1075e27ab269284ceb80548216831790557f87b862e567050afc1a6a123351aee4404fe9a136b16d8206c86a57f5bb002a0a80548216831790557fd4325ed382e102aeccc64fb8e70e0e3b6a488dc4406b9295ec780b27d4d1345780548216831790557f585157d29d023392ed881672bd4b58e456b9ccb412efc6bd6d5e702829d4367080548216831790557fa3934f000e664e64dd6c24fc5a804edad8cb17f33c1ab9b2267ea61ae386b41580548216831790557ff403bb3bfec90c9fe99922006d5c626289eca5ef67b0f6bb1d94162c60ea127080548216831790557f6f7f9a78d394abbb76744cd433204e216556647f942c0e5f67a091989ee428d080548216831790557f69c12b6d8c6a3a78163171ce9e07dc4dbd5d23c187cd98b1cd7d5d6f6e1f66f380548216831790557fc123a24462845d767b309e2758da685193fee11fa93dd3aa16e02914e566480b8054821683179055736556751caf10474b9bd8b31ee4b0bb4420aaffb45f527f5faba452889bbb8ba6e4834de01fbc807c4be21d8b233f90729da5f7b1376fd880549091169091179055565b62007f12601360205260377fe97b33c798e522c0ee66ac63d81fcaacb91fe1230ea7fe98cb11eac8850b3ea355601e7fd7ebcd2e4c36ea88d35f5a587b99cf25b85ee177603ae43a80c072163b2fcaba81905560c37f90e564f4f9e5d96486cc226dbe7ead5bbd8af6f550be79e94a8177e4cea5e744557fed87ddc5512de4e99ecdd45d48d907a08b9df3b613f86f3c45975c77b925a5c85560187fb45efa928ec38b7b8bf44e5f2daa7d7dedcea2c462503204636ef33f5d1d9c31819055602c7f5a8dd471ad1e9070ee0ffe636f063e1ec4e4662203cb325fc2c0433997e5f6868190557f80a046ebb85c8f69992d25ba068299d3344a207afb4e5b58255a4d0211b744af919091557fe198c9e1d2507bd7d056a5d8d596d5fb1b497de3f2b87a7a962e2ff05ec5986f5560127f0ad26bb12a2bebaa7a062ed67628445e2986f440b3562276103df402eea752905560b77f0daa5cb3e4669acce2983c947b61a9115d75ae94db35d6e9fda40808489855f555601c7fe7ca6562c01c8be050ea0e4a4f7d144e5c6dd74435562738e6e7dd47f13e016555600c7fc38a8fce8b6569773b39be9961e9980c2c5ffb351a3ec4fa9fbc81c31b6c7c1f8190557f8affcf7ba897ae533a767dfee8f3c5e28152f2f5cb67e4924d0cca40b212a30181905560167fed8982527c96dc250e34fae4cafb645fa2c64c3f7df7c409c04576748219b7818190557f8a5657f6e797f1e08492dab8bf088082c25f6bde94d3adf7a0ad267b04fea8318190557f6debc93dd8716e7e141231802777d35e6b006e8eb79c2a0d6d94fe956f36687f8190557f60074eb006df77576de19e2c08c6b3ef34e392af2090b80703bcaa4307801efd8290557fb6c9c892dbe39ef654eda234f77cf58654854bb07904dca0c287a521d05487c98190557fd9b5427a936a7012db086a32990c5cece5e0c3391b8a4fddc977b7617dbec9f9829055602a7f3d53427d4f6a84d88d8a988b9aea0f5faecd08cc3d0635f760139daf839f3ae9557fe8afc5544abfc3bfdcd516e094f3d6526acc0b7bdb596f3dac2e69a78feafcf28290557fb9720ab6e6c7929f9ff01095ef5f4b22eb550e62cc94231378d05abaf65499e38290557f7e3d649a4b68a556c7831fe8faae572ff889157d0b76a065eeaafd8a865e1df68190557f1b773a845ff01fc0a8482834d15e150c721fcd1c12fb39a8f552511459f7c6ce8290557f26c5f062d59b2daa707a8d55d6c0ca1692299a59b3be1b362ba73cdef5d61d238190557f289dc1cf7719245211538897ccb5a8f4886334727e172045e2cd04d013c4f2cb919091557fa0f1fcc9692db4509f0a598804b62e919c05ed22ecf96e1c889eccc6d43a2e0c55600b7f526287565ba6d8e278a7274b43289a9d5f178e918ba7e4ca07e302fd6c49fb4481905560067f958c8dca5e9ee2e5c4c7c2a56d8042989e37fb036f659e501a169bdbc51912fa8190557fdbad4eab6732a470bd99e6a8a86a604ddd3ed0e5c0db3db9c5b84e833f43ff1281905560107f8d0c67fcc903d592019f85b0962102d38df8106ab468494b110e526a067890418190557f96e9062bb24267c106f1b0a5f151d4b5ad722ff6057f8d653d73eed889090f6e8390557f2642768ad11c10a0a39fd63ae60ef2b386f99141328788231c11cff70ddadf6f8190557f855e04eb30c951826208e745f7c791b838a004f3dafd15e2dd4a17230c60cc4b8390557f5a649c4b3c2c50ce4248289f754671348e6db97d2aeddc5c960ff83b12acaba68290557f8c05d9c65e97d9e17124e13eb4fa4159a5a949ba30ac72b32edf0a2377677ecc8290557fc07e0d316f0b2d8d77cadc5cdfbdd2d5b8ef0cc4dc9555ae7bbbe7734f20e2f68290557f8d69b7879398d98157d26480aca6b3b10b8eea811f95c0750a4bf4b592d35aa98390557f39f64ae42730837012504cfcfab42d29f1a1bcccb97dc976385b5bfc3b59b97b8290557f990bf5416760969c72dab8dc2682e270783940724452b0bf1f08b6ecf72530ac8290557facde06ce5bb67fcea5a644ccccc0d82e8d37798af6d457d892a0f59a844340198290557f804eeadc9d4b726f5f5045d631c9dfe7ecba611930810c1a806078d7d35ac6f78390557f10f99d900f935197f6c12fd9f830339c29e291c6fae449e9aaf727e2f64dd50f8290557fb31d4381dce6f2dc039fd3a27227b456202e38bc024b62e39e31fe4b40c9a97a8290557f205da443a0219fc3143dc695cba524433142c690bdf92046a11126b2a9e56b9f8390557fe11ab97d543f240b13ed502bd246cd828541c27faa23312a4dfddf2f9da8fc9e8290557f54a7e27adb2a66909f4f4fa676a9250fb886e94276627c7c3291651f4c7253f88390557f1fd9dc678914b3b5e87c2d3c1c16029eb0fe958adb439dcf879c5dbc5dc8b65e8390557fb14cf5d2b2db6ef1f4a68387c87f14f37d5aac3548f3690db8ac2a5510e691d88190557f7908062dde16d62495a79f2a8b6b0fab6a2a0d175a2f9d175823653f01910fb28290557ff53a842b98f4134dc197c1f305b83fbbaffb6c8b2ee7669f6214a825a471becc8390557f5baa21b3b574261a55f2ea6926a6bb09393c8010a3fe0f981b061bc05e8fed628390557fb3a7574b4e7a50537baab5e20e7e59417eebca57ee9a2da9ca67839c667e8ebb8290557f9d245f3549c358e89bec887b6ea6be0e1cc5b3edd97e15f2aded47cc56219a558390557f47ac3f5dfa2c2ff7e70f97066b1e68882e5e581ca0a0781b36fb7bf580dc7cf18390557fdc848a84eb73fbf798b6b0c91d2e0a1221f32b5d102668f54f8b04e2aa90442a8390557f97438e4aef3584bf66fa9968f619c3a32c90bb19e5c129bb41ffd4593c157b628390557f58312e3dbf509422c78e3a52c0c5f547586b71ca02d112ddd238d47b32ca81658390557fc69c6ab7d21ff9e9d30e8eeed1112c2c915b4815178bdc96c167a1623c2b85228390557fc6f60bdc41689eabfb35f4caafebe77b88baa4f6aa8f7bc063795b01fb54cfa08390557f6e069c79021100af47c4e81ede34af1ee79757a998a39200d9a52bdcc0fcd1688290557fd790db4ebdd5c82ac4556d8866b06eed0bb77afdd84fd25dafcb48ef2bfcbb6e8290557ecd1ef3fdfbbdf7f35caf1816bfde759dffdd7560707c04022df98c3c75bf88557fd9addb85865ff796727b92775b76da8ae6755be4486ff9d5d24d1059f66eac2d8190557f35c39b7ab43deaae4c552dc22ada6e174679f74319b06318be751ef124b5de778290557fa558b942720ce92d7d46ce8c55bd33b777aac709e217faa568636abedbf6dc63819055601a7f3bde33daca76424aaa26b7a68e4c36db50493bcd8ef91e484687377af21bd0e4557f3034484e9546c6d6f173a5ee67a8a08a15ee285125471718b0cd3e3f060d66f08190557ff1a7eb8dc018277b1de2569d4b570e49c24855b77519c11602c59db3cecb8a0b8190557f199872d3b095f95de203dec5d5ff8de49b508017e3e53a30016562e6f9a30299557f7ce05743862d9651ba3a95578e59538b7511879b6539396577ddd264f7748b075560827fa0900260829c74d7299fd11d2c477e92dc1996871975a291fb37d5259fccd6b35560557f9af454daf7e6dd35f8eb915df15d77afe68f7fcebb921c898cb325276183fc7f5560417f839c4267726257807e5ab5bbb2b891f30e93adc4ccb9cc202af959802aa231338190557ff119513118e05c53f6f5e02d73ca41ac6ea5f9f50a398276e11ed2ce500fffcb8190557f84276daf1211780fc4938a99bf1b11c6baaebe48b832e1c5a151ea944c3b0f1a5560287f225f709eb18b7888ce648d4a17d528d41bc882c5a5ef82d1d29e952d5c9db9d25560197f27a41d59a905a32604f1c498048ed0a5e526110fc5497ddb230f8052bae13aef8190557f96d436fde5483c8180d3ffaa6fa4bb9f205d466bbda7fc957a7c48d27cd3cf9d8190557f6fa27868c39beff8f183fcb3f1b28e3839ca04ac06bd6153dbbf8c5fee13bdad5560147ff44a36e2fd05d68423f8e95b4d84378cce0d69ffbe0a4ce9cbb29e4dd3619a6a8190557f7783cfec539728551d561156cbb72f4d5b60d4dd0f6d9e41e97cd702c960a0668190557f8af6261d3cdff930edd1f6417c1e21b6f970309026a27f486a7967b60f40fb178190557f1bbf0758ca1e14e28dc3227c91852cc4ff125d22d471bbe3643bd7d1dcb029458190557fe7fda38584f0f530a329e37fd6dc0bad0c9ab75a8078682376968caddc1e59888190557f88e196322e1abfc98443ab3fa630197b4a37e7264386a8f7460f6a3c80ee00778190557f7b15cd957aab0e74d4f8efac6a5a0f405e02b2d735b33e8c76d98067447ca5108190557f5f29e02a4857c7abfeba85865353389cf6e10818e908afbbc7fe71c7085db3408190557f5d037f8e4c53a2cdea7e7dda318a82983ee7e5fe10499339b26b8eacbaba46518190557f3cc181e697f895ab1d53be1c5320f87efb8d9e224b92f3dd072b590d075ceb028190557f4fc4e2df5a6f6fc008300b307c6c60d71dc89a9c69a2958383a9136a5867b9018190557f558a31a3f4070bcd76e39606ae520e731328d40f2d866b7a80bf51f3446959a78190557f27628309e7f96e229e82cf31deb7fc66dd173cfd4c4e709ace0f3aa99904d25a8190557f5cb625928f95e193fcf908fdbb46ddd0c1b072c22be6bb2560b8783c9390691b8190557fbffa22fe7e4dbcf5c9c6b7517cd2b479d0a33c249e53ca710e2e06bd05f22eb78190557fa20b6bab1763726651881be7268005ca2fe29f5921a7ff9c9bbe3dae081e20d88190557f3175782163ec1f36c94c288eb4c72ea3dfa1a668a6c820ece36a741ed62d91a68190557fa3a5ff32d31cb7f4d6803180345498402505ed30d80ac84373a23114d32a48f78190557f645e50e4f4da4830d6214372c99885fe6edc304a17179577c36170b1131bd88155600f7fe862ade6ca3a0b5939572d8ee2a9627ab7489c19e479236277a0b53897345c1155600a7f40fd1f5e7382fdf3c0613217fd8fd29cc9566af0b0569464af97b804b91c44e98190557f74174688f2be9e345c20dfa1d3d8844cf55bbbbf2f27dd51d404aacc94ac704f8190557f1a733862cc423269cce4d852982b3316339795de718c87b7426a323eccbc9aa28190557fb187463fecac8b94d3edee57b8459128e6f17f7df40ac08d3e21df3fe3fa196f8190557feec77d6cb6921f92e8c8196d29bb5ab11f919c3cff4000b0921b6c767e802edd8190557fbff1838f953dd0681b88396e4610e6166cc1734825e7cd2f5845f4964de931dc8190557f92f2d0041ca54e1115c0362169f40caf17bb8601c44d2fe53fe10ef1466c15c88190557fa50b6540533b5b205cb36b473e358e9634d461a436b7cfea95984fe44ed6affd8190557f469e3018329844f2b5bd81967a718a9bb7d2cc9ac2bffe47d63bbf9bc2a39a438190557f633c49f589b599dbf5882df920b3a6691d83438a539588a5f93c1798ca5f15598190557f74f3339623dfb3f37b561ba3234f292af197da308e57b5d75c1330de740a70518190557f4c09f91dcad955d6853f6631bac10f8a2c4209d65bce3eb62a9301a26d71f7308190557fbf7c0055f6cd0a65533e7168319f259b3814939ca1a1b61d393db7fb7cd616028190557f4208a977d7b9940363f3c7b6430ca83acebd262433c0d7dd1c4e69d4cd3cd1918190557f2d1ee6f5660933785c09913296359429866da7fc3bb27ed21c8d9eb46b9f3ecf8190557fc88d105060ab88e08ac77b41519434f32bdbb8c95e0fc172dd6d198e144130468190557f4c1244a3a200bcb1eb81eb83103036f451f434ea8557ccf99ec722c56e3773668190557fad1a0b4310485224c5eba32902c6924501824fb51d4166d6a94cb1c354fe2e978190557f0fee5bf32c2982b65c426bd98dd7037154a21c8125ffb7dc76d51a432719e5125560057f27aad975ff7a1a3c0c8fe9a92692d73c6c447f214bc659290752ba58aa7583208190557f43f58a3e9dd713f0152ebd197f20902fcb21dd109c53dde93a80ab0562aa0a378190557fd18922dd4ef2c06a46920fc676c35f67b9dadd83045a1e9534d934961b7d92478190557f7346499d2f034ac74a2c01169052c6fb83f647da815f9ae32ebf2d2ec7337e348190557fb7253610d5cfdf0da5406c503351f6be7e2f62c7a63c35a3eb966aad1969703b8190557f0b928c27e2a2afc17ec822d80b3c90dc4522fac292642e7fa6d77774f07e24c58190557fc6ef73c38f77d3b6e0b0330bd1344f30c943c4cb9d11c1874159dd50558084698190557f5ea835159e0ba5b1d3c1a2abc47270bdef3221d256c78fdaab86e981965b08048190557f8fb66a8b319eecc5b406b4c4050a4c10a0b17620f8ea4e13a17ce3ab724506698190557fa345f8191514fbd4a3655e72065e1ab62aea047fa50fd45ece25126010030f6a8190557fc4eeed215f6c765eb7f164599fb072fceede01014cbaa2e881fa845eb05dd1ca8190557f12e5d37c945beaa92b724be849c079db7cfda63d4352b81c88519423071f80208190557f56c891e68b5a4532b2e2b8847d89eb626721588b16c1a4c3655ccec1483013928190557f32d46d73cf7ffde6ae7cd1a7208ddfda3e8103caf07a47267266633dc18dc0288190557fddd03421461a34f303a1825f32c02004ff5c21516baa8db6381f8ef15c4bf8e98190557fd894a5f4963cd55c15050d184ec9cfc676757f03edae13fcf20ffa52f50abf6b8190557f236aef2191b287453613e290fe4a4464ff3887ea6961e0661645b3baeb7af47d8190557fdf0e11aed59f3e8f119321f99f970e661951d6809ea0a5960df02771af1d450f8190557f0d531fcf1d8296cec1e2c20726d44ee942cf15c1d2ec4ce3be83d5026bd817b08190557f2a64dc963d38b371497dc2ae2725f250d57b230f4153b464bcebaffd6584c6e58190557f6b78130a9059f799d77e4520839358ba677d4adb5d11061be5a85d3c8c7704788190557f9ed7f3b4428e88f40c97a35a27824c129c310073af82e95acb6c13e1013bdc2c8190557f2d46a799d5394bf242f376929329a92d568e80a50655b4a1601ae12506ac59078190557f9cf7fb86d1c9a756ba9e964a2ed628fbd0142b2ef9732f03b6e903c773731bf48190557f1551d28b9893affe8396e7012831a931023e010a3b45fbfef2b3a6023017d62b8190557f1f22a96095bdae311bd7a9fbddae3c48efcabf82ca8d771927b2c7eb4e33d1908190557f6971e40a4ec57cfb06e55cdb22b2d28a6f23e920d254c022f45105e59edd31dc8190557fbedddd03fa144789ecf8cdaccb524b41c52cae6a6022be4dfc02a72af102dc788190557fbcc0e97f300003c7c5e63b1d10c531ed19536600347f6df88e8a274ff26888a78190557fdd8dce2d781dd1f62b8c5c3866016fd6e148f5a5b87b5db30f224e31fc35c61e8190557f0a3af4da02bb589108753292a8b5c4c7116de1418772b4ffb3f9928ec9e7cc4e8190557f614cd9c3442db64766167d04fbbacd2a719c626d53f86670286bc98a63119f8c8190557fda01cad0c83208dde6cc77b9c717728c6244cb65f4e01ab8a6b0579695bcdb238190557fa44a4cb0bbfac7c3e4171f2b085baa7f2f452e93cac769bdbc143114fc6658168190557f345cf4f041b9c96d657bcd69b03b8cd10a1ad5e6dce8b4ff9537af25676298b88190557f3a878bafd28376917a2d88155b88ac96316353577a39b82a144404daba73a0aa8190557f30181fe56f94cdba9ea46f99aa7b3bdd3a01852dda80634f845be1bd33e910f18190557fc575432cd54bb0a46f5a1492f064195af14b08d9b99f4c75774e707b441398ec8190557f6de74c4f9e1759c2f8230ca98ee92e0214b580c2f6e35990c5871ecd7ec91d3c8190557fe9fd64686d327ae854eafc73fff8ebe39eb8e8010fd80eb1b6e6e2b2eb0172d38190557f3269d21613ad3632caee801bd127d1798443554c078b715f362ce9a81b41ca4a8190557f69ca660c5bbcd3a3424dbd30696a9e8066ea640fdfb94904c84374ede2c11da98190557fe7e0cf451d2bd9998eebe3ff4dbe80d243081e849632e1a67bf75a4eca68e2978190557f90354f18ada17d33792becdeb034c652a5cd68c7b54b03e0d559c9186223c2158190557f959aebcff3817e638e48bf56a77590376577f66f9f0de8e1d79981860437fe268190557feeb727134fcdadce08d11b26e69ee4dd16fa4d40ba61e7a4c231f8449a0ffe9c8190557fda9e5c86b880599d527fc51304a771686f12c115272f0db2e41d0c731bb8e5a28190557fd0d646893e1120a1849de8417c9fcb39ce47e15f2a647e1378361894ce6fadf48190557f266f47d7e8857abab130eebd23c5eeace7e3249e6eb7c6d1603c8a344ea7a0228190557f50b077dca92b495bcb5e507b860a50e34cbe96613d27610c8103f396e770f43a8190557f7817dfc31793c67d20db41093777caa3722e67da1e6faf2462eb2586e58bf8e68190557f91a050bf024cd31196c481fd0a50d17ccacc293e7a8628208441fe27d074e90c8190557f541214cf9514e829bca9548aa75cb9651084d1ec0ad00f03f73eaf194ad7ff758190557f39d7ce9caaf826fd8f388f7d361b6173d073ce69c33d4dee2cfe0346bcfb062d8190557f2276bfcdbc9833463d6c2b56f4c35fa0abd424cc2cf9b66be6512199e3201a748190557fe629fa539020245c5d20bbd77b710c5131e5574488c4f444313fe84ae9012a4b8190557f207f9b4fb511ddfb17be79b96ed7fba0e0169b468ac03fc32c1aa4d67786fe7d8190557f96baebd5ebb7ce34beb23f873673d90be41ac971ca070f27871d5115d308efa48190557f34f743d337e080354bb005845ff920f320935938e6793134d6c0851808cb4a558190557f59d869da31620416e5e33a53ec5c2c19d77347a88ef7d4dd8166d5612a1df5c48190557f869d554ccd26029f67cd5d14aaed36e9b9ef50196acba6b82992348b79cd08a98190557f9609ac8268ad4e547ad37b871b4c166827fdb29218730ba3dc368076eba94e408190557ff065ed8816052625d4c1a8aa752628de06d80993d867eafc9889d3ea4a96a8798190557f6eaabe689cef9be38f3b332d9ea0e6daa6eff872ae646e4803768d5a439ab6a48190557f8955b60d38f302b41c04ab23b849516e738f57baee34ed956e3ac219bbdbc9248190557f710994a17b4c232716591065ae0f4a641cc1cc9b8903ca3f7eca349f988570878190557f588b05629153829d9d53415f6ac4edda41d700d64b9f79df4d2afb74e4f323af8190557fde8ac09412ca86b79371cc5c3fb6341f71c0cfe43d27abd63d8c3ae56433a0d18190557f20b8142dda1594bfe9bd1bc2c6cf524819a0a1308b57cdd0d56147905567b2e78190557ff7f9f46c617b4bc2d3733aef4f2694921f2b7d6d9213933493d3e66be03c1b7d8190557f66a5298558f83daa64788331d1f00458ad7dab55841380280289eb9d25ee4b8e8190557f45f01d611b7dd5fbc8286acfe2f532c20944f116736075332cc858b16dde2c0e8190557f220cdc2b52fe4aebe97327e06acacf40881765d2a4c3bd057e21a092bd4044858190557f82d79bfb2c22f59b4acde85e1334113c2ca78aed567d9292db0d9d0376604e088190557fcfe7bcbc61ca46c2a5735f11c8384660d90e15992f86373dd727dcd2e96af8298190557f54e2a73b10e8a809fcc78df9044c6f9631118f274949a2d22a8995793b92cdd68190557fd4776259352a381344d3af84f5099dd0d4555bb87208c964a05278732ccd6e008190557fb4df803a1fcc8f0990fde5e036586b0acb1955f96a423a71d8079d225726df568190557fe8f6ecebfa36b238705cf05936ddcf59a43b23efc9b41e3e558b66e679e42e518190557fbe2d8afe837a3a9f39d1b1eab4b66fba8016c5cf397f6cc6ab27f5ca6a8ce28e8190557f14a3b9a57a31fa6b9c3895912ecd1c60e3aa8a85d61f147b147b582702d6f9fd8190557f023f201c892c64b3d2c359ba17f3a7ff48878f447c3706b962b5fd18af07bfd38190557f7f5a8fa266c05514716949d15fe3a8f994f32c8130baf7ccc0f89be8264764b48190557fa67784487ffd09d696aaa2bbc788e8cd61d84c9c2c21af3b64833e7e5674af178190557fbb730508ca062cde247231bc4476206155cbd8ca5b32d710438c6bb6ed96e9558190557fdd2db4b85050a4976bfbf15642a184376485dc6f12075c263fd6c900f5bda8298190557f7b19189dae539016e3adc148e7973df23abf2b68975ec9802083fd9f649e4c9b8190557f4eeed13d10e59758ab985efa32111cf1887a77ae93c3afe5c545481ce47cd1538190557f517ace9361073a75a633db20ce6a4f2624126ba1ea94112ce53b0cbbccea3e3b8190557fccb6451b9527f3062eeb8ad07afcfadd3c0e1ce1fc936d2f297971344ce6052c8190557f6c7abb4056c9ba6adf788786cf44c5a85633617655aceb718671fee212c466758190557f3556e83b81283038a7d158f8faebdc6c85e56ef759870fb0650dc81f7f22a5e68190557fd05b407ad728765c8a7c0761aef87d91f828d2273ebfd080fa6510c003d15ace8190557f133b713268c2a2ff6c1c4b4ac20a2110b119cb56ffbd100d5b6932572aa02c1b8190557f03cc6ac1ab9619006dcf48ee8332459cef2fafe8d72b59b4c4ff86b469d4dd118190557fc164e967c5466a8fb3cc339ab898f50b60b745676542446263db8761cd6f46398190557fedf3f806fdffc9c3611b12d024f6ea5cd770cefca4b3e6b4d70dc575b4477bfb8190557fdcfc2ecc2e9a2d8370dcaa7a608e22ea6c362362a3412d2ee142d26757bab0228190557ff9aff53c1e73dd22f24b683c6204ba0909cc09174e7fe0be0b94be65ebb863228190557fcdf3b1050dcd717dd1203a34f3a1572087419b245774d75ce12631997089a4068190557f5e01af5d109e31a64a6e1f4b884c5007478802fb17e033939ef2db65ca658e8d8190557f8c2a366c33bc375fea274fef2d2773afa88f09a08ac8fe5a4f667257eefa062c8190557f9ed9e20f58f9c77de9036235518fe461a967725f9fd3950ed92ac1e7a7c5f3048190557f03bf5fb42330e8c235fecec1528798a02bd6a35aca45e964903a530816fff90f8190557f8177d71748a65ace540c19413b4095efbdd5ce2c1fd9d240e828ec3da3078f818190557fc42a1bc3367a2eadfe781c1fe044ec9baaf9c29eb5939e47a34cafc15874881d8190557fac4409ab7c4151f1f965f63935a1df8011347adbd424ff8bd45013938692fa8b8190557f3b08dca6caf9f54a40031c80e490ca71b37c946ec65364cfe5d5dcf77111162d8190557f96cebb960aba9db620a78e552f53dac2a9406ad304821741ddedebedf33169ee8190557f9ef41e797540437f6ce1e3ffb8bf04365747bda9935420b90f90b6f43224ae338190557fd4eebee1e6a5a1e0ec3c0284672ba605b760b87721ef8baa67f63b950d6c48e18190557fb05da2992d82699638ad98aab8fce5bf9dfa6abf47ab01e7a4fb451976c2ab7f8190557f0d8ef48e214990dff7af6fc6973aceb85c1300428a2d455429637a7f7b608de98190557fcf4626dd079ef27c3793e297874383a1bb08ce51e437374f2dbd7f4b061ce5228190557fe9be573273e39a7153f5de4e913460e195acaac7cac6930dd7baeff4f1f3c0898190557fe08791b9fbf78888458195aba42d4e701154962fe615cd998dbdd30a8801e6aa8190557f785e8a9a28deb7c404356ddb776edfc641d64043dedde0a59437b4dfbdee597b8190557f33093c894ea60f332230554a054f5765560f5fbbe11eae75b6f779d01b56aa8b5560017f12f1f99de79691846fdc6f80b77b5fb0e5f3cb40597b93b1c35aafb43f3d58088190557f297bc375008d1380a49d67f453654254ca7d4c489e2054f2c00149f67c54edf38190557f51a4d95ca42c2d860de73bebf935cd38927fb2caa178f9982f6b1355d7043f6c8190557f0c0c7f3f7ac9e44c171d4791029b2cf3391d543db3ee3623d718cfe5058ae85b8190557fc320e853dcc21c6dc115c88ca12ce6318815f891a6c764d29f1add61ead021e955736556751caf10474b9bd8b31ee4b0bb4420aaffb45f5260237f716b985c0a6137e1c4e2ee1c69b60beab76e6347321c7350760d8a2e3cc7990855565b620081d6565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6127106001600160601b038216111562007fdd5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620080355760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640162007fd4565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806200809757607f821691505b602082108103620080b657634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562008109575f81815260208120601f850160051c81016020861015620080e45750805b601f850160051c820191505b818110156200810557828155600101620080f0565b5050505b505050565b81516001600160401b038111156200812a576200812a6200806e565b62008142816200813b845462008082565b84620080bc565b602080601f83116001811462008178575f8415620081605750858301515b5f19600386901b1c1916600185901b17855562008105565b5f85815260208120601f198616915b82811015620081a85788860151825594840194600190910190840162008187565b5085821015620081c657878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b608051612a0e620081f65f395f818161077801526109640152612a0e5ff3fe608060405260043610610275575f3560e01c806370a082311161014a578063ae104265116100be578063d123973011610078578063d12397301461074b578063d5abeb011461076a578063e222c7f91461079c578063e985e9c5146107b0578063ecba222a146107cf578063f2fde38b146107ef575f80fd5b8063ae10426514610691578063b0ccc31e146106b0578063b88d4fde146106cf578063b8d1e532146106ee578063c87b56dd1461070d578063cc47a40b1461072c575f80fd5b806391b7f5ed1161010f57806391b7f5ed146105d157806395d89b41146105f05780639b19251a14610604578063a035b1fe14610632578063a22cb46514610647578063a87430ba14610666575f80fd5b806370a082311461054c578063715018a61461056b5780638da5cb5b1461057f5780638f2fc60b14610593578063900f187a146105b2575f80fd5b80633ccfd60b116101ec57806353d6fd59116101a657806353d6fd59146104a957806355f804b3146104c857806359eda1b5146104e75780635ef9432a146104fb5780636352211e1461050f5780636caede3d1461052e575f80fd5b80633ccfd60b1461041257806342842e0e1461042657806343d13124146104455780634618163e146104645780634875bccb146104775780634b3ea9341461048a575f80fd5b806318160ddd1161023d57806318160ddd1461033f57806318a5bbdc146103615780631ae100821461038c57806322541b4d146103a157806323b872dd146103b55780632a55205a146103d4575f80fd5b806301ffc9a71461027957806306fdde03146102ad578063081812fc146102ce578063095ea7b314610305578063147031fe14610326575b5f80fd5b348015610284575f80fd5b50610298610293366004612304565b61080e565b60405190151581526020015b60405180910390f35b3480156102b8575f80fd5b506102c161081e565b6040516102a4919061236c565b3480156102d9575f80fd5b506102ed6102e836600461237e565b6108ad565b6040516001600160a01b0390911681526020016102a4565b348015610310575f80fd5b5061032461031f3660046123ab565b610945565b005b348015610331575f80fd5b506010546102989060ff1681565b34801561034a575f80fd5b5061035361095e565b6040519081526020016102a4565b34801561036c575f80fd5b5061035361037b3660046123d3565b60136020525f908152604090205481565b348015610397575f80fd5b50610353600d5481565b3480156103ac575f80fd5b50610324610992565b3480156103c0575f80fd5b506103246103cf3660046123ec565b6109ae565b3480156103df575f80fd5b506103f36103ee366004612425565b6109d9565b604080516001600160a01b0390931683526020830191909152016102a4565b34801561041d575f80fd5b50610324610a83565b348015610431575f80fd5b506103246104403660046123ec565b610b16565b348015610450575f80fd5b5061032461045f366004612445565b610b3b565b61032461047236600461237e565b610b6a565b61032461048536600461237e565b610ca7565b348015610495575f80fd5b506103246104a436600461237e565b610cf5565b3480156104b4575f80fd5b506103246104c3366004612492565b610dd4565b3480156104d3575f80fd5b506103246104e23660046124bc565b610e06565b3480156104f2575f80fd5b50610324610e1b565b348015610506575f80fd5b50610324610e40565b34801561051a575f80fd5b506102ed61052936600461237e565b610ee4565b348015610539575f80fd5b5060105461029890610100900460ff1681565b348015610557575f80fd5b506103536105663660046123d3565b610f5a565b348015610576575f80fd5b50610324610fdf565b34801561058a575f80fd5b506102ed610ff2565b34801561059e575f80fd5b506103246105ad366004612445565b611005565b3480156105bd575f80fd5b506103246105cc36600461237e565b61101b565b3480156105dc575f80fd5b506103246105eb36600461237e565b61108b565b3480156105fb575f80fd5b506102c1611098565b34801561060f575f80fd5b5061029861061e3660046123d3565b60126020525f908152604090205460ff1681565b34801561063d575f80fd5b50610353600e5481565b348015610652575f80fd5b50610324610661366004612492565b6110a7565b348015610671575f80fd5b506103536106803660046123d3565b60116020525f908152604090205481565b34801561069c575f80fd5b506103536106ab36600461237e565b6110bb565b3480156106bb575f80fd5b50600c546102ed906001600160a01b031681565b3480156106da575f80fd5b506103246106e936600461253c565b611111565b3480156106f9575f80fd5b506103246107083660046123d3565b61113e565b348015610718575f80fd5b506102c161072736600461237e565b6111f6565b348015610737575f80fd5b506103246107463660046123ab565b6112cd565b348015610756575f80fd5b506010546102989062010000900460ff1681565b348015610775575f80fd5b507f0000000000000000000000000000000000000000000000000000000000000000610353565b3480156107a7575f80fd5b5061032461133c565b3480156107bb575f80fd5b506102986107ca366004612611565b611363565b3480156107da575f80fd5b50600c5461029890600160a01b900460ff1681565b3480156107fa575f80fd5b506103246108093660046123d3565b611390565b5f61081882611406565b92915050565b60605f805461082c90612642565b80601f016020809104026020016040519081016040528092919081815260200182805461085890612642565b80156108a35780601f1061087a576101008083540402835291602001916108a3565b820191905f5260205f20905b81548152906001019060200180831161088657829003601f168201915b5050505050905090565b5f818152600460205260408120546001600160a01b031661092a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b505f908152600660205260409020546001600160a01b031690565b8161094f8161142a565b61095983836114e9565b505050565b5f6003547f000000000000000000000000000000000000000000000000000000000000000061098d919061268e565b905090565b61099a6115f8565b6010805460ff19811660ff90911615179055565b826001600160a01b03811633146109c8576109c83361142a565b6109d3848484611657565b50505050565b5f8281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610a4d5750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b60208101515f9061271090610a6b906001600160601b0316876126a1565b610a7591906126cc565b915196919550909350505050565b610a8b6115f8565b6040515f90339047908381818185875af1925050503d805f8114610aca576040519150601f19603f3d011682016040523d82523d5f602084013e610acf565b606091505b5050905080610b135760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610921565b50565b826001600160a01b0381163314610b3057610b303361142a565b6109d3848484611688565b610b436115f8565b6001600160a01b039091165f9081526013602052604090206001600160601b039091169055565b601054610100900460ff16610bc15760405162461bcd60e51b815260206004820152601d60248201527f57686974656c6973742073616c65206973206e6f7420656e61626c65640000006044820152606401610921565b335f9081526012602052604090205460ff1680610be45750335f52601360205260015b610c305760405162461bcd60e51b815260206004820152601960248201527f57616c6c6574206973206e6f742077686974656c6973746564000000000000006044820152606401610921565b34610c3a826110bb565b1115610c795760405162461bcd60e51b815260206004820152600e60248201526d09cdee840cadcdeeaced0408aa8960931b6044820152606401610921565b335f9081526011602052604081208054839290610c979084906126df565b90915550610b13905033826116a2565b60105462010000900460ff16610c305760405162461bcd60e51b815260206004820152601360248201527214d85b19481a5cc81b9bdd08195b98589b1959606a1b6044820152606401610921565b60105460ff16610d475760405162461bcd60e51b815260206004820152601a60248201527f486f6c6465722073616c65206973206e6f7420656e61626c65640000000000006044820152606401610921565b335f90815260136020526040902054811115610db65760405162461bcd60e51b815260206004820152602860248201527f45786365656473206d6178206d696e7420686f6c646572206c696d69742070656044820152671c881dd85b1b195d60c21b6064820152608401610921565b335f9081526013602052604081208054839290610c9790849061268e565b610ddc6115f8565b6001600160a01b03919091165f908152601260205260409020805460ff1916911515919091179055565b610e0e6115f8565b600f61095982848361273f565b610e236115f8565b6010805461ff001981166101009182900460ff1615909102179055565b610e48610ff2565b6001600160a01b0316336001600160a01b031614610e7957604051635fc483c560e01b815260040160405180910390fd5b600c54600160a01b900460ff1615610ea457604051631551a48f60e11b815260040160405180910390fd5b600c80546001600160a81b031916600160a01b1790556040517f51e2d870cc2e10853e38dc06fcdae46ad3c3f588f326608803dac6204541ad16905f90a1565b5f818152600460205260408120546001600160a01b0316806108185760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610921565b5f6001600160a01b038216610fc45760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610921565b506001600160a01b03165f9081526005602052604090205490565b610fe76115f8565b610ff05f6116ac565b565b5f61098d600a546001600160a01b031690565b61100d6115f8565b61101782826116fd565b5050565b6110236115f8565b80600d54036110865760405162461bcd60e51b815260206004820152602960248201527f4e6577206c696d6974206973207468652073616d6520617320746865206578696044820152687374696e67206f6e6560b81b6064820152608401610921565b600d55565b6110936115f8565b600e55565b60606001805461082c90612642565b816110b18161142a565b61095983836117fa565b5f600a8210156110d35781600e5461081891906126a1565b600a82101580156110e45750601e82105b15611101576110f460018361268e565b600e5461081891906126a1565b6110f460058361268e565b919050565b836001600160a01b038116331461112b5761112b3361142a565b61113785858585611805565b5050505050565b611146610ff2565b6001600160a01b0316336001600160a01b03161461117757604051635fc483c560e01b815260040160405180910390fd5b600c54600160a01b900460ff16156111a257604051631551a48f60e11b815260040160405180910390fd5b600c80546001600160a01b0319166001600160a01b0383169081179091556040519081527f9f513fe86dc42fdbac355fa4d9b1d5be7b5e6cd2df67e30db8003766568de4769060200160405180910390a150565b5f818152600460205260409020546060906001600160a01b03166112745760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610921565b5f61127d611837565b90505f81511161129b5760405180602001604052805f8152506112c6565b806112a584611846565b6040516020016112b69291906127fa565b6040516020818303038152906040525b9392505050565b6112d56115f8565b5f818152600460205260409020546001600160a01b0316156113325760405162461bcd60e51b81526020600482015260166024820152752a37b5b2b7103430b9903132b2b71036b4b73a32b21760511b6044820152606401610921565b61101782826118d6565b6113446115f8565b6010805462ff0000198116620100009182900460ff1615909102179055565b6001600160a01b039182165f90815260076020908152604080832093909416825291909152205460ff1690565b6113986115f8565b6001600160a01b0381166113fd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610921565b610b13816116ac565b5f6001600160e01b0319821663152a902d60e11b14806108185750610818826119f3565b600c546001600160a01b0316801580159061144e57505f816001600160a01b03163b115b1561101757604051633185c44d60e21b81523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa15801561149d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114c19190612838565b61101757604051633b79c77360e21b81526001600160a01b0383166004820152602401610921565b5f6114f382610ee4565b9050806001600160a01b0316836001600160a01b0316036115605760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610921565b336001600160a01b038216148061157c575061157c8133611363565b6115ee5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610921565b6109598383611a42565b33611601610ff2565b6001600160a01b031614610ff05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610921565b6116613382611aaf565b61167d5760405162461bcd60e51b815260040161092190612853565b610959838383611b84565b61095983838360405180602001604052805f815250611111565b6110178282611d1c565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6127106001600160601b038216111561176b5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610921565b6001600160a01b0382166117c15760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610921565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b611017338383611ea9565b61180f3383611aaf565b61182b5760405162461bcd60e51b815260040161092190612853565b6109d384848484611f76565b6060600f805461082c90612642565b60605f61185283611fa9565b60010190505f8167ffffffffffffffff81111561187157611871612528565b6040519080825280601f01601f19166020018201604052801561189b576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846118a557509392505050565b33321461191d5760405162461bcd60e51b815260206004820152601560248201527410dbdb9d1c9858dd1cc818d85b9b9bdd081b5a5b9d605a1b6044820152606401610921565b6001600160a01b0382166119735760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610921565b600160035410156119965760405162461bcd60e51b8152600401610921906128a4565b5f6119a382600354612080565b905060035f81546119b3906128ef565b909155506119c18382612111565b6001600160a01b0383165f9081526005602052604081208054600192906119e99084906126df565b9091555050505050565b5f6001600160e01b031982166380ac58cd60e01b1480611a2357506001600160e01b03198216635b5e139f60e01b145b8061081857506301ffc9a760e01b6001600160e01b0319831614610818565b5f81815260066020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611a7682610ee4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b5f818152600460205260408120546001600160a01b0316611b275760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610921565b5f611b3183610ee4565b9050806001600160a01b0316846001600160a01b03161480611b6c5750836001600160a01b0316611b61846108ad565b6001600160a01b0316145b80611b7c5750611b7c8185611363565b949350505050565b826001600160a01b0316611b9782610ee4565b6001600160a01b031614611bfb5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610921565b6001600160a01b038216611c5d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610921565b611c675f82611a42565b6001600160a01b0383165f908152600560205260408120805460019290611c8f90849061268e565b90915550506001600160a01b0382165f908152600560205260408120805460019290611cbc9084906126df565b90915550505f8181526004602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b333214611d635760405162461bcd60e51b815260206004820152601560248201527410dbdb9d1c9858dd1cc818d85b9b9bdd081b5a5b9d605a1b6044820152606401610921565b6001600160a01b038216611db95760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610921565b5f8111611e195760405162461bcd60e51b815260206004820152602860248201527f455243373231723a206e65656420746f206d696e74206174206c65617374206f6044820152673732903a37b5b2b760c11b6064820152608401610921565b806003541015611e3b5760405162461bcd60e51b8152600401610921906128a4565b6003545f5b82811015611e7c575f611e538584612169565b9050611e5f8582612111565b611e68836128ef565b92505080611e7590612904565b9050611e40565b5060038190556001600160a01b0383165f90815260056020526040812080548492906119e99084906126df565b816001600160a01b0316836001600160a01b031603611f0a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610921565b6001600160a01b038381165f81815260076020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611f81848484611b84565b611f8d848484846121f2565b6109d35760405162461bcd60e51b81526004016109219061291c565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611fe75772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612013576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061203157662386f26fc10000830492506010015b6305f5e1008310612049576305f5e100830492506008015b612710831061205d57612710830492506004015b6064831061206f576064830492506002015b600a83106108185760010192915050565b5f828152600260205260408120548181810361209d5750836120a0565b50805b5f6120ac60018661268e565b5f818152600260205260409020549091508682146120f157805f036120e0575f8781526002602052604090208290556120f1565b5f8781526002602052604090208190555b8015612106575f828152600260205260408120555b509095945050505050565b5f8181526004602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5f80833a434261217a60018361268e565b604080516001600160a01b039096166020870152850193909352606084019190915260808301524060a08201523060c082015260e081018490526101000160408051601f19818403018152919052805160209091012090505f6121dd848361296e565b90506121e98185612080565b95945050505050565b5f6001600160a01b0384163b156122e457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612235903390899088908890600401612981565b6020604051808303815f875af192505050801561226f575060408051601f3d908101601f1916820190925261226c918101906129bd565b60015b6122ca573d80801561229c576040519150601f19603f3d011682016040523d82523d5f602084013e6122a1565b606091505b5080515f036122c25760405162461bcd60e51b81526004016109219061291c565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611b7c565b506001949350505050565b6001600160e01b031981168114610b13575f80fd5b5f60208284031215612314575f80fd5b81356112c6816122ef565b5f5b83811015612339578181015183820152602001612321565b50505f910152565b5f815180845261235881602086016020860161231f565b601f01601f19169290920160200192915050565b602081525f6112c66020830184612341565b5f6020828403121561238e575f80fd5b5035919050565b80356001600160a01b038116811461110c575f80fd5b5f80604083850312156123bc575f80fd5b6123c583612395565b946020939093013593505050565b5f602082840312156123e3575f80fd5b6112c682612395565b5f805f606084860312156123fe575f80fd5b61240784612395565b925061241560208501612395565b9150604084013590509250925092565b5f8060408385031215612436575f80fd5b50508035926020909101359150565b5f8060408385031215612456575f80fd5b61245f83612395565b915060208301356001600160601b038116811461247a575f80fd5b809150509250929050565b8015158114610b13575f80fd5b5f80604083850312156124a3575f80fd5b6124ac83612395565b9150602083013561247a81612485565b5f80602083850312156124cd575f80fd5b823567ffffffffffffffff808211156124e4575f80fd5b818501915085601f8301126124f7575f80fd5b813581811115612505575f80fd5b866020828501011115612516575f80fd5b60209290920196919550909350505050565b634e487b7160e01b5f52604160045260245ffd5b5f805f806080858703121561254f575f80fd5b61255885612395565b935061256660208601612395565b925060408501359150606085013567ffffffffffffffff80821115612589575f80fd5b818701915087601f83011261259c575f80fd5b8135818111156125ae576125ae612528565b604051601f8201601f19908116603f011681019083821181831017156125d6576125d6612528565b816040528281528a60208487010111156125ee575f80fd5b826020860160208301375f60208483010152809550505050505092959194509250565b5f8060408385031215612622575f80fd5b61262b83612395565b915061263960208401612395565b90509250929050565b600181811c9082168061265657607f821691505b60208210810361267457634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156108185761081861267a565b80820281158282048414176108185761081861267a565b634e487b7160e01b5f52601260045260245ffd5b5f826126da576126da6126b8565b500490565b808201808211156108185761081861267a565b601f821115610959575f81815260208120601f850160051c810160208610156127185750805b601f850160051c820191505b8181101561273757828155600101612724565b505050505050565b67ffffffffffffffff83111561275757612757612528565b61276b836127658354612642565b836126f2565b5f601f84116001811461279c575f85156127855750838201355b5f19600387901b1c1916600186901b178355611137565b5f83815260209020601f19861690835b828110156127cc57868501358255602094850194600190920191016127ac565b50868210156127e8575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f835161280b81846020880161231f565b83519083019061281f81836020880161231f565b64173539b7b760d91b9101908152600501949350505050565b5f60208284031215612848575f80fd5b81516112c681612485565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602b908201527f455243373231723a206d696e74696e67206d6f726520746f6b656e732074686160408201526a6e20617661696c61626c6560a81b606082015260800190565b5f816128fd576128fd61267a565b505f190190565b5f600182016129155761291561267a565b5060010190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b5f8261297c5761297c6126b8565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f906129b390830184612341565b9695505050505050565b5f602082840312156129cd575f80fd5b81516112c6816122ef56fea2646970667358221220aa0ee337e59e246b058f6b289cb3ba5f4567e3e802e0bbd35823ff9db263c1e164736f6c634300081400339f280f8c462d2959678e5e88adb7b39151a9604a40e1b9214c6b8e1e9890964681ac65e332bd70eada056b1f824d4357ab7ecb2c4fa6141ca89a5164c7df6a5a4172b59e4cb0de6cd960ff0710acda41db79fcb996d76b0e575e8481a2efc7dfe868d0da2de224b1f881a57e8839a52f2882a79026bde2551c0adad679635c48763bbdc6160515abe049218fc141b3f9221c884b0cee9846b44e259f828567c419c84406546f91309d76ef4fbea99e2f9f27846f29193dc4efad3e3e4f7fa8bc1867605868fda19ee25c745e45f84c472617754d6f831678f09292ceb201a182cc2bb212ed7b450ed0d467da736c2deb1b77432586eed1f3144bf3bfc4712d1164404e1bc053af4368cd865cde9ee180e4f03562d2ce7f9dff568335cd40621ec053b92114bc3533f4809508efbf24cde4c5fa6fac80f692117620bd4fd439dfe8ea520ba70e948aa033b331a8ec29123796638a257e100a67b1e91f5798c2a0934ff54fc60648f49cc5396e9317fcf0c03da344ce9c168a3316fd22087e7334b6d55ae82311fa3de7a90812c8dfc72220e5a9a7adede36639af8edca487cfdb8ff381103934b321f2b515441142565ddfa9ad37f76e07fc8a9064c0d44f4cf856a3af224d695f71578b0be6dfab90dd391514ebabb9559101bdc0532f76c16c08322e2a5370485d3f69ec6195c412518c3e3011a6f2710ce9ba3151f72fe8d091b78b65963b22bbf458a4f83cfb0460d319fcfe91ff454e1c93a841941b75b65727268020858cac390672382afdad1c5575183c7f71902e083efd74fd4cbb68690ae406cc805d25d4a206c27eeb505d5d7c8f9876423d7471c75bd3b3fe1888d34f7734d27ae68728ca1224dc898c986665606652a4bb459ede4e33365a0cfa

Deployed Bytecode

0x608060405260043610610275575f3560e01c806370a082311161014a578063ae104265116100be578063d123973011610078578063d12397301461074b578063d5abeb011461076a578063e222c7f91461079c578063e985e9c5146107b0578063ecba222a146107cf578063f2fde38b146107ef575f80fd5b8063ae10426514610691578063b0ccc31e146106b0578063b88d4fde146106cf578063b8d1e532146106ee578063c87b56dd1461070d578063cc47a40b1461072c575f80fd5b806391b7f5ed1161010f57806391b7f5ed146105d157806395d89b41146105f05780639b19251a14610604578063a035b1fe14610632578063a22cb46514610647578063a87430ba14610666575f80fd5b806370a082311461054c578063715018a61461056b5780638da5cb5b1461057f5780638f2fc60b14610593578063900f187a146105b2575f80fd5b80633ccfd60b116101ec57806353d6fd59116101a657806353d6fd59146104a957806355f804b3146104c857806359eda1b5146104e75780635ef9432a146104fb5780636352211e1461050f5780636caede3d1461052e575f80fd5b80633ccfd60b1461041257806342842e0e1461042657806343d13124146104455780634618163e146104645780634875bccb146104775780634b3ea9341461048a575f80fd5b806318160ddd1161023d57806318160ddd1461033f57806318a5bbdc146103615780631ae100821461038c57806322541b4d146103a157806323b872dd146103b55780632a55205a146103d4575f80fd5b806301ffc9a71461027957806306fdde03146102ad578063081812fc146102ce578063095ea7b314610305578063147031fe14610326575b5f80fd5b348015610284575f80fd5b50610298610293366004612304565b61080e565b60405190151581526020015b60405180910390f35b3480156102b8575f80fd5b506102c161081e565b6040516102a4919061236c565b3480156102d9575f80fd5b506102ed6102e836600461237e565b6108ad565b6040516001600160a01b0390911681526020016102a4565b348015610310575f80fd5b5061032461031f3660046123ab565b610945565b005b348015610331575f80fd5b506010546102989060ff1681565b34801561034a575f80fd5b5061035361095e565b6040519081526020016102a4565b34801561036c575f80fd5b5061035361037b3660046123d3565b60136020525f908152604090205481565b348015610397575f80fd5b50610353600d5481565b3480156103ac575f80fd5b50610324610992565b3480156103c0575f80fd5b506103246103cf3660046123ec565b6109ae565b3480156103df575f80fd5b506103f36103ee366004612425565b6109d9565b604080516001600160a01b0390931683526020830191909152016102a4565b34801561041d575f80fd5b50610324610a83565b348015610431575f80fd5b506103246104403660046123ec565b610b16565b348015610450575f80fd5b5061032461045f366004612445565b610b3b565b61032461047236600461237e565b610b6a565b61032461048536600461237e565b610ca7565b348015610495575f80fd5b506103246104a436600461237e565b610cf5565b3480156104b4575f80fd5b506103246104c3366004612492565b610dd4565b3480156104d3575f80fd5b506103246104e23660046124bc565b610e06565b3480156104f2575f80fd5b50610324610e1b565b348015610506575f80fd5b50610324610e40565b34801561051a575f80fd5b506102ed61052936600461237e565b610ee4565b348015610539575f80fd5b5060105461029890610100900460ff1681565b348015610557575f80fd5b506103536105663660046123d3565b610f5a565b348015610576575f80fd5b50610324610fdf565b34801561058a575f80fd5b506102ed610ff2565b34801561059e575f80fd5b506103246105ad366004612445565b611005565b3480156105bd575f80fd5b506103246105cc36600461237e565b61101b565b3480156105dc575f80fd5b506103246105eb36600461237e565b61108b565b3480156105fb575f80fd5b506102c1611098565b34801561060f575f80fd5b5061029861061e3660046123d3565b60126020525f908152604090205460ff1681565b34801561063d575f80fd5b50610353600e5481565b348015610652575f80fd5b50610324610661366004612492565b6110a7565b348015610671575f80fd5b506103536106803660046123d3565b60116020525f908152604090205481565b34801561069c575f80fd5b506103536106ab36600461237e565b6110bb565b3480156106bb575f80fd5b50600c546102ed906001600160a01b031681565b3480156106da575f80fd5b506103246106e936600461253c565b611111565b3480156106f9575f80fd5b506103246107083660046123d3565b61113e565b348015610718575f80fd5b506102c161072736600461237e565b6111f6565b348015610737575f80fd5b506103246107463660046123ab565b6112cd565b348015610756575f80fd5b506010546102989062010000900460ff1681565b348015610775575f80fd5b507f0000000000000000000000000000000000000000000000000000000000002710610353565b3480156107a7575f80fd5b5061032461133c565b3480156107bb575f80fd5b506102986107ca366004612611565b611363565b3480156107da575f80fd5b50600c5461029890600160a01b900460ff1681565b3480156107fa575f80fd5b506103246108093660046123d3565b611390565b5f61081882611406565b92915050565b60605f805461082c90612642565b80601f016020809104026020016040519081016040528092919081815260200182805461085890612642565b80156108a35780601f1061087a576101008083540402835291602001916108a3565b820191905f5260205f20905b81548152906001019060200180831161088657829003601f168201915b5050505050905090565b5f818152600460205260408120546001600160a01b031661092a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b505f908152600660205260409020546001600160a01b031690565b8161094f8161142a565b61095983836114e9565b505050565b5f6003547f000000000000000000000000000000000000000000000000000000000000271061098d919061268e565b905090565b61099a6115f8565b6010805460ff19811660ff90911615179055565b826001600160a01b03811633146109c8576109c83361142a565b6109d3848484611657565b50505050565b5f8281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610a4d5750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b60208101515f9061271090610a6b906001600160601b0316876126a1565b610a7591906126cc565b915196919550909350505050565b610a8b6115f8565b6040515f90339047908381818185875af1925050503d805f8114610aca576040519150601f19603f3d011682016040523d82523d5f602084013e610acf565b606091505b5050905080610b135760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610921565b50565b826001600160a01b0381163314610b3057610b303361142a565b6109d3848484611688565b610b436115f8565b6001600160a01b039091165f9081526013602052604090206001600160601b039091169055565b601054610100900460ff16610bc15760405162461bcd60e51b815260206004820152601d60248201527f57686974656c6973742073616c65206973206e6f7420656e61626c65640000006044820152606401610921565b335f9081526012602052604090205460ff1680610be45750335f52601360205260015b610c305760405162461bcd60e51b815260206004820152601960248201527f57616c6c6574206973206e6f742077686974656c6973746564000000000000006044820152606401610921565b34610c3a826110bb565b1115610c795760405162461bcd60e51b815260206004820152600e60248201526d09cdee840cadcdeeaced0408aa8960931b6044820152606401610921565b335f9081526011602052604081208054839290610c979084906126df565b90915550610b13905033826116a2565b60105462010000900460ff16610c305760405162461bcd60e51b815260206004820152601360248201527214d85b19481a5cc81b9bdd08195b98589b1959606a1b6044820152606401610921565b60105460ff16610d475760405162461bcd60e51b815260206004820152601a60248201527f486f6c6465722073616c65206973206e6f7420656e61626c65640000000000006044820152606401610921565b335f90815260136020526040902054811115610db65760405162461bcd60e51b815260206004820152602860248201527f45786365656473206d6178206d696e7420686f6c646572206c696d69742070656044820152671c881dd85b1b195d60c21b6064820152608401610921565b335f9081526013602052604081208054839290610c9790849061268e565b610ddc6115f8565b6001600160a01b03919091165f908152601260205260409020805460ff1916911515919091179055565b610e0e6115f8565b600f61095982848361273f565b610e236115f8565b6010805461ff001981166101009182900460ff1615909102179055565b610e48610ff2565b6001600160a01b0316336001600160a01b031614610e7957604051635fc483c560e01b815260040160405180910390fd5b600c54600160a01b900460ff1615610ea457604051631551a48f60e11b815260040160405180910390fd5b600c80546001600160a81b031916600160a01b1790556040517f51e2d870cc2e10853e38dc06fcdae46ad3c3f588f326608803dac6204541ad16905f90a1565b5f818152600460205260408120546001600160a01b0316806108185760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610921565b5f6001600160a01b038216610fc45760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610921565b506001600160a01b03165f9081526005602052604090205490565b610fe76115f8565b610ff05f6116ac565b565b5f61098d600a546001600160a01b031690565b61100d6115f8565b61101782826116fd565b5050565b6110236115f8565b80600d54036110865760405162461bcd60e51b815260206004820152602960248201527f4e6577206c696d6974206973207468652073616d6520617320746865206578696044820152687374696e67206f6e6560b81b6064820152608401610921565b600d55565b6110936115f8565b600e55565b60606001805461082c90612642565b816110b18161142a565b61095983836117fa565b5f600a8210156110d35781600e5461081891906126a1565b600a82101580156110e45750601e82105b15611101576110f460018361268e565b600e5461081891906126a1565b6110f460058361268e565b919050565b836001600160a01b038116331461112b5761112b3361142a565b61113785858585611805565b5050505050565b611146610ff2565b6001600160a01b0316336001600160a01b03161461117757604051635fc483c560e01b815260040160405180910390fd5b600c54600160a01b900460ff16156111a257604051631551a48f60e11b815260040160405180910390fd5b600c80546001600160a01b0319166001600160a01b0383169081179091556040519081527f9f513fe86dc42fdbac355fa4d9b1d5be7b5e6cd2df67e30db8003766568de4769060200160405180910390a150565b5f818152600460205260409020546060906001600160a01b03166112745760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610921565b5f61127d611837565b90505f81511161129b5760405180602001604052805f8152506112c6565b806112a584611846565b6040516020016112b69291906127fa565b6040516020818303038152906040525b9392505050565b6112d56115f8565b5f818152600460205260409020546001600160a01b0316156113325760405162461bcd60e51b81526020600482015260166024820152752a37b5b2b7103430b9903132b2b71036b4b73a32b21760511b6044820152606401610921565b61101782826118d6565b6113446115f8565b6010805462ff0000198116620100009182900460ff1615909102179055565b6001600160a01b039182165f90815260076020908152604080832093909416825291909152205460ff1690565b6113986115f8565b6001600160a01b0381166113fd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610921565b610b13816116ac565b5f6001600160e01b0319821663152a902d60e11b14806108185750610818826119f3565b600c546001600160a01b0316801580159061144e57505f816001600160a01b03163b115b1561101757604051633185c44d60e21b81523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa15801561149d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114c19190612838565b61101757604051633b79c77360e21b81526001600160a01b0383166004820152602401610921565b5f6114f382610ee4565b9050806001600160a01b0316836001600160a01b0316036115605760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610921565b336001600160a01b038216148061157c575061157c8133611363565b6115ee5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610921565b6109598383611a42565b33611601610ff2565b6001600160a01b031614610ff05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610921565b6116613382611aaf565b61167d5760405162461bcd60e51b815260040161092190612853565b610959838383611b84565b61095983838360405180602001604052805f815250611111565b6110178282611d1c565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6127106001600160601b038216111561176b5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610921565b6001600160a01b0382166117c15760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610921565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600855565b611017338383611ea9565b61180f3383611aaf565b61182b5760405162461bcd60e51b815260040161092190612853565b6109d384848484611f76565b6060600f805461082c90612642565b60605f61185283611fa9565b60010190505f8167ffffffffffffffff81111561187157611871612528565b6040519080825280601f01601f19166020018201604052801561189b576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846118a557509392505050565b33321461191d5760405162461bcd60e51b815260206004820152601560248201527410dbdb9d1c9858dd1cc818d85b9b9bdd081b5a5b9d605a1b6044820152606401610921565b6001600160a01b0382166119735760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610921565b600160035410156119965760405162461bcd60e51b8152600401610921906128a4565b5f6119a382600354612080565b905060035f81546119b3906128ef565b909155506119c18382612111565b6001600160a01b0383165f9081526005602052604081208054600192906119e99084906126df565b9091555050505050565b5f6001600160e01b031982166380ac58cd60e01b1480611a2357506001600160e01b03198216635b5e139f60e01b145b8061081857506301ffc9a760e01b6001600160e01b0319831614610818565b5f81815260066020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611a7682610ee4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b5f818152600460205260408120546001600160a01b0316611b275760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610921565b5f611b3183610ee4565b9050806001600160a01b0316846001600160a01b03161480611b6c5750836001600160a01b0316611b61846108ad565b6001600160a01b0316145b80611b7c5750611b7c8185611363565b949350505050565b826001600160a01b0316611b9782610ee4565b6001600160a01b031614611bfb5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610921565b6001600160a01b038216611c5d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610921565b611c675f82611a42565b6001600160a01b0383165f908152600560205260408120805460019290611c8f90849061268e565b90915550506001600160a01b0382165f908152600560205260408120805460019290611cbc9084906126df565b90915550505f8181526004602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b333214611d635760405162461bcd60e51b815260206004820152601560248201527410dbdb9d1c9858dd1cc818d85b9b9bdd081b5a5b9d605a1b6044820152606401610921565b6001600160a01b038216611db95760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610921565b5f8111611e195760405162461bcd60e51b815260206004820152602860248201527f455243373231723a206e65656420746f206d696e74206174206c65617374206f6044820152673732903a37b5b2b760c11b6064820152608401610921565b806003541015611e3b5760405162461bcd60e51b8152600401610921906128a4565b6003545f5b82811015611e7c575f611e538584612169565b9050611e5f8582612111565b611e68836128ef565b92505080611e7590612904565b9050611e40565b5060038190556001600160a01b0383165f90815260056020526040812080548492906119e99084906126df565b816001600160a01b0316836001600160a01b031603611f0a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610921565b6001600160a01b038381165f81815260076020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611f81848484611b84565b611f8d848484846121f2565b6109d35760405162461bcd60e51b81526004016109219061291c565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611fe75772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612013576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061203157662386f26fc10000830492506010015b6305f5e1008310612049576305f5e100830492506008015b612710831061205d57612710830492506004015b6064831061206f576064830492506002015b600a83106108185760010192915050565b5f828152600260205260408120548181810361209d5750836120a0565b50805b5f6120ac60018661268e565b5f818152600260205260409020549091508682146120f157805f036120e0575f8781526002602052604090208290556120f1565b5f8781526002602052604090208190555b8015612106575f828152600260205260408120555b509095945050505050565b5f8181526004602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5f80833a434261217a60018361268e565b604080516001600160a01b039096166020870152850193909352606084019190915260808301524060a08201523060c082015260e081018490526101000160408051601f19818403018152919052805160209091012090505f6121dd848361296e565b90506121e98185612080565b95945050505050565b5f6001600160a01b0384163b156122e457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612235903390899088908890600401612981565b6020604051808303815f875af192505050801561226f575060408051601f3d908101601f1916820190925261226c918101906129bd565b60015b6122ca573d80801561229c576040519150601f19603f3d011682016040523d82523d5f602084013e6122a1565b606091505b5080515f036122c25760405162461bcd60e51b81526004016109219061291c565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611b7c565b506001949350505050565b6001600160e01b031981168114610b13575f80fd5b5f60208284031215612314575f80fd5b81356112c6816122ef565b5f5b83811015612339578181015183820152602001612321565b50505f910152565b5f815180845261235881602086016020860161231f565b601f01601f19169290920160200192915050565b602081525f6112c66020830184612341565b5f6020828403121561238e575f80fd5b5035919050565b80356001600160a01b038116811461110c575f80fd5b5f80604083850312156123bc575f80fd5b6123c583612395565b946020939093013593505050565b5f602082840312156123e3575f80fd5b6112c682612395565b5f805f606084860312156123fe575f80fd5b61240784612395565b925061241560208501612395565b9150604084013590509250925092565b5f8060408385031215612436575f80fd5b50508035926020909101359150565b5f8060408385031215612456575f80fd5b61245f83612395565b915060208301356001600160601b038116811461247a575f80fd5b809150509250929050565b8015158114610b13575f80fd5b5f80604083850312156124a3575f80fd5b6124ac83612395565b9150602083013561247a81612485565b5f80602083850312156124cd575f80fd5b823567ffffffffffffffff808211156124e4575f80fd5b818501915085601f8301126124f7575f80fd5b813581811115612505575f80fd5b866020828501011115612516575f80fd5b60209290920196919550909350505050565b634e487b7160e01b5f52604160045260245ffd5b5f805f806080858703121561254f575f80fd5b61255885612395565b935061256660208601612395565b925060408501359150606085013567ffffffffffffffff80821115612589575f80fd5b818701915087601f83011261259c575f80fd5b8135818111156125ae576125ae612528565b604051601f8201601f19908116603f011681019083821181831017156125d6576125d6612528565b816040528281528a60208487010111156125ee575f80fd5b826020860160208301375f60208483010152809550505050505092959194509250565b5f8060408385031215612622575f80fd5b61262b83612395565b915061263960208401612395565b90509250929050565b600181811c9082168061265657607f821691505b60208210810361267457634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156108185761081861267a565b80820281158282048414176108185761081861267a565b634e487b7160e01b5f52601260045260245ffd5b5f826126da576126da6126b8565b500490565b808201808211156108185761081861267a565b601f821115610959575f81815260208120601f850160051c810160208610156127185750805b601f850160051c820191505b8181101561273757828155600101612724565b505050505050565b67ffffffffffffffff83111561275757612757612528565b61276b836127658354612642565b836126f2565b5f601f84116001811461279c575f85156127855750838201355b5f19600387901b1c1916600186901b178355611137565b5f83815260209020601f19861690835b828110156127cc57868501358255602094850194600190920191016127ac565b50868210156127e8575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f835161280b81846020880161231f565b83519083019061281f81836020880161231f565b64173539b7b760d91b9101908152600501949350505050565b5f60208284031215612848575f80fd5b81516112c681612485565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602b908201527f455243373231723a206d696e74696e67206d6f726520746f6b656e732074686160408201526a6e20617661696c61626c6560a81b606082015260800190565b5f816128fd576128fd61267a565b505f190190565b5f600182016129155761291561267a565b5060010190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b5f8261297c5761297c6126b8565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f906129b390830184612341565b9695505050505050565b5f602082840312156129cd575f80fd5b81516112c6816122ef56fea2646970667358221220aa0ee337e59e246b058f6b289cb3ba5f4567e3e802e0bbd35823ff9db263c1e164736f6c63430008140033

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.