ETH Price: $2,493.59 (+3.24%)

Token

GemScanTools (GS)
 

Overview

Max Total Supply

34 GS

Holders

16

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 GS
0xCF77301Ef4811B6C449aE3B08CC098De50bCEb83
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:
GemScanTools

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 7 of 15: GemScanTools.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import {ERC721A, IERC721A} from "ERC721A.sol";
import {Ownable} from "Ownable.sol";
import {MerkleProof} from "MerkleProof.sol";
import {OperatorFilterer} from "OperatorFilterer.sol";
import {IERC2981} from "IERC2981.sol";
import {ERC2981} from "ERC2981.sol";
import {ERC721ABurnable} from "ERC721ABurnable.sol";
import {ERC721AQueryable} from "ERC721AQueryable.sol";

error MintingPaused();
error MaxSupplyReached();
error WithdrawalFailed();
error WrongEtherAmount();
error InvalidMintAddress();
error ArrayLengthMismatch();
error MaxPerTransactionReached();
error MaxPerWalletReached();
error NoWL();

contract GemScanTools is
  Ownable,
  ERC721A,
  ERC2981,
  ERC721ABurnable,
  ERC721AQueryable,
  OperatorFilterer
{
  enum Step {
        Paused,
        Whitelist,
        Public
  }

  Step public sellingStep;
  uint256 public constant MAX_SUPPLY = 444;
  uint256 public constant MAX_PER_WALLET_WL = 1;
  uint256 public constant MAX_PER_TRANSACTION_PUBLIC = 3;
  uint256 public MINT_PRICE = 0.05 ether;
  uint256 public WL_MAX_SUPPLY = 1;
  bool public operatorFilteringEnabled = true;
  bytes32 public merkleRootWL;
  mapping(address => uint8) public NFTsperWalletWL;

  string tokenBaseUri = "";

  constructor(address deployer) ERC721A("GemScanTools", "GS") {
    sellingStep = Step(0);
    _transferOwnership(deployer);
    _registerForOperatorFiltering();
    _setDefaultRoyalty(deployer, 300);
  }

  function mint(uint8 quantity) external payable {
    if (sellingStep != Step(2)) revert MintingPaused();
    if (_totalMinted() + quantity > MAX_SUPPLY - WL_MAX_SUPPLY) revert MaxSupplyReached();
    if (quantity > MAX_PER_TRANSACTION_PUBLIC) revert MaxPerTransactionReached();
    if (msg.value < quantity * MINT_PRICE) revert WrongEtherAmount();

    _mint(msg.sender, quantity);
  }



  function setStep(uint8 step) external onlyOwner {
    sellingStep = Step(step);
  }

  function setMintPrice(uint256 newMintPrice) external onlyOwner {
    MINT_PRICE = newMintPrice;
  }

  function getMintPrice() public view returns (uint256) {
    return MINT_PRICE;
  }

  function setWLMaxSupply(uint256 newWLMaxSupply) external onlyOwner {
    WL_MAX_SUPPLY = newWLMaxSupply;
  }

  function setDefaultRoyalty(
    address receiver,
    uint96 feeNumerator
  ) public onlyOwner {
    _setDefaultRoyalty(receiver, feeNumerator);
  }

  function setOperatorFilteringEnabled(bool value) public onlyOwner {
    operatorFilteringEnabled = value;
  }

  function setBaseURI(string calldata newBaseUri) external onlyOwner {
    tokenBaseUri = newBaseUri;
  }

  function collectReserves(uint16 quantity) external onlyOwner {
    if (_totalMinted() + quantity > MAX_SUPPLY) revert MaxSupplyReached();

    _mint(msg.sender, quantity);
  }

  function withdraw() public onlyOwner {
    (bool success, ) = payable(owner()).call{value: address(this).balance}("");

    if (!success) {
      revert WithdrawalFailed();
    }
  }

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

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

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

  function _operatorFilteringEnabled() internal view override returns (bool) {
    return operatorFilteringEnabled;
  }

  function _isPriorityOperator(
    address operator
  ) internal pure override returns (bool) {
    return operator == address(0x1E0049783F008A0085193E00003D00cd54003c71);
  }

  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 15: 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 2 of 15: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 3 of 15: ERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

import "IERC2981.sol";
import "ERC165.sol";

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

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

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

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

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

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

        return (royalty.receiver, royaltyAmount);
    }

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

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

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

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

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

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

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

File 4 of 15: 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) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // 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, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        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.
     * 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) public payable virtual override {
        address owner = ownerOf(tokenId);

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

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

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

    // =============================================================
    //                        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 5 of 15: ERC721ABurnable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721ABurnable.sol';
import '../ERC721A.sol';

/**
 * @title ERC721ABurnable.
 *
 * @dev ERC721A token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual override {
        _burn(tokenId, true);
    }
}

File 6 of 15: 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 8 of 15: IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 9 of 15: 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 10 of 15: 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 11 of 15: IERC721ABurnable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import '../IERC721A.sol';

/**
 * @dev Interface of ERC721ABurnable.
 */
interface IERC721ABurnable is IERC721A {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) external;
}

File 12 of 15: 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 13 of 15: MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
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 Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle 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++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

File 14 of 15: OperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Optimized and flexible operator filterer to abide to OpenSea's
/// mandatory on-chain royalty enforcement in order for new collections to
/// receive royalties.
/// For more information, see:
/// See: https://github.com/ProjectOpenSea/operator-filter-registry
abstract contract OperatorFilterer {
    /// @dev The default OpenSea operator blocklist subscription.
    address internal constant _DEFAULT_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

    /// @dev The OpenSea operator filter registry.
    address internal constant _OPERATOR_FILTER_REGISTRY = 0x000000000000AAeB6D7670E522A718067333cd4E;

    /// @dev Registers the current contract to OpenSea's operator filter,
    /// and subscribe to the default OpenSea operator blocklist.
    /// Note: Will not revert nor update existing settings for repeated registration.
    function _registerForOperatorFiltering() internal virtual {
        _registerForOperatorFiltering(_DEFAULT_SUBSCRIPTION, true);
    }

    /// @dev Registers the current contract to OpenSea's operator filter.
    /// Note: Will not revert nor update existing settings for repeated registration.
    function _registerForOperatorFiltering(address subscriptionOrRegistrantToCopy, bool subscribe)
        internal
        virtual
    {
        /// @solidity memory-safe-assembly
        assembly {
            let functionSelector := 0x7d3e3dbe // `registerAndSubscribe(address,address)`.

            // Clean the upper 96 bits of `subscriptionOrRegistrantToCopy` in case they are dirty.
            subscriptionOrRegistrantToCopy := shr(96, shl(96, subscriptionOrRegistrantToCopy))

            for {} iszero(subscribe) {} {
                if iszero(subscriptionOrRegistrantToCopy) {
                    functionSelector := 0x4420e486 // `register(address)`.
                    break
                }
                functionSelector := 0xa0af2903 // `registerAndCopyEntries(address,address)`.
                break
            }
            // Store the function selector.
            mstore(0x00, shl(224, functionSelector))
            // Store the `address(this)`.
            mstore(0x04, address())
            // Store the `subscriptionOrRegistrantToCopy`.
            mstore(0x24, subscriptionOrRegistrantToCopy)
            // Register into the registry.
            if iszero(call(gas(), _OPERATOR_FILTER_REGISTRY, 0, 0x00, 0x44, 0x00, 0x04)) {
                // If the function selector has not been overwritten,
                // it is an out-of-gas error.
                if eq(shr(224, mload(0x00)), functionSelector) {
                    // To prevent gas under-estimation.
                    revert(0, 0)
                }
            }
            // Restore the part of the free memory pointer that was overwritten,
            // which is guaranteed to be zero, because of Solidity's memory size limits.
            mstore(0x24, 0)
        }
    }

    /// @dev Modifier to guard a function and revert if the caller is a blocked operator.
    modifier onlyAllowedOperator(address from) virtual {
        if (from != msg.sender) {
            if (!_isPriorityOperator(msg.sender)) {
                if (_operatorFilteringEnabled()) _revertIfBlocked(msg.sender);
            }
        }
        _;
    }

    /// @dev Modifier to guard a function from approving a blocked operator..
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        if (!_isPriorityOperator(operator)) {
            if (_operatorFilteringEnabled()) _revertIfBlocked(operator);
        }
        _;
    }

    /// @dev Helper function that reverts if the `operator` is blocked by the registry.
    function _revertIfBlocked(address operator) private view {
        /// @solidity memory-safe-assembly
        assembly {
            // Store the function selector of `isOperatorAllowed(address,address)`,
            // shifted left by 6 bytes, which is enough for 8tb of memory.
            // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL).
            mstore(0x00, 0xc6171134001122334455)
            // Store the `address(this)`.
            mstore(0x1a, address())
            // Store the `operator`.
            mstore(0x3a, operator)

            // `isOperatorAllowed` always returns true if it does not revert.
            if iszero(staticcall(gas(), _OPERATOR_FILTER_REGISTRY, 0x16, 0x44, 0x00, 0x00)) {
                // Bubble up the revert if the staticcall reverts.
                returndatacopy(0x00, 0x00, returndatasize())
                revert(0x00, returndatasize())
            }

            // We'll skip checking if `from` is inside the blacklist.
            // Even though that can block transferring out of wrapper contracts,
            // we don't want tokens to be stuck.

            // Restore the part of the free memory pointer that was overwritten,
            // which is guaranteed to be zero, if less than 8tb of memory is used.
            mstore(0x3a, 0)
        }
    }

    /// @dev For deriving contracts to override, so that operator filtering
    /// can be turned on / off.
    /// Returns true by default.
    function _operatorFilteringEnabled() internal view virtual returns (bool) {
        return true;
    }

    /// @dev For deriving contracts to override, so that preferred marketplaces can
    /// skip operator filtering, helping users save gas.
    /// Returns false for all inputs by default.
    function _isPriorityOperator(address) internal view virtual returns (bool) {
        return false;
    }
}

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"deployer","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":"MaxPerTransactionReached","type":"error"},{"inputs":[],"name":"MaxSupplyReached","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"MintingPaused","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"},{"inputs":[],"name":"WithdrawalFailed","type":"error"},{"inputs":[],"name":"WrongEtherAmount","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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_PER_TRANSACTION_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_WALLET_WL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"NFTsperWalletWL","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WL_MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"quantity","type":"uint16"}],"name":"collectReserves","outputs":[],"stateMutability":"nonpayable","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":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRootWL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"quantity","type":"uint8"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilteringEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"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":[],"name":"sellingStep","outputs":[{"internalType":"enum GemScanTools.Step","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintPrice","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setOperatorFilteringEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"step","type":"uint8"}],"name":"setStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newWLMaxSupply","type":"uint256"}],"name":"setWLMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405266b1a2bc2ec50000600c556001600d556001600e60006101000a81548160ff02191690831515021790555060405180602001604052806000815250601190816200004f919062000769565b503480156200005d57600080fd5b5060405162004e0138038062004e018339818101604052810190620000839190620008ba565b6040518060400160405280600c81526020017f47656d5363616e546f6f6c7300000000000000000000000000000000000000008152506040518060400160405280600281526020017f47530000000000000000000000000000000000000000000000000000000000008152506200010f62000103620001ca60201b60201c565b620001d260201b60201c565b816003908162000120919062000769565b50806004908162000132919062000769565b50620001436200029660201b60201c565b600181905550505060006002811115620001625762000161620008ec565b5b600b60006101000a81548160ff02191690836002811115620001895762000188620008ec565b5b02179055506200019f81620001d260201b60201c565b620001af6200029f60201b60201c565b620001c38161012c620002c860201b60201c565b5062000a36565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006001905090565b620002c6733cc6cdda760b79bafa08df41ecfa224f810dceb660016200046b60201b60201c565b565b620002d8620004e560201b60201c565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562000339576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200033090620009a2565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620003ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003a29062000a14565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600960008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b637d3e3dbe8260601b60601c9250816200049a57826200049257634420e48690506200049a565b63a0af290390505b8060e01b60005230600452826024526004600060446000806daaeb6d7670e522a718067333cd4e5af1620004db578060005160e01c03620004da57600080fd5b5b6000602452505050565b6000612710905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200057157607f821691505b60208210810362000587576200058662000529565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005f17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620005b2565b620005fd8683620005b2565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200064a620006446200063e8462000615565b6200061f565b62000615565b9050919050565b6000819050919050565b620006668362000629565b6200067e620006758262000651565b848454620005bf565b825550505050565b600090565b6200069562000686565b620006a28184846200065b565b505050565b5b81811015620006ca57620006be6000826200068b565b600181019050620006a8565b5050565b601f8211156200071957620006e3816200058d565b620006ee84620005a2565b81016020851015620006fe578190505b620007166200070d85620005a2565b830182620006a7565b50505b505050565b600082821c905092915050565b60006200073e600019846008026200071e565b1980831691505092915050565b60006200075983836200072b565b9150826002028217905092915050565b6200077482620004ef565b67ffffffffffffffff81111562000790576200078f620004fa565b5b6200079c825462000558565b620007a9828285620006ce565b600060209050601f831160018114620007e15760008415620007cc578287015190505b620007d885826200074b565b86555062000848565b601f198416620007f1866200058d565b60005b828110156200081b57848901518255600182019150602085019450602081019050620007f4565b868310156200083b578489015162000837601f8916826200072b565b8355505b6001600288020188555050505b505050505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620008828262000855565b9050919050565b620008948162000875565b8114620008a057600080fd5b50565b600081519050620008b48162000889565b92915050565b600060208284031215620008d357620008d262000850565b5b6000620008e384828501620008a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600082825260208201905092915050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b60006200098a602a836200091b565b915062000997826200092c565b604082019050919050565b60006020820190508181036000830152620009bd816200097b565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b6000620009fc6019836200091b565b915062000a0982620009c4565b602082019050919050565b6000602082019050818103600083015262000a2f81620009ed565b9050919050565b6143bb8062000a466000396000f3fe6080604052600436106102515760003560e01c8063715018a611610139578063b88d4fde116100b6578063d6492d811161007a578063d6492d81146108a8578063e985e9c5146108d3578063f2fde38b14610910578063f4a0a52814610939578063f8b89dfb14610962578063fb796e6c1461098b57610251565b8063b88d4fde146107bc578063c002d23d146107d8578063c23dc68f14610803578063c87b56dd14610840578063cbccefb21461087d57610251565b806399a2557a116100fd57806399a2557a146106d9578063a22cb46514610716578063a7f93ebd1461073f578063b53cff0f1461076a578063b7c0b8e81461079357610251565b8063715018a614610604578063828122ab1461061b5780638462151c146106465780638da5cb5b1461068357806395d89b41146106ae57610251565b806332cb6b0c116101d257806355f804b31161019657806355f804b3146104dd5780635ade26c6146105065780635bbb2177146105315780636352211e1461056e5780636ecd2306146105ab57806370a08231146105c757610251565b806332cb6b0c1461042b5780633ccfd60b1461045657806342842e0e1461046d57806342966c681461048957806350c96509146104b257610251565b806318160ddd1161021957806318160ddd146103405780631ac08c1f1461036b5780631b1f4019146103a857806323b872dd146103d15780632a55205a146103ed57610251565b806301ffc9a71461025657806304634d8d1461029357806306fdde03146102bc578063081812fc146102e7578063095ea7b314610324575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190612f14565b6109b6565b60405161028a9190612f5c565b60405180910390f35b34801561029f57600080fd5b506102ba60048036038101906102b59190613019565b6109d8565b005b3480156102c857600080fd5b506102d16109ee565b6040516102de91906130e9565b60405180910390f35b3480156102f357600080fd5b5061030e60048036038101906103099190613141565b610a80565b60405161031b919061317d565b60405180910390f35b61033e60048036038101906103399190613198565b610aff565b005b34801561034c57600080fd5b50610355610b34565b60405161036291906131e7565b60405180910390f35b34801561037757600080fd5b50610392600480360381019061038d9190613202565b610b4b565b60405161039f919061324b565b60405180910390f35b3480156103b457600080fd5b506103cf60048036038101906103ca91906132a0565b610b6b565b005b6103eb60048036038101906103e691906132cd565b610bd6565b005b3480156103f957600080fd5b50610414600480360381019061040f9190613320565b610c41565b604051610422929190613360565b60405180910390f35b34801561043757600080fd5b50610440610e2b565b60405161044d91906131e7565b60405180910390f35b34801561046257600080fd5b5061046b610e31565b005b610487600480360381019061048291906132cd565b610ee6565b005b34801561049557600080fd5b506104b060048036038101906104ab9190613141565b610f51565b005b3480156104be57600080fd5b506104c7610f5f565b6040516104d491906131e7565b60405180910390f35b3480156104e957600080fd5b5061050460048036038101906104ff91906133ee565b610f65565b005b34801561051257600080fd5b5061051b610f83565b60405161052891906131e7565b60405180910390f35b34801561053d57600080fd5b5061055860048036038101906105539190613491565b610f88565b6040516105659190613641565b60405180910390f35b34801561057a57600080fd5b5061059560048036038101906105909190613141565b61104b565b6040516105a2919061317d565b60405180910390f35b6105c560048036038101906105c0919061368f565b61105d565b005b3480156105d357600080fd5b506105ee60048036038101906105e99190613202565b6111d1565b6040516105fb91906131e7565b60405180910390f35b34801561061057600080fd5b50610619611289565b005b34801561062757600080fd5b5061063061129d565b60405161063d91906131e7565b60405180910390f35b34801561065257600080fd5b5061066d60048036038101906106689190613202565b6112a2565b60405161067a919061377a565b60405180910390f35b34801561068f57600080fd5b506106986113e5565b6040516106a5919061317d565b60405180910390f35b3480156106ba57600080fd5b506106c361140e565b6040516106d091906130e9565b60405180910390f35b3480156106e557600080fd5b5061070060048036038101906106fb919061379c565b6114a0565b60405161070d919061377a565b60405180910390f35b34801561072257600080fd5b5061073d6004803603810190610738919061381b565b6116ac565b005b34801561074b57600080fd5b506107546116e1565b60405161076191906131e7565b60405180910390f35b34801561077657600080fd5b50610791600480360381019061078c9190613141565b6116eb565b005b34801561079f57600080fd5b506107ba60048036038101906107b5919061385b565b6116fd565b005b6107d660048036038101906107d191906139b8565b611722565b005b3480156107e457600080fd5b506107ed61178f565b6040516107fa91906131e7565b60405180910390f35b34801561080f57600080fd5b5061082a60048036038101906108259190613141565b611795565b6040516108379190613a90565b60405180910390f35b34801561084c57600080fd5b5061086760048036038101906108629190613141565b6117ff565b60405161087491906130e9565b60405180910390f35b34801561088957600080fd5b5061089261189d565b60405161089f9190613b22565b60405180910390f35b3480156108b457600080fd5b506108bd6118b0565b6040516108ca9190613b56565b60405180910390f35b3480156108df57600080fd5b506108fa60048036038101906108f59190613b71565b6118b6565b6040516109079190612f5c565b60405180910390f35b34801561091c57600080fd5b5061093760048036038101906109329190613202565b61194a565b005b34801561094557600080fd5b50610960600480360381019061095b9190613141565b6119cd565b005b34801561096e57600080fd5b506109896004803603810190610984919061368f565b6119df565b005b34801561099757600080fd5b506109a0611a29565b6040516109ad9190612f5c565b60405180910390f35b60006109c182611a3c565b806109d157506109d082611ace565b5b9050919050565b6109e0611b48565b6109ea8282611bc6565b5050565b6060600380546109fd90613be0565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2990613be0565b8015610a765780601f10610a4b57610100808354040283529160200191610a76565b820191906000526020600020905b815481529060010190602001808311610a5957829003601f168201915b5050505050905090565b6000610a8b82611d5b565b610ac1576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610b0981611dba565b610b2557610b15611e06565b15610b2457610b2381611e1d565b5b5b610b2f8383611e61565b505050565b6000610b3e611fa5565b6002546001540303905090565b60106020528060005260406000206000915054906101000a900460ff1681565b610b73611b48565b6101bc8161ffff16610b83611fae565b610b8d9190613c40565b1115610bc5576040517fd05cb60900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd3338261ffff16611fc1565b50565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c3057610c1333611dba565b610c2f57610c1f611e06565b15610c2e57610c2d33611e1d565b5b5b5b610c3b84848461217d565b50505050565b6000806000600a60008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610dd65760096040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610de061249f565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610e0c9190613c74565b610e169190613ce5565b90508160000151819350935050509250929050565b6101bc81565b610e39611b48565b6000610e436113e5565b73ffffffffffffffffffffffffffffffffffffffff1647604051610e6690613d47565b60006040518083038185875af1925050503d8060008114610ea3576040519150601f19603f3d011682016040523d82523d6000602084013e610ea8565b606091505b5050905080610ee3576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f4057610f2333611dba565b610f3f57610f2f611e06565b15610f3e57610f3d33611e1d565b5b5b5b610f4b8484846124a9565b50505050565b610f5c8160016124c9565b50565b600d5481565b610f6d611b48565b818160119182610f7e929190613f13565b505050565b600381565b6060600083839050905060008167ffffffffffffffff811115610fae57610fad61388d565b5b604051908082528060200260200182016040528015610fe757816020015b610fd4612e59565b815260200190600190039081610fcc5790505b50905060005b82811461103f5761101686868381811061100a57611009613fe3565b5b90506020020135611795565b82828151811061102957611028613fe3565b5b6020026020010181905250806001019050610fed565b50809250505092915050565b60006110568261271b565b9050919050565b6002808111156110705761106f613aab565b5b600281111561108257611081613aab565b5b600b60009054906101000a900460ff1660028111156110a4576110a3613aab565b5b146110db576040517feb56075600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d546101bc6110eb9190614012565b8160ff166110f7611fae565b6111019190613c40565b1115611139576040517fd05cb60900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60038160ff161115611177576040517f4b231f9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c548160ff166111889190613c74565b3410156111c1576040517f31fc877f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111ce338260ff16611fc1565b50565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611238576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611291611b48565b61129b60006127e7565b565b600181565b606060008060006112b2856111d1565b905060008167ffffffffffffffff8111156112d0576112cf61388d565b5b6040519080825280602002602001820160405280156112fe5781602001602082028036833780820191505090505b509050611309612e59565b6000611313611fa5565b90505b8386146113d757611326816128ab565b915081604001516113cc57600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461137157816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113cb57808387806001019850815181106113be576113bd613fe3565b5b6020026020010181815250505b5b806001019050611316565b508195505050505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606004805461141d90613be0565b80601f016020809104026020016040519081016040528092919081815260200182805461144990613be0565b80156114965780601f1061146b57610100808354040283529160200191611496565b820191906000526020600020905b81548152906001019060200180831161147957829003601f168201915b5050505050905090565b60608183106114db576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806114e66128d6565b90506114f0611fa5565b851015611502576114ff611fa5565b94505b8084111561150e578093505b6000611519876111d1565b90508486101561153c576000868603905081811015611536578091505b50611541565b600090505b60008167ffffffffffffffff81111561155d5761155c61388d565b5b60405190808252806020026020018201604052801561158b5781602001602082028036833780820191505090505b509050600082036115a257809450505050506116a5565b60006115ad88611795565b9050600081604001516115c257816000015190505b60008990505b8881141580156115d85750848714155b15611697576115e6816128ab565b9250826040015161168c57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161461163157826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361168b578084888060010199508151811061167e5761167d613fe3565b5b6020026020010181815250505b5b8060010190506115c8565b508583528296505050505050505b9392505050565b816116b681611dba565b6116d2576116c2611e06565b156116d1576116d081611e1d565b5b5b6116dc83836128e0565b505050565b6000600c54905090565b6116f3611b48565b80600d8190555050565b611705611b48565b80600e60006101000a81548160ff02191690831515021790555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461177c5761175f33611dba565b61177b5761176b611e06565b1561177a5761177933611e1d565b5b5b5b611788858585856129eb565b5050505050565b600c5481565b61179d612e59565b6117a5612e59565b6117ad611fa5565b8310806117c157506117bd6128d6565b8310155b156117cf57809150506117fa565b6117d8836128ab565b90508060400151156117ed57809150506117fa565b6117f683612a5e565b9150505b919050565b606061180a82611d5b565b611840576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061184a612a7e565b9050600081510361186a5760405180602001604052806000815250611895565b8061187484612b10565b604051602001611885929190614082565b6040516020818303038152906040525b915050919050565b600b60009054906101000a900460ff1681565b600f5481565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611952611b48565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b890614118565b60405180910390fd5b6119ca816127e7565b50565b6119d5611b48565b80600c8190555050565b6119e7611b48565b8060ff1660028111156119fd576119fc613aab565b5b600b60006101000a81548160ff02191690836002811115611a2157611a20613aab565b5b021790555050565b600e60009054906101000a900460ff1681565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a9757506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611ac75750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611b415750611b4082611a3c565b5b9050919050565b611b50612b60565b73ffffffffffffffffffffffffffffffffffffffff16611b6e6113e5565b73ffffffffffffffffffffffffffffffffffffffff1614611bc4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bbb90614184565b60405180910390fd5b565b611bce61249f565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115611c2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2390614216565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611c9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9290614282565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600960008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b600081611d66611fa5565b11158015611d75575060015482105b8015611db3575060007c0100000000000000000000000000000000000000000000000000000000600560008581526020019081526020016000205416145b9050919050565b6000731e0049783f008a0085193e00003d00cd54003c7173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b6000600e60009054906101000a900460ff16905090565b69c617113400112233445560005230601a5280603a52600080604460166daaeb6d7670e522a718067333cd4e5afa611e59573d6000803e3d6000fd5b6000603a5250565b6000611e6c8261104b565b90508073ffffffffffffffffffffffffffffffffffffffff16611e8d612b68565b73ffffffffffffffffffffffffffffffffffffffff1614611ef057611eb981611eb4612b68565b6118b6565b611eef576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826007600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b6000611fb8611fa5565b60015403905090565b6000600154905060008203612002576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61200f6000848385612b70565b600160406001901b178202600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612086836120776000866000612b76565b61208085612b9e565b17612bae565b6005600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461212757808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506120ec565b5060008203612162576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060018190555050506121786000848385612bd9565b505050565b60006121888261271b565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146121ef576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806121fb84612bdf565b91509150612211818761220c612b68565b612c06565b61225d5761222686612221612b68565b6118b6565b61225c576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036122c3576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122d08686866001612b70565b80156122db57600082555b600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506123a985612385888887612b76565b7c020000000000000000000000000000000000000000000000000000000017612bae565b600560008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361242f576000600185019050600060056000838152602001908152602001600020540361242d57600154811461242c578360056000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46124978686866001612bd9565b505050505050565b6000612710905090565b6124c483838360405180602001604052806000815250611722565b505050565b60006124d48361271b565b905060008190506000806124e786612bdf565b9150915084156125505761250381846124fe612b68565b612c06565b61254f5761251883612513612b68565b6118b6565b61254e576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b61255e836000886001612b70565b801561256957600082555b600160806001901b03600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612611836125ce85600088612b76565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717612bae565b600560008881526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008516036126975760006001870190506000600560008381526020019081526020016000205403612695576001548114612694578460056000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612701836000886001612bd9565b600260008154809291906001019190505550505050505050565b6000808290508061272a611fa5565b116127b0576001548110156127af5760006005600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036127ad575b600081036127a3576005600083600190039350838152602001908152602001600020549050612779565b80925050506127e2565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6128b3612e59565b6128cf6005600084815260200190815260200160002054612c4a565b9050919050565b6000600154905090565b80600860006128ed612b68565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661299a612b68565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516129df9190612f5c565b60405180910390a35050565b6129f6848484610bd6565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612a5857612a2184848484612d00565b612a57576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b612a66612e59565b612a77612a728361271b565b612c4a565b9050919050565b606060118054612a8d90613be0565b80601f0160208091040260200160405190810160405280929190818152602001828054612ab990613be0565b8015612b065780601f10612adb57610100808354040283529160200191612b06565b820191906000526020600020905b815481529060010190602001808311612ae957829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b600115612b4b57600184039350600a81066030018453600a8104905080612b29575b50828103602084039350808452505050919050565b600033905090565b600033905090565b50505050565b60008060e883901c905060e8612b8d868684612e50565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60008060006007600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b612c52612e59565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612d26612b68565b8786866040518563ffffffff1660e01b8152600401612d4894939291906142f7565b6020604051808303816000875af1925050508015612d8457506040513d601f19601f82011682018060405250810190612d819190614358565b60015b612dfd573d8060008114612db4576040519150601f19603f3d011682016040523d82523d6000602084013e612db9565b606091505b506000815103612df5576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612ef181612ebc565b8114612efc57600080fd5b50565b600081359050612f0e81612ee8565b92915050565b600060208284031215612f2a57612f29612eb2565b5b6000612f3884828501612eff565b91505092915050565b60008115159050919050565b612f5681612f41565b82525050565b6000602082019050612f716000830184612f4d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612fa282612f77565b9050919050565b612fb281612f97565b8114612fbd57600080fd5b50565b600081359050612fcf81612fa9565b92915050565b60006bffffffffffffffffffffffff82169050919050565b612ff681612fd5565b811461300157600080fd5b50565b60008135905061301381612fed565b92915050565b600080604083850312156130305761302f612eb2565b5b600061303e85828601612fc0565b925050602061304f85828601613004565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613093578082015181840152602081019050613078565b60008484015250505050565b6000601f19601f8301169050919050565b60006130bb82613059565b6130c58185613064565b93506130d5818560208601613075565b6130de8161309f565b840191505092915050565b6000602082019050818103600083015261310381846130b0565b905092915050565b6000819050919050565b61311e8161310b565b811461312957600080fd5b50565b60008135905061313b81613115565b92915050565b60006020828403121561315757613156612eb2565b5b60006131658482850161312c565b91505092915050565b61317781612f97565b82525050565b6000602082019050613192600083018461316e565b92915050565b600080604083850312156131af576131ae612eb2565b5b60006131bd85828601612fc0565b92505060206131ce8582860161312c565b9150509250929050565b6131e18161310b565b82525050565b60006020820190506131fc60008301846131d8565b92915050565b60006020828403121561321857613217612eb2565b5b600061322684828501612fc0565b91505092915050565b600060ff82169050919050565b6132458161322f565b82525050565b6000602082019050613260600083018461323c565b92915050565b600061ffff82169050919050565b61327d81613266565b811461328857600080fd5b50565b60008135905061329a81613274565b92915050565b6000602082840312156132b6576132b5612eb2565b5b60006132c48482850161328b565b91505092915050565b6000806000606084860312156132e6576132e5612eb2565b5b60006132f486828701612fc0565b935050602061330586828701612fc0565b92505060406133168682870161312c565b9150509250925092565b6000806040838503121561333757613336612eb2565b5b60006133458582860161312c565b92505060206133568582860161312c565b9150509250929050565b6000604082019050613375600083018561316e565b61338260208301846131d8565b9392505050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133ae576133ad613389565b5b8235905067ffffffffffffffff8111156133cb576133ca61338e565b5b6020830191508360018202830111156133e7576133e6613393565b5b9250929050565b6000806020838503121561340557613404612eb2565b5b600083013567ffffffffffffffff81111561342357613422612eb7565b5b61342f85828601613398565b92509250509250929050565b60008083601f84011261345157613450613389565b5b8235905067ffffffffffffffff81111561346e5761346d61338e565b5b60208301915083602082028301111561348a57613489613393565b5b9250929050565b600080602083850312156134a8576134a7612eb2565b5b600083013567ffffffffffffffff8111156134c6576134c5612eb7565b5b6134d28582860161343b565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61351381612f97565b82525050565b600067ffffffffffffffff82169050919050565b61353681613519565b82525050565b61354581612f41565b82525050565b600062ffffff82169050919050565b6135638161354b565b82525050565b60808201600082015161357f600085018261350a565b506020820151613592602085018261352d565b5060408201516135a5604085018261353c565b5060608201516135b8606085018261355a565b50505050565b60006135ca8383613569565b60808301905092915050565b6000602082019050919050565b60006135ee826134de565b6135f881856134e9565b9350613603836134fa565b8060005b8381101561363457815161361b88826135be565b9750613626836135d6565b925050600181019050613607565b5085935050505092915050565b6000602082019050818103600083015261365b81846135e3565b905092915050565b61366c8161322f565b811461367757600080fd5b50565b60008135905061368981613663565b92915050565b6000602082840312156136a5576136a4612eb2565b5b60006136b38482850161367a565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6136f18161310b565b82525050565b600061370383836136e8565b60208301905092915050565b6000602082019050919050565b6000613727826136bc565b61373181856136c7565b935061373c836136d8565b8060005b8381101561376d57815161375488826136f7565b975061375f8361370f565b925050600181019050613740565b5085935050505092915050565b60006020820190508181036000830152613794818461371c565b905092915050565b6000806000606084860312156137b5576137b4612eb2565b5b60006137c386828701612fc0565b93505060206137d48682870161312c565b92505060406137e58682870161312c565b9150509250925092565b6137f881612f41565b811461380357600080fd5b50565b600081359050613815816137ef565b92915050565b6000806040838503121561383257613831612eb2565b5b600061384085828601612fc0565b925050602061385185828601613806565b9150509250929050565b60006020828403121561387157613870612eb2565b5b600061387f84828501613806565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6138c58261309f565b810181811067ffffffffffffffff821117156138e4576138e361388d565b5b80604052505050565b60006138f7612ea8565b905061390382826138bc565b919050565b600067ffffffffffffffff8211156139235761392261388d565b5b61392c8261309f565b9050602081019050919050565b82818337600083830152505050565b600061395b61395684613908565b6138ed565b90508281526020810184848401111561397757613976613888565b5b613982848285613939565b509392505050565b600082601f83011261399f5761399e613389565b5b81356139af848260208601613948565b91505092915050565b600080600080608085870312156139d2576139d1612eb2565b5b60006139e087828801612fc0565b94505060206139f187828801612fc0565b9350506040613a028782880161312c565b925050606085013567ffffffffffffffff811115613a2357613a22612eb7565b5b613a2f8782880161398a565b91505092959194509250565b608082016000820151613a51600085018261350a565b506020820151613a64602085018261352d565b506040820151613a77604085018261353c565b506060820151613a8a606085018261355a565b50505050565b6000608082019050613aa56000830184613a3b565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110613aeb57613aea613aab565b5b50565b6000819050613afc82613ada565b919050565b6000613b0c82613aee565b9050919050565b613b1c81613b01565b82525050565b6000602082019050613b376000830184613b13565b92915050565b6000819050919050565b613b5081613b3d565b82525050565b6000602082019050613b6b6000830184613b47565b92915050565b60008060408385031215613b8857613b87612eb2565b5b6000613b9685828601612fc0565b9250506020613ba785828601612fc0565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613bf857607f821691505b602082108103613c0b57613c0a613bb1565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613c4b8261310b565b9150613c568361310b565b9250828201905080821115613c6e57613c6d613c11565b5b92915050565b6000613c7f8261310b565b9150613c8a8361310b565b9250828202613c988161310b565b91508282048414831517613caf57613cae613c11565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613cf08261310b565b9150613cfb8361310b565b925082613d0b57613d0a613cb6565b5b828204905092915050565b600081905092915050565b50565b6000613d31600083613d16565b9150613d3c82613d21565b600082019050919050565b6000613d5282613d24565b9150819050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613dc97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613d8c565b613dd38683613d8c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000613e10613e0b613e068461310b565b613deb565b61310b565b9050919050565b6000819050919050565b613e2a83613df5565b613e3e613e3682613e17565b848454613d99565b825550505050565b600090565b613e53613e46565b613e5e818484613e21565b505050565b5b81811015613e8257613e77600082613e4b565b600181019050613e64565b5050565b601f821115613ec757613e9881613d67565b613ea184613d7c565b81016020851015613eb0578190505b613ec4613ebc85613d7c565b830182613e63565b50505b505050565b600082821c905092915050565b6000613eea60001984600802613ecc565b1980831691505092915050565b6000613f038383613ed9565b9150826002028217905092915050565b613f1d8383613d5c565b67ffffffffffffffff811115613f3657613f3561388d565b5b613f408254613be0565b613f4b828285613e86565b6000601f831160018114613f7a5760008415613f68578287013590505b613f728582613ef7565b865550613fda565b601f198416613f8886613d67565b60005b82811015613fb057848901358255600182019150602085019450602081019050613f8b565b86831015613fcd5784890135613fc9601f891682613ed9565b8355505b6001600288020188555050505b50505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061401d8261310b565b91506140288361310b565b92508282039050818111156140405761403f613c11565b5b92915050565b600081905092915050565b600061405c82613059565b6140668185614046565b9350614076818560208601613075565b80840191505092915050565b600061408e8285614051565b915061409a8284614051565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614102602683613064565b915061410d826140a6565b604082019050919050565b60006020820190508181036000830152614131816140f5565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061416e602083613064565b915061417982614138565b602082019050919050565b6000602082019050818103600083015261419d81614161565b9050919050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b6000614200602a83613064565b915061420b826141a4565b604082019050919050565b6000602082019050818103600083015261422f816141f3565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b600061426c601983613064565b915061427782614236565b602082019050919050565b6000602082019050818103600083015261429b8161425f565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006142c9826142a2565b6142d381856142ad565b93506142e3818560208601613075565b6142ec8161309f565b840191505092915050565b600060808201905061430c600083018761316e565b614319602083018661316e565b61432660408301856131d8565b818103606083015261433881846142be565b905095945050505050565b60008151905061435281612ee8565b92915050565b60006020828403121561436e5761436d612eb2565b5b600061437c84828501614343565b9150509291505056fea2646970667358221220978d358a2975767dcd2c15c68c31bedad9d53abe79a1d0ef1aba08794b01c0c864736f6c63430008130033000000000000000000000000c2077f0796aba93168616504320e15117d9282fa

Deployed Bytecode

0x6080604052600436106102515760003560e01c8063715018a611610139578063b88d4fde116100b6578063d6492d811161007a578063d6492d81146108a8578063e985e9c5146108d3578063f2fde38b14610910578063f4a0a52814610939578063f8b89dfb14610962578063fb796e6c1461098b57610251565b8063b88d4fde146107bc578063c002d23d146107d8578063c23dc68f14610803578063c87b56dd14610840578063cbccefb21461087d57610251565b806399a2557a116100fd57806399a2557a146106d9578063a22cb46514610716578063a7f93ebd1461073f578063b53cff0f1461076a578063b7c0b8e81461079357610251565b8063715018a614610604578063828122ab1461061b5780638462151c146106465780638da5cb5b1461068357806395d89b41146106ae57610251565b806332cb6b0c116101d257806355f804b31161019657806355f804b3146104dd5780635ade26c6146105065780635bbb2177146105315780636352211e1461056e5780636ecd2306146105ab57806370a08231146105c757610251565b806332cb6b0c1461042b5780633ccfd60b1461045657806342842e0e1461046d57806342966c681461048957806350c96509146104b257610251565b806318160ddd1161021957806318160ddd146103405780631ac08c1f1461036b5780631b1f4019146103a857806323b872dd146103d15780632a55205a146103ed57610251565b806301ffc9a71461025657806304634d8d1461029357806306fdde03146102bc578063081812fc146102e7578063095ea7b314610324575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190612f14565b6109b6565b60405161028a9190612f5c565b60405180910390f35b34801561029f57600080fd5b506102ba60048036038101906102b59190613019565b6109d8565b005b3480156102c857600080fd5b506102d16109ee565b6040516102de91906130e9565b60405180910390f35b3480156102f357600080fd5b5061030e60048036038101906103099190613141565b610a80565b60405161031b919061317d565b60405180910390f35b61033e60048036038101906103399190613198565b610aff565b005b34801561034c57600080fd5b50610355610b34565b60405161036291906131e7565b60405180910390f35b34801561037757600080fd5b50610392600480360381019061038d9190613202565b610b4b565b60405161039f919061324b565b60405180910390f35b3480156103b457600080fd5b506103cf60048036038101906103ca91906132a0565b610b6b565b005b6103eb60048036038101906103e691906132cd565b610bd6565b005b3480156103f957600080fd5b50610414600480360381019061040f9190613320565b610c41565b604051610422929190613360565b60405180910390f35b34801561043757600080fd5b50610440610e2b565b60405161044d91906131e7565b60405180910390f35b34801561046257600080fd5b5061046b610e31565b005b610487600480360381019061048291906132cd565b610ee6565b005b34801561049557600080fd5b506104b060048036038101906104ab9190613141565b610f51565b005b3480156104be57600080fd5b506104c7610f5f565b6040516104d491906131e7565b60405180910390f35b3480156104e957600080fd5b5061050460048036038101906104ff91906133ee565b610f65565b005b34801561051257600080fd5b5061051b610f83565b60405161052891906131e7565b60405180910390f35b34801561053d57600080fd5b5061055860048036038101906105539190613491565b610f88565b6040516105659190613641565b60405180910390f35b34801561057a57600080fd5b5061059560048036038101906105909190613141565b61104b565b6040516105a2919061317d565b60405180910390f35b6105c560048036038101906105c0919061368f565b61105d565b005b3480156105d357600080fd5b506105ee60048036038101906105e99190613202565b6111d1565b6040516105fb91906131e7565b60405180910390f35b34801561061057600080fd5b50610619611289565b005b34801561062757600080fd5b5061063061129d565b60405161063d91906131e7565b60405180910390f35b34801561065257600080fd5b5061066d60048036038101906106689190613202565b6112a2565b60405161067a919061377a565b60405180910390f35b34801561068f57600080fd5b506106986113e5565b6040516106a5919061317d565b60405180910390f35b3480156106ba57600080fd5b506106c361140e565b6040516106d091906130e9565b60405180910390f35b3480156106e557600080fd5b5061070060048036038101906106fb919061379c565b6114a0565b60405161070d919061377a565b60405180910390f35b34801561072257600080fd5b5061073d6004803603810190610738919061381b565b6116ac565b005b34801561074b57600080fd5b506107546116e1565b60405161076191906131e7565b60405180910390f35b34801561077657600080fd5b50610791600480360381019061078c9190613141565b6116eb565b005b34801561079f57600080fd5b506107ba60048036038101906107b5919061385b565b6116fd565b005b6107d660048036038101906107d191906139b8565b611722565b005b3480156107e457600080fd5b506107ed61178f565b6040516107fa91906131e7565b60405180910390f35b34801561080f57600080fd5b5061082a60048036038101906108259190613141565b611795565b6040516108379190613a90565b60405180910390f35b34801561084c57600080fd5b5061086760048036038101906108629190613141565b6117ff565b60405161087491906130e9565b60405180910390f35b34801561088957600080fd5b5061089261189d565b60405161089f9190613b22565b60405180910390f35b3480156108b457600080fd5b506108bd6118b0565b6040516108ca9190613b56565b60405180910390f35b3480156108df57600080fd5b506108fa60048036038101906108f59190613b71565b6118b6565b6040516109079190612f5c565b60405180910390f35b34801561091c57600080fd5b5061093760048036038101906109329190613202565b61194a565b005b34801561094557600080fd5b50610960600480360381019061095b9190613141565b6119cd565b005b34801561096e57600080fd5b506109896004803603810190610984919061368f565b6119df565b005b34801561099757600080fd5b506109a0611a29565b6040516109ad9190612f5c565b60405180910390f35b60006109c182611a3c565b806109d157506109d082611ace565b5b9050919050565b6109e0611b48565b6109ea8282611bc6565b5050565b6060600380546109fd90613be0565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2990613be0565b8015610a765780601f10610a4b57610100808354040283529160200191610a76565b820191906000526020600020905b815481529060010190602001808311610a5957829003601f168201915b5050505050905090565b6000610a8b82611d5b565b610ac1576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610b0981611dba565b610b2557610b15611e06565b15610b2457610b2381611e1d565b5b5b610b2f8383611e61565b505050565b6000610b3e611fa5565b6002546001540303905090565b60106020528060005260406000206000915054906101000a900460ff1681565b610b73611b48565b6101bc8161ffff16610b83611fae565b610b8d9190613c40565b1115610bc5576040517fd05cb60900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd3338261ffff16611fc1565b50565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c3057610c1333611dba565b610c2f57610c1f611e06565b15610c2e57610c2d33611e1d565b5b5b5b610c3b84848461217d565b50505050565b6000806000600a60008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610dd65760096040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610de061249f565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610e0c9190613c74565b610e169190613ce5565b90508160000151819350935050509250929050565b6101bc81565b610e39611b48565b6000610e436113e5565b73ffffffffffffffffffffffffffffffffffffffff1647604051610e6690613d47565b60006040518083038185875af1925050503d8060008114610ea3576040519150601f19603f3d011682016040523d82523d6000602084013e610ea8565b606091505b5050905080610ee3576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f4057610f2333611dba565b610f3f57610f2f611e06565b15610f3e57610f3d33611e1d565b5b5b5b610f4b8484846124a9565b50505050565b610f5c8160016124c9565b50565b600d5481565b610f6d611b48565b818160119182610f7e929190613f13565b505050565b600381565b6060600083839050905060008167ffffffffffffffff811115610fae57610fad61388d565b5b604051908082528060200260200182016040528015610fe757816020015b610fd4612e59565b815260200190600190039081610fcc5790505b50905060005b82811461103f5761101686868381811061100a57611009613fe3565b5b90506020020135611795565b82828151811061102957611028613fe3565b5b6020026020010181905250806001019050610fed565b50809250505092915050565b60006110568261271b565b9050919050565b6002808111156110705761106f613aab565b5b600281111561108257611081613aab565b5b600b60009054906101000a900460ff1660028111156110a4576110a3613aab565b5b146110db576040517feb56075600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d546101bc6110eb9190614012565b8160ff166110f7611fae565b6111019190613c40565b1115611139576040517fd05cb60900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60038160ff161115611177576040517f4b231f9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c548160ff166111889190613c74565b3410156111c1576040517f31fc877f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111ce338260ff16611fc1565b50565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611238576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611291611b48565b61129b60006127e7565b565b600181565b606060008060006112b2856111d1565b905060008167ffffffffffffffff8111156112d0576112cf61388d565b5b6040519080825280602002602001820160405280156112fe5781602001602082028036833780820191505090505b509050611309612e59565b6000611313611fa5565b90505b8386146113d757611326816128ab565b915081604001516113cc57600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461137157816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113cb57808387806001019850815181106113be576113bd613fe3565b5b6020026020010181815250505b5b806001019050611316565b508195505050505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606004805461141d90613be0565b80601f016020809104026020016040519081016040528092919081815260200182805461144990613be0565b80156114965780601f1061146b57610100808354040283529160200191611496565b820191906000526020600020905b81548152906001019060200180831161147957829003601f168201915b5050505050905090565b60608183106114db576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806114e66128d6565b90506114f0611fa5565b851015611502576114ff611fa5565b94505b8084111561150e578093505b6000611519876111d1565b90508486101561153c576000868603905081811015611536578091505b50611541565b600090505b60008167ffffffffffffffff81111561155d5761155c61388d565b5b60405190808252806020026020018201604052801561158b5781602001602082028036833780820191505090505b509050600082036115a257809450505050506116a5565b60006115ad88611795565b9050600081604001516115c257816000015190505b60008990505b8881141580156115d85750848714155b15611697576115e6816128ab565b9250826040015161168c57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161461163157826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361168b578084888060010199508151811061167e5761167d613fe3565b5b6020026020010181815250505b5b8060010190506115c8565b508583528296505050505050505b9392505050565b816116b681611dba565b6116d2576116c2611e06565b156116d1576116d081611e1d565b5b5b6116dc83836128e0565b505050565b6000600c54905090565b6116f3611b48565b80600d8190555050565b611705611b48565b80600e60006101000a81548160ff02191690831515021790555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461177c5761175f33611dba565b61177b5761176b611e06565b1561177a5761177933611e1d565b5b5b5b611788858585856129eb565b5050505050565b600c5481565b61179d612e59565b6117a5612e59565b6117ad611fa5565b8310806117c157506117bd6128d6565b8310155b156117cf57809150506117fa565b6117d8836128ab565b90508060400151156117ed57809150506117fa565b6117f683612a5e565b9150505b919050565b606061180a82611d5b565b611840576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061184a612a7e565b9050600081510361186a5760405180602001604052806000815250611895565b8061187484612b10565b604051602001611885929190614082565b6040516020818303038152906040525b915050919050565b600b60009054906101000a900460ff1681565b600f5481565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611952611b48565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b890614118565b60405180910390fd5b6119ca816127e7565b50565b6119d5611b48565b80600c8190555050565b6119e7611b48565b8060ff1660028111156119fd576119fc613aab565b5b600b60006101000a81548160ff02191690836002811115611a2157611a20613aab565b5b021790555050565b600e60009054906101000a900460ff1681565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a9757506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611ac75750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611b415750611b4082611a3c565b5b9050919050565b611b50612b60565b73ffffffffffffffffffffffffffffffffffffffff16611b6e6113e5565b73ffffffffffffffffffffffffffffffffffffffff1614611bc4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bbb90614184565b60405180910390fd5b565b611bce61249f565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115611c2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2390614216565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611c9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9290614282565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600960008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b600081611d66611fa5565b11158015611d75575060015482105b8015611db3575060007c0100000000000000000000000000000000000000000000000000000000600560008581526020019081526020016000205416145b9050919050565b6000731e0049783f008a0085193e00003d00cd54003c7173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b6000600e60009054906101000a900460ff16905090565b69c617113400112233445560005230601a5280603a52600080604460166daaeb6d7670e522a718067333cd4e5afa611e59573d6000803e3d6000fd5b6000603a5250565b6000611e6c8261104b565b90508073ffffffffffffffffffffffffffffffffffffffff16611e8d612b68565b73ffffffffffffffffffffffffffffffffffffffff1614611ef057611eb981611eb4612b68565b6118b6565b611eef576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826007600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b6000611fb8611fa5565b60015403905090565b6000600154905060008203612002576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61200f6000848385612b70565b600160406001901b178202600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612086836120776000866000612b76565b61208085612b9e565b17612bae565b6005600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461212757808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506120ec565b5060008203612162576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060018190555050506121786000848385612bd9565b505050565b60006121888261271b565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146121ef576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806121fb84612bdf565b91509150612211818761220c612b68565b612c06565b61225d5761222686612221612b68565b6118b6565b61225c576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036122c3576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122d08686866001612b70565b80156122db57600082555b600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506123a985612385888887612b76565b7c020000000000000000000000000000000000000000000000000000000017612bae565b600560008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361242f576000600185019050600060056000838152602001908152602001600020540361242d57600154811461242c578360056000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46124978686866001612bd9565b505050505050565b6000612710905090565b6124c483838360405180602001604052806000815250611722565b505050565b60006124d48361271b565b905060008190506000806124e786612bdf565b9150915084156125505761250381846124fe612b68565b612c06565b61254f5761251883612513612b68565b6118b6565b61254e576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b61255e836000886001612b70565b801561256957600082555b600160806001901b03600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612611836125ce85600088612b76565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717612bae565b600560008881526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008516036126975760006001870190506000600560008381526020019081526020016000205403612695576001548114612694578460056000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612701836000886001612bd9565b600260008154809291906001019190505550505050505050565b6000808290508061272a611fa5565b116127b0576001548110156127af5760006005600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036127ad575b600081036127a3576005600083600190039350838152602001908152602001600020549050612779565b80925050506127e2565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6128b3612e59565b6128cf6005600084815260200190815260200160002054612c4a565b9050919050565b6000600154905090565b80600860006128ed612b68565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661299a612b68565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516129df9190612f5c565b60405180910390a35050565b6129f6848484610bd6565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612a5857612a2184848484612d00565b612a57576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b612a66612e59565b612a77612a728361271b565b612c4a565b9050919050565b606060118054612a8d90613be0565b80601f0160208091040260200160405190810160405280929190818152602001828054612ab990613be0565b8015612b065780601f10612adb57610100808354040283529160200191612b06565b820191906000526020600020905b815481529060010190602001808311612ae957829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b600115612b4b57600184039350600a81066030018453600a8104905080612b29575b50828103602084039350808452505050919050565b600033905090565b600033905090565b50505050565b60008060e883901c905060e8612b8d868684612e50565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60008060006007600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b612c52612e59565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612d26612b68565b8786866040518563ffffffff1660e01b8152600401612d4894939291906142f7565b6020604051808303816000875af1925050508015612d8457506040513d601f19601f82011682018060405250810190612d819190614358565b60015b612dfd573d8060008114612db4576040519150601f19603f3d011682016040523d82523d6000602084013e612db9565b606091505b506000815103612df5576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612ef181612ebc565b8114612efc57600080fd5b50565b600081359050612f0e81612ee8565b92915050565b600060208284031215612f2a57612f29612eb2565b5b6000612f3884828501612eff565b91505092915050565b60008115159050919050565b612f5681612f41565b82525050565b6000602082019050612f716000830184612f4d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612fa282612f77565b9050919050565b612fb281612f97565b8114612fbd57600080fd5b50565b600081359050612fcf81612fa9565b92915050565b60006bffffffffffffffffffffffff82169050919050565b612ff681612fd5565b811461300157600080fd5b50565b60008135905061301381612fed565b92915050565b600080604083850312156130305761302f612eb2565b5b600061303e85828601612fc0565b925050602061304f85828601613004565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613093578082015181840152602081019050613078565b60008484015250505050565b6000601f19601f8301169050919050565b60006130bb82613059565b6130c58185613064565b93506130d5818560208601613075565b6130de8161309f565b840191505092915050565b6000602082019050818103600083015261310381846130b0565b905092915050565b6000819050919050565b61311e8161310b565b811461312957600080fd5b50565b60008135905061313b81613115565b92915050565b60006020828403121561315757613156612eb2565b5b60006131658482850161312c565b91505092915050565b61317781612f97565b82525050565b6000602082019050613192600083018461316e565b92915050565b600080604083850312156131af576131ae612eb2565b5b60006131bd85828601612fc0565b92505060206131ce8582860161312c565b9150509250929050565b6131e18161310b565b82525050565b60006020820190506131fc60008301846131d8565b92915050565b60006020828403121561321857613217612eb2565b5b600061322684828501612fc0565b91505092915050565b600060ff82169050919050565b6132458161322f565b82525050565b6000602082019050613260600083018461323c565b92915050565b600061ffff82169050919050565b61327d81613266565b811461328857600080fd5b50565b60008135905061329a81613274565b92915050565b6000602082840312156132b6576132b5612eb2565b5b60006132c48482850161328b565b91505092915050565b6000806000606084860312156132e6576132e5612eb2565b5b60006132f486828701612fc0565b935050602061330586828701612fc0565b92505060406133168682870161312c565b9150509250925092565b6000806040838503121561333757613336612eb2565b5b60006133458582860161312c565b92505060206133568582860161312c565b9150509250929050565b6000604082019050613375600083018561316e565b61338260208301846131d8565b9392505050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133ae576133ad613389565b5b8235905067ffffffffffffffff8111156133cb576133ca61338e565b5b6020830191508360018202830111156133e7576133e6613393565b5b9250929050565b6000806020838503121561340557613404612eb2565b5b600083013567ffffffffffffffff81111561342357613422612eb7565b5b61342f85828601613398565b92509250509250929050565b60008083601f84011261345157613450613389565b5b8235905067ffffffffffffffff81111561346e5761346d61338e565b5b60208301915083602082028301111561348a57613489613393565b5b9250929050565b600080602083850312156134a8576134a7612eb2565b5b600083013567ffffffffffffffff8111156134c6576134c5612eb7565b5b6134d28582860161343b565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61351381612f97565b82525050565b600067ffffffffffffffff82169050919050565b61353681613519565b82525050565b61354581612f41565b82525050565b600062ffffff82169050919050565b6135638161354b565b82525050565b60808201600082015161357f600085018261350a565b506020820151613592602085018261352d565b5060408201516135a5604085018261353c565b5060608201516135b8606085018261355a565b50505050565b60006135ca8383613569565b60808301905092915050565b6000602082019050919050565b60006135ee826134de565b6135f881856134e9565b9350613603836134fa565b8060005b8381101561363457815161361b88826135be565b9750613626836135d6565b925050600181019050613607565b5085935050505092915050565b6000602082019050818103600083015261365b81846135e3565b905092915050565b61366c8161322f565b811461367757600080fd5b50565b60008135905061368981613663565b92915050565b6000602082840312156136a5576136a4612eb2565b5b60006136b38482850161367a565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6136f18161310b565b82525050565b600061370383836136e8565b60208301905092915050565b6000602082019050919050565b6000613727826136bc565b61373181856136c7565b935061373c836136d8565b8060005b8381101561376d57815161375488826136f7565b975061375f8361370f565b925050600181019050613740565b5085935050505092915050565b60006020820190508181036000830152613794818461371c565b905092915050565b6000806000606084860312156137b5576137b4612eb2565b5b60006137c386828701612fc0565b93505060206137d48682870161312c565b92505060406137e58682870161312c565b9150509250925092565b6137f881612f41565b811461380357600080fd5b50565b600081359050613815816137ef565b92915050565b6000806040838503121561383257613831612eb2565b5b600061384085828601612fc0565b925050602061385185828601613806565b9150509250929050565b60006020828403121561387157613870612eb2565b5b600061387f84828501613806565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6138c58261309f565b810181811067ffffffffffffffff821117156138e4576138e361388d565b5b80604052505050565b60006138f7612ea8565b905061390382826138bc565b919050565b600067ffffffffffffffff8211156139235761392261388d565b5b61392c8261309f565b9050602081019050919050565b82818337600083830152505050565b600061395b61395684613908565b6138ed565b90508281526020810184848401111561397757613976613888565b5b613982848285613939565b509392505050565b600082601f83011261399f5761399e613389565b5b81356139af848260208601613948565b91505092915050565b600080600080608085870312156139d2576139d1612eb2565b5b60006139e087828801612fc0565b94505060206139f187828801612fc0565b9350506040613a028782880161312c565b925050606085013567ffffffffffffffff811115613a2357613a22612eb7565b5b613a2f8782880161398a565b91505092959194509250565b608082016000820151613a51600085018261350a565b506020820151613a64602085018261352d565b506040820151613a77604085018261353c565b506060820151613a8a606085018261355a565b50505050565b6000608082019050613aa56000830184613a3b565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110613aeb57613aea613aab565b5b50565b6000819050613afc82613ada565b919050565b6000613b0c82613aee565b9050919050565b613b1c81613b01565b82525050565b6000602082019050613b376000830184613b13565b92915050565b6000819050919050565b613b5081613b3d565b82525050565b6000602082019050613b6b6000830184613b47565b92915050565b60008060408385031215613b8857613b87612eb2565b5b6000613b9685828601612fc0565b9250506020613ba785828601612fc0565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613bf857607f821691505b602082108103613c0b57613c0a613bb1565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613c4b8261310b565b9150613c568361310b565b9250828201905080821115613c6e57613c6d613c11565b5b92915050565b6000613c7f8261310b565b9150613c8a8361310b565b9250828202613c988161310b565b91508282048414831517613caf57613cae613c11565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613cf08261310b565b9150613cfb8361310b565b925082613d0b57613d0a613cb6565b5b828204905092915050565b600081905092915050565b50565b6000613d31600083613d16565b9150613d3c82613d21565b600082019050919050565b6000613d5282613d24565b9150819050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613dc97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613d8c565b613dd38683613d8c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000613e10613e0b613e068461310b565b613deb565b61310b565b9050919050565b6000819050919050565b613e2a83613df5565b613e3e613e3682613e17565b848454613d99565b825550505050565b600090565b613e53613e46565b613e5e818484613e21565b505050565b5b81811015613e8257613e77600082613e4b565b600181019050613e64565b5050565b601f821115613ec757613e9881613d67565b613ea184613d7c565b81016020851015613eb0578190505b613ec4613ebc85613d7c565b830182613e63565b50505b505050565b600082821c905092915050565b6000613eea60001984600802613ecc565b1980831691505092915050565b6000613f038383613ed9565b9150826002028217905092915050565b613f1d8383613d5c565b67ffffffffffffffff811115613f3657613f3561388d565b5b613f408254613be0565b613f4b828285613e86565b6000601f831160018114613f7a5760008415613f68578287013590505b613f728582613ef7565b865550613fda565b601f198416613f8886613d67565b60005b82811015613fb057848901358255600182019150602085019450602081019050613f8b565b86831015613fcd5784890135613fc9601f891682613ed9565b8355505b6001600288020188555050505b50505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061401d8261310b565b91506140288361310b565b92508282039050818111156140405761403f613c11565b5b92915050565b600081905092915050565b600061405c82613059565b6140668185614046565b9350614076818560208601613075565b80840191505092915050565b600061408e8285614051565b915061409a8284614051565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614102602683613064565b915061410d826140a6565b604082019050919050565b60006020820190508181036000830152614131816140f5565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061416e602083613064565b915061417982614138565b602082019050919050565b6000602082019050818103600083015261419d81614161565b9050919050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b6000614200602a83613064565b915061420b826141a4565b604082019050919050565b6000602082019050818103600083015261422f816141f3565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b600061426c601983613064565b915061427782614236565b602082019050919050565b6000602082019050818103600083015261429b8161425f565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006142c9826142a2565b6142d381856142ad565b93506142e3818560208601613075565b6142ec8161309f565b840191505092915050565b600060808201905061430c600083018761316e565b614319602083018661316e565b61432660408301856131d8565b818103606083015261433881846142be565b905095945050505050565b60008151905061435281612ee8565b92915050565b60006020828403121561436e5761436d612eb2565b5b600061437c84828501614343565b9150509291505056fea2646970667358221220978d358a2975767dcd2c15c68c31bedad9d53abe79a1d0ef1aba08794b01c0c864736f6c63430008130033

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

000000000000000000000000c2077f0796aba93168616504320e15117d9282fa

-----Decoded View---------------
Arg [0] : deployer (address): 0xC2077F0796aBA93168616504320e15117D9282FA

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000c2077f0796aba93168616504320e15117d9282fa


Deployed Bytecode Sourcemap

687:4277:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3301:243;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2337:153;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10312:100:3;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16803:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4069:216:6;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6063:323:3;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1232:48:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2724:179;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4291:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1670:442:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;918:40:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2909:188;;;;;;;;;;;;;:::i;:::-;;4501:212;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;532:94:4;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1115:32:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2613:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1013:54;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1696:528:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11705:152:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1531:392:6;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7247:233:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1882:103:14;;;;;;;;;;;;;:::i;:::-;;963:45:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5572:900:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1234:87:14;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10488:104:3;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2612:2513:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3859:204:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2131:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2221:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2496:111;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4719:242;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1072:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1109:428:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10698:318:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;890:23:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1200:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17752:164:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2140:201:14;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2024:101:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1933:85;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1152:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3301:243;3424:4;3451:38;3477:11;3451:25;:38::i;:::-;:87;;;;3500:38;3526:11;3500:25;:38::i;:::-;3451:87;3437:101;;3301:243;;;:::o;2337:153::-;1120:13:14;:11;:13::i;:::-;2442:42:6::1;2461:8;2471:12;2442:18;:42::i;:::-;2337:153:::0;;:::o;10312:100:3:-;10366:13;10399:5;10392:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10312:100;:::o;16803:218::-;16879:7;16904:16;16912:7;16904;:16::i;:::-;16899:64;;16929:34;;;;;;;;;;;;;;16899:64;16983:15;:24;16999:7;16983:24;;;;;;;;;;;:30;;;;;;;;;;;;16976:37;;16803:218;;;:::o;4069:216:6:-;4227:8;3578:29:13;3598:8;3578:19;:29::i;:::-;3573:122;;3628:27;:25;:27::i;:::-;3624:59;;;3657:26;3674:8;3657:16;:26::i;:::-;3624:59;3573:122;4247:32:6::1;4261:8;4271:7;4247:13;:32::i;:::-;4069:216:::0;;;:::o;6063:323:3:-;6124:7;6352:15;:13;:15::i;:::-;6337:12;;6321:13;;:28;:46;6314:53;;6063:323;:::o;1232:48:6:-;;;;;;;;;;;;;;;;;;;;;;:::o;2724:179::-;1120:13:14;:11;:13::i;:::-;955:3:6::1;2813:8;2796:25;;:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:38;2792:69;;;2843:18;;;;;;;;;;;;;;2792:69;2870:27;2876:10;2888:8;2870:27;;:5;:27::i;:::-;2724:179:::0;:::o;4291:204::-;4439:4;3221:10:13;3213:18;;:4;:18;;;3209:184;;3253:31;3273:10;3253:19;:31::i;:::-;3248:134;;3309:27;:25;:27::i;:::-;3305:61;;;3338:28;3355:10;3338:16;:28::i;:::-;3305:61;3248:134;3209:184;4452:37:6::1;4471:4;4477:2;4481:7;4452:18;:37::i;:::-;4291:204:::0;;;;:::o;1670:442:2:-;1767:7;1776;1796:26;1825:17;:27;1843:8;1825:27;;;;;;;;;;;1796:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1897:1;1869:30;;:7;:16;;;:30;;;1865:92;;1926:19;1916:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1865:92;1969:21;2034:17;:15;:17::i;:::-;1993:58;;2007:7;:23;;;1994:36;;:10;:36;;;;:::i;:::-;1993:58;;;;:::i;:::-;1969:82;;2072:7;:16;;;2090:13;2064:40;;;;;;1670:442;;;;;:::o;918:40:6:-;955:3;918:40;:::o;2909:188::-;1120:13:14;:11;:13::i;:::-;2954:12:6::1;2980:7;:5;:7::i;:::-;2972:21;;3001;2972:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2953:74;;;3041:7;3036:56;;3066:18;;;;;;;;;;;;;;3036:56;2946:151;2909:188::o:0;4501:212::-;4653:4;3221:10:13;3213:18;;:4;:18;;;3209:184;;3253:31;3273:10;3253:19;:31::i;:::-;3248:134;;3309:27;:25;:27::i;:::-;3305:61;;;3338:28;3355:10;3338:16;:28::i;:::-;3305:61;3248:134;3209:184;4666:41:6::1;4689:4;4695:2;4699:7;4666:22;:41::i;:::-;4501:212:::0;;;;:::o;532:94:4:-;598:20;604:7;613:4;598:5;:20::i;:::-;532:94;:::o;1115:32:6:-;;;;:::o;2613:105::-;1120:13:14;:11;:13::i;:::-;2702:10:6::1;;2687:12;:25;;;;;;;:::i;:::-;;2613:105:::0;;:::o;1013:54::-;1066:1;1013:54;:::o;1696:528:5:-;1840:23;1906:22;1931:8;;:15;;1906:40;;1961:34;2019:14;1998:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;1961:73;;2054:9;2049:125;2070:14;2065:1;:19;2049:125;;2126:32;2146:8;;2155:1;2146:11;;;;;;;:::i;:::-;;;;;;;;2126:19;:32::i;:::-;2110:10;2121:1;2110:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;2086:3;;;;;2049:125;;;;2195:10;2188:17;;;;1696:528;;;;:::o;11705:152:3:-;11777:7;11820:27;11839:7;11820:18;:27::i;:::-;11797:52;;11705:152;;;:::o;1531:392:6:-;1609:1;1604:7;;;;;;;;:::i;:::-;;1589:22;;;;;;;;:::i;:::-;;:11;;;;;;;;;;;:22;;;;;;;;:::i;:::-;;;1585:50;;1620:15;;;;;;;;;;;;;;1585:50;1687:13;;955:3;1674:26;;;;:::i;:::-;1663:8;1646:25;;:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:54;1642:85;;;1709:18;;;;;;;;;;;;;;1642:85;1066:1;1738:8;:37;;;1734:76;;;1784:26;;;;;;;;;;;;;;1734:76;1844:10;;1833:8;:21;;;;;;:::i;:::-;1821:9;:33;1817:64;;;1863:18;;;;;;;;;;;;;;1817:64;1890:27;1896:10;1908:8;1890:27;;:5;:27::i;:::-;1531:392;:::o;7247:233:3:-;7319:7;7360:1;7343:19;;:5;:19;;;7339:60;;7371:28;;;;;;;;;;;;;;7339:60;1406:13;7417:18;:25;7436:5;7417:25;;;;;;;;;;;;;;;;:55;7410:62;;7247:233;;;:::o;1882:103:14:-;1120:13;:11;:13::i;:::-;1947:30:::1;1974:1;1947:18;:30::i;:::-;1882:103::o:0;963:45:6:-;1007:1;963:45;:::o;5572:900:5:-;5650:16;5704:19;5738:25;5778:22;5803:16;5813:5;5803:9;:16::i;:::-;5778:41;;5834:25;5876:14;5862:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5834:57;;5906:31;;:::i;:::-;5957:9;5969:15;:13;:15::i;:::-;5957:27;;5952:472;6001:14;5986:11;:29;5952:472;;6053:15;6066:1;6053:12;:15::i;:::-;6041:27;;6091:9;:16;;;6132:8;6087:73;6208:1;6182:28;;:9;:14;;;:28;;;6178:111;;6255:9;:14;;;6235:34;;6178:111;6332:5;6311:26;;:17;:26;;;6307:102;;6388:1;6362:8;6371:13;;;;;;6362:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;6307:102;5952:472;6017:3;;;;;5952:472;;;;6445:8;6438:15;;;;;;;5572:900;;;:::o;1234:87:14:-;1280:7;1307:6;;;;;;;;;;;1300:13;;1234:87;:::o;10488:104:3:-;10544:13;10577:7;10570:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10488:104;:::o;2612:2513:5:-;2755:16;2822:4;2813:5;:13;2809:45;;2835:19;;;;;;;;;;;;;;2809:45;2869:19;2903:17;2923:14;:12;:14::i;:::-;2903:34;;3023:15;:13;:15::i;:::-;3015:5;:23;3011:87;;;3067:15;:13;:15::i;:::-;3059:23;;3011:87;3174:9;3167:4;:16;3163:73;;;3211:9;3204:16;;3163:73;3250:25;3278:16;3288:5;3278:9;:16::i;:::-;3250:44;;3472:4;3464:5;:12;3460:278;;;3497:19;3526:5;3519:4;:12;3497:34;;3568:17;3554:11;:31;3550:111;;;3630:11;3610:31;;3550:111;3478:198;3460:278;;;3721:1;3701:21;;3460:278;3752:25;3794:17;3780:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3752:60;;3852:1;3831:17;:22;3827:78;;3881:8;3874:15;;;;;;;;3827:78;4049:31;4083:26;4103:5;4083:19;:26::i;:::-;4049:60;;4124:25;4369:9;:16;;;4364:92;;4426:9;:14;;;4406:34;;4364:92;4475:9;4487:5;4475:17;;4470:478;4499:4;4494:1;:9;;:45;;;;;4522:17;4507:11;:32;;4494:45;4470:478;;;4577:15;4590:1;4577:12;:15::i;:::-;4565:27;;4615:9;:16;;;4656:8;4611:73;4732:1;4706:28;;:9;:14;;;:28;;;4702:111;;4779:9;:14;;;4759:34;;4702:111;4856:5;4835:26;;:17;:26;;;4831:102;;4912:1;4886:8;4895:13;;;;;;4886:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;4831:102;4470:478;4541:3;;;;;4470:478;;;;5050:11;5040:8;5033:29;5098:8;5091:15;;;;;;;;2612:2513;;;;;;:::o;3859:204:6:-;3997:8;3578:29:13;3598:8;3578:19;:29::i;:::-;3573:122;;3628:27;:25;:27::i;:::-;3624:59;;;3657:26;3674:8;3657:16;:26::i;:::-;3624:59;3573:122;4014:43:6::1;4038:8;4048;4014:23;:43::i;:::-;3859:204:::0;;;:::o;2131:84::-;2176:7;2199:10;;2192:17;;2131:84;:::o;2221:110::-;1120:13:14;:11;:13::i;:::-;2311:14:6::1;2295:13;:30;;;;2221:110:::0;:::o;2496:111::-;1120:13:14;:11;:13::i;:::-;2596:5:6::1;2569:24;;:32;;;;;;;;;;;;;;;;;;2496:111:::0;:::o;4719:242::-;4895:4;3221:10:13;3213:18;;:4;:18;;;3209:184;;3253:31;3273:10;3253:19;:31::i;:::-;3248:134;;3309:27;:25;:27::i;:::-;3305:61;;;3338:28;3355:10;3338:16;:28::i;:::-;3305:61;3248:134;3209:184;4908:47:6::1;4931:4;4937:2;4941:7;4950:4;4908:22;:47::i;:::-;4719:242:::0;;;;;:::o;1072:38::-;;;;:::o;1109:428:5:-;1193:21;;:::i;:::-;1227:31;;:::i;:::-;1283:15;:13;:15::i;:::-;1273:7;:25;:54;;;;1313:14;:12;:14::i;:::-;1302:7;:25;;1273:54;1269:103;;;1351:9;1344:16;;;;;1269:103;1394:21;1407:7;1394:12;:21::i;:::-;1382:33;;1430:9;:16;;;1426:65;;;1470:9;1463:16;;;;;1426:65;1508:21;1521:7;1508:12;:21::i;:::-;1501:28;;;1109:428;;;;:::o;10698:318:3:-;10771:13;10802:16;10810:7;10802;:16::i;:::-;10797:59;;10827:29;;;;;;;;;;;;;;10797:59;10869:21;10893:10;:8;:10::i;:::-;10869:34;;10946:1;10927:7;10921:21;:26;:87;;;;;;;;;;;;;;;;;10974:7;10983:18;10993:7;10983:9;:18::i;:::-;10957:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10921:87;10914:94;;;10698:318;;;:::o;890:23:6:-;;;;;;;;;;;;;:::o;1200:27::-;;;;:::o;17752:164:3:-;17849:4;17873:18;:25;17892:5;17873:25;;;;;;;;;;;;;;;:35;17899:8;17873:35;;;;;;;;;;;;;;;;;;;;;;;;;17866:42;;17752:164;;;;:::o;2140:201:14:-;1120:13;:11;:13::i;:::-;2249:1:::1;2229:22;;:8;:22;;::::0;2221:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;2305:28;2324:8;2305:18;:28::i;:::-;2140:201:::0;:::o;2024:101:6:-;1120:13:14;:11;:13::i;:::-;2107:12:6::1;2094:10;:25;;;;2024:101:::0;:::o;1933:85::-;1120:13:14;:11;:13::i;:::-;2007:4:6::1;2002:10;;;;;;;;;;:::i;:::-;;1988:11;;:24;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;1933:85:::0;:::o;1152:43::-;;;;;;;;;;;;;:::o;9410:639:3:-;9495:4;9834:10;9819:25;;:11;:25;;;;:102;;;;9911:10;9896:25;;:11;:25;;;;9819:102;:179;;;;9988:10;9973:25;;:11;:25;;;;9819:179;9799:199;;9410:639;;;:::o;1400:215:2:-;1502:4;1541:26;1526:41;;;:11;:41;;;;:81;;;;1571:36;1595:11;1571:23;:36::i;:::-;1526:81;1519:88;;1400:215;;;:::o;1399:132:14:-;1474:12;:10;:12::i;:::-;1463:23;;:7;:5;:7::i;:::-;:23;;;1455:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1399:132::o;2762:332:2:-;2881:17;:15;:17::i;:::-;2865:33;;:12;:33;;;;2857:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;2984:1;2964:22;;:8;:22;;;2956:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;3051:35;;;;;;;;3063:8;3051:35;;;;;;3073:12;3051:35;;;;;3029:19;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2762:332;;:::o;18174:282:3:-;18239:4;18295:7;18276:15;:13;:15::i;:::-;:26;;:66;;;;;18329:13;;18319:7;:23;18276:66;:153;;;;;18428:1;2182:8;18380:17;:26;18398:7;18380:26;;;;;;;;;;;;:44;:49;18276:153;18256:173;;18174:282;;;:::o;3675:178:6:-;3764:4;3804:42;3784:63;;:8;:63;;;3777:70;;3675:178;;;:::o;3550:119::-;3619:4;3639:24;;;;;;;;;;;3632:31;;3550:119;:::o;3811:1359:13:-;4204:22;4198:4;4191:36;4297:9;4291:4;4284:23;4372:8;4366:4;4359:22;4549:4;4543;4537;4531;4504:25;4497:5;4486:68;4476:274;;4670:16;4664:4;4658;4643:44;4718:16;4712:4;4705:30;4476:274;5150:1;5144:4;5137:15;3811:1359;:::o;16236:408:3:-;16325:13;16341:16;16349:7;16341;:16::i;:::-;16325:32;;16397:5;16374:28;;:19;:17;:19::i;:::-;:28;;;16370:175;;16422:44;16439:5;16446:19;:17;:19::i;:::-;16422:16;:44::i;:::-;16417:128;;16494:35;;;;;;;;;;;;;;16417:128;16370:175;16590:2;16557:15;:24;16573:7;16557:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;16628:7;16624:2;16608:28;;16617:5;16608:28;;;;;;;;;;;;16314:330;16236:408;;:::o;3103:87:6:-;3160:7;3183:1;3176:8;;3103:87;:::o;6484:296:3:-;6539:7;6746:15;:13;:15::i;:::-;6730:13;;:31;6723:38;;6484:296;:::o;27823:2966::-;27896:20;27919:13;;27896:36;;27959:1;27947:8;:13;27943:44;;27969:18;;;;;;;;;;;;;;27943:44;28000:61;28030:1;28034:2;28038:12;28052:8;28000:21;:61::i;:::-;28544:1;1544:2;28514:1;:26;;28513:32;28501:8;:45;28475:18;:22;28494:2;28475:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;28823:139;28860:2;28914:33;28937:1;28941:2;28945:1;28914:14;:33::i;:::-;28881:30;28902:8;28881:20;:30::i;:::-;:66;28823:18;:139::i;:::-;28789:17;:31;28807:12;28789:31;;;;;;;;;;;:173;;;;28979:16;29010:11;29039:8;29024:12;:23;29010:37;;29560:16;29556:2;29552:25;29540:37;;29932:12;29892:8;29851:1;29789:25;29730:1;29669;29642:335;30303:1;30289:12;30285:20;30243:346;30344:3;30335:7;30332:16;30243:346;;30562:7;30552:8;30549:1;30522:25;30519:1;30516;30511:59;30397:1;30388:7;30384:15;30373:26;;30243:346;;;30247:77;30634:1;30622:8;:13;30618:45;;30644:19;;;;;;;;;;;;;;30618:45;30696:3;30680:13;:19;;;;28249:2462;;30721:60;30750:1;30754:2;30758:12;30772:8;30721:20;:60::i;:::-;27885:2904;27823:2966;;:::o;20442:2825::-;20584:27;20614;20633:7;20614:18;:27::i;:::-;20584:57;;20699:4;20658:45;;20674:19;20658:45;;;20654:86;;20712:28;;;;;;;;;;;;;;20654:86;20754:27;20783:23;20810:35;20837:7;20810:26;:35::i;:::-;20753:92;;;;20945:68;20970:15;20987:4;20993:19;:17;:19::i;:::-;20945:24;:68::i;:::-;20940:180;;21033:43;21050:4;21056:19;:17;:19::i;:::-;21033:16;:43::i;:::-;21028:92;;21085:35;;;;;;;;;;;;;;21028:92;20940:180;21151:1;21137:16;;:2;:16;;;21133:52;;21162:23;;;;;;;;;;;;;;21133:52;21198:43;21220:4;21226:2;21230:7;21239:1;21198:21;:43::i;:::-;21334:15;21331:160;;;21474:1;21453:19;21446:30;21331:160;21871:18;:24;21890:4;21871:24;;;;;;;;;;;;;;;;21869:26;;;;;;;;;;;;21940:18;:22;21959:2;21940:22;;;;;;;;;;;;;;;;21938:24;;;;;;;;;;;22262:146;22299:2;22348:45;22363:4;22369:2;22373:19;22348:14;:45::i;:::-;2462:8;22320:73;22262:18;:146::i;:::-;22233:17;:26;22251:7;22233:26;;;;;;;;;;;:175;;;;22579:1;2462:8;22528:19;:47;:52;22524:627;;22601:19;22633:1;22623:7;:11;22601:33;;22790:1;22756:17;:30;22774:11;22756:30;;;;;;;;;;;;:35;22752:384;;22894:13;;22879:11;:28;22875:242;;23074:19;23041:17;:30;23059:11;23041:30;;;;;;;;;;;:52;;;;22875:242;22752:384;22582:569;22524:627;23198:7;23194:2;23179:27;;23188:4;23179:27;;;;;;;;;;;;23217:42;23238:4;23244:2;23248:7;23257:1;23217:20;:42::i;:::-;20573:2694;;;20442:2825;;;:::o;2394:97:2:-;2452:6;2478:5;2471:12;;2394:97;:::o;23363:193:3:-;23509:39;23526:4;23532:2;23536:7;23509:39;;;;;;;;;;;;:16;:39::i;:::-;23363:193;;;:::o;35011:3081::-;35091:27;35121;35140:7;35121:18;:27::i;:::-;35091:57;;35161:12;35192:19;35161:52;;35227:27;35256:23;35283:35;35310:7;35283:26;:35::i;:::-;35226:92;;;;35335:13;35331:316;;;35456:68;35481:15;35498:4;35504:19;:17;:19::i;:::-;35456:24;:68::i;:::-;35451:184;;35548:43;35565:4;35571:19;:17;:19::i;:::-;35548:16;:43::i;:::-;35543:92;;35600:35;;;;;;;;;;;;;;35543:92;35451:184;35331:316;35659:51;35681:4;35695:1;35699:7;35708:1;35659:21;:51::i;:::-;35803:15;35800:160;;;35943:1;35922:19;35915:30;35800:160;36621:1;1671:3;36591:1;:26;;36590:32;36562:18;:24;36581:4;36562:24;;;;;;;;;;;;;;;;:60;;;;;;;;;;;36889:176;36926:4;36997:53;37012:4;37026:1;37030:19;36997:14;:53::i;:::-;2462:8;2182;36950:43;36949:101;36889:18;:176::i;:::-;36860:17;:26;36878:7;36860:26;;;;;;;;;;;:205;;;;37236:1;2462:8;37185:19;:47;:52;37181:627;;37258:19;37290:1;37280:7;:11;37258:33;;37447:1;37413:17;:30;37431:11;37413:30;;;;;;;;;;;;:35;37409:384;;37551:13;;37536:11;:28;37532:242;;37731:19;37698:17;:30;37716:11;37698:30;;;;;;;;;;;:52;;;;37532:242;37409:384;37239:569;37181:627;37863:7;37859:1;37836:35;;37845:4;37836:35;;;;;;;;;;;;37882:50;37903:4;37917:1;37921:7;37930:1;37882:20;:50::i;:::-;38059:12;;:14;;;;;;;;;;;;;35080:3012;;;;35011:3081;;:::o;12860:1275::-;12927:7;12947:12;12962:7;12947:22;;13030:4;13011:15;:13;:15::i;:::-;:23;13007:1061;;13064:13;;13057:4;:20;13053:1015;;;13102:14;13119:17;:23;13137:4;13119:23;;;;;;;;;;;;13102:40;;13236:1;2182:8;13208:6;:24;:29;13204:845;;13873:113;13890:1;13880:6;:11;13873:113;;13933:17;:25;13951:6;;;;;;;13933:25;;;;;;;;;;;;13924:34;;13873:113;;;14019:6;14012:13;;;;;;13204:845;13079:989;13053:1015;13007:1061;14096:31;;;;;;;;;;;;;;12860:1275;;;;:::o;2501:191:14:-;2575:16;2594:6;;;;;;;;;;;2575:25;;2620:8;2611:6;;:17;;;;;;;;;;;;;;;;;;2675:8;2644:40;;2665:8;2644:40;;;;;;;;;;;;2564:128;2501:191;:::o;12308:161:3:-;12376:21;;:::i;:::-;12417:44;12436:17;:24;12454:5;12436:24;;;;;;;;;;;;12417:18;:44::i;:::-;12410:51;;12308:161;;;:::o;5750:103::-;5805:7;5832:13;;5825:20;;5750:103;:::o;17361:234::-;17508:8;17456:18;:39;17475:19;:17;:19::i;:::-;17456:39;;;;;;;;;;;;;;;:49;17496:8;17456:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;17568:8;17532:55;;17547:19;:17;:19::i;:::-;17532:55;;;17578:8;17532:55;;;;;;:::i;:::-;;;;;;;;17361:234;;:::o;24154:407::-;24329:31;24342:4;24348:2;24352:7;24329:12;:31::i;:::-;24393:1;24375:2;:14;;;:19;24371:183;;24414:56;24445:4;24451:2;24455:7;24464:5;24414:30;:56::i;:::-;24409:145;;24498:40;;;;;;;;;;;;;;24409:145;24371:183;24154:407;;;;:::o;12046:166::-;12116:21;;:::i;:::-;12157:47;12176:27;12195:7;12176:18;:27::i;:::-;12157:18;:47::i;:::-;12150:54;;12046:166;;;:::o;3196:99:6:-;3248:13;3277:12;3270:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3196:99;:::o;40689:1745:3:-;40754:17;41188:4;41181;41175:11;41171:22;41280:1;41274:4;41267:15;41355:4;41352:1;41348:12;41341:19;;41437:1;41432:3;41425:14;41541:3;41780:5;41762:428;41788:1;41762:428;;;41828:1;41823:3;41819:11;41812:18;;41999:2;41993:4;41989:13;41985:2;41981:22;41976:3;41968:36;42093:2;42087:4;42083:13;42075:21;;42160:4;41762:428;42150:25;41762:428;41766:21;42229:3;42224;42220:13;42344:4;42339:3;42335:14;42328:21;;42409:6;42404:3;42397:19;40793:1634;;;40689:1745;;;:::o;656:98:0:-;709:7;736:10;729:17;;656:98;:::o;40482:105:3:-;40542:7;40569:10;40562:17;;40482:105;:::o;25223:159::-;;;;;:::o;39791:311::-;39926:7;39946:16;2586:3;39972:19;:41;;39946:68;;2586:3;40040:31;40051:4;40057:2;40061:9;40040:10;:31::i;:::-;40032:40;;:62;;40025:69;;;39791:311;;;;;:::o;15235:324::-;15305:14;15538:1;15528:8;15525:15;15499:24;15495:46;15485:56;;15235:324;;;:::o;14683:450::-;14763:14;14931:16;14924:5;14920:28;14911:37;;15108:5;15094:11;15069:23;15065:41;15062:52;15055:5;15052:63;15042:73;;14683:450;;;;:::o;26047:158::-;;;;;:::o;19337:485::-;19439:27;19468:23;19509:38;19550:15;:24;19566:7;19550:24;;;;;;;;;;;19509:65;;19727:18;19704:41;;19784:19;19778:26;19759:45;;19689:126;19337:485;;;:::o;18565:659::-;18714:11;18879:16;18872:5;18868:28;18859:37;;19039:16;19028:9;19024:32;19011:45;;19189:15;19178:9;19175:30;19167:5;19156:9;19153:20;19150:56;19140:66;;18565:659;;;;;:::o;14234:366::-;14300:31;;:::i;:::-;14377:6;14344:9;:14;;:41;;;;;;;;;;;2065:3;14430:6;:33;;14396:9;:24;;:68;;;;;;;;;;;14522:1;2182:8;14494:6;:24;:29;;14475:9;:16;;:48;;;;;;;;;;;2586:3;14563:6;:28;;14534:9;:19;;:58;;;;;;;;;;;14234:366;;;:::o;26645:716::-;26808:4;26854:2;26829:45;;;26875:19;:17;:19::i;:::-;26896:4;26902:7;26911:5;26829:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;26825:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27129:1;27112:6;:13;:18;27108:235;;27158:40;;;;;;;;;;;;;;27108:235;27301:6;27295:13;27286:6;27282:2;27278:15;27271:38;26825:529;26998:54;;;26988:64;;;:6;:64;;;;26981:71;;;26645:716;;;;;;:::o;39492:147::-;39629:6;39492:147;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:15:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:126::-;1555:7;1595:42;1588:5;1584:54;1573:65;;1518:126;;;:::o;1650:96::-;1687:7;1716:24;1734:5;1716:24;:::i;:::-;1705:35;;1650:96;;;:::o;1752:122::-;1825:24;1843:5;1825:24;:::i;:::-;1818:5;1815:35;1805:63;;1864:1;1861;1854:12;1805:63;1752:122;:::o;1880:139::-;1926:5;1964:6;1951:20;1942:29;;1980:33;2007:5;1980:33;:::i;:::-;1880:139;;;;:::o;2025:109::-;2061:7;2101:26;2094:5;2090:38;2079:49;;2025:109;;;:::o;2140:120::-;2212:23;2229:5;2212:23;:::i;:::-;2205:5;2202:34;2192:62;;2250:1;2247;2240:12;2192:62;2140:120;:::o;2266:137::-;2311:5;2349:6;2336:20;2327:29;;2365:32;2391:5;2365:32;:::i;:::-;2266:137;;;;:::o;2409:472::-;2476:6;2484;2533:2;2521:9;2512:7;2508:23;2504:32;2501:119;;;2539:79;;:::i;:::-;2501:119;2659:1;2684:53;2729:7;2720:6;2709:9;2705:22;2684:53;:::i;:::-;2674:63;;2630:117;2786:2;2812:52;2856:7;2847:6;2836:9;2832:22;2812:52;:::i;:::-;2802:62;;2757:117;2409:472;;;;;:::o;2887:99::-;2939:6;2973:5;2967:12;2957:22;;2887:99;;;:::o;2992:169::-;3076:11;3110:6;3105:3;3098:19;3150:4;3145:3;3141:14;3126:29;;2992:169;;;;:::o;3167:246::-;3248:1;3258:113;3272:6;3269:1;3266:13;3258:113;;;3357:1;3352:3;3348:11;3342:18;3338:1;3333:3;3329:11;3322:39;3294:2;3291:1;3287:10;3282:15;;3258:113;;;3405:1;3396:6;3391:3;3387:16;3380:27;3229:184;3167:246;;;:::o;3419:102::-;3460:6;3511:2;3507:7;3502:2;3495:5;3491:14;3487:28;3477:38;;3419:102;;;:::o;3527:377::-;3615:3;3643:39;3676:5;3643:39;:::i;:::-;3698:71;3762:6;3757:3;3698:71;:::i;:::-;3691:78;;3778:65;3836:6;3831:3;3824:4;3817:5;3813:16;3778:65;:::i;:::-;3868:29;3890:6;3868:29;:::i;:::-;3863:3;3859:39;3852:46;;3619:285;3527:377;;;;:::o;3910:313::-;4023:4;4061:2;4050:9;4046:18;4038:26;;4110:9;4104:4;4100:20;4096:1;4085:9;4081:17;4074:47;4138:78;4211:4;4202:6;4138:78;:::i;:::-;4130:86;;3910:313;;;;:::o;4229:77::-;4266:7;4295:5;4284:16;;4229:77;;;:::o;4312:122::-;4385:24;4403:5;4385:24;:::i;:::-;4378:5;4375:35;4365:63;;4424:1;4421;4414:12;4365:63;4312:122;:::o;4440:139::-;4486:5;4524:6;4511:20;4502:29;;4540:33;4567:5;4540:33;:::i;:::-;4440:139;;;;:::o;4585:329::-;4644:6;4693:2;4681:9;4672:7;4668:23;4664:32;4661:119;;;4699:79;;:::i;:::-;4661:119;4819:1;4844:53;4889:7;4880:6;4869:9;4865:22;4844:53;:::i;:::-;4834:63;;4790:117;4585:329;;;;:::o;4920:118::-;5007:24;5025:5;5007:24;:::i;:::-;5002:3;4995:37;4920:118;;:::o;5044:222::-;5137:4;5175:2;5164:9;5160:18;5152:26;;5188:71;5256:1;5245:9;5241:17;5232:6;5188:71;:::i;:::-;5044:222;;;;:::o;5272:474::-;5340:6;5348;5397:2;5385:9;5376:7;5372:23;5368:32;5365:119;;;5403:79;;:::i;:::-;5365:119;5523:1;5548:53;5593:7;5584:6;5573:9;5569:22;5548:53;:::i;:::-;5538:63;;5494:117;5650:2;5676:53;5721:7;5712:6;5701:9;5697:22;5676:53;:::i;:::-;5666:63;;5621:118;5272:474;;;;;:::o;5752:118::-;5839:24;5857:5;5839:24;:::i;:::-;5834:3;5827:37;5752:118;;:::o;5876:222::-;5969:4;6007:2;5996:9;5992:18;5984:26;;6020:71;6088:1;6077:9;6073:17;6064:6;6020:71;:::i;:::-;5876:222;;;;:::o;6104:329::-;6163:6;6212:2;6200:9;6191:7;6187:23;6183:32;6180:119;;;6218:79;;:::i;:::-;6180:119;6338:1;6363:53;6408:7;6399:6;6388:9;6384:22;6363:53;:::i;:::-;6353:63;;6309:117;6104:329;;;;:::o;6439:86::-;6474:7;6514:4;6507:5;6503:16;6492:27;;6439:86;;;:::o;6531:112::-;6614:22;6630:5;6614:22;:::i;:::-;6609:3;6602:35;6531:112;;:::o;6649:214::-;6738:4;6776:2;6765:9;6761:18;6753:26;;6789:67;6853:1;6842:9;6838:17;6829:6;6789:67;:::i;:::-;6649:214;;;;:::o;6869:89::-;6905:7;6945:6;6938:5;6934:18;6923:29;;6869:89;;;:::o;6964:120::-;7036:23;7053:5;7036:23;:::i;:::-;7029:5;7026:34;7016:62;;7074:1;7071;7064:12;7016:62;6964:120;:::o;7090:137::-;7135:5;7173:6;7160:20;7151:29;;7189:32;7215:5;7189:32;:::i;:::-;7090:137;;;;:::o;7233:327::-;7291:6;7340:2;7328:9;7319:7;7315:23;7311:32;7308:119;;;7346:79;;:::i;:::-;7308:119;7466:1;7491:52;7535:7;7526:6;7515:9;7511:22;7491:52;:::i;:::-;7481:62;;7437:116;7233:327;;;;:::o;7566:619::-;7643:6;7651;7659;7708:2;7696:9;7687:7;7683:23;7679:32;7676:119;;;7714:79;;:::i;:::-;7676:119;7834:1;7859:53;7904:7;7895:6;7884:9;7880:22;7859:53;:::i;:::-;7849:63;;7805:117;7961:2;7987:53;8032:7;8023:6;8012:9;8008:22;7987:53;:::i;:::-;7977:63;;7932:118;8089:2;8115:53;8160:7;8151:6;8140:9;8136:22;8115:53;:::i;:::-;8105:63;;8060:118;7566:619;;;;;:::o;8191:474::-;8259:6;8267;8316:2;8304:9;8295:7;8291:23;8287:32;8284:119;;;8322:79;;:::i;:::-;8284:119;8442:1;8467:53;8512:7;8503:6;8492:9;8488:22;8467:53;:::i;:::-;8457:63;;8413:117;8569:2;8595:53;8640:7;8631:6;8620:9;8616:22;8595:53;:::i;:::-;8585:63;;8540:118;8191:474;;;;;:::o;8671:332::-;8792:4;8830:2;8819:9;8815:18;8807:26;;8843:71;8911:1;8900:9;8896:17;8887:6;8843:71;:::i;:::-;8924:72;8992:2;8981:9;8977:18;8968:6;8924:72;:::i;:::-;8671:332;;;;;:::o;9009:117::-;9118:1;9115;9108:12;9132:117;9241:1;9238;9231:12;9255:117;9364:1;9361;9354:12;9392:553;9450:8;9460:6;9510:3;9503:4;9495:6;9491:17;9487:27;9477:122;;9518:79;;:::i;:::-;9477:122;9631:6;9618:20;9608:30;;9661:18;9653:6;9650:30;9647:117;;;9683:79;;:::i;:::-;9647:117;9797:4;9789:6;9785:17;9773:29;;9851:3;9843:4;9835:6;9831:17;9821:8;9817:32;9814:41;9811:128;;;9858:79;;:::i;:::-;9811:128;9392:553;;;;;:::o;9951:529::-;10022:6;10030;10079:2;10067:9;10058:7;10054:23;10050:32;10047:119;;;10085:79;;:::i;:::-;10047:119;10233:1;10222:9;10218:17;10205:31;10263:18;10255:6;10252:30;10249:117;;;10285:79;;:::i;:::-;10249:117;10398:65;10455:7;10446:6;10435:9;10431:22;10398:65;:::i;:::-;10380:83;;;;10176:297;9951:529;;;;;:::o;10503:568::-;10576:8;10586:6;10636:3;10629:4;10621:6;10617:17;10613:27;10603:122;;10644:79;;:::i;:::-;10603:122;10757:6;10744:20;10734:30;;10787:18;10779:6;10776:30;10773:117;;;10809:79;;:::i;:::-;10773:117;10923:4;10915:6;10911:17;10899:29;;10977:3;10969:4;10961:6;10957:17;10947:8;10943:32;10940:41;10937:128;;;10984:79;;:::i;:::-;10937:128;10503:568;;;;;:::o;11077:559::-;11163:6;11171;11220:2;11208:9;11199:7;11195:23;11191:32;11188:119;;;11226:79;;:::i;:::-;11188:119;11374:1;11363:9;11359:17;11346:31;11404:18;11396:6;11393:30;11390:117;;;11426:79;;:::i;:::-;11390:117;11539:80;11611:7;11602:6;11591:9;11587:22;11539:80;:::i;:::-;11521:98;;;;11317:312;11077:559;;;;;:::o;11642:146::-;11741:6;11775:5;11769:12;11759:22;;11642:146;;;:::o;11794:216::-;11925:11;11959:6;11954:3;11947:19;11999:4;11994:3;11990:14;11975:29;;11794:216;;;;:::o;12016:164::-;12115:4;12138:3;12130:11;;12168:4;12163:3;12159:14;12151:22;;12016:164;;;:::o;12186:108::-;12263:24;12281:5;12263:24;:::i;:::-;12258:3;12251:37;12186:108;;:::o;12300:101::-;12336:7;12376:18;12369:5;12365:30;12354:41;;12300:101;;;:::o;12407:105::-;12482:23;12499:5;12482:23;:::i;:::-;12477:3;12470:36;12407:105;;:::o;12518:99::-;12589:21;12604:5;12589:21;:::i;:::-;12584:3;12577:34;12518:99;;:::o;12623:91::-;12659:7;12699:8;12692:5;12688:20;12677:31;;12623:91;;;:::o;12720:105::-;12795:23;12812:5;12795:23;:::i;:::-;12790:3;12783:36;12720:105;;:::o;12903:866::-;13054:4;13049:3;13045:14;13141:4;13134:5;13130:16;13124:23;13160:63;13217:4;13212:3;13208:14;13194:12;13160:63;:::i;:::-;13069:164;13325:4;13318:5;13314:16;13308:23;13344:61;13399:4;13394:3;13390:14;13376:12;13344:61;:::i;:::-;13243:172;13499:4;13492:5;13488:16;13482:23;13518:57;13569:4;13564:3;13560:14;13546:12;13518:57;:::i;:::-;13425:160;13672:4;13665:5;13661:16;13655:23;13691:61;13746:4;13741:3;13737:14;13723:12;13691:61;:::i;:::-;13595:167;13023:746;12903:866;;:::o;13775:307::-;13908:10;13929:110;14035:3;14027:6;13929:110;:::i;:::-;14071:4;14066:3;14062:14;14048:28;;13775:307;;;;:::o;14088:145::-;14190:4;14222;14217:3;14213:14;14205:22;;14088:145;;;:::o;14315:988::-;14498:3;14527:86;14607:5;14527:86;:::i;:::-;14629:118;14740:6;14735:3;14629:118;:::i;:::-;14622:125;;14771:88;14853:5;14771:88;:::i;:::-;14882:7;14913:1;14898:380;14923:6;14920:1;14917:13;14898:380;;;14999:6;14993:13;15026:127;15149:3;15134:13;15026:127;:::i;:::-;15019:134;;15176:92;15261:6;15176:92;:::i;:::-;15166:102;;14958:320;14945:1;14942;14938:9;14933:14;;14898:380;;;14902:14;15294:3;15287:10;;14503:800;;;14315:988;;;;:::o;15309:501::-;15516:4;15554:2;15543:9;15539:18;15531:26;;15603:9;15597:4;15593:20;15589:1;15578:9;15574:17;15567:47;15631:172;15798:4;15789:6;15631:172;:::i;:::-;15623:180;;15309:501;;;;:::o;15816:118::-;15887:22;15903:5;15887:22;:::i;:::-;15880:5;15877:33;15867:61;;15924:1;15921;15914:12;15867:61;15816:118;:::o;15940:135::-;15984:5;16022:6;16009:20;16000:29;;16038:31;16063:5;16038:31;:::i;:::-;15940:135;;;;:::o;16081:325::-;16138:6;16187:2;16175:9;16166:7;16162:23;16158:32;16155:119;;;16193:79;;:::i;:::-;16155:119;16313:1;16338:51;16381:7;16372:6;16361:9;16357:22;16338:51;:::i;:::-;16328:61;;16284:115;16081:325;;;;:::o;16412:114::-;16479:6;16513:5;16507:12;16497:22;;16412:114;;;:::o;16532:184::-;16631:11;16665:6;16660:3;16653:19;16705:4;16700:3;16696:14;16681:29;;16532:184;;;;:::o;16722:132::-;16789:4;16812:3;16804:11;;16842:4;16837:3;16833:14;16825:22;;16722:132;;;:::o;16860:108::-;16937:24;16955:5;16937:24;:::i;:::-;16932:3;16925:37;16860:108;;:::o;16974:179::-;17043:10;17064:46;17106:3;17098:6;17064:46;:::i;:::-;17142:4;17137:3;17133:14;17119:28;;16974:179;;;;:::o;17159:113::-;17229:4;17261;17256:3;17252:14;17244:22;;17159:113;;;:::o;17308:732::-;17427:3;17456:54;17504:5;17456:54;:::i;:::-;17526:86;17605:6;17600:3;17526:86;:::i;:::-;17519:93;;17636:56;17686:5;17636:56;:::i;:::-;17715:7;17746:1;17731:284;17756:6;17753:1;17750:13;17731:284;;;17832:6;17826:13;17859:63;17918:3;17903:13;17859:63;:::i;:::-;17852:70;;17945:60;17998:6;17945:60;:::i;:::-;17935:70;;17791:224;17778:1;17775;17771:9;17766:14;;17731:284;;;17735:14;18031:3;18024:10;;17432:608;;;17308:732;;;;:::o;18046:373::-;18189:4;18227:2;18216:9;18212:18;18204:26;;18276:9;18270:4;18266:20;18262:1;18251:9;18247:17;18240:47;18304:108;18407:4;18398:6;18304:108;:::i;:::-;18296:116;;18046:373;;;;:::o;18425:619::-;18502:6;18510;18518;18567:2;18555:9;18546:7;18542:23;18538:32;18535:119;;;18573:79;;:::i;:::-;18535:119;18693:1;18718:53;18763:7;18754:6;18743:9;18739:22;18718:53;:::i;:::-;18708:63;;18664:117;18820:2;18846:53;18891:7;18882:6;18871:9;18867:22;18846:53;:::i;:::-;18836:63;;18791:118;18948:2;18974:53;19019:7;19010:6;18999:9;18995:22;18974:53;:::i;:::-;18964:63;;18919:118;18425:619;;;;;:::o;19050:116::-;19120:21;19135:5;19120:21;:::i;:::-;19113:5;19110:32;19100:60;;19156:1;19153;19146:12;19100:60;19050:116;:::o;19172:133::-;19215:5;19253:6;19240:20;19231:29;;19269:30;19293:5;19269:30;:::i;:::-;19172:133;;;;:::o;19311:468::-;19376:6;19384;19433:2;19421:9;19412:7;19408:23;19404:32;19401:119;;;19439:79;;:::i;:::-;19401:119;19559:1;19584:53;19629:7;19620:6;19609:9;19605:22;19584:53;:::i;:::-;19574:63;;19530:117;19686:2;19712:50;19754:7;19745:6;19734:9;19730:22;19712:50;:::i;:::-;19702:60;;19657:115;19311:468;;;;;:::o;19785:323::-;19841:6;19890:2;19878:9;19869:7;19865:23;19861:32;19858:119;;;19896:79;;:::i;:::-;19858:119;20016:1;20041:50;20083:7;20074:6;20063:9;20059:22;20041:50;:::i;:::-;20031:60;;19987:114;19785:323;;;;:::o;20114:117::-;20223:1;20220;20213:12;20237:180;20285:77;20282:1;20275:88;20382:4;20379:1;20372:15;20406:4;20403:1;20396:15;20423:281;20506:27;20528:4;20506:27;:::i;:::-;20498:6;20494:40;20636:6;20624:10;20621:22;20600:18;20588:10;20585:34;20582:62;20579:88;;;20647:18;;:::i;:::-;20579:88;20687:10;20683:2;20676:22;20466:238;20423:281;;:::o;20710:129::-;20744:6;20771:20;;:::i;:::-;20761:30;;20800:33;20828:4;20820:6;20800:33;:::i;:::-;20710:129;;;:::o;20845:307::-;20906:4;20996:18;20988:6;20985:30;20982:56;;;21018:18;;:::i;:::-;20982:56;21056:29;21078:6;21056:29;:::i;:::-;21048:37;;21140:4;21134;21130:15;21122:23;;20845:307;;;:::o;21158:146::-;21255:6;21250:3;21245;21232:30;21296:1;21287:6;21282:3;21278:16;21271:27;21158:146;;;:::o;21310:423::-;21387:5;21412:65;21428:48;21469:6;21428:48;:::i;:::-;21412:65;:::i;:::-;21403:74;;21500:6;21493:5;21486:21;21538:4;21531:5;21527:16;21576:3;21567:6;21562:3;21558:16;21555:25;21552:112;;;21583:79;;:::i;:::-;21552:112;21673:54;21720:6;21715:3;21710;21673:54;:::i;:::-;21393:340;21310:423;;;;;:::o;21752:338::-;21807:5;21856:3;21849:4;21841:6;21837:17;21833:27;21823:122;;21864:79;;:::i;:::-;21823:122;21981:6;21968:20;22006:78;22080:3;22072:6;22065:4;22057:6;22053:17;22006:78;:::i;:::-;21997:87;;21813:277;21752:338;;;;:::o;22096:943::-;22191:6;22199;22207;22215;22264:3;22252:9;22243:7;22239:23;22235:33;22232:120;;;22271:79;;:::i;:::-;22232:120;22391:1;22416:53;22461:7;22452:6;22441:9;22437:22;22416:53;:::i;:::-;22406:63;;22362:117;22518:2;22544:53;22589:7;22580:6;22569:9;22565:22;22544:53;:::i;:::-;22534:63;;22489:118;22646:2;22672:53;22717:7;22708:6;22697:9;22693:22;22672:53;:::i;:::-;22662:63;;22617:118;22802:2;22791:9;22787:18;22774:32;22833:18;22825:6;22822:30;22819:117;;;22855:79;;:::i;:::-;22819:117;22960:62;23014:7;23005:6;22994:9;22990:22;22960:62;:::i;:::-;22950:72;;22745:287;22096:943;;;;;;;:::o;23117:876::-;23278:4;23273:3;23269:14;23365:4;23358:5;23354:16;23348:23;23384:63;23441:4;23436:3;23432:14;23418:12;23384:63;:::i;:::-;23293:164;23549:4;23542:5;23538:16;23532:23;23568:61;23623:4;23618:3;23614:14;23600:12;23568:61;:::i;:::-;23467:172;23723:4;23716:5;23712:16;23706:23;23742:57;23793:4;23788:3;23784:14;23770:12;23742:57;:::i;:::-;23649:160;23896:4;23889:5;23885:16;23879:23;23915:61;23970:4;23965:3;23961:14;23947:12;23915:61;:::i;:::-;23819:167;23247:746;23117:876;;:::o;23999:351::-;24156:4;24194:3;24183:9;24179:19;24171:27;;24208:135;24340:1;24329:9;24325:17;24316:6;24208:135;:::i;:::-;23999:351;;;;:::o;24356:180::-;24404:77;24401:1;24394:88;24501:4;24498:1;24491:15;24525:4;24522:1;24515:15;24542:114;24624:1;24617:5;24614:12;24604:46;;24630:18;;:::i;:::-;24604:46;24542:114;:::o;24662:129::-;24708:7;24737:5;24726:16;;24743:42;24779:5;24743:42;:::i;:::-;24662:129;;;:::o;24797:::-;24854:9;24887:33;24914:5;24887:33;:::i;:::-;24874:46;;24797:129;;;:::o;24932:145::-;25026:44;25064:5;25026:44;:::i;:::-;25021:3;25014:57;24932:145;;:::o;25083:236::-;25183:4;25221:2;25210:9;25206:18;25198:26;;25234:78;25309:1;25298:9;25294:17;25285:6;25234:78;:::i;:::-;25083:236;;;;:::o;25325:77::-;25362:7;25391:5;25380:16;;25325:77;;;:::o;25408:118::-;25495:24;25513:5;25495:24;:::i;:::-;25490:3;25483:37;25408:118;;:::o;25532:222::-;25625:4;25663:2;25652:9;25648:18;25640:26;;25676:71;25744:1;25733:9;25729:17;25720:6;25676:71;:::i;:::-;25532:222;;;;:::o;25760:474::-;25828:6;25836;25885:2;25873:9;25864:7;25860:23;25856:32;25853:119;;;25891:79;;:::i;:::-;25853:119;26011:1;26036:53;26081:7;26072:6;26061:9;26057:22;26036:53;:::i;:::-;26026:63;;25982:117;26138:2;26164:53;26209:7;26200:6;26189:9;26185:22;26164:53;:::i;:::-;26154:63;;26109:118;25760:474;;;;;:::o;26240:180::-;26288:77;26285:1;26278:88;26385:4;26382:1;26375:15;26409:4;26406:1;26399:15;26426:320;26470:6;26507:1;26501:4;26497:12;26487:22;;26554:1;26548:4;26544:12;26575:18;26565:81;;26631:4;26623:6;26619:17;26609:27;;26565:81;26693:2;26685:6;26682:14;26662:18;26659:38;26656:84;;26712:18;;:::i;:::-;26656:84;26477:269;26426:320;;;:::o;26752:180::-;26800:77;26797:1;26790:88;26897:4;26894:1;26887:15;26921:4;26918:1;26911:15;26938:191;26978:3;26997:20;27015:1;26997:20;:::i;:::-;26992:25;;27031:20;27049:1;27031:20;:::i;:::-;27026:25;;27074:1;27071;27067:9;27060:16;;27095:3;27092:1;27089:10;27086:36;;;27102:18;;:::i;:::-;27086:36;26938:191;;;;:::o;27135:410::-;27175:7;27198:20;27216:1;27198:20;:::i;:::-;27193:25;;27232:20;27250:1;27232:20;:::i;:::-;27227:25;;27287:1;27284;27280:9;27309:30;27327:11;27309:30;:::i;:::-;27298:41;;27488:1;27479:7;27475:15;27472:1;27469:22;27449:1;27442:9;27422:83;27399:139;;27518:18;;:::i;:::-;27399:139;27183:362;27135:410;;;;:::o;27551:180::-;27599:77;27596:1;27589:88;27696:4;27693:1;27686:15;27720:4;27717:1;27710:15;27737:185;27777:1;27794:20;27812:1;27794:20;:::i;:::-;27789:25;;27828:20;27846:1;27828:20;:::i;:::-;27823:25;;27867:1;27857:35;;27872:18;;:::i;:::-;27857:35;27914:1;27911;27907:9;27902:14;;27737:185;;;;:::o;27928:147::-;28029:11;28066:3;28051:18;;27928:147;;;;:::o;28081:114::-;;:::o;28201:398::-;28360:3;28381:83;28462:1;28457:3;28381:83;:::i;:::-;28374:90;;28473:93;28562:3;28473:93;:::i;:::-;28591:1;28586:3;28582:11;28575:18;;28201:398;;;:::o;28605:379::-;28789:3;28811:147;28954:3;28811:147;:::i;:::-;28804:154;;28975:3;28968:10;;28605:379;;;:::o;28990:97::-;29049:6;29077:3;29067:13;;28990:97;;;;:::o;29093:141::-;29142:4;29165:3;29157:11;;29188:3;29185:1;29178:14;29222:4;29219:1;29209:18;29201:26;;29093:141;;;:::o;29240:93::-;29277:6;29324:2;29319;29312:5;29308:14;29304:23;29294:33;;29240:93;;;:::o;29339:107::-;29383:8;29433:5;29427:4;29423:16;29402:37;;29339:107;;;;:::o;29452:393::-;29521:6;29571:1;29559:10;29555:18;29594:97;29624:66;29613:9;29594:97;:::i;:::-;29712:39;29742:8;29731:9;29712:39;:::i;:::-;29700:51;;29784:4;29780:9;29773:5;29769:21;29760:30;;29833:4;29823:8;29819:19;29812:5;29809:30;29799:40;;29528:317;;29452:393;;;;;:::o;29851:60::-;29879:3;29900:5;29893:12;;29851:60;;;:::o;29917:142::-;29967:9;30000:53;30018:34;30027:24;30045:5;30027:24;:::i;:::-;30018:34;:::i;:::-;30000:53;:::i;:::-;29987:66;;29917:142;;;:::o;30065:75::-;30108:3;30129:5;30122:12;;30065:75;;;:::o;30146:269::-;30256:39;30287:7;30256:39;:::i;:::-;30317:91;30366:41;30390:16;30366:41;:::i;:::-;30358:6;30351:4;30345:11;30317:91;:::i;:::-;30311:4;30304:105;30222:193;30146:269;;;:::o;30421:73::-;30466:3;30421:73;:::o;30500:189::-;30577:32;;:::i;:::-;30618:65;30676:6;30668;30662:4;30618:65;:::i;:::-;30553:136;30500:189;;:::o;30695:186::-;30755:120;30772:3;30765:5;30762:14;30755:120;;;30826:39;30863:1;30856:5;30826:39;:::i;:::-;30799:1;30792:5;30788:13;30779:22;;30755:120;;;30695:186;;:::o;30887:543::-;30988:2;30983:3;30980:11;30977:446;;;31022:38;31054:5;31022:38;:::i;:::-;31106:29;31124:10;31106:29;:::i;:::-;31096:8;31092:44;31289:2;31277:10;31274:18;31271:49;;;31310:8;31295:23;;31271:49;31333:80;31389:22;31407:3;31389:22;:::i;:::-;31379:8;31375:37;31362:11;31333:80;:::i;:::-;30992:431;;30977:446;30887:543;;;:::o;31436:117::-;31490:8;31540:5;31534:4;31530:16;31509:37;;31436:117;;;;:::o;31559:169::-;31603:6;31636:51;31684:1;31680:6;31672:5;31669:1;31665:13;31636:51;:::i;:::-;31632:56;31717:4;31711;31707:15;31697:25;;31610:118;31559:169;;;;:::o;31733:295::-;31809:4;31955:29;31980:3;31974:4;31955:29;:::i;:::-;31947:37;;32017:3;32014:1;32010:11;32004:4;32001:21;31993:29;;31733:295;;;;:::o;32033:1403::-;32157:44;32197:3;32192;32157:44;:::i;:::-;32266:18;32258:6;32255:30;32252:56;;;32288:18;;:::i;:::-;32252:56;32332:38;32364:4;32358:11;32332:38;:::i;:::-;32417:67;32477:6;32469;32463:4;32417:67;:::i;:::-;32511:1;32540:2;32532:6;32529:14;32557:1;32552:632;;;;33228:1;33245:6;33242:84;;;33301:9;33296:3;33292:19;33279:33;33270:42;;33242:84;33352:67;33412:6;33405:5;33352:67;:::i;:::-;33346:4;33339:81;33201:229;32522:908;;32552:632;32604:4;32600:9;32592:6;32588:22;32638:37;32670:4;32638:37;:::i;:::-;32697:1;32711:215;32725:7;32722:1;32719:14;32711:215;;;32811:9;32806:3;32802:19;32789:33;32781:6;32774:49;32862:1;32854:6;32850:14;32840:24;;32909:2;32898:9;32894:18;32881:31;;32748:4;32745:1;32741:12;32736:17;;32711:215;;;32954:6;32945:7;32942:19;32939:186;;;33019:9;33014:3;33010:19;32997:33;33062:48;33104:4;33096:6;33092:17;33081:9;33062:48;:::i;:::-;33054:6;33047:64;32962:163;32939:186;33171:1;33167;33159:6;33155:14;33151:22;33145:4;33138:36;32559:625;;;32522:908;;32132:1304;;;32033:1403;;;:::o;33442:180::-;33490:77;33487:1;33480:88;33587:4;33584:1;33577:15;33611:4;33608:1;33601:15;33628:194;33668:4;33688:20;33706:1;33688:20;:::i;:::-;33683:25;;33722:20;33740:1;33722:20;:::i;:::-;33717:25;;33766:1;33763;33759:9;33751:17;;33790:1;33784:4;33781:11;33778:37;;;33795:18;;:::i;:::-;33778:37;33628:194;;;;:::o;33828:148::-;33930:11;33967:3;33952:18;;33828:148;;;;:::o;33982:390::-;34088:3;34116:39;34149:5;34116:39;:::i;:::-;34171:89;34253:6;34248:3;34171:89;:::i;:::-;34164:96;;34269:65;34327:6;34322:3;34315:4;34308:5;34304:16;34269:65;:::i;:::-;34359:6;34354:3;34350:16;34343:23;;34092:280;33982:390;;;;:::o;34378:435::-;34558:3;34580:95;34671:3;34662:6;34580:95;:::i;:::-;34573:102;;34692:95;34783:3;34774:6;34692:95;:::i;:::-;34685:102;;34804:3;34797:10;;34378:435;;;;;:::o;34819:225::-;34959:34;34955:1;34947:6;34943:14;34936:58;35028:8;35023:2;35015:6;35011:15;35004:33;34819:225;:::o;35050:366::-;35192:3;35213:67;35277:2;35272:3;35213:67;:::i;:::-;35206:74;;35289:93;35378:3;35289:93;:::i;:::-;35407:2;35402:3;35398:12;35391:19;;35050:366;;;:::o;35422:419::-;35588:4;35626:2;35615:9;35611:18;35603:26;;35675:9;35669:4;35665:20;35661:1;35650:9;35646:17;35639:47;35703:131;35829:4;35703:131;:::i;:::-;35695:139;;35422:419;;;:::o;35847:182::-;35987:34;35983:1;35975:6;35971:14;35964:58;35847:182;:::o;36035:366::-;36177:3;36198:67;36262:2;36257:3;36198:67;:::i;:::-;36191:74;;36274:93;36363:3;36274:93;:::i;:::-;36392:2;36387:3;36383:12;36376:19;;36035:366;;;:::o;36407:419::-;36573:4;36611:2;36600:9;36596:18;36588:26;;36660:9;36654:4;36650:20;36646:1;36635:9;36631:17;36624:47;36688:131;36814:4;36688:131;:::i;:::-;36680:139;;36407:419;;;:::o;36832:229::-;36972:34;36968:1;36960:6;36956:14;36949:58;37041:12;37036:2;37028:6;37024:15;37017:37;36832:229;:::o;37067:366::-;37209:3;37230:67;37294:2;37289:3;37230:67;:::i;:::-;37223:74;;37306:93;37395:3;37306:93;:::i;:::-;37424:2;37419:3;37415:12;37408:19;;37067:366;;;:::o;37439:419::-;37605:4;37643:2;37632:9;37628:18;37620:26;;37692:9;37686:4;37682:20;37678:1;37667:9;37663:17;37656:47;37720:131;37846:4;37720:131;:::i;:::-;37712:139;;37439:419;;;:::o;37864:175::-;38004:27;38000:1;37992:6;37988:14;37981:51;37864:175;:::o;38045:366::-;38187:3;38208:67;38272:2;38267:3;38208:67;:::i;:::-;38201:74;;38284:93;38373:3;38284:93;:::i;:::-;38402:2;38397:3;38393:12;38386:19;;38045:366;;;:::o;38417:419::-;38583:4;38621:2;38610:9;38606:18;38598:26;;38670:9;38664:4;38660:20;38656:1;38645:9;38641:17;38634:47;38698:131;38824:4;38698:131;:::i;:::-;38690:139;;38417:419;;;:::o;38842:98::-;38893:6;38927:5;38921:12;38911:22;;38842:98;;;:::o;38946:168::-;39029:11;39063:6;39058:3;39051:19;39103:4;39098:3;39094:14;39079:29;;38946:168;;;;:::o;39120:373::-;39206:3;39234:38;39266:5;39234:38;:::i;:::-;39288:70;39351:6;39346:3;39288:70;:::i;:::-;39281:77;;39367:65;39425:6;39420:3;39413:4;39406:5;39402:16;39367:65;:::i;:::-;39457:29;39479:6;39457:29;:::i;:::-;39452:3;39448:39;39441:46;;39210:283;39120:373;;;;:::o;39499:640::-;39694:4;39732:3;39721:9;39717:19;39709:27;;39746:71;39814:1;39803:9;39799:17;39790:6;39746:71;:::i;:::-;39827:72;39895:2;39884:9;39880:18;39871:6;39827:72;:::i;:::-;39909;39977:2;39966:9;39962:18;39953:6;39909:72;:::i;:::-;40028:9;40022:4;40018:20;40013:2;40002:9;39998:18;39991:48;40056:76;40127:4;40118:6;40056:76;:::i;:::-;40048:84;;39499:640;;;;;;;:::o;40145:141::-;40201:5;40232:6;40226:13;40217:22;;40248:32;40274:5;40248:32;:::i;:::-;40145:141;;;;:::o;40292:349::-;40361:6;40410:2;40398:9;40389:7;40385:23;40381:32;40378:119;;;40416:79;;:::i;:::-;40378:119;40536:1;40561:63;40616:7;40607:6;40596:9;40592:22;40561:63;:::i;:::-;40551:73;;40507:127;40292:349;;;;:::o

Swarm Source

ipfs://978d358a2975767dcd2c15c68c31bedad9d53abe79a1d0ef1aba08794b01c0c8
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.