ETH Price: $3,382.00 (+3.80%)

Token

Amber Vittoria X Save The Date (AVXSTD)
 

Overview

Max Total Supply

307 AVXSTD

Holders

181

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3 AVXSTD
0x602f2604fb08c8e972e51a40e7a55655869e2664
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:
AmberVittoriaXSaveTheDate

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 2 of 22: AmberVittoriaXSaveTheDate.sol
// SPDX-License-Identifier: MIT
/***
 *  
 *  8""""8                      
 *  8      eeeee ee   e eeee    
 *  8eeeee 8   8 88   8 8       
 *      88 8eee8 88  e8 8eee    
 *  e   88 88  8  8  8  88      
 *  8eee88 88  8  8ee8  88ee    
 *  ""8""                       
 *    8   e   e eeee            
 *    8e  8   8 8               
 *    88  8eee8 8eee            
 *    88  88  8 88              
 *    88  88  8 88ee            
 *  8""""8                      
 *  8    8 eeeee eeeee eeee     
 *  8e   8 8   8   8   8        
 *  88   8 8eee8   8e  8eee     
 *  88   8 88  8   88  88       
 *  88eee8 88  8   88  88ee     
 *  
 */
pragma solidity >=0.8.9 <0.9.0;

import './ERC721AQueryable.sol';
import './MerkleProof.sol';
import './Ownable.sol';
import './ReentrancyGuard.sol';
import './RefundContract.sol';
import './ERC2981.sol';
import './DefaultOperatorFilterer.sol';


contract AmberVittoriaXSaveTheDate is ERC721AQueryable, Ownable, ReentrancyGuard, ERC2981, DefaultOperatorFilterer {
  using Strings for uint256;

  event NftsMinted(address owner, uint256[] std_ids, uint256 currentIndex, uint256 mintAmount);

  mapping(uint256 => bool) public freelistClaimed;
  string public uriPrefix = '';
  uint256 public maxSupply = 18000;
  uint256 public maxMintAmountPerTx = 1;
  uint256 public cost = 0 ether;
  bytes32 public merkleRoot;

  string  public tokenName = "Amber Vittoria X Save The Date";
  string  public tokenSymbol = "AVXSTD";
  bool public paused = true;
  bool public whitelistMintEnabled = false;

  IERC721 internal saveTheDateContract;
  RefundContract internal refundContract;
  string internal uriSuffix = '.json';  

  constructor(string memory baseURI, address _saveTheDateContract, address _refundContract) ERC721A(tokenName, tokenSymbol) {
    setUriPrefix(baseURI);
    saveTheDateContract = IERC721(_saveTheDateContract);
    refundContract = RefundContract(_refundContract);
  }

  modifier mintCompliance(uint256 _mintAmount) {
    require(_mintAmount > 0 && _mintAmount <= maxMintAmountPerTx, 'Invalid mint amount!');
    require(totalSupply() + _mintAmount <= maxSupply, 'Max supply exceeded!');
    _;
  }

  modifier mintPriceCompliance(uint256 _mintAmount) {
    require(msg.value >= cost * _mintAmount, 'Insufficient funds!');
    _;
  }

  function mint(uint256 std_id) public payable mintCompliance(1) mintPriceCompliance(1) {
    require(!paused, 'The contract is paused!');
    require(!freelistClaimed[std_id], 'Token already claimed!');
    address _owner = saveTheDateContract.ownerOf(std_id);
    require(_owner == msg.sender, "Must be an owner to mint");
    safeMint(_msgSender(), std_id);
    freelistClaimed[std_id] = true;
    refundContract.claimReward(std_id);
  }

  function safeMint(address to, uint256 std_id) internal {
    uint256[] memory tmp = new uint256[](1);
    tmp[0] = std_id;
    bulkSafeMint(to, tmp);
    delete tmp;
  }

  function bulkSafeMint(address to, uint256[] memory std_ids) internal {
    uint256 currentIndex = _nextTokenId();
    uint256 amount = std_ids.length;
    _safeMint(to, amount);
    emit NftsMinted(to, std_ids, currentIndex, amount);
  }

 function internalMint(uint256[] memory std_ids) external onlyOwner  {
    require(totalSupply() + std_ids.length <= maxSupply, 'Max supply exceeded!');
    bulkSafeMint(_msgSender(), std_ids);
  }
   
  function mintForAddress(uint256[] memory std_ids, address _receiver) public onlyOwner {
    require(totalSupply() + std_ids.length <= maxSupply, 'Max supply exceeded!');
    bulkSafeMint(_receiver, std_ids);
  }

  function mintForAddresses(uint256[] memory std_ids, address[] memory _addresses) public onlyOwner {
    uint256[] memory tmp = new uint256[](1);
    for (uint i = 0; i < std_ids.length; i++) {
      tmp[0] = std_ids[i];
      mintForAddress(tmp, _addresses[i]);
    }
    delete tmp;
  }

  function _startTokenId() internal view virtual override returns (uint256) {
    return 1;
  }

  function setMaxSupply(uint256 _maxSupply) public onlyOwner {
    maxSupply = _maxSupply;
  }

  function setMaxMintAmountPerTx(uint256 _maxMintAmountPerTx) public onlyOwner {
    maxMintAmountPerTx = _maxMintAmountPerTx;
  }

  function setUriPrefix(string memory _uriPrefix) public onlyOwner {
    uriPrefix = _uriPrefix;
  }

  function setUriSuffix(string memory _uriSuffix) public onlyOwner {
    uriSuffix = _uriSuffix;
  }

  function setCost(uint256 _cost) public onlyOwner {
    cost = _cost;
  }

  function setPaused(bool _state) public onlyOwner {
    paused = _state;
  }

  function setRoyaltyInfo(address payable receiver, uint96 numerator) public onlyOwner {
    _setDefaultRoyalty(receiver, numerator);
  }

  function withdraw() public onlyOwner nonReentrant {
    (bool os, ) = payable(owner()).call{value: address(this).balance}('');
    require(os);
  }

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

  function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, IERC721A, ERC2981) returns (bool) {
    return ERC721A.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId);
  }

    function setApprovalForAll(address operator, bool approved) public override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

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

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

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

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

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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

pragma solidity ^0.8.0;

import './ERC165.sol';
import './IERC2981.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 7 of 22: ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev Interface of ERC721 token receiver.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant _BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant _BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant _BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant _BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See {_packedOwnershipOf} implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view virtual returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        // Counter underflow is impossible as `_currentIndex` does not decrement,
        // and it is initialized to `_startTokenId()`.
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view virtual returns (uint256) {
        return _burnCounter;
    }

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal virtual {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

    /**
     * @dev Returns the token collection name.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

    /**
     * @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, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @dev Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around over time.
     */
    function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal virtual {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) {
        if (_startTokenId() <= tokenId) {
            packed = _packedOwnerships[tokenId];
            // If not burned.
            if (packed & _BITMASK_BURNED == 0) {
                // If the data at the starting slot does not exist, start the scan.
                if (packed == 0) {
                    if (tokenId >= _currentIndex) revert OwnerQueryForNonexistentToken();
                    // Invariant:
                    // There will always be an initialized ownership slot
                    // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                    // before an unintialized ownership slot
                    // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                    // Hence, `tokenId` will not underflow.
                    //
                    // We can directly compare the packed value.
                    // If the address is zero, packed will be zero.
                    for (;;) {
                        unchecked {
                            packed = _packedOwnerships[--tokenId];
                        }
                        if (packed == 0) continue;
                        return packed;
                    }
                }
                // Otherwise, the data exists and is not burned. We can skip the scan.
                // This is possible because we have already achieved the target condition.
                // This saves 2143 gas on transfers of initialized tokens.
                return packed;
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     */
    function approve(address to, uint256 tokenId) public payable virtual override {
        _approve(to, tokenId, true);
    }

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @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) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @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. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @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 memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token IDs
     * are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * 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, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token IDs
     * have been transferred. This includes minting.
     * And also called after one token has been burned.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns whether the call correctly returned the expected magic value.
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, quantity, '');
    }

    // =============================================================
    //                       APPROVAL OPERATIONS
    // =============================================================

    /**
     * @dev Equivalent to `_approve(to, tokenId, false)`.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _approve(to, tokenId, false);
    }

    /**
     * @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:
     *
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        bool approvalCheck
    ) internal virtual {
        address owner = ownerOf(tokenId);

        if (approvalCheck)
            if (_msgSenderERC721A() != owner)
                if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                    revert ApprovalCallerNotOwnerNorApproved();
                }

        _tokenApprovals[tokenId].value = to;
        emit Approval(owner, to, tokenId);
    }

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

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

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * 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, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value) internal pure virtual returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }
}

File 8 of 22: ERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721AQueryable.sol';
import './ERC721A.sol';

/**
 * @title ERC721AQueryable.
 *
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) {
        TokenOwnership memory ownership;
        if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
            return ownership;
        }
        ownership = _ownershipAt(tokenId);
        if (ownership.burned) {
            return ownership;
        }
        return _ownershipOf(tokenId);
    }

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] calldata tokenIds)
        external
        view
        virtual
        override
        returns (TokenOwnership[] memory)
    {
        unchecked {
            uint256 tokenIdsLength = tokenIds.length;
            TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
            for (uint256 i; i != tokenIdsLength; ++i) {
                ownerships[i] = explicitOwnershipOf(tokenIds[i]);
            }
            return ownerships;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view virtual override returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();
            uint256 tokenIdsIdx;
            uint256 stopLimit = _nextTokenId();
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            // Set `stop = min(stop, stopLimit)`.
            if (stop > stopLimit) {
                stop = stopLimit;
            }
            uint256 tokenIdsMaxLength = balanceOf(owner);
            // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
            // to cater for cases where `balanceOf(owner)` is too big.
            if (start < stop) {
                uint256 rangeLength = stop - start;
                if (rangeLength < tokenIdsMaxLength) {
                    tokenIdsMaxLength = rangeLength;
                }
            } else {
                tokenIdsMaxLength = 0;
            }
            uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
            if (tokenIdsMaxLength == 0) {
                return tokenIds;
            }
            // We need to call `explicitOwnershipOf(start)`,
            // because the slot at `start` may not be initialized.
            TokenOwnership memory ownership = explicitOwnershipOf(start);
            address currOwnershipAddr;
            // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
            // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
            if (!ownership.burned) {
                currOwnershipAddr = ownership.addr;
            }
            for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            // Downsize the array to fit.
            assembly {
                mstore(tokenIds, tokenIdsIdx)
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }
}

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

import './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 11 of 22: IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 12 of 22: IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721A.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the
     * ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

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

    // =============================================================
    //                            IERC721
    // =============================================================

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

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

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

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

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

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

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

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

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

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

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

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

File 13 of 22: IERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev Interface of ERC721AQueryable.
 */
interface IERC721AQueryable is IERC721A {
    /**
     * Invalid query range (`start` >= `stop`).
     */
    error InvalidQueryRange();

    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) external view returns (uint256[] memory);
}

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

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

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

pragma solidity ^0.8.0;

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

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

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

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

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

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

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

/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @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 OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // 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(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            // 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) {
                _;
                return;
            }
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), msg.sender)) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
        _;
    }
}

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

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

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

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

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

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

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

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

File 20 of 22: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

File 21 of 22: RefundContract.sol
// SPDX-License-Identifier: MIT
/***
 *  
 *  8""""8                      
 *  8      eeeee ee   e eeee    
 *  8eeeee 8   8 88   8 8       
 *      88 8eee8 88  e8 8eee    
 *  e   88 88  8  8  8  88      
 *  8eee88 88  8  8ee8  88ee    
 *  ""8""                       
 *    8   e   e eeee            
 *    8e  8   8 8               
 *    88  8eee8 8eee            
 *    88  88  8 88              
 *    88  88  8 88ee            
 *  8""""8                      
 *  8    8 eeeee eeeee eeee     
 *  8e   8 8   8   8   8        
 *  88   8 8eee8   8e  8eee     
 *  88   8 88  8   88  88       
 *  88eee8 88  8   88  88ee     
 *  
 */
pragma solidity >=0.8.9 <0.9.0;

import './IERC721.sol';
import './Ownable.sol';
import './MerkleProof.sol';
import './ReentrancyGuard.sol';
import './Strings.sol';
import './IERC721Receiver.sol';


contract RefundContract is Ownable, ReentrancyGuard, IERC721Receiver {
  using Strings for uint256;
  using Strings for address;

  event DateRefunded(address owner, uint256 tokenId);

    bytes32 public merkleRoot;
    bool public paused = true;
    uint256 public refundPrice = 0.07 ether;
    address public rewardsContractAddress;
    mapping(uint256 => bool) public claimedRewardTokens;

    IERC721 saveTheDateContract;

    constructor(address _saveTheDateContract) {
      saveTheDateContract = IERC721(_saveTheDateContract);
    }

  function refund(uint256 _tokenId, bytes32[] calldata _merkleProof) public nonReentrant {
    require(!paused, 'The contract is paused!');
    verifyWhitelistRequirements(_tokenId, _merkleProof);
    require(!claimedRewardTokens[_tokenId], 'Token claimed reward already');
    address _owner = saveTheDateContract.ownerOf(_tokenId);
    require(_owner == msg.sender, "Must be an owner to get refund");
    saveTheDateContract.transferFrom(msg.sender, address(this), _tokenId);
    payable(msg.sender).transfer(refundPrice);
    emit DateRefunded(_owner, _tokenId);
    delete _owner;
  }

  function claimReward(uint256 _tokenId) public {
    require(rewardsContractAddress == msg.sender, "Must be rewardsContractAddress to mark the token as claimed");
    claimedRewardTokens[_tokenId] = true;
  }

  function claimRewards(uint256[] calldata _tokenIds) public {
    require(rewardsContractAddress == msg.sender, "Must be rewardsContractAddress to mark the token as claimed");
    for (uint256 i = 0; i < _tokenIds.length; i++) {
      claimedRewardTokens[_tokenIds[i]] = true;
    }
  }

  function verifyWhitelistRequirements(uint256 _tokenId, bytes32[] calldata _merkleProof) public view { 
    bytes32 leaf = keccak256(buildMerkleLeaf(_tokenId));
    require(MerkleProof.verify(_merkleProof, merkleRoot, leaf), 'Invalid proof!');
  }

  function deposit() public payable onlyOwner {
  }

  function setSaveTheDateContract(address _contractAddress) public onlyOwner {
    saveTheDateContract = IERC721(_contractAddress);
  }

  function setRewardsContractAddress(address _rewardsContractAddress) public onlyOwner {
    rewardsContractAddress = _rewardsContractAddress;
  }

  function setMerkleRoot(bytes32 _merkleRoot) public onlyOwner {
    merkleRoot = _merkleRoot;
  }

  function setPaused(bool _state) public onlyOwner {
    paused = _state;
  }

  function setRefundPrice(uint256 _refundPrice) public onlyOwner {
    refundPrice = _refundPrice;
  }

  function withdraw() public onlyOwner nonReentrant {
    (bool os, ) = payable(owner()).call{value: address(this).balance}('');
    require(os);
  }

  function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4)
    {
      return bytes4(keccak256("onERC721Received(address,uint256,bytes)"));
    }

  function buildMerkleLeaf(uint256 _tokenId) internal view returns(bytes memory){ 
    return abi.encodePacked(_msgSender().toString(), "-", _tokenId.toString());
  }
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

    function toHexString(bytes memory data) internal pure returns(string memory) {
        bytes memory str = new bytes(2 + data.length * 2);
        str[0] = "0";
        str[1] = "x";
        for (uint i = 0; i < data.length; i++) {
          str[2+i*2] = _HEX_SYMBOLS[uint(uint8(data[i] >> 4))];
            str[3+i*2] = _HEX_SYMBOLS[uint(uint8(data[i] & 0x0f))];
        }
        return string(str);
    }

   function toString(address account) internal pure returns(string memory) {
    return toHexString(abi.encodePacked(account));
   }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"address","name":"_saveTheDateContract","type":"address"},{"internalType":"address","name":"_refundContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","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":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"std_ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"currentIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"NftsMinted","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":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"freelistClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"uint256[]","name":"std_ids","type":"uint256[]"}],"name":"internalMint","outputs":[],"stateMutability":"nonpayable","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":"maxMintAmountPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"std_id","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"std_ids","type":"uint256[]"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"mintForAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"std_ids","type":"uint256[]"},{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"mintForAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"payable","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMintAmountPerTx","type":"uint256"}],"name":"setMaxMintAmountPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint96","name":"numerator","type":"uint96"}],"name":"setRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriPrefix","type":"string"}],"name":"setUriPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriSuffix","type":"string"}],"name":"setUriSuffix","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":"tokenName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenSymbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"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"}]

60a06040819052600060808190526200001b91600d91620004ec565b50614650600e556001600f55600060105560408051808201909152601e8082527f416d62657220566974746f72696120582053617665205468652044617465000060209092019182526200007291601291620004ec565b506040805180820190915260068082526510559614d51160d21b6020909201918252620000a291601391620004ec565b506014805461ffff1916600117905560408051808201909152600580825264173539b7b760d91b6020909201918252620000df91601691620004ec565b50348015620000ed57600080fd5b50604051620035ea380380620035ea8339810160408190526200011091620005c5565b733cc6cdda760b79bafa08df41ecfa224f810dceb66001601280546200013690620006c8565b80601f01602080910402602001604051908101604052809291908181526020018280546200016490620006c8565b8015620001b55780601f106200018957610100808354040283529160200191620001b5565b820191906000526020600020905b8154815290600101906020018083116200019757829003601f168201915b505050505060138054620001c990620006c8565b80601f0160208091040260200160405190810160405280929190818152602001828054620001f790620006c8565b8015620002485780601f106200021c5761010080835404028352916020019162000248565b820191906000526020600020905b8154815290600101906020018083116200022a57829003601f168201915b5050845162000262935060029250602086019150620004ec565b50805162000278906003906020840190620004ec565b50506001600055506200028b3362000422565b60016009556daaeb6d7670e522a718067333cd4e3b15620003d55780156200032357604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200030457600080fd5b505af115801562000319573d6000803e3d6000fd5b50505050620003d5565b6001600160a01b03821615620003745760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af290390604401620002e9565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620003bb57600080fd5b505af1158015620003d0573d6000803e3d6000fd5b505050505b50620003e390508362000474565b6014805462010000600160b01b031916620100006001600160a01b0394851602179055601580546001600160a01b031916919092161790555062000704565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6008546001600160a01b03163314620004d35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b8051620004e890600d906020840190620004ec565b5050565b828054620004fa90620006c8565b90600052602060002090601f0160209004810192826200051e576000855562000569565b82601f106200053957805160ff191683800117855562000569565b8280016001018555821562000569579182015b82811115620005695782518255916020019190600101906200054c565b50620005779291506200057b565b5090565b5b808211156200057757600081556001016200057c565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b0381168114620005c057600080fd5b919050565b600080600060608486031215620005db57600080fd5b83516001600160401b0380821115620005f357600080fd5b818601915086601f8301126200060857600080fd5b8151818111156200061d576200061d62000592565b604051601f8201601f19908116603f0116810190838211818310171562000648576200064862000592565b816040528281526020935089848487010111156200066557600080fd5b600091505b828210156200068957848201840151818301850152908301906200066a565b828211156200069b5760008484830101525b9650620006ad915050868201620005a8565b93505050620006bf60408501620005a8565b90509250925092565b600181811c90821680620006dd57607f821691505b602082108103620006fe57634e487b7160e01b600052602260045260246000fd5b50919050565b612ed680620007146000396000f3fe6080604052600436106102725760003560e01c80636352211e1161014f57806395d89b41116100c1578063b88d4fde1161007a578063b88d4fde14610742578063c23dc68f14610755578063c87b56dd14610782578063d5abeb01146107a2578063e985e9c5146107b8578063f2fde38b1461080157600080fd5b806395d89b411461069a57806399a2557a146106af578063a0712d68146106cf578063a22cb465146106e2578063a583542414610702578063b071401b1461072257600080fd5b8063715018a611610113578063715018a6146105ef5780637b61c320146106045780637ec4a659146106195780638462151c146106395780638da5cb5b1461066657806394354fd01461068457600080fd5b80636352211e1461055b5780636c02a9311461057b5780636caede3d146105905780636f8b44b0146105af57806370a08231146105cf57600080fd5b80632a55205a116101e857806342842e0e116101ac57806342842e0e1461049c57806344a0d68a146104af5780635bbb2177146104cf5780635c975abb146104fc5780635ffa777d1461051657806362b99ad41461054657600080fd5b80632a55205a146103f05780632a8255691461042f5780632eb4a7ab1461044f5780633ccfd60b1461046557806341f434341461047a57600080fd5b806313faede61161023a57806313faede61461033b57806316ba10e01461035f57806316c38b3c1461037f57806316da55c41461039f57806318160ddd146103bf57806323b872dd146103dd57600080fd5b806301ffc9a71461027757806302fa7c47146102ac57806306fdde03146102ce578063081812fc146102f0578063095ea7b314610328575b600080fd5b34801561028357600080fd5b5061029761029236600461258b565b610821565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102cc6102c73660046125bd565b610841565b005b3480156102da57600080fd5b506102e3610882565b6040516102a3919061265a565b3480156102fc57600080fd5b5061031061030b36600461266d565b610914565b6040516001600160a01b0390911681526020016102a3565b6102cc610336366004612686565b610958565b34801561034757600080fd5b5061035160105481565b6040519081526020016102a3565b34801561036b57600080fd5b506102cc61037a36600461274f565b610a21565b34801561038b57600080fd5b506102cc61039a3660046127a5565b610a5e565b3480156103ab57600080fd5b506102cc6103ba366004612850565b610a9b565b3480156103cb57600080fd5b50610351600154600054036000190190565b6102cc6103eb366004612896565b610b0d565b3480156103fc57600080fd5b5061041061040b3660046128d7565b610be6565b604080516001600160a01b0390931683526020830191909152016102a3565b34801561043b57600080fd5b506102cc61044a3660046128f9565b610c92565b34801561045b57600080fd5b5061035160115481565b34801561047157600080fd5b506102cc610d58565b34801561048657600080fd5b506103106daaeb6d7670e522a718067333cd4e81565b6102cc6104aa366004612896565b610e52565b3480156104bb57600080fd5b506102cc6104ca36600461266d565b610f20565b3480156104db57600080fd5b506104ef6104ea3660046129bc565b610f4f565b6040516102a39190612a6c565b34801561050857600080fd5b506014546102979060ff1681565b34801561052257600080fd5b5061029761053136600461266d565b600c6020526000908152604090205460ff1681565b34801561055257600080fd5b506102e361101a565b34801561056757600080fd5b5061031061057636600461266d565b6110a8565b34801561058757600080fd5b506102e36110b3565b34801561059c57600080fd5b5060145461029790610100900460ff1681565b3480156105bb57600080fd5b506102cc6105ca36600461266d565b6110c0565b3480156105db57600080fd5b506103516105ea366004612aae565b6110ef565b3480156105fb57600080fd5b506102cc61113d565b34801561061057600080fd5b506102e3611173565b34801561062557600080fd5b506102cc61063436600461274f565b611180565b34801561064557600080fd5b50610659610654366004612aae565b6111bd565b6040516102a39190612b06565b34801561067257600080fd5b506008546001600160a01b0316610310565b34801561069057600080fd5b50610351600f5481565b3480156106a657600080fd5b506102e36112c5565b3480156106bb57600080fd5b506106596106ca366004612b19565b6112d4565b6102cc6106dd36600461266d565b61145b565b3480156106ee57600080fd5b506102cc6106fd366004612b4e565b611739565b34801561070e57600080fd5b506102cc61071d366004612b7c565b6117fd565b34801561072e57600080fd5b506102cc61073d36600461266d565b611872565b6102cc610750366004612bb0565b6118a1565b34801561076157600080fd5b5061077561077036600461266d565b61197d565b6040516102a39190612c2f565b34801561078e57600080fd5b506102e361079d36600461266d565b611a05565b3480156107ae57600080fd5b50610351600e5481565b3480156107c457600080fd5b506102976107d3366004612c3d565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561080d57600080fd5b506102cc61081c366004612aae565b611a88565b600061082c82611b20565b8061083b575061083b82611b6e565b92915050565b6008546001600160a01b031633146108745760405162461bcd60e51b815260040161086b90612c6b565b60405180910390fd5b61087e8282611ba3565b5050565b60606002805461089190612ca0565b80601f01602080910402602001604051908101604052809291908181526020018280546108bd90612ca0565b801561090a5780601f106108df5761010080835404028352916020019161090a565b820191906000526020600020905b8154815290600101906020018083116108ed57829003601f168201915b5050505050905090565b600061091f82611ca0565b61093c576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b816daaeb6d7670e522a718067333cd4e3b15610a1257604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156109c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ea9190612cda565b610a1257604051633b79c77360e21b81526001600160a01b038216600482015260240161086b565b610a1c8383611cd5565b505050565b6008546001600160a01b03163314610a4b5760405162461bcd60e51b815260040161086b90612c6b565b805161087e9060169060208401906124dc565b6008546001600160a01b03163314610a885760405162461bcd60e51b815260040161086b90612c6b565b6014805460ff1916911515919091179055565b6008546001600160a01b03163314610ac55760405162461bcd60e51b815260040161086b90612c6b565b600e548251610adb600154600054036000190190565b610ae59190612d0d565b1115610b035760405162461bcd60e51b815260040161086b90612d25565b61087e8183611ce1565b826daaeb6d7670e522a718067333cd4e3b15610bd557336001600160a01b03821603610b4357610b3e848484611d33565b610be0565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015610b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb69190612cda565b610bd557604051633b79c77360e21b815233600482015260240161086b565b610be0848484611d33565b50505050565b6000828152600b602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610c5b575060408051808201909152600a546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610c7a906001600160601b031687612d53565b610c849190612d72565b915196919550909350505050565b6008546001600160a01b03163314610cbc5760405162461bcd60e51b815260040161086b90612c6b565b6040805160018082528183019092526000916020808301908036833701905050905060005b8351811015610be057838181518110610cfc57610cfc612d94565b602002602001015182600081518110610d1757610d17612d94565b602002602001018181525050610d4682848381518110610d3957610d39612d94565b6020026020010151610a9b565b80610d5081612daa565b915050610ce1565b6008546001600160a01b03163314610d825760405162461bcd60e51b815260040161086b90612c6b565b600260095403610dd45760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161086b565b60026009556000610ded6008546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610e37576040519150601f19603f3d011682016040523d82523d6000602084013e610e3c565b606091505b5050905080610e4a57600080fd5b506001600955565b826daaeb6d7670e522a718067333cd4e3b15610f1557336001600160a01b03821603610e8357610b3e848484611ecb565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015610ed2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef69190612cda565b610f1557604051633b79c77360e21b815233600482015260240161086b565b610be0848484611ecb565b6008546001600160a01b03163314610f4a5760405162461bcd60e51b815260040161086b90612c6b565b601055565b6060816000816001600160401b03811115610f6c57610f6c6126b2565b604051908082528060200260200182016040528015610fbe57816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610f8a5790505b50905060005b82811461101157610fec868683818110610fe057610fe0612d94565b9050602002013561197d565b828281518110610ffe57610ffe612d94565b6020908102919091010152600101610fc4565b50949350505050565b600d805461102790612ca0565b80601f016020809104026020016040519081016040528092919081815260200182805461105390612ca0565b80156110a05780601f10611075576101008083540402835291602001916110a0565b820191906000526020600020905b81548152906001019060200180831161108357829003601f168201915b505050505081565b600061083b82611ee6565b6012805461102790612ca0565b6008546001600160a01b031633146110ea5760405162461bcd60e51b815260040161086b90612c6b565b600e55565b60006001600160a01b038216611118576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b031633146111675760405162461bcd60e51b815260040161086b90612c6b565b6111716000611f72565b565b6013805461102790612ca0565b6008546001600160a01b031633146111aa5760405162461bcd60e51b815260040161086b90612c6b565b805161087e90600d9060208401906124dc565b606060008060006111cd856110ef565b90506000816001600160401b038111156111e9576111e96126b2565b604051908082528060200260200182016040528015611212578160200160208202803683370190505b50905061123f60408051608081018252600080825260208201819052918101829052606081019190915290565b60015b8386146112b95761125281611fc4565b915081604001516112b15781516001600160a01b03161561127257815194505b876001600160a01b0316856001600160a01b0316036112b157808387806001019850815181106112a4576112a4612d94565b6020026020010181815250505b600101611242565b50909695505050505050565b60606003805461089190612ca0565b60608183106112f657604051631960ccad60e11b815260040160405180910390fd5b60008061130260005490565b9050600185101561131257600194505b8084111561131e578093505b6000611329876110ef565b9050848610156113485785850381811015611342578091505b5061134c565b5060005b6000816001600160401b03811115611366576113666126b2565b60405190808252806020026020018201604052801561138f578160200160208202803683370190505b509050816000036113a557935061145492505050565b60006113b08861197d565b9050600081604001516113c1575080515b885b8881141580156113d35750848714155b15611448576113e181611fc4565b925082604001516114405782516001600160a01b03161561140157825191505b8a6001600160a01b0316826001600160a01b031603611440578084888060010199508151811061143357611433612d94565b6020026020010181815250505b6001016113c3565b50505092835250909150505b9392505050565b6001600f548111156114a65760405162461bcd60e51b8152602060048201526014602482015273496e76616c6964206d696e7420616d6f756e742160601b604482015260640161086b565b600e54816114bb600154600054036000190190565b6114c59190612d0d565b11156114e35760405162461bcd60e51b815260040161086b90612d25565b6001806010546114f39190612d53565b3410156115385760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742066756e64732160681b604482015260640161086b565b60145460ff161561158b5760405162461bcd60e51b815260206004820152601760248201527f54686520636f6e74726163742069732070617573656421000000000000000000604482015260640161086b565b6000838152600c602052604090205460ff16156115e35760405162461bcd60e51b8152602060048201526016602482015275546f6b656e20616c726561647920636c61696d65642160501b604482015260640161086b565b6014546040516331a9108f60e11b8152600481018590526000916201000090046001600160a01b031690636352211e90602401602060405180830381865afa158015611633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116579190612dc3565b90506001600160a01b03811633146116b15760405162461bcd60e51b815260206004820152601860248201527f4d75737420626520616e206f776e657220746f206d696e740000000000000000604482015260640161086b565b6116bb3385612000565b6000848152600c602052604090819020805460ff191660011790556015549051630ae169a560e41b8152600481018690526001600160a01b039091169063ae169a5090602401600060405180830381600087803b15801561171b57600080fd5b505af115801561172f573d6000803e3d6000fd5b5050505050505050565b816daaeb6d7670e522a718067333cd4e3b156117f357604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156117a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cb9190612cda565b6117f357604051633b79c77360e21b81526001600160a01b038216600482015260240161086b565b610a1c838361204c565b6008546001600160a01b031633146118275760405162461bcd60e51b815260040161086b90612c6b565b600e54815161183d600154600054036000190190565b6118479190612d0d565b11156118655760405162461bcd60e51b815260040161086b90612d25565b61186f3382611ce1565b50565b6008546001600160a01b0316331461189c5760405162461bcd60e51b815260040161086b90612c6b565b600f55565b836daaeb6d7670e522a718067333cd4e3b1561196a57336001600160a01b038216036118d8576118d3858585856120b8565b611976565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611927573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194b9190612cda565b61196a57604051633b79c77360e21b815233600482015260240161086b565b611976858585856120b8565b5050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260018310806119d657506000548310155b156119e15792915050565b6119ea83611fc4565b90508060400151156119fc5792915050565b611454836120fc565b6060611a1082611ca0565b611a2d57604051630a14c4b560e41b815260040160405180910390fd5b6000611a37612131565b90508051600003611a575760405180602001604052806000815250611454565b80611a6184612140565b604051602001611a72929190612de0565b6040516020818303038152906040529392505050565b6008546001600160a01b03163314611ab25760405162461bcd60e51b815260040161086b90612c6b565b6001600160a01b038116611b175760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161086b565b61186f81611f72565b60006301ffc9a760e01b6001600160e01b031983161480611b5157506380ac58cd60e01b6001600160e01b03198316145b8061083b5750506001600160e01b031916635b5e139f60e01b1490565b60006001600160e01b0319821663152a902d60e11b148061083b57506301ffc9a760e01b6001600160e01b031983161461083b565b6127106001600160601b0382161115611c115760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b606482015260840161086b565b6001600160a01b038216611c675760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640161086b565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600a55565b600081600111158015611cb4575060005482105b801561083b575050600090815260046020526040902054600160e01b161590565b61087e82826001612184565b6000548151611cf0848261222b565b7f102e9d07c211550df36fe13636ecaa163325a38a6c48d8de1a7b6070601b215784848484604051611d259493929190612e0f565b60405180910390a150505050565b6000611d3e82611ee6565b9050836001600160a01b0316816001600160a01b031614611d715760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417611dbe57611da186336107d3565b611dbe57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516611de557604051633a954ecd60e21b815260040160405180910390fd5b8015611df057600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003611e8257600184016000818152600460205260408120549003611e80576000548114611e805760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b610a1c838383604051806020016040528060008152506118a1565b600081600111611f59575060008181526004602052604081205490600160e01b82169003611f595780600003611f54576000548210611f3857604051636f96cda160e11b815260040160405180910390fd5b5b50600019016000818152600460205260409020548015611f39575b919050565b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60408051608081018252600080825260208201819052918101829052606081019190915260008281526004602052604090205461083b90612245565b60408051600180825281830190925260009160208083019080368337019050509050818160008151811061203657612036612d94565b602002602001018181525050610a1c8382611ce1565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6120c3848484610b0d565b6001600160a01b0383163b15610be0576120df8484848461228c565b610be0576040516368d2bf6b60e11b815260040160405180910390fd5b60408051608081018252600080825260208201819052918101829052606081019190915261083b61212c83611ee6565b612245565b6060600d805461089190612ca0565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061215a5750819003601f19909101908152919050565b600061218f836110a8565b905081156121ce57336001600160a01b038216146121ce576121b181336107d3565b6121ce576040516367d9dca160e11b815260040160405180910390fd5b60008381526006602052604080822080546001600160a01b0319166001600160a01b0388811691821790925591518693918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b61087e828260405180602001604052806000815250612378565b604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906122c1903390899088908890600401612e46565b6020604051808303816000875af19250505080156122fc575060408051601f3d908101601f191682019092526122f991810190612e83565b60015b61235a573d80801561232a576040519150601f19603f3d011682016040523d82523d6000602084013e61232f565b606091505b508051600003612352576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b61238283836123de565b6001600160a01b0383163b15610a1c576000548281035b6123ac600086838060010194508661228c565b6123c9576040516368d2bf6b60e11b815260040160405180910390fd5b81811061239957816000541461197657600080fd5b60008054908290036124035760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b8181146124b257808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460010161247a565b50816000036124d357604051622e076360e81b815260040160405180910390fd5b60005550505050565b8280546124e890612ca0565b90600052602060002090601f01602090048101928261250a5760008555612550565b82601f1061252357805160ff1916838001178555612550565b82800160010185558215612550579182015b82811115612550578251825591602001919060010190612535565b5061255c929150612560565b5090565b5b8082111561255c5760008155600101612561565b6001600160e01b03198116811461186f57600080fd5b60006020828403121561259d57600080fd5b813561145481612575565b6001600160a01b038116811461186f57600080fd5b600080604083850312156125d057600080fd5b82356125db816125a8565b915060208301356001600160601b03811681146125f757600080fd5b809150509250929050565b60005b8381101561261d578181015183820152602001612605565b83811115610be05750506000910152565b60008151808452612646816020860160208601612602565b601f01601f19169290920160200192915050565b602081526000611454602083018461262e565b60006020828403121561267f57600080fd5b5035919050565b6000806040838503121561269957600080fd5b82356126a4816125a8565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156126f0576126f06126b2565b604052919050565b60006001600160401b03831115612711576127116126b2565b612724601f8401601f19166020016126c8565b905082815283838301111561273857600080fd5b828260208301376000602084830101529392505050565b60006020828403121561276157600080fd5b81356001600160401b0381111561277757600080fd5b8201601f8101841361278857600080fd5b612370848235602084016126f8565b801515811461186f57600080fd5b6000602082840312156127b757600080fd5b813561145481612797565b60006001600160401b038211156127db576127db6126b2565b5060051b60200190565b600082601f8301126127f657600080fd5b8135602061280b612806836127c2565b6126c8565b82815260059290921b8401810191818101908684111561282a57600080fd5b8286015b84811015612845578035835291830191830161282e565b509695505050505050565b6000806040838503121561286357600080fd5b82356001600160401b0381111561287957600080fd5b612885858286016127e5565b92505060208301356125f7816125a8565b6000806000606084860312156128ab57600080fd5b83356128b6816125a8565b925060208401356128c6816125a8565b929592945050506040919091013590565b600080604083850312156128ea57600080fd5b50508035926020909101359150565b6000806040838503121561290c57600080fd5b82356001600160401b038082111561292357600080fd5b61292f868387016127e5565b935060209150818501358181111561294657600080fd5b85019050601f8101861361295957600080fd5b8035612967612806826127c2565b81815260059190911b8201830190838101908883111561298657600080fd5b928401925b828410156129ad57833561299e816125a8565b8252928401929084019061298b565b80955050505050509250929050565b600080602083850312156129cf57600080fd5b82356001600160401b03808211156129e657600080fd5b818501915085601f8301126129fa57600080fd5b813581811115612a0957600080fd5b8660208260051b8501011115612a1e57600080fd5b60209290920196919550909350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b818110156112b957612a9b838551612a30565b9284019260809290920191600101612a88565b600060208284031215612ac057600080fd5b8135611454816125a8565b600081518084526020808501945080840160005b83811015612afb57815187529582019590820190600101612adf565b509495945050505050565b6020815260006114546020830184612acb565b600080600060608486031215612b2e57600080fd5b8335612b39816125a8565b95602085013595506040909401359392505050565b60008060408385031215612b6157600080fd5b8235612b6c816125a8565b915060208301356125f781612797565b600060208284031215612b8e57600080fd5b81356001600160401b03811115612ba457600080fd5b612370848285016127e5565b60008060008060808587031215612bc657600080fd5b8435612bd1816125a8565b93506020850135612be1816125a8565b92506040850135915060608501356001600160401b03811115612c0357600080fd5b8501601f81018713612c1457600080fd5b612c23878235602084016126f8565b91505092959194509250565b6080810161083b8284612a30565b60008060408385031215612c5057600080fd5b8235612c5b816125a8565b915060208301356125f7816125a8565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c90821680612cb457607f821691505b602082108103612cd457634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215612cec57600080fd5b815161145481612797565b634e487b7160e01b600052601160045260246000fd5b60008219821115612d2057612d20612cf7565b500190565b6020808252601490820152734d617820737570706c792065786365656465642160601b604082015260600190565b6000816000190483118215151615612d6d57612d6d612cf7565b500290565b600082612d8f57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600060018201612dbc57612dbc612cf7565b5060010190565b600060208284031215612dd557600080fd5b8151611454816125a8565b60008351612df2818460208801612602565b835190830190612e06818360208801612602565b01949350505050565b6001600160a01b0385168152608060208201819052600090612e3390830186612acb565b6040830194909452506060015292915050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612e799083018461262e565b9695505050505050565b600060208284031215612e9557600080fd5b81516114548161257556fea26469706673582212205cc93d9c6f3b565ddfaed3f1680bf7d7cc08c326f2952a35bc1cc516b457546f64736f6c634300080d0033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000005e90ae496c133b2c22286767a20907b8fed8818000000000000000000000000e80f06f7ceb7f295643f1e83418d21f53c94fcd2000000000000000000000000000000000000000000000000000000000000002d687474703a2f2f6170692e776861746973796f7572646174652e78797a2f6d657461646174612f616d6265722f00000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102725760003560e01c80636352211e1161014f57806395d89b41116100c1578063b88d4fde1161007a578063b88d4fde14610742578063c23dc68f14610755578063c87b56dd14610782578063d5abeb01146107a2578063e985e9c5146107b8578063f2fde38b1461080157600080fd5b806395d89b411461069a57806399a2557a146106af578063a0712d68146106cf578063a22cb465146106e2578063a583542414610702578063b071401b1461072257600080fd5b8063715018a611610113578063715018a6146105ef5780637b61c320146106045780637ec4a659146106195780638462151c146106395780638da5cb5b1461066657806394354fd01461068457600080fd5b80636352211e1461055b5780636c02a9311461057b5780636caede3d146105905780636f8b44b0146105af57806370a08231146105cf57600080fd5b80632a55205a116101e857806342842e0e116101ac57806342842e0e1461049c57806344a0d68a146104af5780635bbb2177146104cf5780635c975abb146104fc5780635ffa777d1461051657806362b99ad41461054657600080fd5b80632a55205a146103f05780632a8255691461042f5780632eb4a7ab1461044f5780633ccfd60b1461046557806341f434341461047a57600080fd5b806313faede61161023a57806313faede61461033b57806316ba10e01461035f57806316c38b3c1461037f57806316da55c41461039f57806318160ddd146103bf57806323b872dd146103dd57600080fd5b806301ffc9a71461027757806302fa7c47146102ac57806306fdde03146102ce578063081812fc146102f0578063095ea7b314610328575b600080fd5b34801561028357600080fd5b5061029761029236600461258b565b610821565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102cc6102c73660046125bd565b610841565b005b3480156102da57600080fd5b506102e3610882565b6040516102a3919061265a565b3480156102fc57600080fd5b5061031061030b36600461266d565b610914565b6040516001600160a01b0390911681526020016102a3565b6102cc610336366004612686565b610958565b34801561034757600080fd5b5061035160105481565b6040519081526020016102a3565b34801561036b57600080fd5b506102cc61037a36600461274f565b610a21565b34801561038b57600080fd5b506102cc61039a3660046127a5565b610a5e565b3480156103ab57600080fd5b506102cc6103ba366004612850565b610a9b565b3480156103cb57600080fd5b50610351600154600054036000190190565b6102cc6103eb366004612896565b610b0d565b3480156103fc57600080fd5b5061041061040b3660046128d7565b610be6565b604080516001600160a01b0390931683526020830191909152016102a3565b34801561043b57600080fd5b506102cc61044a3660046128f9565b610c92565b34801561045b57600080fd5b5061035160115481565b34801561047157600080fd5b506102cc610d58565b34801561048657600080fd5b506103106daaeb6d7670e522a718067333cd4e81565b6102cc6104aa366004612896565b610e52565b3480156104bb57600080fd5b506102cc6104ca36600461266d565b610f20565b3480156104db57600080fd5b506104ef6104ea3660046129bc565b610f4f565b6040516102a39190612a6c565b34801561050857600080fd5b506014546102979060ff1681565b34801561052257600080fd5b5061029761053136600461266d565b600c6020526000908152604090205460ff1681565b34801561055257600080fd5b506102e361101a565b34801561056757600080fd5b5061031061057636600461266d565b6110a8565b34801561058757600080fd5b506102e36110b3565b34801561059c57600080fd5b5060145461029790610100900460ff1681565b3480156105bb57600080fd5b506102cc6105ca36600461266d565b6110c0565b3480156105db57600080fd5b506103516105ea366004612aae565b6110ef565b3480156105fb57600080fd5b506102cc61113d565b34801561061057600080fd5b506102e3611173565b34801561062557600080fd5b506102cc61063436600461274f565b611180565b34801561064557600080fd5b50610659610654366004612aae565b6111bd565b6040516102a39190612b06565b34801561067257600080fd5b506008546001600160a01b0316610310565b34801561069057600080fd5b50610351600f5481565b3480156106a657600080fd5b506102e36112c5565b3480156106bb57600080fd5b506106596106ca366004612b19565b6112d4565b6102cc6106dd36600461266d565b61145b565b3480156106ee57600080fd5b506102cc6106fd366004612b4e565b611739565b34801561070e57600080fd5b506102cc61071d366004612b7c565b6117fd565b34801561072e57600080fd5b506102cc61073d36600461266d565b611872565b6102cc610750366004612bb0565b6118a1565b34801561076157600080fd5b5061077561077036600461266d565b61197d565b6040516102a39190612c2f565b34801561078e57600080fd5b506102e361079d36600461266d565b611a05565b3480156107ae57600080fd5b50610351600e5481565b3480156107c457600080fd5b506102976107d3366004612c3d565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561080d57600080fd5b506102cc61081c366004612aae565b611a88565b600061082c82611b20565b8061083b575061083b82611b6e565b92915050565b6008546001600160a01b031633146108745760405162461bcd60e51b815260040161086b90612c6b565b60405180910390fd5b61087e8282611ba3565b5050565b60606002805461089190612ca0565b80601f01602080910402602001604051908101604052809291908181526020018280546108bd90612ca0565b801561090a5780601f106108df5761010080835404028352916020019161090a565b820191906000526020600020905b8154815290600101906020018083116108ed57829003601f168201915b5050505050905090565b600061091f82611ca0565b61093c576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b816daaeb6d7670e522a718067333cd4e3b15610a1257604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156109c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ea9190612cda565b610a1257604051633b79c77360e21b81526001600160a01b038216600482015260240161086b565b610a1c8383611cd5565b505050565b6008546001600160a01b03163314610a4b5760405162461bcd60e51b815260040161086b90612c6b565b805161087e9060169060208401906124dc565b6008546001600160a01b03163314610a885760405162461bcd60e51b815260040161086b90612c6b565b6014805460ff1916911515919091179055565b6008546001600160a01b03163314610ac55760405162461bcd60e51b815260040161086b90612c6b565b600e548251610adb600154600054036000190190565b610ae59190612d0d565b1115610b035760405162461bcd60e51b815260040161086b90612d25565b61087e8183611ce1565b826daaeb6d7670e522a718067333cd4e3b15610bd557336001600160a01b03821603610b4357610b3e848484611d33565b610be0565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015610b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb69190612cda565b610bd557604051633b79c77360e21b815233600482015260240161086b565b610be0848484611d33565b50505050565b6000828152600b602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610c5b575060408051808201909152600a546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610c7a906001600160601b031687612d53565b610c849190612d72565b915196919550909350505050565b6008546001600160a01b03163314610cbc5760405162461bcd60e51b815260040161086b90612c6b565b6040805160018082528183019092526000916020808301908036833701905050905060005b8351811015610be057838181518110610cfc57610cfc612d94565b602002602001015182600081518110610d1757610d17612d94565b602002602001018181525050610d4682848381518110610d3957610d39612d94565b6020026020010151610a9b565b80610d5081612daa565b915050610ce1565b6008546001600160a01b03163314610d825760405162461bcd60e51b815260040161086b90612c6b565b600260095403610dd45760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161086b565b60026009556000610ded6008546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610e37576040519150601f19603f3d011682016040523d82523d6000602084013e610e3c565b606091505b5050905080610e4a57600080fd5b506001600955565b826daaeb6d7670e522a718067333cd4e3b15610f1557336001600160a01b03821603610e8357610b3e848484611ecb565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015610ed2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef69190612cda565b610f1557604051633b79c77360e21b815233600482015260240161086b565b610be0848484611ecb565b6008546001600160a01b03163314610f4a5760405162461bcd60e51b815260040161086b90612c6b565b601055565b6060816000816001600160401b03811115610f6c57610f6c6126b2565b604051908082528060200260200182016040528015610fbe57816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610f8a5790505b50905060005b82811461101157610fec868683818110610fe057610fe0612d94565b9050602002013561197d565b828281518110610ffe57610ffe612d94565b6020908102919091010152600101610fc4565b50949350505050565b600d805461102790612ca0565b80601f016020809104026020016040519081016040528092919081815260200182805461105390612ca0565b80156110a05780601f10611075576101008083540402835291602001916110a0565b820191906000526020600020905b81548152906001019060200180831161108357829003601f168201915b505050505081565b600061083b82611ee6565b6012805461102790612ca0565b6008546001600160a01b031633146110ea5760405162461bcd60e51b815260040161086b90612c6b565b600e55565b60006001600160a01b038216611118576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b031633146111675760405162461bcd60e51b815260040161086b90612c6b565b6111716000611f72565b565b6013805461102790612ca0565b6008546001600160a01b031633146111aa5760405162461bcd60e51b815260040161086b90612c6b565b805161087e90600d9060208401906124dc565b606060008060006111cd856110ef565b90506000816001600160401b038111156111e9576111e96126b2565b604051908082528060200260200182016040528015611212578160200160208202803683370190505b50905061123f60408051608081018252600080825260208201819052918101829052606081019190915290565b60015b8386146112b95761125281611fc4565b915081604001516112b15781516001600160a01b03161561127257815194505b876001600160a01b0316856001600160a01b0316036112b157808387806001019850815181106112a4576112a4612d94565b6020026020010181815250505b600101611242565b50909695505050505050565b60606003805461089190612ca0565b60608183106112f657604051631960ccad60e11b815260040160405180910390fd5b60008061130260005490565b9050600185101561131257600194505b8084111561131e578093505b6000611329876110ef565b9050848610156113485785850381811015611342578091505b5061134c565b5060005b6000816001600160401b03811115611366576113666126b2565b60405190808252806020026020018201604052801561138f578160200160208202803683370190505b509050816000036113a557935061145492505050565b60006113b08861197d565b9050600081604001516113c1575080515b885b8881141580156113d35750848714155b15611448576113e181611fc4565b925082604001516114405782516001600160a01b03161561140157825191505b8a6001600160a01b0316826001600160a01b031603611440578084888060010199508151811061143357611433612d94565b6020026020010181815250505b6001016113c3565b50505092835250909150505b9392505050565b6001600f548111156114a65760405162461bcd60e51b8152602060048201526014602482015273496e76616c6964206d696e7420616d6f756e742160601b604482015260640161086b565b600e54816114bb600154600054036000190190565b6114c59190612d0d565b11156114e35760405162461bcd60e51b815260040161086b90612d25565b6001806010546114f39190612d53565b3410156115385760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742066756e64732160681b604482015260640161086b565b60145460ff161561158b5760405162461bcd60e51b815260206004820152601760248201527f54686520636f6e74726163742069732070617573656421000000000000000000604482015260640161086b565b6000838152600c602052604090205460ff16156115e35760405162461bcd60e51b8152602060048201526016602482015275546f6b656e20616c726561647920636c61696d65642160501b604482015260640161086b565b6014546040516331a9108f60e11b8152600481018590526000916201000090046001600160a01b031690636352211e90602401602060405180830381865afa158015611633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116579190612dc3565b90506001600160a01b03811633146116b15760405162461bcd60e51b815260206004820152601860248201527f4d75737420626520616e206f776e657220746f206d696e740000000000000000604482015260640161086b565b6116bb3385612000565b6000848152600c602052604090819020805460ff191660011790556015549051630ae169a560e41b8152600481018690526001600160a01b039091169063ae169a5090602401600060405180830381600087803b15801561171b57600080fd5b505af115801561172f573d6000803e3d6000fd5b5050505050505050565b816daaeb6d7670e522a718067333cd4e3b156117f357604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa1580156117a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cb9190612cda565b6117f357604051633b79c77360e21b81526001600160a01b038216600482015260240161086b565b610a1c838361204c565b6008546001600160a01b031633146118275760405162461bcd60e51b815260040161086b90612c6b565b600e54815161183d600154600054036000190190565b6118479190612d0d565b11156118655760405162461bcd60e51b815260040161086b90612d25565b61186f3382611ce1565b50565b6008546001600160a01b0316331461189c5760405162461bcd60e51b815260040161086b90612c6b565b600f55565b836daaeb6d7670e522a718067333cd4e3b1561196a57336001600160a01b038216036118d8576118d3858585856120b8565b611976565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611927573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194b9190612cda565b61196a57604051633b79c77360e21b815233600482015260240161086b565b611976858585856120b8565b5050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260018310806119d657506000548310155b156119e15792915050565b6119ea83611fc4565b90508060400151156119fc5792915050565b611454836120fc565b6060611a1082611ca0565b611a2d57604051630a14c4b560e41b815260040160405180910390fd5b6000611a37612131565b90508051600003611a575760405180602001604052806000815250611454565b80611a6184612140565b604051602001611a72929190612de0565b6040516020818303038152906040529392505050565b6008546001600160a01b03163314611ab25760405162461bcd60e51b815260040161086b90612c6b565b6001600160a01b038116611b175760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161086b565b61186f81611f72565b60006301ffc9a760e01b6001600160e01b031983161480611b5157506380ac58cd60e01b6001600160e01b03198316145b8061083b5750506001600160e01b031916635b5e139f60e01b1490565b60006001600160e01b0319821663152a902d60e11b148061083b57506301ffc9a760e01b6001600160e01b031983161461083b565b6127106001600160601b0382161115611c115760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b606482015260840161086b565b6001600160a01b038216611c675760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640161086b565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600a55565b600081600111158015611cb4575060005482105b801561083b575050600090815260046020526040902054600160e01b161590565b61087e82826001612184565b6000548151611cf0848261222b565b7f102e9d07c211550df36fe13636ecaa163325a38a6c48d8de1a7b6070601b215784848484604051611d259493929190612e0f565b60405180910390a150505050565b6000611d3e82611ee6565b9050836001600160a01b0316816001600160a01b031614611d715760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417611dbe57611da186336107d3565b611dbe57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516611de557604051633a954ecd60e21b815260040160405180910390fd5b8015611df057600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003611e8257600184016000818152600460205260408120549003611e80576000548114611e805760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b610a1c838383604051806020016040528060008152506118a1565b600081600111611f59575060008181526004602052604081205490600160e01b82169003611f595780600003611f54576000548210611f3857604051636f96cda160e11b815260040160405180910390fd5b5b50600019016000818152600460205260409020548015611f39575b919050565b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60408051608081018252600080825260208201819052918101829052606081019190915260008281526004602052604090205461083b90612245565b60408051600180825281830190925260009160208083019080368337019050509050818160008151811061203657612036612d94565b602002602001018181525050610a1c8382611ce1565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6120c3848484610b0d565b6001600160a01b0383163b15610be0576120df8484848461228c565b610be0576040516368d2bf6b60e11b815260040160405180910390fd5b60408051608081018252600080825260208201819052918101829052606081019190915261083b61212c83611ee6565b612245565b6060600d805461089190612ca0565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061215a5750819003601f19909101908152919050565b600061218f836110a8565b905081156121ce57336001600160a01b038216146121ce576121b181336107d3565b6121ce576040516367d9dca160e11b815260040160405180910390fd5b60008381526006602052604080822080546001600160a01b0319166001600160a01b0388811691821790925591518693918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b61087e828260405180602001604052806000815250612378565b604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906122c1903390899088908890600401612e46565b6020604051808303816000875af19250505080156122fc575060408051601f3d908101601f191682019092526122f991810190612e83565b60015b61235a573d80801561232a576040519150601f19603f3d011682016040523d82523d6000602084013e61232f565b606091505b508051600003612352576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b61238283836123de565b6001600160a01b0383163b15610a1c576000548281035b6123ac600086838060010194508661228c565b6123c9576040516368d2bf6b60e11b815260040160405180910390fd5b81811061239957816000541461197657600080fd5b60008054908290036124035760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b8181146124b257808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460010161247a565b50816000036124d357604051622e076360e81b815260040160405180910390fd5b60005550505050565b8280546124e890612ca0565b90600052602060002090601f01602090048101928261250a5760008555612550565b82601f1061252357805160ff1916838001178555612550565b82800160010185558215612550579182015b82811115612550578251825591602001919060010190612535565b5061255c929150612560565b5090565b5b8082111561255c5760008155600101612561565b6001600160e01b03198116811461186f57600080fd5b60006020828403121561259d57600080fd5b813561145481612575565b6001600160a01b038116811461186f57600080fd5b600080604083850312156125d057600080fd5b82356125db816125a8565b915060208301356001600160601b03811681146125f757600080fd5b809150509250929050565b60005b8381101561261d578181015183820152602001612605565b83811115610be05750506000910152565b60008151808452612646816020860160208601612602565b601f01601f19169290920160200192915050565b602081526000611454602083018461262e565b60006020828403121561267f57600080fd5b5035919050565b6000806040838503121561269957600080fd5b82356126a4816125a8565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156126f0576126f06126b2565b604052919050565b60006001600160401b03831115612711576127116126b2565b612724601f8401601f19166020016126c8565b905082815283838301111561273857600080fd5b828260208301376000602084830101529392505050565b60006020828403121561276157600080fd5b81356001600160401b0381111561277757600080fd5b8201601f8101841361278857600080fd5b612370848235602084016126f8565b801515811461186f57600080fd5b6000602082840312156127b757600080fd5b813561145481612797565b60006001600160401b038211156127db576127db6126b2565b5060051b60200190565b600082601f8301126127f657600080fd5b8135602061280b612806836127c2565b6126c8565b82815260059290921b8401810191818101908684111561282a57600080fd5b8286015b84811015612845578035835291830191830161282e565b509695505050505050565b6000806040838503121561286357600080fd5b82356001600160401b0381111561287957600080fd5b612885858286016127e5565b92505060208301356125f7816125a8565b6000806000606084860312156128ab57600080fd5b83356128b6816125a8565b925060208401356128c6816125a8565b929592945050506040919091013590565b600080604083850312156128ea57600080fd5b50508035926020909101359150565b6000806040838503121561290c57600080fd5b82356001600160401b038082111561292357600080fd5b61292f868387016127e5565b935060209150818501358181111561294657600080fd5b85019050601f8101861361295957600080fd5b8035612967612806826127c2565b81815260059190911b8201830190838101908883111561298657600080fd5b928401925b828410156129ad57833561299e816125a8565b8252928401929084019061298b565b80955050505050509250929050565b600080602083850312156129cf57600080fd5b82356001600160401b03808211156129e657600080fd5b818501915085601f8301126129fa57600080fd5b813581811115612a0957600080fd5b8660208260051b8501011115612a1e57600080fd5b60209290920196919550909350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b818110156112b957612a9b838551612a30565b9284019260809290920191600101612a88565b600060208284031215612ac057600080fd5b8135611454816125a8565b600081518084526020808501945080840160005b83811015612afb57815187529582019590820190600101612adf565b509495945050505050565b6020815260006114546020830184612acb565b600080600060608486031215612b2e57600080fd5b8335612b39816125a8565b95602085013595506040909401359392505050565b60008060408385031215612b6157600080fd5b8235612b6c816125a8565b915060208301356125f781612797565b600060208284031215612b8e57600080fd5b81356001600160401b03811115612ba457600080fd5b612370848285016127e5565b60008060008060808587031215612bc657600080fd5b8435612bd1816125a8565b93506020850135612be1816125a8565b92506040850135915060608501356001600160401b03811115612c0357600080fd5b8501601f81018713612c1457600080fd5b612c23878235602084016126f8565b91505092959194509250565b6080810161083b8284612a30565b60008060408385031215612c5057600080fd5b8235612c5b816125a8565b915060208301356125f7816125a8565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c90821680612cb457607f821691505b602082108103612cd457634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215612cec57600080fd5b815161145481612797565b634e487b7160e01b600052601160045260246000fd5b60008219821115612d2057612d20612cf7565b500190565b6020808252601490820152734d617820737570706c792065786365656465642160601b604082015260600190565b6000816000190483118215151615612d6d57612d6d612cf7565b500290565b600082612d8f57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600060018201612dbc57612dbc612cf7565b5060010190565b600060208284031215612dd557600080fd5b8151611454816125a8565b60008351612df2818460208801612602565b835190830190612e06818360208801612602565b01949350505050565b6001600160a01b0385168152608060208201819052600090612e3390830186612acb565b6040830194909452506060015292915050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612e799083018461262e565b9695505050505050565b600060208284031215612e9557600080fd5b81516114548161257556fea26469706673582212205cc93d9c6f3b565ddfaed3f1680bf7d7cc08c326f2952a35bc1cc516b457546f64736f6c634300080d0033

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

000000000000000000000000000000000000000000000000000000000000006000000000000000000000000005e90ae496c133b2c22286767a20907b8fed8818000000000000000000000000e80f06f7ceb7f295643f1e83418d21f53c94fcd2000000000000000000000000000000000000000000000000000000000000002d687474703a2f2f6170692e776861746973796f7572646174652e78797a2f6d657461646174612f616d6265722f00000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : baseURI (string): http://api.whatisyourdate.xyz/metadata/amber/
Arg [1] : _saveTheDateContract (address): 0x05E90ae496C133B2c22286767a20907b8FEd8818
Arg [2] : _refundContract (address): 0xe80F06F7CeB7F295643F1e83418d21f53C94fCd2

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000005e90ae496c133b2c22286767a20907b8fed8818
Arg [2] : 000000000000000000000000e80f06f7ceb7f295643f1e83418d21f53c94fcd2
Arg [3] : 000000000000000000000000000000000000000000000000000000000000002d
Arg [4] : 687474703a2f2f6170692e776861746973796f7572646174652e78797a2f6d65
Arg [5] : 7461646174612f616d6265722f00000000000000000000000000000000000000


Deployed Bytecode Sourcemap

926:5425:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5099:219;;;;;;;;;;-1:-1:-1;5099:219:1;;;;;:::i;:::-;;:::i;:::-;;;565:14:22;;558:22;540:41;;528:2;513:18;5099:219:1;;;;;;;;4689:137;;;;;;;;;;-1:-1:-1;4689:137:1;;;;;:::i;:::-;;:::i;:::-;;10312:100:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16712:218::-;;;;;;;;;;-1:-1:-1;16712:218:6;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2292:32:22;;;2274:51;;2262:2;2247:18;16712:218:6;2128:203:22;5529:184:1;;;;;;:::i;:::-;;:::i;1341:29::-;;;;;;;;;;;;;;;;;;;2810:25:22;;;2798:2;2783:18;1341:29:1;2664:177:22;4420:100:1;;;;;;;;;;-1:-1:-1;4420:100:1;;;;;:::i;:::-;;:::i;4606:77::-;;;;;;;;;;-1:-1:-1;4606:77:1;;;;;:::i;:::-;;:::i;3457:214::-;;;;;;;;;;-1:-1:-1;3457:214:1;;;;;:::i;:::-;;:::i;6063:323:6:-;;;;;;;;;;;;4065:1:1;6337:12:6;6124:7;6321:13;:28;-1:-1:-1;;6321:46:6;;6063:323;5721:190:1;;;;;;:::i;:::-;;:::i;1674:442:5:-;;;;;;;;;;-1:-1:-1;1674:442:5;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;6768:32:22;;;6750:51;;6832:2;6817:18;;6810:34;;;;6723:18;1674:442:5;6576:274:22;3677:294:1;;;;;;;;;;-1:-1:-1;3677:294:1;;;;;:::i;:::-;;:::i;1375:25::-;;;;;;;;;;;;;;;;4832:150;;;;;;;;;;;;;:::i;753:143:17:-;;;;;;;;;;;;853:42;753:143;;5919:198:1;;;;;;:::i;:::-;;:::i;4526:74::-;;;;;;;;;;-1:-1:-1;4526:74:1;;;;;:::i;:::-;;:::i;1695:528:7:-;;;;;;;;;;-1:-1:-1;1695:528:7;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1513:25:1:-;;;;;;;;;;-1:-1:-1;1513:25:1;;;;;;;;1177:47;;;;;;;;;;-1:-1:-1;1177:47:1;;;;;:::i;:::-;;;;;;;;;;;;;;;;1229:28;;;;;;;;;;;;;:::i;11705:152:6:-;;;;;;;;;;-1:-1:-1;11705:152:6;;;;;:::i;:::-;;:::i;1407:59:1:-;;;;;;;;;;;;;:::i;1543:40::-;;;;;;;;;;-1:-1:-1;1543:40:1;;;;;;;;;;;4078:94;;;;;;;;;;-1:-1:-1;4078:94:1;;;;;:::i;:::-;;:::i;7247:233:6:-;;;;;;;;;;-1:-1:-1;7247:233:6;;;;;:::i;:::-;;:::i;1714:103:18:-;;;;;;;;;;;;;:::i;1471:37:1:-;;;;;;;;;;;;;:::i;4314:100::-;;;;;;;;;;-1:-1:-1;4314:100:1;;;;;:::i;:::-;;:::i;5571:900:7:-;;;;;;;;;;-1:-1:-1;5571:900:7;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1063:87:18:-;;;;;;;;;;-1:-1:-1;1136:6:18;;-1:-1:-1;;;;;1136:6:18;1063:87;;1299:37:1;;;;;;;;;;;;;;;;10488:104:6;;;;;;;;;;;;;:::i;2611:2513:7:-;;;;;;;;;;-1:-1:-1;2611:2513:7;;;;;:::i;:::-;;:::i;2370:446:1:-;;;;;;:::i;:::-;;:::i;5326:195::-;;;;;;;;;;-1:-1:-1;5326:195:1;;;;;:::i;:::-;;:::i;3249:199::-;;;;;;;;;;-1:-1:-1;3249:199:1;;;;;:::i;:::-;;:::i;4178:130::-;;;;;;;;;;-1:-1:-1;4178:130:1;;;;;:::i;:::-;;:::i;6125:223::-;;;;;;:::i;:::-;;:::i;1108:428:7:-;;;;;;;;;;-1:-1:-1;1108:428:7;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;10698:318:6:-;;;;;;;;;;-1:-1:-1;10698:318:6;;;;;:::i;:::-;;:::i;1262:32:1:-;;;;;;;;;;;;;;;;17661:164:6;;;;;;;;;;-1:-1:-1;17661:164:6;;;;;:::i;:::-;-1:-1:-1;;;;;17782:25:6;;;17758:4;17782:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;17661:164;1972:201:18;;;;;;;;;;-1:-1:-1;1972:201:18;;;;;:::i;:::-;;:::i;5099:219:1:-;5212:4;5232:38;5258:11;5232:25;:38::i;:::-;:80;;;;5274:38;5300:11;5274:25;:38::i;:::-;5225:87;5099:219;-1:-1:-1;;5099:219:1:o;4689:137::-;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;;;;;;;;;4781:39:1::1;4800:8;4810:9;4781:18;:39::i;:::-;4689:137:::0;;:::o;10312:100:6:-;10366:13;10399:5;10392:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10312:100;:::o;16712:218::-;16788:7;16813:16;16821:7;16813;:16::i;:::-;16808:64;;16838:34;;-1:-1:-1;;;16838:34:6;;;;;;;;;;;16808:64;-1:-1:-1;16892:24:6;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;16892:30:6;;16712:218::o;5529:184:1:-;5652:8;853:42:17;2747:45;:49;2743:225;;2818:67;;-1:-1:-1;;;2818:67:17;;2869:4;2818:67;;;14772:34:22;-1:-1:-1;;;;;14842:15:22;;14822:18;;;14815:43;853:42:17;;2818;;14707:18:22;;2818:67:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2813:144;;2913:28;;-1:-1:-1;;;2913:28:17;;-1:-1:-1;;;;;2292:32:22;;2913:28:17;;;2274:51:22;2247:18;;2913:28:17;2128:203:22;2813:144:17;5673:32:1::1;5687:8;5697:7;5673:13;:32::i;:::-;5529:184:::0;;;:::o;4420:100::-;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;4492:22:1;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;4606:77::-:0;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;4662:6:1::1;:15:::0;;-1:-1:-1;;4662:15:1::1;::::0;::::1;;::::0;;;::::1;::::0;;4606:77::o;3457:214::-;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;3592:9:1::1;;3574:7;:14;3558:13;4065:1:::0;6337:12:6;6124:7;6321:13;:28;-1:-1:-1;;6321:46:6;;6063:323;3558:13:1::1;:30;;;;:::i;:::-;:43;;3550:76;;;;-1:-1:-1::0;;;3550:76:1::1;;;;;;;:::i;:::-;3633:32;3646:9;3657:7;3633:12;:32::i;5721:190::-:0;5849:4;853:42:17;2001:45;:49;1997:539;;2290:10;-1:-1:-1;;;;;2282:18:17;;;2278:85;;5866:37:1::1;5885:4;5891:2;5895:7;5866:18;:37::i;:::-;2341:7:17::0;;2278:85;2382:69;;-1:-1:-1;;;2382:69:17;;2433:4;2382:69;;;14772:34:22;2440:10:17;14822:18:22;;;14815:43;853:42:17;;2382;;14707:18:22;;2382:69:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2377:148;;2479:30;;-1:-1:-1;;;2479:30:17;;2498:10;2479:30;;;2274:51:22;2247:18;;2479:30:17;2128:203:22;2377:148:17;5866:37:1::1;5885:4;5891:2;5895:7;5866:18;:37::i;:::-;5721:190:::0;;;;:::o;1674:442:5:-;1771:7;1829:27;;;:17;:27;;;;;;;;1800:56;;;;;;;;;-1:-1:-1;;;;;1800:56:5;;;;;-1:-1:-1;;;1800:56:5;;;-1:-1:-1;;;;;1800:56:5;;;;;;;;1771:7;;1869:92;;-1:-1:-1;1920:29:5;;;;;;;;;1930:19;1920:29;-1:-1:-1;;;;;1920:29:5;;;;-1:-1:-1;;;1920:29:5;;-1:-1:-1;;;;;1920:29:5;;;;;1869:92;2011:23;;;;1973:21;;2482:5;;1998:36;;-1:-1:-1;;;;;1998:36:5;:10;:36;:::i;:::-;1997:58;;;;:::i;:::-;2076:16;;;;;-1:-1:-1;1674:442:5;;-1:-1:-1;;;;1674:442:5:o;3677:294:1:-;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;3805:16:1::1;::::0;;3819:1:::1;3805:16:::0;;;;;::::1;::::0;;;3782:20:::1;::::0;3805:16:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;3805:16:1::1;3782:39;;3833:6;3828:121;3849:7;:14;3845:1;:18;3828:121;;;3888:7;3896:1;3888:10;;;;;;;;:::i;:::-;;;;;;;3879:3;3883:1;3879:6;;;;;;;;:::i;:::-;;;;;;:19;;;::::0;::::1;3907:34;3922:3;3927:10;3938:1;3927:13;;;;;;;;:::i;:::-;;;;;;;3907:14;:34::i;:::-;3865:3:::0;::::1;::::0;::::1;:::i;:::-;;;;3828:121;;4832:150:::0;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;1778:1:19::1;2376:7;;:19:::0;2368:63:::1;;;::::0;-1:-1:-1;;;2368:63:19;;16602:2:22;2368:63:19::1;::::0;::::1;16584:21:22::0;16641:2;16621:18;;;16614:30;16680:33;16660:18;;;16653:61;16731:18;;2368:63:19::1;16400:355:22::0;2368:63:19::1;1778:1;2509:7;:18:::0;4890:7:1::2;4911;1136:6:18::0;;-1:-1:-1;;;;;1136:6:18;;1063:87;4911:7:1::2;-1:-1:-1::0;;;;;4903:21:1::2;4932;4903:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4889:69;;;4973:2;4965:11;;;::::0;::::2;;-1:-1:-1::0;1734:1:19::1;2688:7;:22:::0;4832:150:1:o;5919:198::-;6051:4;853:42:17;2001:45;:49;1997:539;;2290:10;-1:-1:-1;;;;;2282:18:17;;;2278:85;;6068:41:1::1;6091:4;6097:2;6101:7;6068:22;:41::i;2278:85:17:-:0;2382:69;;-1:-1:-1;;;2382:69:17;;2433:4;2382:69;;;14772:34:22;2440:10:17;14822:18:22;;;14815:43;853:42:17;;2382;;14707:18:22;;2382:69:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2377:148;;2479:30;;-1:-1:-1;;;2479:30:17;;2498:10;2479:30;;;2274:51:22;2247:18;;2479:30:17;2128:203:22;2377:148:17;6068:41:1::1;6091:4;6097:2;6101:7;6068:22;:41::i;4526:74::-:0;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;4582:4:1::1;:12:::0;4526:74::o;1695:528:7:-;1839:23;1930:8;1905:22;1930:8;-1:-1:-1;;;;;1997:36:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1997:36:7;;-1:-1:-1;;1997:36:7;;;;;;;;;;;;1960:73;;2053:9;2048:125;2069:14;2064:1;:19;2048:125;;2125:32;2145:8;;2154:1;2145:11;;;;;;;:::i;:::-;;;;;;;2125:19;:32::i;:::-;2109:10;2120:1;2109:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;2085:3;;2048:125;;;-1:-1:-1;2194:10:7;1695:528;-1:-1:-1;;;;1695:528:7:o;1229:28:1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;11705:152:6:-;11777:7;11820:27;11839:7;11820:18;:27::i;1407:59:1:-;;;;;;;:::i;4078:94::-;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;4144:9:1::1;:22:::0;4078:94::o;7247:233:6:-;7319:7;-1:-1:-1;;;;;7343:19:6;;7339:60;;7371:28;;-1:-1:-1;;;7371:28:6;;;;;;;;;;;7339:60;-1:-1:-1;;;;;;7417:25:6;;;;;:18;:25;;;;;;-1:-1:-1;;;;;7417:55:6;;7247:233::o;1714:103:18:-;1136:6;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;1779:30:::1;1806:1;1779:18;:30::i;:::-;1714:103::o:0;1471:37:1:-;;;;;;;:::i;4314:100::-;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;4386:22:1;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;5571:900:7:-:0;5649:16;5703:19;5737:25;5777:22;5802:16;5812:5;5802:9;:16::i;:::-;5777:41;;5833:25;5875:14;-1:-1:-1;;;;;5861:29:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5861:29:7;;5833:57;;5905:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5905:31:7;4065:1:1;5951:472:7;6000:14;5985:11;:29;5951:472;;6052:15;6065:1;6052:12;:15::i;:::-;6040:27;;6090:9;:16;;;6131:8;6086:73;6181:14;;-1:-1:-1;;;;;6181:28:7;;6177:111;;6254:14;;;-1:-1:-1;6177:111:7;6331:5;-1:-1:-1;;;;;6310:26:7;:17;-1:-1:-1;;;;;6310:26:7;;6306:102;;6387:1;6361:8;6370:13;;;;;;6361:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;6306:102;6016:3;;5951:472;;;-1:-1:-1;6444:8:7;;5571:900;-1:-1:-1;;;;;;5571:900:7:o;10488:104:6:-;10544:13;10577:7;10570:14;;;;;:::i;2611:2513:7:-;2754:16;2821:4;2812:5;:13;2808:45;;2834:19;;-1:-1:-1;;;2834:19:7;;;;;;;;;;;2808:45;2868:19;2902:17;2922:14;5805:7:6;5832:13;;5750:103;2922:14:7;2902:34;-1:-1:-1;4065:1:1;3014:5:7;:23;3010:87;;;4065:1:1;3058:23:7;;3010:87;3173:9;3166:4;:16;3162:73;;;3210:9;3203:16;;3162:73;3249:25;3277:16;3287:5;3277:9;:16::i;:::-;3249:44;;3471:4;3463:5;:12;3459:278;;;3518:12;;;3553:31;;;3549:111;;;3629:11;3609:31;;3549:111;3477:198;3459:278;;;-1:-1:-1;3720:1:7;3459:278;3751:25;3793:17;-1:-1:-1;;;;;3779:32:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3779:32:7;;3751:60;;3830:17;3851:1;3830:22;3826:78;;3880:8;-1:-1:-1;3873:15:7;;-1:-1:-1;;;3873:15:7;3826:78;4048:31;4082:26;4102:5;4082:19;:26::i;:::-;4048:60;;4123:25;4368:9;:16;;;4363:92;;-1:-1:-1;4425:14:7;;4363:92;4486:5;4469:478;4498:4;4493:1;:9;;:45;;;;;4521:17;4506:11;:32;;4493:45;4469:478;;;4576:15;4589:1;4576:12;:15::i;:::-;4564:27;;4614:9;:16;;;4655:8;4610:73;4705:14;;-1:-1:-1;;;;;4705:28:7;;4701:111;;4778:14;;;-1:-1:-1;4701:111:7;4855:5;-1:-1:-1;;;;;4834:26:7;:17;-1:-1:-1;;;;;4834:26:7;;4830:102;;4911:1;4885:8;4894:13;;;;;;4885:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;4830:102;4540:3;;4469:478;;;-1:-1:-1;;;5032:29:7;;;-1:-1:-1;5039:8:7;;-1:-1:-1;;2611:2513:7;;;;;;:::o;2370:446:1:-;2430:1;2087:18;;2072:11;:33;;2045:85;;;;-1:-1:-1;;;2045:85:1;;17172:2:22;2045:85:1;;;17154:21:22;17211:2;17191:18;;;17184:30;-1:-1:-1;;;17230:18:22;;;17223:50;17290:18;;2045:85:1;16970:344:22;2045:85:1;2176:9;;2161:11;2145:13;4065:1;6337:12:6;6124:7;6321:13;:28;-1:-1:-1;;6321:46:6;;6063:323;2145:13:1;:27;;;;:::i;:::-;:40;;2137:73;;;;-1:-1:-1;;;2137:73:1;;;;;;;:::i;:::-;2453:1:::1;2315:11;2308:4;;:18;;;;:::i;:::-;2295:9;:31;;2287:63;;;::::0;-1:-1:-1;;;2287:63:1;;17521:2:22;2287:63:1::1;::::0;::::1;17503:21:22::0;17560:2;17540:18;;;17533:30;-1:-1:-1;;;17579:18:22;;;17572:49;17638:18;;2287:63:1::1;17319:343:22::0;2287:63:1::1;2472:6:::2;::::0;::::2;;2471:7;2463:43;;;::::0;-1:-1:-1;;;2463:43:1;;17869:2:22;2463:43:1::2;::::0;::::2;17851:21:22::0;17908:2;17888:18;;;17881:30;17947:25;17927:18;;;17920:53;17990:18;;2463:43:1::2;17667:347:22::0;2463:43:1::2;2522:23;::::0;;;:15:::2;:23;::::0;;;;;::::2;;2521:24;2513:59;;;::::0;-1:-1:-1;;;2513:59:1;;18221:2:22;2513:59:1::2;::::0;::::2;18203:21:22::0;18260:2;18240:18;;;18233:30;-1:-1:-1;;;18279:18:22;;;18272:52;18341:18;;2513:59:1::2;18019:346:22::0;2513:59:1::2;2596:19;::::0;:35:::2;::::0;-1:-1:-1;;;2596:35:1;;::::2;::::0;::::2;2810:25:22::0;;;2579:14:1::2;::::0;2596:19;;::::2;-1:-1:-1::0;;;;;2596:19:1::2;::::0;:27:::2;::::0;2783:18:22;;2596:35:1::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2579:52:::0;-1:-1:-1;;;;;;2646:20:1;::::2;2656:10;2646:20;2638:57;;;::::0;-1:-1:-1;;;2638:57:1;;18836:2:22;2638:57:1::2;::::0;::::2;18818:21:22::0;18875:2;18855:18;;;18848:30;18914:26;18894:18;;;18887:54;18958:18;;2638:57:1::2;18634:348:22::0;2638:57:1::2;2702:30;736:10:2::0;2725:6:1::2;2702:8;:30::i;:::-;2739:23;::::0;;;:15:::2;:23;::::0;;;;;;:30;;-1:-1:-1;;2739:30:1::2;2765:4;2739:30;::::0;;2776:14:::2;::::0;:34;;-1:-1:-1;;;2776:34:1;;::::2;::::0;::::2;2810:25:22::0;;;-1:-1:-1;;;;;2776:14:1;;::::2;::::0;:26:::2;::::0;2783:18:22;;2776:34:1::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;2456:360;2217:1:::1;2370:446:::0;;:::o;5326:195::-;5449:8;853:42:17;2747:45;:49;2743:225;;2818:67;;-1:-1:-1;;;2818:67:17;;2869:4;2818:67;;;14772:34:22;-1:-1:-1;;;;;14842:15:22;;14822:18;;;14815:43;853:42:17;;2818;;14707:18:22;;2818:67:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2813:144;;2913:28;;-1:-1:-1;;;2913:28:17;;-1:-1:-1;;;;;2292:32:22;;2913:28:17;;;2274:51:22;2247:18;;2913:28:17;2128:203:22;2813:144:17;5470:43:1::1;5494:8;5504;5470:23;:43::i;3249:199::-:0;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;3366:9:1::1;;3348:7;:14;3332:13;4065:1:::0;6337:12:6;6124:7;6321:13;:28;-1:-1:-1;;6321:46:6;;6063:323;3332:13:1::1;:30;;;;:::i;:::-;:43;;3324:76;;;;-1:-1:-1::0;;;3324:76:1::1;;;;;;;:::i;:::-;3407:35;736:10:2::0;3434:7:1::1;3407:12;:35::i;:::-;3249:199:::0;:::o;4178:130::-;1136:6:18;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;4262:18:1::1;:40:::0;4178:130::o;6125:223::-;6276:4;853:42:17;2001:45;:49;1997:539;;2290:10;-1:-1:-1;;;;;2282:18:17;;;2278:85;;6293:47:1::1;6316:4;6322:2;6326:7;6335:4;6293:22;:47::i;:::-;2341:7:17::0;;2278:85;2382:69;;-1:-1:-1;;;2382:69:17;;2433:4;2382:69;;;14772:34:22;2440:10:17;14822:18:22;;;14815:43;853:42:17;;2382;;14707:18:22;;2382:69:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2377:148;;2479:30;;-1:-1:-1;;;2479:30:17;;2498:10;2479:30;;;2274:51:22;2247:18;;2479:30:17;2128:203:22;2377:148:17;6293:47:1::1;6316:4;6322:2;6326:7;6335:4;6293:22;:47::i;:::-;6125:223:::0;;;;;:::o;1108:428:7:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4065:1:1;1272:7:7;:25;:54;;;-1:-1:-1;5805:7:6;5832:13;1301:7:7;:25;;1272:54;1268:103;;;1350:9;1108:428;-1:-1:-1;;1108:428:7:o;1268:103::-;1393:21;1406:7;1393:12;:21::i;:::-;1381:33;;1429:9;:16;;;1425:65;;;1469:9;1108:428;-1:-1:-1;;1108:428:7:o;1425:65::-;1507:21;1520:7;1507:12;:21::i;10698:318:6:-;10771:13;10802:16;10810:7;10802;:16::i;:::-;10797:59;;10827:29;;-1:-1:-1;;;10827:29:6;;;;;;;;;;;10797:59;10869:21;10893:10;:8;:10::i;:::-;10869:34;;10927:7;10921:21;10946:1;10921:26;:87;;;;;;;;;;;;;;;;;10974:7;10983:18;10993:7;10983:9;:18::i;:::-;10957:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10914:94;10698:318;-1:-1:-1;;;10698:318:6:o;1972:201:18:-;1136:6;;-1:-1:-1;;;;;1136:6:18;736:10:2;1283:23:18;1275:68;;;;-1:-1:-1;;;1275:68:18;;;;;;;:::i;:::-;-1:-1:-1;;;;;2061:22:18;::::1;2053:73;;;::::0;-1:-1:-1;;;2053:73:18;;19664:2:22;2053:73:18::1;::::0;::::1;19646:21:22::0;19703:2;19683:18;;;19676:30;19742:34;19722:18;;;19715:62;-1:-1:-1;;;19793:18:22;;;19786:36;19839:19;;2053:73:18::1;19462:402:22::0;2053:73:18::1;2137:28;2156:8;2137:18;:28::i;9410:639:6:-:0;9495:4;-1:-1:-1;;;;;;;;;9819:25:6;;;;:102;;-1:-1:-1;;;;;;;;;;9896:25:6;;;9819:102;:179;;;-1:-1:-1;;;;;;;;9973:25:6;-1:-1:-1;;;9973:25:6;;9410:639::o;1404:215:5:-;1506:4;-1:-1:-1;;;;;;1530:41:5;;-1:-1:-1;;;1530:41:5;;:81;;-1:-1:-1;;;;;;;;;;963:40:4;;;1575:36:5;854:157:4;2766:332:5;2482:5;-1:-1:-1;;;;;2869:33:5;;;;2861:88;;;;-1:-1:-1;;;2861:88:5;;20071:2:22;2861:88:5;;;20053:21:22;20110:2;20090:18;;;20083:30;20149:34;20129:18;;;20122:62;-1:-1:-1;;;20200:18:22;;;20193:40;20250:19;;2861:88:5;19869:406:22;2861:88:5;-1:-1:-1;;;;;2968:22:5;;2960:60;;;;-1:-1:-1;;;2960:60:5;;20482:2:22;2960:60:5;;;20464:21:22;20521:2;20501:18;;;20494:30;20560:27;20540:18;;;20533:55;20605:18;;2960:60:5;20280:349:22;2960:60:5;3055:35;;;;;;;;;-1:-1:-1;;;;;3055:35:5;;;;;;-1:-1:-1;;;;;3055:35:5;;;;;;;;;;-1:-1:-1;;;3033:57:5;;;;:19;:57;2766:332::o;18083:282:6:-;18148:4;18204:7;4065:1:1;18185:26:6;;:66;;;;;18238:13;;18228:7;:23;18185:66;:153;;;;-1:-1:-1;;18289:26:6;;;;:17;:26;;;;;;-1:-1:-1;;;18289:44:6;:49;;18083:282::o;16429:124::-;16518:27;16527:2;16531:7;16540:4;16518:8;:27::i;3002:242:1:-;3078:20;5832:13:6;3139:14:1;;3160:21;3170:2;3139:14;3160:9;:21::i;:::-;3193:45;3204:2;3208:7;3217:12;3231:6;3193:45;;;;;;;;;:::i;:::-;;;;;;;;3071:173;;3002:242;;:::o;20351:2825:6:-;20493:27;20523;20542:7;20523:18;:27::i;:::-;20493:57;;20608:4;-1:-1:-1;;;;;20567:45:6;20583:19;-1:-1:-1;;;;;20567:45:6;;20563:86;;20621:28;;-1:-1:-1;;;20621:28:6;;;;;;;;;;;20563:86;20663:27;19459:24;;;:15;:24;;;;;19687:26;;736:10:2;19084:30:6;;;-1:-1:-1;;;;;18777:28:6;;19062:20;;;19059:56;20849:180;;20942:43;20959:4;736:10:2;17661:164:6;:::i;20942:43::-;20937:92;;20994:35;;-1:-1:-1;;;20994:35:6;;;;;;;;;;;20937:92;-1:-1:-1;;;;;21046:16:6;;21042:52;;21071:23;;-1:-1:-1;;;21071:23:6;;;;;;;;;;;21042:52;21243:15;21240:160;;;21383:1;21362:19;21355:30;21240:160;-1:-1:-1;;;;;21780:24:6;;;;;;;:18;:24;;;;;;21778:26;;-1:-1:-1;;21778:26:6;;;21849:22;;;;;;;;;21847:24;;-1:-1:-1;21847:24:6;;;15531:11;15506:23;15502:41;15489:63;-1:-1:-1;;;15489:63:6;22142:26;;;;:17;:26;;;;;:175;;;;-1:-1:-1;;;22437:47:6;;:52;;22433:627;;22542:1;22532:11;;22510:19;22665:30;;;:17;:30;;;;;;:35;;22661:384;;22803:13;;22788:11;:28;22784:242;;22950:30;;;;:17;:30;;;;;:52;;;22784:242;22491:569;22433:627;23107:7;23103:2;-1:-1:-1;;;;;23088:27:6;23097:4;-1:-1:-1;;;;;23088:27:6;;;;;;;;;;;20482:2694;;;20351:2825;;;:::o;23272:193::-;23418:39;23435:4;23441:2;23445:7;23418:39;;;;;;;;;;;;:16;:39::i;12860:1712::-;12927:14;12977:7;4065:1:1;12958:26:6;12954:1562;;-1:-1:-1;13010:26:6;;;;:17;:26;;;;;;;-1:-1:-1;;;13086:24:6;;:29;;13082:1423;;13225:6;13235:1;13225:11;13221:981;;13276:13;;13265:7;:24;13261:68;;13298:31;;-1:-1:-1;;;13298:31:6;;;;;;;;;;;13261:68;13926:257;-1:-1:-1;;;14030:9:6;14012:28;;;;:17;:28;;;;;;14094:25;;13926:257;14094:25;;12860:1712;;;:::o;13082:1423::-;14533:31;;-1:-1:-1;;;14533:31:6;;;;;;;;;;;2333:191:18;2426:6;;;-1:-1:-1;;;;;2443:17:18;;;-1:-1:-1;;;;;;2443:17:18;;;;;;;2476:40;;2426:6;;;2443:17;2426:6;;2476:40;;2407:16;;2476:40;2396:128;2333:191;:::o;12308:161:6:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12436:24:6;;;;:17;:24;;;;;;12417:44;;:18;:44::i;2822:174:1:-;2907:16;;;2921:1;2907:16;;;;;;;;;2884:20;;2907:16;;;;;;;;;;;-1:-1:-1;2907:16:1;2884:39;;2939:6;2930:3;2934:1;2930:6;;;;;;;;:::i;:::-;;;;;;:15;;;;;2952:21;2965:2;2969:3;2952:12;:21::i;17270:234:6:-;736:10:2;17365:39:6;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;17365:49:6;;;;;;;;;;;;:60;;-1:-1:-1;;17365:60:6;;;;;;;;;;17441:55;;540:41:22;;;17365:49:6;;736:10:2;17441:55:6;;513:18:22;17441:55:6;;;;;;;17270:234;;:::o;24063:407::-;24238:31;24251:4;24257:2;24261:7;24238:12;:31::i;:::-;-1:-1:-1;;;;;24284:14:6;;;:19;24280:183;;24323:56;24354:4;24360:2;24364:7;24373:5;24323:30;:56::i;:::-;24318:145;;24407:40;;-1:-1:-1;;;24407:40:6;;;;;;;;;;;12046:166;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12157:47:6;12176:27;12195:7;12176:18;:27::i;:::-;12157:18;:47::i;4988:104:1:-;5048:13;5077:9;5070:16;;;;;:::i;41896:1745:6:-;41961:17;42395:4;42388;42382:11;42378:22;42487:1;42481:4;42474:15;42562:4;42559:1;42555:12;42548:19;;;42644:1;42639:3;42632:14;42748:3;42987:5;42969:428;43035:1;43030:3;43026:11;43019:18;;43206:2;43200:4;43196:13;43192:2;43188:22;43183:3;43175:36;43300:2;43290:13;;43357:25;42969:428;43357:25;-1:-1:-1;43427:13:6;;;-1:-1:-1;;43542:14:6;;;43604:19;;;43542:14;41896:1745;-1:-1:-1;41896:1745:6:o;35141:492::-;35270:13;35286:16;35294:7;35286;:16::i;:::-;35270:32;;35319:13;35315:219;;;736:10:2;-1:-1:-1;;;;;35351:28:6;;;35347:187;;35403:44;35420:5;736:10:2;17661:164:6;:::i;35403:44::-;35398:136;;35479:35;;-1:-1:-1;;;35479:35:6;;;;;;;;;;;35398:136;35546:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;35546:35:6;-1:-1:-1;;;;;35546:35:6;;;;;;;;;35597:28;;35546:24;;35597:28;;;;;;;35259:374;35141:492;;;:::o;34223:112::-;34300:27;34310:2;34314:8;34300:27;;;;;;;;;;;;:9;:27::i;14671:366::-;-1:-1:-1;;;;;;;;;;;;;14781:41:6;;;;2065:3;14867:33;;;-1:-1:-1;;;;;14833:68:6;-1:-1:-1;;;14833:68:6;-1:-1:-1;;;14931:24:6;;:29;;-1:-1:-1;;;14912:48:6;;;;2586:3;15000:28;;;;-1:-1:-1;;;14971:58:6;-1:-1:-1;14671:366:6:o;26554:716::-;26738:88;;-1:-1:-1;;;26738:88:6;;26717:4;;-1:-1:-1;;;;;26738:45:6;;;;;:88;;736:10:2;;26805:4:6;;26811:7;;26820:5;;26738:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26738:88:6;;;;;;;;-1:-1:-1;;26738:88:6;;;;;;;;;;;;:::i;:::-;;;26734:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27021:6;:13;27038:1;27021:18;27017:235;;27067:40;;-1:-1:-1;;;27067:40:6;;;;;;;;;;;27017:235;27210:6;27204:13;27195:6;27191:2;27187:15;27180:38;26734:529;-1:-1:-1;;;;;;26897:64:6;-1:-1:-1;;;26897:64:6;;-1:-1:-1;26734:529:6;26554:716;;;;;;:::o;33450:689::-;33581:19;33587:2;33591:8;33581:5;:19::i;:::-;-1:-1:-1;;;;;33642:14:6;;;:19;33638:483;;33682:11;33696:13;33744:14;;;33777:233;33808:62;33847:1;33851:2;33855:7;;;;;;33864:5;33808:30;:62::i;:::-;33803:167;;33906:40;;-1:-1:-1;;;33906:40:6;;;;;;;;;;;33803:167;34005:3;33997:5;:11;33777:233;;34092:3;34075:13;;:20;34071:34;;34097:8;;;27732:2966;27805:20;27828:13;;;27856;;;27852:44;;27878:18;;-1:-1:-1;;;27878:18:6;;;;;;;;;;;27852:44;-1:-1:-1;;;;;28384:22:6;;;;;;:18;:22;;;;1544:2;28384:22;;;:71;;28422:32;28410:45;;28384:71;;;28698:31;;;:17;:31;;;;;-1:-1:-1;15962:15:6;;15936:24;15932:46;15531:11;15506:23;15502:41;15499:52;15489:63;;28698:173;;28933:23;;;;28698:31;;28384:22;;29698:25;28384:22;;29551:335;30212:1;30198:12;30194:20;30152:346;30253:3;30244:7;30241:16;30152:346;;30471:7;30461:8;30458:1;30431:25;30428:1;30425;30420:59;30306:1;30293:15;30152:346;;;30156:77;30531:8;30543:1;30531:13;30527:45;;30553:19;;-1:-1:-1;;;30553:19:6;;;;;;;;;;;30527:45;30589:13;:19;-1:-1:-1;5529:184:1;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:22;-1:-1:-1;;;;;;88:32:22;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:139::-;-1:-1:-1;;;;;675:31:22;;665:42;;655:70;;721:1;718;711:12;736:451;811:6;819;872:2;860:9;851:7;847:23;843:32;840:52;;;888:1;885;878:12;840:52;927:9;914:23;946:39;979:5;946:39;:::i;:::-;1004:5;-1:-1:-1;1061:2:22;1046:18;;1033:32;-1:-1:-1;;;;;1096:40:22;;1084:53;;1074:81;;1151:1;1148;1141:12;1074:81;1174:7;1164:17;;;736:451;;;;;:::o;1192:258::-;1264:1;1274:113;1288:6;1285:1;1282:13;1274:113;;;1364:11;;;1358:18;1345:11;;;1338:39;1310:2;1303:10;1274:113;;;1405:6;1402:1;1399:13;1396:48;;;-1:-1:-1;;1440:1:22;1422:16;;1415:27;1192:258::o;1455:::-;1497:3;1535:5;1529:12;1562:6;1557:3;1550:19;1578:63;1634:6;1627:4;1622:3;1618:14;1611:4;1604:5;1600:16;1578:63;:::i;:::-;1695:2;1674:15;-1:-1:-1;;1670:29:22;1661:39;;;;1702:4;1657:50;;1455:258;-1:-1:-1;;1455:258:22:o;1718:220::-;1867:2;1856:9;1849:21;1830:4;1887:45;1928:2;1917:9;1913:18;1905:6;1887:45;:::i;1943:180::-;2002:6;2055:2;2043:9;2034:7;2030:23;2026:32;2023:52;;;2071:1;2068;2061:12;2023:52;-1:-1:-1;2094:23:22;;1943:180;-1:-1:-1;1943:180:22:o;2336:323::-;2404:6;2412;2465:2;2453:9;2444:7;2440:23;2436:32;2433:52;;;2481:1;2478;2471:12;2433:52;2520:9;2507:23;2539:39;2572:5;2539:39;:::i;:::-;2597:5;2649:2;2634:18;;;;2621:32;;-1:-1:-1;;;2336:323:22:o;2846:127::-;2907:10;2902:3;2898:20;2895:1;2888:31;2938:4;2935:1;2928:15;2962:4;2959:1;2952:15;2978:275;3049:2;3043:9;3114:2;3095:13;;-1:-1:-1;;3091:27:22;3079:40;;-1:-1:-1;;;;;3134:34:22;;3170:22;;;3131:62;3128:88;;;3196:18;;:::i;:::-;3232:2;3225:22;2978:275;;-1:-1:-1;2978:275:22:o;3258:407::-;3323:5;-1:-1:-1;;;;;3349:6:22;3346:30;3343:56;;;3379:18;;:::i;:::-;3417:57;3462:2;3441:15;;-1:-1:-1;;3437:29:22;3468:4;3433:40;3417:57;:::i;:::-;3408:66;;3497:6;3490:5;3483:21;3537:3;3528:6;3523:3;3519:16;3516:25;3513:45;;;3554:1;3551;3544:12;3513:45;3603:6;3598:3;3591:4;3584:5;3580:16;3567:43;3657:1;3650:4;3641:6;3634:5;3630:18;3626:29;3619:40;3258:407;;;;;:::o;3670:451::-;3739:6;3792:2;3780:9;3771:7;3767:23;3763:32;3760:52;;;3808:1;3805;3798:12;3760:52;3848:9;3835:23;-1:-1:-1;;;;;3873:6:22;3870:30;3867:50;;;3913:1;3910;3903:12;3867:50;3936:22;;3989:4;3981:13;;3977:27;-1:-1:-1;3967:55:22;;4018:1;4015;4008:12;3967:55;4041:74;4107:7;4102:2;4089:16;4084:2;4080;4076:11;4041:74;:::i;4126:118::-;4212:5;4205:13;4198:21;4191:5;4188:32;4178:60;;4234:1;4231;4224:12;4249:241;4305:6;4358:2;4346:9;4337:7;4333:23;4329:32;4326:52;;;4374:1;4371;4364:12;4326:52;4413:9;4400:23;4432:28;4454:5;4432:28;:::i;4495:183::-;4555:4;-1:-1:-1;;;;;4580:6:22;4577:30;4574:56;;;4610:18;;:::i;:::-;-1:-1:-1;4655:1:22;4651:14;4667:4;4647:25;;4495:183::o;4683:662::-;4737:5;4790:3;4783:4;4775:6;4771:17;4767:27;4757:55;;4808:1;4805;4798:12;4757:55;4844:6;4831:20;4870:4;4894:60;4910:43;4950:2;4910:43;:::i;:::-;4894:60;:::i;:::-;4988:15;;;5074:1;5070:10;;;;5058:23;;5054:32;;;5019:12;;;;5098:15;;;5095:35;;;5126:1;5123;5116:12;5095:35;5162:2;5154:6;5150:15;5174:142;5190:6;5185:3;5182:15;5174:142;;;5256:17;;5244:30;;5294:12;;;;5207;;5174:142;;;-1:-1:-1;5334:5:22;4683:662;-1:-1:-1;;;;;;4683:662:22:o;5350:491::-;5443:6;5451;5504:2;5492:9;5483:7;5479:23;5475:32;5472:52;;;5520:1;5517;5510:12;5472:52;5560:9;5547:23;-1:-1:-1;;;;;5585:6:22;5582:30;5579:50;;;5625:1;5622;5615:12;5579:50;5648:61;5701:7;5692:6;5681:9;5677:22;5648:61;:::i;:::-;5638:71;;;5759:2;5748:9;5744:18;5731:32;5772:39;5805:5;5772:39;:::i;5846:472::-;5923:6;5931;5939;5992:2;5980:9;5971:7;5967:23;5963:32;5960:52;;;6008:1;6005;5998:12;5960:52;6047:9;6034:23;6066:39;6099:5;6066:39;:::i;:::-;6124:5;-1:-1:-1;6181:2:22;6166:18;;6153:32;6194:41;6153:32;6194:41;:::i;:::-;5846:472;;6254:7;;-1:-1:-1;;;6308:2:22;6293:18;;;;6280:32;;5846:472::o;6323:248::-;6391:6;6399;6452:2;6440:9;6431:7;6427:23;6423:32;6420:52;;;6468:1;6465;6458:12;6420:52;-1:-1:-1;;6491:23:22;;;6561:2;6546:18;;;6533:32;;-1:-1:-1;6323:248:22:o;6855:1221::-;6973:6;6981;7034:2;7022:9;7013:7;7009:23;7005:32;7002:52;;;7050:1;7047;7040:12;7002:52;7090:9;7077:23;-1:-1:-1;;;;;7160:2:22;7152:6;7149:14;7146:34;;;7176:1;7173;7166:12;7146:34;7199:61;7252:7;7243:6;7232:9;7228:22;7199:61;:::i;:::-;7189:71;;7279:2;7269:12;;7334:2;7323:9;7319:18;7306:32;7363:2;7353:8;7350:16;7347:36;;;7379:1;7376;7369:12;7347:36;7402:24;;;-1:-1:-1;7457:4:22;7449:13;;7445:27;-1:-1:-1;7435:55:22;;7486:1;7483;7476:12;7435:55;7522:2;7509:16;7545:60;7561:43;7601:2;7561:43;:::i;7545:60::-;7639:15;;;7721:1;7717:10;;;;7709:19;;7705:28;;;7670:12;;;;7745:19;;;7742:39;;;7777:1;7774;7767:12;7742:39;7801:11;;;;7821:225;7837:6;7832:3;7829:15;7821:225;;;7917:3;7904:17;7934:39;7967:5;7934:39;:::i;:::-;7986:18;;7854:12;;;;8024;;;;7821:225;;;8065:5;8055:15;;;;;;;6855:1221;;;;;:::o;8503:615::-;8589:6;8597;8650:2;8638:9;8629:7;8625:23;8621:32;8618:52;;;8666:1;8663;8656:12;8618:52;8706:9;8693:23;-1:-1:-1;;;;;8776:2:22;8768:6;8765:14;8762:34;;;8792:1;8789;8782:12;8762:34;8830:6;8819:9;8815:22;8805:32;;8875:7;8868:4;8864:2;8860:13;8856:27;8846:55;;8897:1;8894;8887:12;8846:55;8937:2;8924:16;8963:2;8955:6;8952:14;8949:34;;;8979:1;8976;8969:12;8949:34;9032:7;9027:2;9017:6;9014:1;9010:14;9006:2;9002:23;8998:32;8995:45;8992:65;;;9053:1;9050;9043:12;8992:65;9084:2;9076:11;;;;;9106:6;;-1:-1:-1;8503:615:22;;-1:-1:-1;;;;8503:615:22:o;9123:349::-;9207:12;;-1:-1:-1;;;;;9203:38:22;9191:51;;9295:4;9284:16;;;9278:23;-1:-1:-1;;;;;9274:48:22;9258:14;;;9251:72;9386:4;9375:16;;;9369:23;9362:31;9355:39;9339:14;;;9332:63;9448:4;9437:16;;;9431:23;9456:8;9427:38;9411:14;;9404:62;9123:349::o;9477:724::-;9712:2;9764:21;;;9834:13;;9737:18;;;9856:22;;;9683:4;;9712:2;9935:15;;;;9909:2;9894:18;;;9683:4;9978:197;9992:6;9989:1;9986:13;9978:197;;;10041:52;10089:3;10080:6;10074:13;10041:52;:::i;:::-;10150:15;;;;10122:4;10113:14;;;;;10014:1;10007:9;9978:197;;10206:255;10265:6;10318:2;10306:9;10297:7;10293:23;10289:32;10286:52;;;10334:1;10331;10324:12;10286:52;10373:9;10360:23;10392:39;10425:5;10392:39;:::i;10466:435::-;10519:3;10557:5;10551:12;10584:6;10579:3;10572:19;10610:4;10639:2;10634:3;10630:12;10623:19;;10676:2;10669:5;10665:14;10697:1;10707:169;10721:6;10718:1;10715:13;10707:169;;;10782:13;;10770:26;;10816:12;;;;10851:15;;;;10743:1;10736:9;10707:169;;;-1:-1:-1;10892:3:22;;10466:435;-1:-1:-1;;;;;10466:435:22:o;10906:261::-;11085:2;11074:9;11067:21;11048:4;11105:56;11157:2;11146:9;11142:18;11134:6;11105:56;:::i;11172:391::-;11249:6;11257;11265;11318:2;11306:9;11297:7;11293:23;11289:32;11286:52;;;11334:1;11331;11324:12;11286:52;11373:9;11360:23;11392:39;11425:5;11392:39;:::i;:::-;11450:5;11502:2;11487:18;;11474:32;;-1:-1:-1;11553:2:22;11538:18;;;11525:32;;11172:391;-1:-1:-1;;;11172:391:22:o;11568:390::-;11633:6;11641;11694:2;11682:9;11673:7;11669:23;11665:32;11662:52;;;11710:1;11707;11700:12;11662:52;11749:9;11736:23;11768:39;11801:5;11768:39;:::i;:::-;11826:5;-1:-1:-1;11883:2:22;11868:18;;11855:32;11896:30;11855:32;11896:30;:::i;11963:348::-;12047:6;12100:2;12088:9;12079:7;12075:23;12071:32;12068:52;;;12116:1;12113;12106:12;12068:52;12156:9;12143:23;-1:-1:-1;;;;;12181:6:22;12178:30;12175:50;;;12221:1;12218;12211:12;12175:50;12244:61;12297:7;12288:6;12277:9;12273:22;12244:61;:::i;12316:811::-;12411:6;12419;12427;12435;12488:3;12476:9;12467:7;12463:23;12459:33;12456:53;;;12505:1;12502;12495:12;12456:53;12544:9;12531:23;12563:39;12596:5;12563:39;:::i;:::-;12621:5;-1:-1:-1;12678:2:22;12663:18;;12650:32;12691:41;12650:32;12691:41;:::i;:::-;12751:7;-1:-1:-1;12805:2:22;12790:18;;12777:32;;-1:-1:-1;12860:2:22;12845:18;;12832:32;-1:-1:-1;;;;;12876:30:22;;12873:50;;;12919:1;12916;12909:12;12873:50;12942:22;;12995:4;12987:13;;12983:27;-1:-1:-1;12973:55:22;;13024:1;13021;13014:12;12973:55;13047:74;13113:7;13108:2;13095:16;13090:2;13086;13082:11;13047:74;:::i;:::-;13037:84;;;12316:811;;;;;;;:::o;13132:268::-;13330:3;13315:19;;13343:51;13319:9;13376:6;13343:51;:::i;13405:404::-;13473:6;13481;13534:2;13522:9;13513:7;13509:23;13505:32;13502:52;;;13550:1;13547;13540:12;13502:52;13589:9;13576:23;13608:39;13641:5;13608:39;:::i;:::-;13666:5;-1:-1:-1;13723:2:22;13708:18;;13695:32;13736:41;13695:32;13736:41;:::i;13814:356::-;14016:2;13998:21;;;14035:18;;;14028:30;14094:34;14089:2;14074:18;;14067:62;14161:2;14146:18;;13814:356::o;14175:380::-;14254:1;14250:12;;;;14297;;;14318:61;;14372:4;14364:6;14360:17;14350:27;;14318:61;14425:2;14417:6;14414:14;14394:18;14391:38;14388:161;;14471:10;14466:3;14462:20;14459:1;14452:31;14506:4;14503:1;14496:15;14534:4;14531:1;14524:15;14388:161;;14175:380;;;:::o;14869:245::-;14936:6;14989:2;14977:9;14968:7;14964:23;14960:32;14957:52;;;15005:1;15002;14995:12;14957:52;15037:9;15031:16;15056:28;15078:5;15056:28;:::i;15119:127::-;15180:10;15175:3;15171:20;15168:1;15161:31;15211:4;15208:1;15201:15;15235:4;15232:1;15225:15;15251:128;15291:3;15322:1;15318:6;15315:1;15312:13;15309:39;;;15328:18;;:::i;:::-;-1:-1:-1;15364:9:22;;15251:128::o;15384:344::-;15586:2;15568:21;;;15625:2;15605:18;;;15598:30;-1:-1:-1;;;15659:2:22;15644:18;;15637:50;15719:2;15704:18;;15384:344::o;15733:168::-;15773:7;15839:1;15835;15831:6;15827:14;15824:1;15821:21;15816:1;15809:9;15802:17;15798:45;15795:71;;;15846:18;;:::i;:::-;-1:-1:-1;15886:9:22;;15733:168::o;15906:217::-;15946:1;15972;15962:132;;16016:10;16011:3;16007:20;16004:1;15997:31;16051:4;16048:1;16041:15;16079:4;16076:1;16069:15;15962:132;-1:-1:-1;16108:9:22;;15906:217::o;16128:127::-;16189:10;16184:3;16180:20;16177:1;16170:31;16220:4;16217:1;16210:15;16244:4;16241:1;16234:15;16260:135;16299:3;16320:17;;;16317:43;;16340:18;;:::i;:::-;-1:-1:-1;16387:1:22;16376:13;;16260:135::o;18370:259::-;18440:6;18493:2;18481:9;18472:7;18468:23;18464:32;18461:52;;;18509:1;18506;18499:12;18461:52;18541:9;18535:16;18560:39;18593:5;18560:39;:::i;18987:470::-;19166:3;19204:6;19198:13;19220:53;19266:6;19261:3;19254:4;19246:6;19242:17;19220:53;:::i;:::-;19336:13;;19295:16;;;;19358:57;19336:13;19295:16;19392:4;19380:17;;19358:57;:::i;:::-;19431:20;;18987:470;-1:-1:-1;;;;18987:470:22:o;20634:502::-;-1:-1:-1;;;;;20897:32:22;;20879:51;;20966:3;20961:2;20946:18;;20939:31;;;-1:-1:-1;;20987:57:22;;21024:19;;21016:6;20987:57;:::i;:::-;21075:2;21060:18;;21053:34;;;;-1:-1:-1;21118:2:22;21103:18;21096:34;20979:65;20634:502;-1:-1:-1;;20634:502:22:o;21141:489::-;-1:-1:-1;;;;;21410:15:22;;;21392:34;;21462:15;;21457:2;21442:18;;21435:43;21509:2;21494:18;;21487:34;;;21557:3;21552:2;21537:18;;21530:31;;;21335:4;;21578:46;;21604:19;;21596:6;21578:46;:::i;:::-;21570:54;21141:489;-1:-1:-1;;;;;;21141:489:22:o;21635:249::-;21704:6;21757:2;21745:9;21736:7;21732:23;21728:32;21725:52;;;21773:1;21770;21763:12;21725:52;21805:9;21799:16;21824:30;21848:5;21824:30;:::i

Swarm Source

ipfs://5cc93d9c6f3b565ddfaed3f1680bf7d7cc08c326f2952a35bc1cc516b457546f
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.