ETH Price: $3,451.80 (-1.01%)

Token

MAYG SYGNE (MAYG_221203)
 

Overview

Max Total Supply

5,500 MAYG_221203

Holders

843

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
blockchainsane.eth
Balance
1 MAYG_221203
0x75cf5e487d4d59cce6f53334241e32515f4403cf
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:
MAYG_721a

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 12 of 22: MAYG_721a.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;

import "./Context.sol";
import "./Ownable.sol";
import "./Strings.sol";
import './ReentrancyGuard.sol';


import "./ERC721A.sol";

  // the rarible dependency files are needed to setup sales royalties on Rarible
import "./RoyaltiesV2Impl.sol";
import "./LibPart.sol";
import "./LibRoyaltiesV2.sol";

import './DefaultOperatorFilterer.sol';

/*

This contract allows for royalties and generational mints.

The Contract also supports pausable as well as the standard ERC721a
functionality (based on ERC721)

The royalty interfaces supported are:
  Rarible
  ERC2981 royalty protocol (mintable, etc)

Images are organized by batches of 500.  Thus the uri will change for every 500 images.

*/

contract MAYG_721a is ERC721A, Ownable, ReentrancyGuard, RoyaltiesV2Impl, DefaultOperatorFilterer {

  bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;

  bool public paused = false;

  string public  constant _baseExtension = ".json";

    // maximum number of tokens that can mint in one batch
  uint256 private _maxFistGenMintBatchSize = 250;
  uint256 private _maxFirstGenTokens = 10000;

  string[20] private _imageRange;

  uint256 private constant _imageRangeBatchSize = 500;
  uint256 private constant _imageRangeBatches = 20;

  event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas);

  constructor(
    string memory _cid
  ) ERC721A(
    "MAYG SYGNE",
    "MAYG_221203"
  ) {
    setCIDforRange(_cid, 0);
  }

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

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

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

  function mint(address _to, uint256 _quantity) public onlyOwner {
      require(!paused);

      require(_quantity > 0, "MAYG_721a: invalid quantity, 0");
      require(_quantity <= _maxFistGenMintBatchSize, "MAYG_721a: invalid quantity, too large");

      uint256 supply = totalSupply();
      require(supply + _quantity <= _maxFirstGenTokens, "MAYG_721a: invalid quantity, too many first gen tokens");

      _safeMint(_to, _quantity);
    }

  /*
  */
  function tokenURI(uint256 _tokenId)
    public
    view
    override
    returns (string memory)
  {
    string memory cid = getCIDForTokenInternal(_tokenId);
    string memory tokenIdStr = Strings.toString(_tokenId);

    bytes memory b = abi.encodePacked(cid, tokenIdStr, _baseExtension);
    return string(b);
  }

  function onERC721Received(
      address operator,
      address from,
      uint256 tokenId,
      bytes memory data
  ) public override returns (bytes4) {
  /*
        // for testing reverts with a message from the receiver contract
      if (bytes1(data) == 0x01) {
          revert('reverted in the receiver contract!');
      }

        // for testing with the returned wrong value from the receiver contract
      if (bytes1(data) == 0x02) {
          return 0x0;
      }

        // for testing the reentrancy protection
      if (bytes1(data) == 0x03) {
          IERC721AMock(_erc721aMock).safeMint(address(this), 1);
     }
  */
      emit Received(operator, from, tokenId, data, 20000);
      return this.onERC721Received.selector;
  }

  function withdraw() public onlyOwner nonReentrant {

    (bool success, ) = payable(msg.sender).call{value: address(this).balance}("");
    require(success);
  }

    // configure royalties for Rariable
    // note:  Royalty percentages are in basis points so a 10% sales royalty should be entered as 1000.
  function setRoyalties(uint _tokenId, address payable _royaltiesRecipientAddress, uint96 _percentageBasisPoints) public onlyOwner {
    LibPart.Part[] memory _royalties = new LibPart.Part[](1);
    _royalties[0].value = _percentageBasisPoints;
    _royalties[0].account = _royaltiesRecipientAddress;
    _saveRoyalties(_tokenId, _royalties);
  }

    // configure royalties for Mintable using the ERC2981 standard
  function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view returns (address receiver, uint256 royaltyAmount) {
      //use the same royalties that were saved for Rariable
    LibPart.Part[] memory _royalties = royalties[_tokenId];
    if(_royalties.length > 0) {
      return (_royalties[0].account, (_salePrice * _royalties[0].value) / 10000);
    }
    _royalties = royalties[0];
    if(_royalties.length > 0) {
      return (_royalties[0].account, (_salePrice * _royalties[0].value) / 10000);
    }
    return (address(0), 0);
  }

  function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A) returns (bool) {
      if(interfaceId == LibRoyaltiesV2._INTERFACE_ID_ROYALTIES) {
          return true;
      }

      if(interfaceId == _INTERFACE_ID_ERC2981) {
        return true;
      }

      return super.supportsInterface(interfaceId);
  }


    //pause the contract and do not allow any more minting
  function pause(bool _state) public onlyOwner {
    paused = _state;
  }

  function burn(uint256 tokenId, bool approvalCheck) public onlyOwner {
    _burn( tokenId, approvalCheck);
  }

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

    /*
    // token minting constraints

      _maxFistGenMintBatchSize : max number of tokens one can mint in a batch in a first gen mint.
      _maxFirstGenTokens : total number of first generation tokens
      */

  function setMintConstraints(uint256 maxFistGenMintBatchSize,
                              uint256 maxFirstGenTokens
                              ) public onlyOwner {
    _maxFistGenMintBatchSize = maxFistGenMintBatchSize;
    _maxFirstGenTokens = maxFirstGenTokens;
  }

    // strings are 128 bytes long
    // CIDs are 48 bytes
    // _imageRangeBatchSize = 500;
    // 20 ranges,  from 0 to 19

    // not ideal, but we are only storing 20 ranges.
    // uint256 => string ) private _imageRange;
    // const uint256 _imageRangeBatchSize = 500;

  function setCIDforRange(string memory _cid, uint256 _rangeNo ) public onlyOwner {
    _imageRange[_rangeNo] = _cid;
  }

  function getCIDForToken( uint256 tokenId ) public onlyOwner view returns (string memory) {
    return getCIDForTokenInternal(tokenId);
  }

  function getCIDForTokenInternal( uint256 tokenId ) internal view returns (string memory) {

    require(tokenId > 0 , "tokenId of zero is out of range" );

    uint256 cidIndex = (tokenId-1) / _imageRangeBatchSize;

    require (cidIndex < _imageRangeBatches, "missing CID value for token");

    return _imageRange[cidIndex];
  }
}

File 1 of 22: AbstractRoyalties.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./LibPart.sol";

abstract contract AbstractRoyalties {
    mapping (uint256 => LibPart.Part[]) internal royalties;

    function _saveRoyalties(uint256 id, LibPart.Part[] memory _royalties) internal {
        uint256 totalValue;
        for (uint i = 0; i < _royalties.length; i++) {
            require(_royalties[i].account != address(0x0), "Recipient should be present");
            require(_royalties[i].value != 0, "Royalty value should be positive");
            totalValue += _royalties[i].value;
            royalties[id].push(_royalties[i]);
        }
        require(totalValue < 10000, "Royalty total value should be < 10000");
        _onRoyaltiesSet(id, _royalties);
    }

    function _updateAccount(uint256 _id, address _from, address _to) internal {
        uint length = royalties[_id].length;
        for(uint i = 0; i < length; i++) {
            if (royalties[_id][i].account == _from) {
                royalties[_id][i].account = payable(address(uint160(_to)));
            }
        }
    }

    function _onRoyaltiesSet(uint256 id, LibPart.Part[] memory _royalties) virtual internal;
}

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

pragma solidity ^0.8.0;

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

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

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

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

abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

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

File 4 of 22: EnumerableSet.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

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

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

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

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

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

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

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

File 5 of 22: ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.0.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';
import "./IERC721Receiver.sol";
//import "hardhat/console.sol";



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

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
abstract contract ERC721A is IERC721A, IERC721Receiver {
    // 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 tokenId of the next token 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`
    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 => address) private _tokenApprovals;

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

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

    /**
     * @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 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 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 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 returns (uint256) {
        return _burnCounter;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    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: 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.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (_addressToUint256(owner) == 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 {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        assembly {
            // Cast aux without masking.
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    /**
     * 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 ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

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

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        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 '';
    }

    /**
     * @dev Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev Casts the boolean to uint256 without branching.
     */
    function _boolToUint256(bool value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = address(uint160(_packedOwnershipOf(tokenId)));

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

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

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, 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.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _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 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 {
        uint256 startTokenId = _currentIndex;
        if (_addressToUint256(to) == 0) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _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] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 offset;
            do {
                emit Transfer(address(0), to, startTokenId + offset++);
            } while (offset < quantity);

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

        address approvedAddress = _tokenApprovals[tokenId];

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            approvedAddress == _msgSenderERC721A());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (_addressToUint256(to) == 0) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

        // 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] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_NEXT_INITIALIZED;

            // 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 `_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));
        address approvedAddress = _tokenApprovals[tokenId];

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                approvedAddress == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

        // 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] =
                _addressToUint256(from) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_BURNED |
                BITMASK_NEXT_INITIALIZED;

            // 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++;
        }
    }

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

    /**
     * @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 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 returns (string memory ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

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

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for {
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp {
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } {
                // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }

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

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

pragma solidity ^0.8.4;

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

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

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

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

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        uint8 mintable;
        // Whether the token has been burned.
        bool burned;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

    // ==============================
    //            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);

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

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

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

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

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

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

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

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

File 7 of 22: IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

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

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

File 9 of 22: LibPart.sol
// SPDX-License-Identifier: MIT

// secondary sales royalties on rarible
//

pragma solidity ^0.8.0;

library LibPart {
    bytes32 public constant TYPE_HASH = keccak256("Part(address account,uint96 value)");

    struct Part {
        address payable account;
        uint96 value;
    }

    function hash(Part memory part) internal pure returns (bytes32) {
        return keccak256(abi.encode(TYPE_HASH, part.account, part.value));
    }
}

File 10 of 22: LibRoyaltiesV2.sol
// SPDX-License-Identifier: MIT

// secondary sales royalties on rarible

pragma solidity ^0.8.0;

library LibRoyaltiesV2 {
    /*
     * bytes4(keccak256('getRaribleV2Royalties(uint256)')) == 0xcad96cca
     */
    bytes4 constant _INTERFACE_ID_ROYALTIES = 0xcad96cca;
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry constant operatorFilterRegistry =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

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

    modifier onlyAllowedOperator(address from) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(operatorFilterRegistry).code.length > 0) {
            // Allow spending tokens from addresses with balance
            // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
            // from an EOA.
            if (from == msg.sender) {
                _;
                return;
            }
            if (
                !(
                    operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)
                        && operatorFilterRegistry.isOperatorAllowed(address(this), from)
                )
            ) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }
}

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

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";
import {Ownable} from "./Ownable.sol";
import {EnumerableSet} from "./EnumerableSet.sol";
import {OperatorFilterRegistryErrorsAndEvents} from "./OperatorFilterRegistryErrorsAndEvents.sol";

/**
 * @title  OperatorFilterRegistry
 * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract:
 *         https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol
 * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be
 * *       restricted according to the isOperatorAllowed function.
 */
contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents {
    using EnumerableSet for EnumerableSet.AddressSet;
    using EnumerableSet for EnumerableSet.Bytes32Set;

    /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)
    /// Note that this will also be a smart contract's codehash when making calls from its constructor.
    bytes32 constant EOA_CODEHASH = keccak256("");

    mapping(address => EnumerableSet.AddressSet) private _filteredOperators;
    mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;
    mapping(address => address) private _registrations;
    mapping(address => EnumerableSet.AddressSet) private _subscribers;

    /**
     * @notice restricts method caller to the address or EIP-173 "owner()"
     */
    modifier onlyAddressOrOwner(address addr) {
        if (msg.sender != addr) {
            try Ownable(addr).owner() returns (address owner) {
                if (msg.sender != owner) {
                    revert OnlyAddressOrOwner();
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert NotOwnable();
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
        _;
    }

    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            EnumerableSet.AddressSet storage filteredOperatorsRef;
            EnumerableSet.Bytes32Set storage filteredCodeHashesRef;

            filteredOperatorsRef = _filteredOperators[registration];
            filteredCodeHashesRef = _filteredCodeHashes[registration];

            if (filteredOperatorsRef.contains(operator)) {
                revert AddressFiltered(operator);
            }
            if (operator.code.length > 0) {
                bytes32 codeHash = operator.codehash;
                if (filteredCodeHashesRef.contains(codeHash)) {
                    revert CodeHashFiltered(operator, codeHash);
                }
            }
        }
        return true;
    }

    //////////////////
    // AUTH METHODS //
    //////////////////

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external onlyAddressOrOwner(registrant) {
        if (_registrations[registrant] != address(0)) {
            revert AlreadyRegistered();
        }
        _registrations[registrant] = registrant;
        emit RegistrationUpdated(registrant, true);
    }

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address registrant) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            _subscribers[registration].remove(registrant);
            emit SubscriptionUpdated(registrant, registration, false);
        }
        _registrations[registrant] = address(0);
        emit RegistrationUpdated(registrant, false);
    }

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            revert AlreadyRegistered();
        }
        if (registrant == subscription) {
            revert CannotSubscribeToSelf();
        }
        address subscriptionRegistration = _registrations[subscription];
        if (subscriptionRegistration == address(0)) {
            revert NotRegistered(subscription);
        }
        if (subscriptionRegistration != subscription) {
            revert CannotSubscribeToRegistrantWithSubscription(subscription);
        }

        _registrations[registrant] = subscription;
        _subscribers[subscription].add(registrant);
        emit RegistrationUpdated(registrant, true);
        emit SubscriptionUpdated(registrant, subscription, true);
    }

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy)
        external
        onlyAddressOrOwner(registrant)
    {
        if (registrantToCopy == registrant) {
            revert CannotCopyFromSelf();
        }
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            revert AlreadyRegistered();
        }
        address registrantRegistration = _registrations[registrantToCopy];
        if (registrantRegistration == address(0)) {
            revert NotRegistered(registrantToCopy);
        }
        _registrations[registrant] = registrant;
        emit RegistrationUpdated(registrant, true);
        _copyEntries(registrant, registrantToCopy);
    }

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];

        if (!filtered) {
            bool removed = filteredOperatorsRef.remove(operator);
            if (!removed) {
                revert AddressNotFiltered(operator);
            }
        } else {
            bool added = filteredOperatorsRef.add(operator);
            if (!added) {
                revert AddressAlreadyFiltered(operator);
            }
        }
        emit OperatorUpdated(registrant, operator, filtered);
    }

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codeHash, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        if (codeHash == EOA_CODEHASH) {
            revert CannotFilterEOAs();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];

        if (!filtered) {
            bool removed = filteredCodeHashesRef.remove(codeHash);
            if (!removed) {
                revert CodeHashNotFiltered(codeHash);
            }
        } else {
            bool added = filteredCodeHashesRef.add(codeHash);
            if (!added) {
                revert CodeHashAlreadyFiltered(codeHash);
            }
        }
        emit CodeHashUpdated(registrant, codeHash, filtered);
    }

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];
        uint256 operatorsLength = operators.length;
        unchecked {
            if (!filtered) {
                for (uint256 i = 0; i < operatorsLength; ++i) {
                    address operator = operators[i];
                    bool removed = filteredOperatorsRef.remove(operator);
                    if (!removed) {
                        revert AddressNotFiltered(operator);
                    }
                }
            } else {
                for (uint256 i = 0; i < operatorsLength; ++i) {
                    address operator = operators[i];
                    bool added = filteredOperatorsRef.add(operator);
                    if (!added) {
                        revert AddressAlreadyFiltered(operator);
                    }
                }
            }
        }
        emit OperatorsUpdated(registrant, operators, filtered);
    }

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];
        uint256 codeHashesLength = codeHashes.length;
        unchecked {
            if (!filtered) {
                for (uint256 i = 0; i < codeHashesLength; ++i) {
                    bytes32 codeHash = codeHashes[i];
                    bool removed = filteredCodeHashesRef.remove(codeHash);
                    if (!removed) {
                        revert CodeHashNotFiltered(codeHash);
                    }
                }
            } else {
                for (uint256 i = 0; i < codeHashesLength; ++i) {
                    bytes32 codeHash = codeHashes[i];
                    if (codeHash == EOA_CODEHASH) {
                        revert CannotFilterEOAs();
                    }
                    bool added = filteredCodeHashesRef.add(codeHash);
                    if (!added) {
                        revert CodeHashAlreadyFiltered(codeHash);
                    }
                }
            }
        }
        emit CodeHashesUpdated(registrant, codeHashes, filtered);
    }

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) {
        if (registrant == newSubscription) {
            revert CannotSubscribeToSelf();
        }
        if (newSubscription == address(0)) {
            revert CannotSubscribeToZeroAddress();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration == newSubscription) {
            revert AlreadySubscribed(newSubscription);
        }
        address newSubscriptionRegistration = _registrations[newSubscription];
        if (newSubscriptionRegistration == address(0)) {
            revert NotRegistered(newSubscription);
        }
        if (newSubscriptionRegistration != newSubscription) {
            revert CannotSubscribeToRegistrantWithSubscription(newSubscription);
        }

        if (registration != registrant) {
            _subscribers[registration].remove(registrant);
            emit SubscriptionUpdated(registrant, registration, false);
        }
        _registrations[registrant] = newSubscription;
        _subscribers[newSubscription].add(registrant);
        emit SubscriptionUpdated(registrant, newSubscription, true);
    }

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration == registrant) {
            revert NotSubscribed();
        }
        _subscribers[registration].remove(registrant);
        _registrations[registrant] = registrant;
        emit SubscriptionUpdated(registrant, registration, false);
        if (copyExistingEntries) {
            _copyEntries(registrant, registration);
        }
    }

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) {
        if (registrant == registrantToCopy) {
            revert CannotCopyFromSelf();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        address registrantRegistration = _registrations[registrantToCopy];
        if (registrantRegistration == address(0)) {
            revert NotRegistered(registrantToCopy);
        }
        _copyEntries(registrant, registrantToCopy);
    }

    /// @dev helper to copy entries from registrantToCopy to registrant and emit events
    function _copyEntries(address registrant, address registrantToCopy) private {
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];
        uint256 filteredOperatorsLength = filteredOperatorsRef.length();
        uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();
        unchecked {
            for (uint256 i = 0; i < filteredOperatorsLength; ++i) {
                address operator = filteredOperatorsRef.at(i);
                bool added = _filteredOperators[registrant].add(operator);
                if (added) {
                    emit OperatorUpdated(registrant, operator, true);
                }
            }
            for (uint256 i = 0; i < filteredCodeHashesLength; ++i) {
                bytes32 codehash = filteredCodeHashesRef.at(i);
                bool added = _filteredCodeHashes[registrant].add(codehash);
                if (added) {
                    emit CodeHashUpdated(registrant, codehash, true);
                }
            }
        }
    }

    //////////////////
    // VIEW METHODS //
    //////////////////

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address registrant) external view returns (address subscription) {
        subscription = _registrations[registrant];
        if (subscription == address(0)) {
            revert NotRegistered(registrant);
        } else if (subscription == registrant) {
            subscription = address(0);
        }
    }

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

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

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].contains(operator);
        }
        return _filteredOperators[registrant].contains(operator);
    }

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].contains(codeHash);
        }
        return _filteredCodeHashes[registrant].contains(codeHash);
    }

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) {
        bytes32 codeHash = operatorWithCode.codehash;
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].contains(codeHash);
        }
        return _filteredCodeHashes[registrant].contains(codeHash);
    }

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address registrant) external view returns (bool) {
        return _registrations[registrant] != address(0);
    }

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address registrant) external view returns (address[] memory) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].values();
        }
        return _filteredOperators[registrant].values();
    }

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].values();
        }
        return _filteredCodeHashes[registrant].values();
    }

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external view returns (address) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].at(index);
        }
        return _filteredOperators[registrant].at(index);
    }

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].at(index);
        }
        return _filteredCodeHashes[registrant].at(index);
    }

    /// @dev Convenience method to compute the code hash of an arbitrary contract
    function codeHashOf(address a) external view returns (bytes32) {
        return a.codehash;
    }
}

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

contract OperatorFilterRegistryErrorsAndEvents {
    error CannotFilterEOAs();
    error AddressAlreadyFiltered(address operator);
    error AddressNotFiltered(address operator);
    error CodeHashAlreadyFiltered(bytes32 codeHash);
    error CodeHashNotFiltered(bytes32 codeHash);
    error OnlyAddressOrOwner();
    error NotRegistered(address registrant);
    error AlreadyRegistered();
    error AlreadySubscribed(address subscription);
    error NotSubscribed();
    error CannotUpdateWhileSubscribed(address subscription);
    error CannotSubscribeToSelf();
    error CannotSubscribeToZeroAddress();
    error NotOwnable();
    error AddressFiltered(address filtered);
    error CodeHashFiltered(address account, bytes32 codeHash);
    error CannotSubscribeToRegistrantWithSubscription(address registrant);
    error CannotCopyFromSelf();

    event RegistrationUpdated(address indexed registrant, bool indexed registered);
    event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);
    event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);
    event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);
    event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);
    event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);
}

File 16 of 22: 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);
    }
}

File 17 of 22: Ownable2Step.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.0;

import "./Ownable.sol";

/**
 * @dev Contract module which provides 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} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

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

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() external {
        address sender = _msgSender();
        require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
        _transferOwnership(sender);
    }
}

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

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

/**
 * @title  OwnedRegistrant
 * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries,
 *         to facilitate a subscription whose ownership can be transferred.
 */
contract OwnedRegistrant is Ownable2Step {
    address constant registry = 0x000000000000AAeB6D7670E522A718067333cd4E;

    constructor(address _owner) {
        IOperatorFilterRegistry(registry).register(address(this));
        transferOwnership(_owner);
    }
}

File 19 of 22: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

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

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

File 20 of 22: RoyaltiesV2.sol
// SPDX-License-Identifier: MIT
// secondary sales royalties on rarible

pragma solidity ^0.8.0;

import "./LibPart.sol";

interface RoyaltiesV2 {
    event RoyaltiesSet(uint256 tokenId, LibPart.Part[] royalties);

    function getRaribleV2Royalties(uint256 id) external view returns (LibPart.Part[] memory);
}

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

pragma solidity ^0.8.0;

import "./AbstractRoyalties.sol";
import "./RoyaltiesV2.sol";

contract RoyaltiesV2Impl is AbstractRoyalties, RoyaltiesV2 {

    function getRaribleV2Royalties(uint256 id) override external view returns (LibPart.Part[] memory) {
      LibPart.Part[] memory _royalties = royalties[id];
      if(_royalties.length > 0) {
        return royalties[id];
      }
      _royalties = royalties[0];
      return _royalties;
    }

    function _onRoyaltiesSet(uint256 id, LibPart.Part[] memory _royalties) override internal {
        emit RoyaltiesSet(id, _royalties);
    }
}

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

pragma solidity ^0.8.0;

import "./Math.sol";

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

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_cid","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"gas","type":"uint256"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"uint96","name":"value","type":"uint96"}],"indexed":false,"internalType":"struct LibPart.Part[]","name":"royalties","type":"tuple[]"}],"name":"RoyaltiesSet","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":"_baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"approvalCheck","type":"bool"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCIDForToken","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getRaribleV2Royalties","outputs":[{"components":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"uint96","name":"value","type":"uint96"}],"internalType":"struct LibPart.Part[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","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":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_cid","type":"string"},{"internalType":"uint256","name":"_rangeNo","type":"uint256"}],"name":"setCIDforRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxFistGenMintBatchSize","type":"uint256"},{"internalType":"uint256","name":"maxFirstGenTokens","type":"uint256"}],"name":"setMintConstraints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address payable","name":"_royaltiesRecipientAddress","type":"address"},{"internalType":"uint96","name":"_percentageBasisPoints","type":"uint96"}],"name":"setRoyalties","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":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600b60006101000a81548160ff02191690831515021790555060fa600c55612710600d553480156200003757600080fd5b506040516200544e3803806200544e83398181016040528101906200005d9190620006b6565b733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600a81526020017f4d415947205359474e45000000000000000000000000000000000000000000008152506040518060400160405280600b81526020017f4d4159475f3232313230330000000000000000000000000000000000000000008152508160029081620000f1919062000952565b50806003908162000103919062000952565b50620001146200035560201b60201c565b60008190555050506200013c620001306200035e60201b60201c565b6200036660201b60201c565b600160098190555060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111562000339578015620001ff576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001c592919062000a7e565b600060405180830381600087803b158015620001e057600080fd5b505af1158015620001f5573d6000803e3d6000fd5b5050505062000338565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620002b9576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200027f92919062000a7e565b600060405180830381600087803b1580156200029a57600080fd5b505af1158015620002af573d6000803e3d6000fd5b5050505062000337565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b815260040162000302919062000aab565b600060405180830381600087803b1580156200031d57600080fd5b505af115801562000332573d6000803e3d6000fd5b505050505b5b5b50506200034e8160006200042c60201b60201c565b5062000b7a565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6200043c6200046860201b60201c565b81600e826014811062000454576200045362000ac8565b5b01908162000463919062000952565b505050565b620004786200035e60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff166200049e620004f960201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620004f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004ee9062000b58565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200058c8262000541565b810181811067ffffffffffffffff82111715620005ae57620005ad62000552565b5b80604052505050565b6000620005c362000523565b9050620005d1828262000581565b919050565b600067ffffffffffffffff821115620005f457620005f362000552565b5b620005ff8262000541565b9050602081019050919050565b60005b838110156200062c5780820151818401526020810190506200060f565b60008484015250505050565b60006200064f6200064984620005d6565b620005b7565b9050828152602081018484840111156200066e576200066d6200053c565b5b6200067b8482856200060c565b509392505050565b600082601f8301126200069b576200069a62000537565b5b8151620006ad84826020860162000638565b91505092915050565b600060208284031215620006cf57620006ce6200052d565b5b600082015167ffffffffffffffff811115620006f057620006ef62000532565b5b620006fe8482850162000683565b91505092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200075a57607f821691505b60208210810362000770576200076f62000712565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620007da7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200079b565b620007e686836200079b565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620008336200082d6200082784620007fe565b62000808565b620007fe565b9050919050565b6000819050919050565b6200084f8362000812565b620008676200085e826200083a565b848454620007a8565b825550505050565b600090565b6200087e6200086f565b6200088b81848462000844565b505050565b5b81811015620008b357620008a760008262000874565b60018101905062000891565b5050565b601f8211156200090257620008cc8162000776565b620008d7846200078b565b81016020851015620008e7578190505b620008ff620008f6856200078b565b83018262000890565b50505b505050565b600082821c905092915050565b6000620009276000198460080262000907565b1980831691505092915050565b600062000942838362000914565b9150826002028217905092915050565b6200095d8262000707565b67ffffffffffffffff81111562000979576200097862000552565b5b62000985825462000741565b62000992828285620008b7565b600060209050601f831160018114620009ca5760008415620009b5578287015190505b620009c1858262000934565b86555062000a31565b601f198416620009da8662000776565b60005b8281101562000a0457848901518255600182019150602085019450602081019050620009dd565b8683101562000a24578489015162000a20601f89168262000914565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000a668262000a39565b9050919050565b62000a788162000a59565b82525050565b600060408201905062000a95600083018562000a6d565b62000aa4602083018462000a6d565b9392505050565b600060208201905062000ac2600083018462000a6d565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600062000b4060208362000af7565b915062000b4d8262000b08565b602082019050919050565b6000602082019050818103600083015262000b738162000b31565b9050919050565b6148c48062000b8a6000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80635c975abb116101045780639fac68cb116100a2578063cad96cca11610071578063cad96cca14610540578063e985e9c514610570578063ed6bd3ed146105a0578063f2fde38b146105bc576101da565b80639fac68cb146104bc578063a22cb465146104d8578063b88d4fde146104f4578063c87b56dd14610510576101da565b8063715018a6116100de578063715018a6146104465780638da5cb5b146104505780638ece17871461046e57806395d89b411461049e576101da565b80635c975abb146103c85780636352211e146103e657806370a0823114610416576101da565b806318160ddd1161017c578063340403131161014b578063340403131461036a5780633ccfd60b1461038657806340c10f191461039057806342842e0e146103ac576101da565b806318160ddd146102e157806323b872dd146102ff5780632672c9021461031b5780632a55205a14610339576101da565b8063081812fc116101b8578063081812fc14610249578063095ea7b314610279578063143094db14610295578063150b7a02146102b1576101da565b806301ffc9a7146101df57806302329a291461020f57806306fdde031461022b575b600080fd5b6101f960048036038101906101f491906132c0565b6105d8565b6040516102069190613308565b60405180910390f35b6102296004803603810190610224919061334f565b610695565b005b6102336106ba565b604051610240919061340c565b60405180910390f35b610263600480360381019061025e9190613464565b61074c565b60405161027091906134d2565b60405180910390f35b610293600480360381019061028e9190613519565b6107c8565b005b6102af60048036038101906102aa91906135db565b610909565b005b6102cb60048036038101906102c69190613763565b610a10565b6040516102d891906137f5565b60405180910390f35b6102e9610a65565b6040516102f6919061381f565b60405180910390f35b6103196004803603810190610314919061383a565b610a7c565b005b610323610c5e565b604051610330919061340c565b60405180910390f35b610353600480360381019061034e919061388d565b610c97565b6040516103619291906138cd565b60405180910390f35b610384600480360381019061037f919061388d565b610f96565b005b61038e610fb0565b005b6103aa60048036038101906103a59190613519565b611041565b005b6103c660048036038101906103c1919061383a565b611156565b005b6103d0611338565b6040516103dd9190613308565b60405180910390f35b61040060048036038101906103fb9190613464565b61134b565b60405161040d91906134d2565b60405180910390f35b610430600480360381019061042b91906138f6565b61135d565b60405161043d919061381f565b60405180910390f35b61044e6113f1565b005b610458611405565b60405161046591906134d2565b60405180910390f35b61048860048036038101906104839190613464565b61142f565b604051610495919061340c565b60405180910390f35b6104a6611449565b6040516104b3919061340c565b60405180910390f35b6104d660048036038101906104d19190613923565b6114db565b005b6104f260048036038101906104ed9190613963565b6114f1565b005b61050e60048036038101906105099190613763565b611668565b005b61052a60048036038101906105259190613464565b61184d565b604051610537919061340c565b60405180910390f35b61055a60048036038101906105559190613464565b6118d1565b6040516105679190613a9f565b60405180910390f35b61058a60048036038101906105859190613ac1565b611be0565b6040516105979190613308565b60405180910390f35b6105ba60048036038101906105b59190613ba2565b611c74565b005b6105d660048036038101906105d191906138f6565b611ca3565b005b600063cad96cca60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361062f5760019050610690565b632a55205a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106845760019050610690565b61068d82611d26565b90505b919050565b61069d611db8565b80600b60006101000a81548160ff02191690831515021790555050565b6060600280546106c990613c2d565b80601f01602080910402602001604051908101604052809291908181526020018280546106f590613c2d565b80156107425780601f1061071757610100808354040283529160200191610742565b820191906000526020600020905b81548152906001019060200180831161072557829003601f168201915b5050505050905090565b600061075782611e36565b61078d576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006107d382611e95565b90508073ffffffffffffffffffffffffffffffffffffffff166107f4611f61565b73ffffffffffffffffffffffffffffffffffffffff1614610857576108208161081b611f61565b611be0565b610856576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b610911611db8565b6000600167ffffffffffffffff81111561092e5761092d613638565b5b60405190808252806020026020018201604052801561096757816020015b610954613216565b81526020019060019003908161094c5790505b509050818160008151811061097f5761097e613c5e565b5b6020026020010151602001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff168152505082816000815181106109c2576109c1613c5e565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610a0a8482611f69565b50505050565b60007f28fa6e16458f9c24aa59ddd4085264573006dbe30304837873c7deafc702b03885858585614e20604051610a4b959493929190613d27565b60405180910390a163150b7a0260e01b9050949350505050565b6000610a6f6121ea565b6001546000540303905090565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610c4c573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610aee57610ae98484846121f3565b610c58565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610b37929190613d81565b602060405180830381865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190613dbf565b8015610c0a57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610bc8929190613d81565b602060405180830381865afa158015610be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c099190613dbf565b5b610c4b57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610c4291906134d2565b60405180910390fd5b5b610c578484846121f3565b5b50505050565b6040518060400160405280600581526020017f2e6a736f6e00000000000000000000000000000000000000000000000000000081525081565b6000806000600a6000868152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610d91578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190610ccf565b505050509050600081511115610e115780600081518110610db557610db4613c5e565b5b60200260200101516000015161271082600081518110610dd857610dd7613c5e565b5b6020026020010151602001516bffffffffffffffffffffffff1686610dfd9190613e1b565b610e079190613e8c565b9250925050610f8f565b600a6000808152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610f06578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190610e44565b505050509050600081511115610f865780600081518110610f2a57610f29613c5e565b5b60200260200101516000015161271082600081518110610f4d57610f4c613c5e565b5b6020026020010151602001516bffffffffffffffffffffffff1686610f729190613e1b565b610f7c9190613e8c565b9250925050610f8f565b60008092509250505b9250929050565b610f9e611db8565b81600c8190555080600d819055505050565b610fb8611db8565b610fc0612203565b60003373ffffffffffffffffffffffffffffffffffffffff1647604051610fe690613eee565b60006040518083038185875af1925050503d8060008114611023576040519150601f19603f3d011682016040523d82523d6000602084013e611028565b606091505b505090508061103657600080fd5b5061103f612252565b565b611049611db8565b600b60009054906101000a900460ff161561106357600080fd5b600081116110a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109d90613f4f565b60405180910390fd5b600c548111156110eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e290613fe1565b60405180910390fd5b60006110f5610a65565b9050600d5482826111069190614001565b1115611147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113e906140a7565b60405180910390fd5b611151838361225c565b505050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611326573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111c8576111c384848461227a565b611332565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611211929190613d81565b602060405180830381865afa15801561122e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112529190613dbf565b80156112e457506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016112a2929190613d81565b602060405180830381865afa1580156112bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e39190613dbf565b5b61132557336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161131c91906134d2565b60405180910390fd5b5b61133184848461227a565b5b50505050565b600b60009054906101000a900460ff1681565b600061135682611e95565b9050919050565b6000806113698361229a565b036113a0576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6113f9611db8565b61140360006122a4565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060611439611db8565b6114428261236a565b9050919050565b60606003805461145890613c2d565b80601f016020809104026020016040519081016040528092919081815260200182805461148490613c2d565b80156114d15780601f106114a6576101008083540402835291602001916114d1565b820191906000526020600020905b8154815290600101906020018083116114b457829003601f168201915b5050505050905090565b6114e3611db8565b6114ed82826124b6565b5050565b6114f9611f61565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361155d576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806007600061156a611f61565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611617611f61565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161165c9190613308565b60405180910390a35050565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611839573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036116db576116d6858585856127ce565b611846565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611724929190613d81565b602060405180830381865afa158015611741573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117659190613dbf565b80156117f757506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016117b5929190613d81565b602060405180830381865afa1580156117d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f69190613dbf565b5b61183857336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161182f91906134d2565b60405180910390fd5b5b611845858585856127ce565b5b5050505050565b6060600061185a8361236a565b9050600061186784612841565b9050600082826040518060400160405280600581526020017f2e6a736f6e0000000000000000000000000000000000000000000000000000008152506040516020016118b593929190614103565b6040516020818303038152906040529050809350505050919050565b60606000600a6000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156119ca578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190611908565b505050509050600081511115611adb57600a6000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611acf578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190611a0d565b50505050915050611bdb565b600a6000808152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611bd0578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190611b0e565b505050509050809150505b919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611c7c611db8565b81600e8260148110611c9157611c90613c5e565b5b019081611c9e91906142d6565b505050565b611cab611db8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d119061441a565b60405180910390fd5b611d23816122a4565b50565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611d8157506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611db15750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b611dc061290f565b73ffffffffffffffffffffffffffffffffffffffff16611dde611405565b73ffffffffffffffffffffffffffffffffffffffff1614611e34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2b90614486565b60405180910390fd5b565b600081611e416121ea565b11158015611e50575060005482105b8015611e8e575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60008082905080611ea46121ea565b11611f2a57600054811015611f295760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611f27575b60008103611f1d576004600083600190039350838152602001908152602001600020549050611ef3565b8092505050611f5c565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600080600090505b825181101561219657600073ffffffffffffffffffffffffffffffffffffffff16838281518110611fa557611fa4613c5e565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603612007576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ffe906144f2565b60405180910390fd5b600083828151811061201c5761201b613c5e565b5b6020026020010151602001516bffffffffffffffffffffffff1603612076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161206d9061455e565b60405180910390fd5b82818151811061208957612088613c5e565b5b6020026020010151602001516bffffffffffffffffffffffff16826120ae9190614001565b9150600a60008581526020019081526020016000208382815181106120d6576120d5613c5e565b5b60200260200101519080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050808061218e9061457e565b915050611f71565b5061271081106121db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121d290614638565b60405180910390fd5b6121e58383612917565b505050565b60006001905090565b6121fe838383612954565b505050565b600260095403612248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223f906146a4565b60405180910390fd5b6002600981905550565b6001600981905550565b612276828260405180602001604052806000815250612d19565b5050565b61229583838360405180602001604052806000815250611668565b505050565b6000819050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060600082116123af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a690614710565b60405180910390fd5b60006101f46001846123c19190614730565b6123cb9190613e8c565b905060148110612410576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612407906147b0565b60405180910390fd5b600e816014811061242457612423613c5e565b5b01805461243090613c2d565b80601f016020809104026020016040519081016040528092919081815260200182805461245c90613c2d565b80156124a95780601f1061247e576101008083540402835291602001916124a9565b820191906000526020600020905b81548152906001019060200180831161248c57829003601f168201915b5050505050915050919050565b60006124c183611e95565b9050600081905060006006600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083156125ce5760008273ffffffffffffffffffffffffffffffffffffffff16612527611f61565b73ffffffffffffffffffffffffffffffffffffffff161480612556575061255583612550611f61565b611be0565b5b806125935750612564611f61565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050806125cc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b6125dc826000876001612db6565b60006125e78261229a565b14612623576006600086815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600160806001901b03600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507c02000000000000000000000000000000000000000000000000000000007c010000000000000000000000000000000000000000000000000000000060a042901b6126c28561229a565b171717600460008781526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361274b5760006001860190506000600460008381526020019081526020016000205403612749576000548114612748578360046000838152602001908152602001600020819055505b5b505b84600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46127b5826000876001612dbc565b6001600081548092919060010191905055505050505050565b6127d9848484612954565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461283b5761280484848484612dc2565b61283a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606000600161285084612f12565b01905060008167ffffffffffffffff81111561286f5761286e613638565b5b6040519080825280601f01601f1916602001820160405280156128a15781602001600182028036833780820191505090505b509050600082602001820190505b600115612904578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816128f8576128f7613e5d565b5b049450600085036128af575b819350505050919050565b600033905090565b7f3fa96d7b6bcbfe71ef171666d84db3cf52fa2d1c8afdb1cc8e486177f208b7df82826040516129489291906147d0565b60405180910390a15050565b600061295f82611e95565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146129c6576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006006600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008573ffffffffffffffffffffffffffffffffffffffff16612a1f611f61565b73ffffffffffffffffffffffffffffffffffffffff161480612a4e5750612a4d86612a48611f61565b611be0565b5b80612a8b5750612a5c611f61565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080612ac4576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612acf8661229a565b03612b06576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b138686866001612db6565b6000612b1e8361229a565b14612b5a576006600085815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b612c218761229a565b1717600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603612ca95760006001850190506000600460008381526020019081526020016000205403612ca7576000548114612ca6578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612d118686866001612dbc565b505050505050565b612d238383613065565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612db157600080549050600083820390505b612d636000868380600101945086612dc2565b612d99576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110612d50578160005414612dae57600080fd5b50505b505050565b50505050565b50505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612de8611f61565b8786866040518563ffffffff1660e01b8152600401612e0a9493929190614800565b6020604051808303816000875af1925050508015612e4657506040513d601f19601f82011682018060405250810190612e439190614861565b60015b612ebf573d8060008114612e76576040519150601f19603f3d011682016040523d82523d6000602084013e612e7b565b606091505b506000815103612eb7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612f70577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612f6657612f65613e5d565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612fad576d04ee2d6d415b85acef81000000008381612fa357612fa2613e5d565b5b0492506020810190505b662386f26fc100008310612fdc57662386f26fc100008381612fd257612fd1613e5d565b5b0492506010810190505b6305f5e1008310613005576305f5e1008381612ffb57612ffa613e5d565b5b0492506008810190505b612710831061302a5761271083816130205761301f613e5d565b5b0492506004810190505b6064831061304d576064838161304357613042613e5d565b5b0492506002810190505b600a831061305c576001810190505b80915050919050565b60008054905060006130768461229a565b036130ad576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082036130e7576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130f46000848385612db6565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16131596001841461320c565b901b60a042901b6131698561229a565b1717600460008381526020019081526020016000208190555060005b8080600101915082018473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a482811061318557828201600081905550506132076000848385612dbc565b505050565b6000819050919050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61329d81613268565b81146132a857600080fd5b50565b6000813590506132ba81613294565b92915050565b6000602082840312156132d6576132d561325e565b5b60006132e4848285016132ab565b91505092915050565b60008115159050919050565b613302816132ed565b82525050565b600060208201905061331d60008301846132f9565b92915050565b61332c816132ed565b811461333757600080fd5b50565b60008135905061334981613323565b92915050565b6000602082840312156133655761336461325e565b5b60006133738482850161333a565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156133b657808201518184015260208101905061339b565b60008484015250505050565b6000601f19601f8301169050919050565b60006133de8261337c565b6133e88185613387565b93506133f8818560208601613398565b613401816133c2565b840191505092915050565b6000602082019050818103600083015261342681846133d3565b905092915050565b6000819050919050565b6134418161342e565b811461344c57600080fd5b50565b60008135905061345e81613438565b92915050565b60006020828403121561347a5761347961325e565b5b60006134888482850161344f565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006134bc82613491565b9050919050565b6134cc816134b1565b82525050565b60006020820190506134e760008301846134c3565b92915050565b6134f6816134b1565b811461350157600080fd5b50565b600081359050613513816134ed565b92915050565b600080604083850312156135305761352f61325e565b5b600061353e85828601613504565b925050602061354f8582860161344f565b9150509250929050565b600061356482613491565b9050919050565b61357481613559565b811461357f57600080fd5b50565b6000813590506135918161356b565b92915050565b60006bffffffffffffffffffffffff82169050919050565b6135b881613597565b81146135c357600080fd5b50565b6000813590506135d5816135af565b92915050565b6000806000606084860312156135f4576135f361325e565b5b60006136028682870161344f565b935050602061361386828701613582565b9250506040613624868287016135c6565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613670826133c2565b810181811067ffffffffffffffff8211171561368f5761368e613638565b5b80604052505050565b60006136a2613254565b90506136ae8282613667565b919050565b600067ffffffffffffffff8211156136ce576136cd613638565b5b6136d7826133c2565b9050602081019050919050565b82818337600083830152505050565b6000613706613701846136b3565b613698565b90508281526020810184848401111561372257613721613633565b5b61372d8482856136e4565b509392505050565b600082601f83011261374a5761374961362e565b5b813561375a8482602086016136f3565b91505092915050565b6000806000806080858703121561377d5761377c61325e565b5b600061378b87828801613504565b945050602061379c87828801613504565b93505060406137ad8782880161344f565b925050606085013567ffffffffffffffff8111156137ce576137cd613263565b5b6137da87828801613735565b91505092959194509250565b6137ef81613268565b82525050565b600060208201905061380a60008301846137e6565b92915050565b6138198161342e565b82525050565b60006020820190506138346000830184613810565b92915050565b6000806000606084860312156138535761385261325e565b5b600061386186828701613504565b935050602061387286828701613504565b92505060406138838682870161344f565b9150509250925092565b600080604083850312156138a4576138a361325e565b5b60006138b28582860161344f565b92505060206138c38582860161344f565b9150509250929050565b60006040820190506138e260008301856134c3565b6138ef6020830184613810565b9392505050565b60006020828403121561390c5761390b61325e565b5b600061391a84828501613504565b91505092915050565b6000806040838503121561393a5761393961325e565b5b60006139488582860161344f565b92505060206139598582860161333a565b9150509250929050565b6000806040838503121561397a5761397961325e565b5b600061398885828601613504565b92505060206139998582860161333a565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6139d881613559565b82525050565b6139e781613597565b82525050565b604082016000820151613a0360008501826139cf565b506020820151613a1660208501826139de565b50505050565b6000613a2883836139ed565b60408301905092915050565b6000602082019050919050565b6000613a4c826139a3565b613a5681856139ae565b9350613a61836139bf565b8060005b83811015613a92578151613a798882613a1c565b9750613a8483613a34565b925050600181019050613a65565b5085935050505092915050565b60006020820190508181036000830152613ab98184613a41565b905092915050565b60008060408385031215613ad857613ad761325e565b5b6000613ae685828601613504565b9250506020613af785828601613504565b9150509250929050565b600067ffffffffffffffff821115613b1c57613b1b613638565b5b613b25826133c2565b9050602081019050919050565b6000613b45613b4084613b01565b613698565b905082815260208101848484011115613b6157613b60613633565b5b613b6c8482856136e4565b509392505050565b600082601f830112613b8957613b8861362e565b5b8135613b99848260208601613b32565b91505092915050565b60008060408385031215613bb957613bb861325e565b5b600083013567ffffffffffffffff811115613bd757613bd6613263565b5b613be385828601613b74565b9250506020613bf48582860161344f565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613c4557607f821691505b602082108103613c5857613c57613bfe565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000613cb482613c8d565b613cbe8185613c98565b9350613cce818560208601613398565b613cd7816133c2565b840191505092915050565b6000819050919050565b6000819050919050565b6000613d11613d0c613d0784613ce2565b613cec565b61342e565b9050919050565b613d2181613cf6565b82525050565b600060a082019050613d3c60008301886134c3565b613d4960208301876134c3565b613d566040830186613810565b8181036060830152613d688185613ca9565b9050613d776080830184613d18565b9695505050505050565b6000604082019050613d9660008301856134c3565b613da360208301846134c3565b9392505050565b600081519050613db981613323565b92915050565b600060208284031215613dd557613dd461325e565b5b6000613de384828501613daa565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613e268261342e565b9150613e318361342e565b9250828202613e3f8161342e565b91508282048414831517613e5657613e55613dec565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613e978261342e565b9150613ea28361342e565b925082613eb257613eb1613e5d565b5b828204905092915050565b600081905092915050565b50565b6000613ed8600083613ebd565b9150613ee382613ec8565b600082019050919050565b6000613ef982613ecb565b9150819050919050565b7f4d4159475f373231613a20696e76616c6964207175616e746974792c20300000600082015250565b6000613f39601e83613387565b9150613f4482613f03565b602082019050919050565b60006020820190508181036000830152613f6881613f2c565b9050919050565b7f4d4159475f373231613a20696e76616c6964207175616e746974792c20746f6f60008201527f206c617267650000000000000000000000000000000000000000000000000000602082015250565b6000613fcb602683613387565b9150613fd682613f6f565b604082019050919050565b60006020820190508181036000830152613ffa81613fbe565b9050919050565b600061400c8261342e565b91506140178361342e565b925082820190508082111561402f5761402e613dec565b5b92915050565b7f4d4159475f373231613a20696e76616c6964207175616e746974792c20746f6f60008201527f206d616e792066697273742067656e20746f6b656e7300000000000000000000602082015250565b6000614091603683613387565b915061409c82614035565b604082019050919050565b600060208201905081810360008301526140c081614084565b9050919050565b600081905092915050565b60006140dd8261337c565b6140e781856140c7565b93506140f7818560208601613398565b80840191505092915050565b600061410f82866140d2565b915061411b82856140d2565b915061412782846140d2565b9150819050949350505050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026141967fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614159565b6141a08683614159565b95508019841693508086168417925050509392505050565b60006141d36141ce6141c98461342e565b613cec565b61342e565b9050919050565b6000819050919050565b6141ed836141b8565b6142016141f9826141da565b848454614166565b825550505050565b600090565b614216614209565b6142218184846141e4565b505050565b5b818110156142455761423a60008261420e565b600181019050614227565b5050565b601f82111561428a5761425b81614134565b61426484614149565b81016020851015614273578190505b61428761427f85614149565b830182614226565b50505b505050565b600082821c905092915050565b60006142ad6000198460080261428f565b1980831691505092915050565b60006142c6838361429c565b9150826002028217905092915050565b6142df8261337c565b67ffffffffffffffff8111156142f8576142f7613638565b5b6143028254613c2d565b61430d828285614249565b600060209050601f831160018114614340576000841561432e578287015190505b61433885826142ba565b8655506143a0565b601f19841661434e86614134565b60005b8281101561437657848901518255600182019150602085019450602081019050614351565b86831015614393578489015161438f601f89168261429c565b8355505b6001600288020188555050505b505050505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614404602683613387565b915061440f826143a8565b604082019050919050565b60006020820190508181036000830152614433816143f7565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614470602083613387565b915061447b8261443a565b602082019050919050565b6000602082019050818103600083015261449f81614463565b9050919050565b7f526563697069656e742073686f756c642062652070726573656e740000000000600082015250565b60006144dc601b83613387565b91506144e7826144a6565b602082019050919050565b6000602082019050818103600083015261450b816144cf565b9050919050565b7f526f79616c74792076616c75652073686f756c6420626520706f736974697665600082015250565b6000614548602083613387565b915061455382614512565b602082019050919050565b600060208201905081810360008301526145778161453b565b9050919050565b60006145898261342e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145bb576145ba613dec565b5b600182019050919050565b7f526f79616c747920746f74616c2076616c75652073686f756c64206265203c2060008201527f3130303030000000000000000000000000000000000000000000000000000000602082015250565b6000614622602583613387565b915061462d826145c6565b604082019050919050565b6000602082019050818103600083015261465181614615565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061468e601f83613387565b915061469982614658565b602082019050919050565b600060208201905081810360008301526146bd81614681565b9050919050565b7f746f6b656e4964206f66207a65726f206973206f7574206f662072616e676500600082015250565b60006146fa601f83613387565b9150614705826146c4565b602082019050919050565b60006020820190508181036000830152614729816146ed565b9050919050565b600061473b8261342e565b91506147468361342e565b925082820390508181111561475e5761475d613dec565b5b92915050565b7f6d697373696e67204349442076616c756520666f7220746f6b656e0000000000600082015250565b600061479a601b83613387565b91506147a582614764565b602082019050919050565b600060208201905081810360008301526147c98161478d565b9050919050565b60006040820190506147e56000830185613810565b81810360208301526147f78184613a41565b90509392505050565b600060808201905061481560008301876134c3565b61482260208301866134c3565b61482f6040830185613810565b81810360608301526148418184613ca9565b905095945050505050565b60008151905061485b81613294565b92915050565b6000602082840312156148775761487661325e565b5b60006148858482850161484c565b9150509291505056fea2646970667358221220a54fa0ae72a15494fc22efc8ddb9b17fa57cb1554149af36c8c090c40fb012cc64736f6c634300081100330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005068747470733a2f2f6d6179672e6d7970696e6174612e636c6f75642f697066732f516d646945314876506e6b4b655370633359334d673856544e545458447133365032364c687667545953644255352f00000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80635c975abb116101045780639fac68cb116100a2578063cad96cca11610071578063cad96cca14610540578063e985e9c514610570578063ed6bd3ed146105a0578063f2fde38b146105bc576101da565b80639fac68cb146104bc578063a22cb465146104d8578063b88d4fde146104f4578063c87b56dd14610510576101da565b8063715018a6116100de578063715018a6146104465780638da5cb5b146104505780638ece17871461046e57806395d89b411461049e576101da565b80635c975abb146103c85780636352211e146103e657806370a0823114610416576101da565b806318160ddd1161017c578063340403131161014b578063340403131461036a5780633ccfd60b1461038657806340c10f191461039057806342842e0e146103ac576101da565b806318160ddd146102e157806323b872dd146102ff5780632672c9021461031b5780632a55205a14610339576101da565b8063081812fc116101b8578063081812fc14610249578063095ea7b314610279578063143094db14610295578063150b7a02146102b1576101da565b806301ffc9a7146101df57806302329a291461020f57806306fdde031461022b575b600080fd5b6101f960048036038101906101f491906132c0565b6105d8565b6040516102069190613308565b60405180910390f35b6102296004803603810190610224919061334f565b610695565b005b6102336106ba565b604051610240919061340c565b60405180910390f35b610263600480360381019061025e9190613464565b61074c565b60405161027091906134d2565b60405180910390f35b610293600480360381019061028e9190613519565b6107c8565b005b6102af60048036038101906102aa91906135db565b610909565b005b6102cb60048036038101906102c69190613763565b610a10565b6040516102d891906137f5565b60405180910390f35b6102e9610a65565b6040516102f6919061381f565b60405180910390f35b6103196004803603810190610314919061383a565b610a7c565b005b610323610c5e565b604051610330919061340c565b60405180910390f35b610353600480360381019061034e919061388d565b610c97565b6040516103619291906138cd565b60405180910390f35b610384600480360381019061037f919061388d565b610f96565b005b61038e610fb0565b005b6103aa60048036038101906103a59190613519565b611041565b005b6103c660048036038101906103c1919061383a565b611156565b005b6103d0611338565b6040516103dd9190613308565b60405180910390f35b61040060048036038101906103fb9190613464565b61134b565b60405161040d91906134d2565b60405180910390f35b610430600480360381019061042b91906138f6565b61135d565b60405161043d919061381f565b60405180910390f35b61044e6113f1565b005b610458611405565b60405161046591906134d2565b60405180910390f35b61048860048036038101906104839190613464565b61142f565b604051610495919061340c565b60405180910390f35b6104a6611449565b6040516104b3919061340c565b60405180910390f35b6104d660048036038101906104d19190613923565b6114db565b005b6104f260048036038101906104ed9190613963565b6114f1565b005b61050e60048036038101906105099190613763565b611668565b005b61052a60048036038101906105259190613464565b61184d565b604051610537919061340c565b60405180910390f35b61055a60048036038101906105559190613464565b6118d1565b6040516105679190613a9f565b60405180910390f35b61058a60048036038101906105859190613ac1565b611be0565b6040516105979190613308565b60405180910390f35b6105ba60048036038101906105b59190613ba2565b611c74565b005b6105d660048036038101906105d191906138f6565b611ca3565b005b600063cad96cca60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361062f5760019050610690565b632a55205a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106845760019050610690565b61068d82611d26565b90505b919050565b61069d611db8565b80600b60006101000a81548160ff02191690831515021790555050565b6060600280546106c990613c2d565b80601f01602080910402602001604051908101604052809291908181526020018280546106f590613c2d565b80156107425780601f1061071757610100808354040283529160200191610742565b820191906000526020600020905b81548152906001019060200180831161072557829003601f168201915b5050505050905090565b600061075782611e36565b61078d576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006107d382611e95565b90508073ffffffffffffffffffffffffffffffffffffffff166107f4611f61565b73ffffffffffffffffffffffffffffffffffffffff1614610857576108208161081b611f61565b611be0565b610856576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b610911611db8565b6000600167ffffffffffffffff81111561092e5761092d613638565b5b60405190808252806020026020018201604052801561096757816020015b610954613216565b81526020019060019003908161094c5790505b509050818160008151811061097f5761097e613c5e565b5b6020026020010151602001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff168152505082816000815181106109c2576109c1613c5e565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610a0a8482611f69565b50505050565b60007f28fa6e16458f9c24aa59ddd4085264573006dbe30304837873c7deafc702b03885858585614e20604051610a4b959493929190613d27565b60405180910390a163150b7a0260e01b9050949350505050565b6000610a6f6121ea565b6001546000540303905090565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610c4c573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610aee57610ae98484846121f3565b610c58565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610b37929190613d81565b602060405180830381865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190613dbf565b8015610c0a57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610bc8929190613d81565b602060405180830381865afa158015610be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c099190613dbf565b5b610c4b57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610c4291906134d2565b60405180910390fd5b5b610c578484846121f3565b5b50505050565b6040518060400160405280600581526020017f2e6a736f6e00000000000000000000000000000000000000000000000000000081525081565b6000806000600a6000868152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610d91578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190610ccf565b505050509050600081511115610e115780600081518110610db557610db4613c5e565b5b60200260200101516000015161271082600081518110610dd857610dd7613c5e565b5b6020026020010151602001516bffffffffffffffffffffffff1686610dfd9190613e1b565b610e079190613e8c565b9250925050610f8f565b600a6000808152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610f06578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190610e44565b505050509050600081511115610f865780600081518110610f2a57610f29613c5e565b5b60200260200101516000015161271082600081518110610f4d57610f4c613c5e565b5b6020026020010151602001516bffffffffffffffffffffffff1686610f729190613e1b565b610f7c9190613e8c565b9250925050610f8f565b60008092509250505b9250929050565b610f9e611db8565b81600c8190555080600d819055505050565b610fb8611db8565b610fc0612203565b60003373ffffffffffffffffffffffffffffffffffffffff1647604051610fe690613eee565b60006040518083038185875af1925050503d8060008114611023576040519150601f19603f3d011682016040523d82523d6000602084013e611028565b606091505b505090508061103657600080fd5b5061103f612252565b565b611049611db8565b600b60009054906101000a900460ff161561106357600080fd5b600081116110a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109d90613f4f565b60405180910390fd5b600c548111156110eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e290613fe1565b60405180910390fd5b60006110f5610a65565b9050600d5482826111069190614001565b1115611147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113e906140a7565b60405180910390fd5b611151838361225c565b505050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611326573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111c8576111c384848461227a565b611332565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611211929190613d81565b602060405180830381865afa15801561122e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112529190613dbf565b80156112e457506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016112a2929190613d81565b602060405180830381865afa1580156112bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e39190613dbf565b5b61132557336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161131c91906134d2565b60405180910390fd5b5b61133184848461227a565b5b50505050565b600b60009054906101000a900460ff1681565b600061135682611e95565b9050919050565b6000806113698361229a565b036113a0576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6113f9611db8565b61140360006122a4565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060611439611db8565b6114428261236a565b9050919050565b60606003805461145890613c2d565b80601f016020809104026020016040519081016040528092919081815260200182805461148490613c2d565b80156114d15780601f106114a6576101008083540402835291602001916114d1565b820191906000526020600020905b8154815290600101906020018083116114b457829003601f168201915b5050505050905090565b6114e3611db8565b6114ed82826124b6565b5050565b6114f9611f61565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361155d576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806007600061156a611f61565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611617611f61565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161165c9190613308565b60405180910390a35050565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611839573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036116db576116d6858585856127ce565b611846565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611724929190613d81565b602060405180830381865afa158015611741573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117659190613dbf565b80156117f757506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016117b5929190613d81565b602060405180830381865afa1580156117d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f69190613dbf565b5b61183857336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161182f91906134d2565b60405180910390fd5b5b611845858585856127ce565b5b5050505050565b6060600061185a8361236a565b9050600061186784612841565b9050600082826040518060400160405280600581526020017f2e6a736f6e0000000000000000000000000000000000000000000000000000008152506040516020016118b593929190614103565b6040516020818303038152906040529050809350505050919050565b60606000600a6000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156119ca578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190611908565b505050509050600081511115611adb57600a6000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611acf578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190611a0d565b50505050915050611bdb565b600a6000808152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611bd0578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505081526020019060010190611b0e565b505050509050809150505b919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611c7c611db8565b81600e8260148110611c9157611c90613c5e565b5b019081611c9e91906142d6565b505050565b611cab611db8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d119061441a565b60405180910390fd5b611d23816122a4565b50565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611d8157506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611db15750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b611dc061290f565b73ffffffffffffffffffffffffffffffffffffffff16611dde611405565b73ffffffffffffffffffffffffffffffffffffffff1614611e34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2b90614486565b60405180910390fd5b565b600081611e416121ea565b11158015611e50575060005482105b8015611e8e575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60008082905080611ea46121ea565b11611f2a57600054811015611f295760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611f27575b60008103611f1d576004600083600190039350838152602001908152602001600020549050611ef3565b8092505050611f5c565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600080600090505b825181101561219657600073ffffffffffffffffffffffffffffffffffffffff16838281518110611fa557611fa4613c5e565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603612007576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ffe906144f2565b60405180910390fd5b600083828151811061201c5761201b613c5e565b5b6020026020010151602001516bffffffffffffffffffffffff1603612076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161206d9061455e565b60405180910390fd5b82818151811061208957612088613c5e565b5b6020026020010151602001516bffffffffffffffffffffffff16826120ae9190614001565b9150600a60008581526020019081526020016000208382815181106120d6576120d5613c5e565b5b60200260200101519080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050808061218e9061457e565b915050611f71565b5061271081106121db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121d290614638565b60405180910390fd5b6121e58383612917565b505050565b60006001905090565b6121fe838383612954565b505050565b600260095403612248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223f906146a4565b60405180910390fd5b6002600981905550565b6001600981905550565b612276828260405180602001604052806000815250612d19565b5050565b61229583838360405180602001604052806000815250611668565b505050565b6000819050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060600082116123af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a690614710565b60405180910390fd5b60006101f46001846123c19190614730565b6123cb9190613e8c565b905060148110612410576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612407906147b0565b60405180910390fd5b600e816014811061242457612423613c5e565b5b01805461243090613c2d565b80601f016020809104026020016040519081016040528092919081815260200182805461245c90613c2d565b80156124a95780601f1061247e576101008083540402835291602001916124a9565b820191906000526020600020905b81548152906001019060200180831161248c57829003601f168201915b5050505050915050919050565b60006124c183611e95565b9050600081905060006006600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083156125ce5760008273ffffffffffffffffffffffffffffffffffffffff16612527611f61565b73ffffffffffffffffffffffffffffffffffffffff161480612556575061255583612550611f61565b611be0565b5b806125935750612564611f61565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050806125cc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b6125dc826000876001612db6565b60006125e78261229a565b14612623576006600086815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600160806001901b03600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507c02000000000000000000000000000000000000000000000000000000007c010000000000000000000000000000000000000000000000000000000060a042901b6126c28561229a565b171717600460008781526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361274b5760006001860190506000600460008381526020019081526020016000205403612749576000548114612748578360046000838152602001908152602001600020819055505b5b505b84600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46127b5826000876001612dbc565b6001600081548092919060010191905055505050505050565b6127d9848484612954565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461283b5761280484848484612dc2565b61283a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606000600161285084612f12565b01905060008167ffffffffffffffff81111561286f5761286e613638565b5b6040519080825280601f01601f1916602001820160405280156128a15781602001600182028036833780820191505090505b509050600082602001820190505b600115612904578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816128f8576128f7613e5d565b5b049450600085036128af575b819350505050919050565b600033905090565b7f3fa96d7b6bcbfe71ef171666d84db3cf52fa2d1c8afdb1cc8e486177f208b7df82826040516129489291906147d0565b60405180910390a15050565b600061295f82611e95565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146129c6576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006006600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008573ffffffffffffffffffffffffffffffffffffffff16612a1f611f61565b73ffffffffffffffffffffffffffffffffffffffff161480612a4e5750612a4d86612a48611f61565b611be0565b5b80612a8b5750612a5c611f61565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080612ac4576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612acf8661229a565b03612b06576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b138686866001612db6565b6000612b1e8361229a565b14612b5a576006600085815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b612c218761229a565b1717600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603612ca95760006001850190506000600460008381526020019081526020016000205403612ca7576000548114612ca6578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612d118686866001612dbc565b505050505050565b612d238383613065565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612db157600080549050600083820390505b612d636000868380600101945086612dc2565b612d99576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110612d50578160005414612dae57600080fd5b50505b505050565b50505050565b50505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612de8611f61565b8786866040518563ffffffff1660e01b8152600401612e0a9493929190614800565b6020604051808303816000875af1925050508015612e4657506040513d601f19601f82011682018060405250810190612e439190614861565b60015b612ebf573d8060008114612e76576040519150601f19603f3d011682016040523d82523d6000602084013e612e7b565b606091505b506000815103612eb7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612f70577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612f6657612f65613e5d565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612fad576d04ee2d6d415b85acef81000000008381612fa357612fa2613e5d565b5b0492506020810190505b662386f26fc100008310612fdc57662386f26fc100008381612fd257612fd1613e5d565b5b0492506010810190505b6305f5e1008310613005576305f5e1008381612ffb57612ffa613e5d565b5b0492506008810190505b612710831061302a5761271083816130205761301f613e5d565b5b0492506004810190505b6064831061304d576064838161304357613042613e5d565b5b0492506002810190505b600a831061305c576001810190505b80915050919050565b60008054905060006130768461229a565b036130ad576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082036130e7576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130f46000848385612db6565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16131596001841461320c565b901b60a042901b6131698561229a565b1717600460008381526020019081526020016000208190555060005b8080600101915082018473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a482811061318557828201600081905550506132076000848385612dbc565b505050565b6000819050919050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61329d81613268565b81146132a857600080fd5b50565b6000813590506132ba81613294565b92915050565b6000602082840312156132d6576132d561325e565b5b60006132e4848285016132ab565b91505092915050565b60008115159050919050565b613302816132ed565b82525050565b600060208201905061331d60008301846132f9565b92915050565b61332c816132ed565b811461333757600080fd5b50565b60008135905061334981613323565b92915050565b6000602082840312156133655761336461325e565b5b60006133738482850161333a565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156133b657808201518184015260208101905061339b565b60008484015250505050565b6000601f19601f8301169050919050565b60006133de8261337c565b6133e88185613387565b93506133f8818560208601613398565b613401816133c2565b840191505092915050565b6000602082019050818103600083015261342681846133d3565b905092915050565b6000819050919050565b6134418161342e565b811461344c57600080fd5b50565b60008135905061345e81613438565b92915050565b60006020828403121561347a5761347961325e565b5b60006134888482850161344f565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006134bc82613491565b9050919050565b6134cc816134b1565b82525050565b60006020820190506134e760008301846134c3565b92915050565b6134f6816134b1565b811461350157600080fd5b50565b600081359050613513816134ed565b92915050565b600080604083850312156135305761352f61325e565b5b600061353e85828601613504565b925050602061354f8582860161344f565b9150509250929050565b600061356482613491565b9050919050565b61357481613559565b811461357f57600080fd5b50565b6000813590506135918161356b565b92915050565b60006bffffffffffffffffffffffff82169050919050565b6135b881613597565b81146135c357600080fd5b50565b6000813590506135d5816135af565b92915050565b6000806000606084860312156135f4576135f361325e565b5b60006136028682870161344f565b935050602061361386828701613582565b9250506040613624868287016135c6565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613670826133c2565b810181811067ffffffffffffffff8211171561368f5761368e613638565b5b80604052505050565b60006136a2613254565b90506136ae8282613667565b919050565b600067ffffffffffffffff8211156136ce576136cd613638565b5b6136d7826133c2565b9050602081019050919050565b82818337600083830152505050565b6000613706613701846136b3565b613698565b90508281526020810184848401111561372257613721613633565b5b61372d8482856136e4565b509392505050565b600082601f83011261374a5761374961362e565b5b813561375a8482602086016136f3565b91505092915050565b6000806000806080858703121561377d5761377c61325e565b5b600061378b87828801613504565b945050602061379c87828801613504565b93505060406137ad8782880161344f565b925050606085013567ffffffffffffffff8111156137ce576137cd613263565b5b6137da87828801613735565b91505092959194509250565b6137ef81613268565b82525050565b600060208201905061380a60008301846137e6565b92915050565b6138198161342e565b82525050565b60006020820190506138346000830184613810565b92915050565b6000806000606084860312156138535761385261325e565b5b600061386186828701613504565b935050602061387286828701613504565b92505060406138838682870161344f565b9150509250925092565b600080604083850312156138a4576138a361325e565b5b60006138b28582860161344f565b92505060206138c38582860161344f565b9150509250929050565b60006040820190506138e260008301856134c3565b6138ef6020830184613810565b9392505050565b60006020828403121561390c5761390b61325e565b5b600061391a84828501613504565b91505092915050565b6000806040838503121561393a5761393961325e565b5b60006139488582860161344f565b92505060206139598582860161333a565b9150509250929050565b6000806040838503121561397a5761397961325e565b5b600061398885828601613504565b92505060206139998582860161333a565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6139d881613559565b82525050565b6139e781613597565b82525050565b604082016000820151613a0360008501826139cf565b506020820151613a1660208501826139de565b50505050565b6000613a2883836139ed565b60408301905092915050565b6000602082019050919050565b6000613a4c826139a3565b613a5681856139ae565b9350613a61836139bf565b8060005b83811015613a92578151613a798882613a1c565b9750613a8483613a34565b925050600181019050613a65565b5085935050505092915050565b60006020820190508181036000830152613ab98184613a41565b905092915050565b60008060408385031215613ad857613ad761325e565b5b6000613ae685828601613504565b9250506020613af785828601613504565b9150509250929050565b600067ffffffffffffffff821115613b1c57613b1b613638565b5b613b25826133c2565b9050602081019050919050565b6000613b45613b4084613b01565b613698565b905082815260208101848484011115613b6157613b60613633565b5b613b6c8482856136e4565b509392505050565b600082601f830112613b8957613b8861362e565b5b8135613b99848260208601613b32565b91505092915050565b60008060408385031215613bb957613bb861325e565b5b600083013567ffffffffffffffff811115613bd757613bd6613263565b5b613be385828601613b74565b9250506020613bf48582860161344f565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613c4557607f821691505b602082108103613c5857613c57613bfe565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000613cb482613c8d565b613cbe8185613c98565b9350613cce818560208601613398565b613cd7816133c2565b840191505092915050565b6000819050919050565b6000819050919050565b6000613d11613d0c613d0784613ce2565b613cec565b61342e565b9050919050565b613d2181613cf6565b82525050565b600060a082019050613d3c60008301886134c3565b613d4960208301876134c3565b613d566040830186613810565b8181036060830152613d688185613ca9565b9050613d776080830184613d18565b9695505050505050565b6000604082019050613d9660008301856134c3565b613da360208301846134c3565b9392505050565b600081519050613db981613323565b92915050565b600060208284031215613dd557613dd461325e565b5b6000613de384828501613daa565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613e268261342e565b9150613e318361342e565b9250828202613e3f8161342e565b91508282048414831517613e5657613e55613dec565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613e978261342e565b9150613ea28361342e565b925082613eb257613eb1613e5d565b5b828204905092915050565b600081905092915050565b50565b6000613ed8600083613ebd565b9150613ee382613ec8565b600082019050919050565b6000613ef982613ecb565b9150819050919050565b7f4d4159475f373231613a20696e76616c6964207175616e746974792c20300000600082015250565b6000613f39601e83613387565b9150613f4482613f03565b602082019050919050565b60006020820190508181036000830152613f6881613f2c565b9050919050565b7f4d4159475f373231613a20696e76616c6964207175616e746974792c20746f6f60008201527f206c617267650000000000000000000000000000000000000000000000000000602082015250565b6000613fcb602683613387565b9150613fd682613f6f565b604082019050919050565b60006020820190508181036000830152613ffa81613fbe565b9050919050565b600061400c8261342e565b91506140178361342e565b925082820190508082111561402f5761402e613dec565b5b92915050565b7f4d4159475f373231613a20696e76616c6964207175616e746974792c20746f6f60008201527f206d616e792066697273742067656e20746f6b656e7300000000000000000000602082015250565b6000614091603683613387565b915061409c82614035565b604082019050919050565b600060208201905081810360008301526140c081614084565b9050919050565b600081905092915050565b60006140dd8261337c565b6140e781856140c7565b93506140f7818560208601613398565b80840191505092915050565b600061410f82866140d2565b915061411b82856140d2565b915061412782846140d2565b9150819050949350505050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026141967fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614159565b6141a08683614159565b95508019841693508086168417925050509392505050565b60006141d36141ce6141c98461342e565b613cec565b61342e565b9050919050565b6000819050919050565b6141ed836141b8565b6142016141f9826141da565b848454614166565b825550505050565b600090565b614216614209565b6142218184846141e4565b505050565b5b818110156142455761423a60008261420e565b600181019050614227565b5050565b601f82111561428a5761425b81614134565b61426484614149565b81016020851015614273578190505b61428761427f85614149565b830182614226565b50505b505050565b600082821c905092915050565b60006142ad6000198460080261428f565b1980831691505092915050565b60006142c6838361429c565b9150826002028217905092915050565b6142df8261337c565b67ffffffffffffffff8111156142f8576142f7613638565b5b6143028254613c2d565b61430d828285614249565b600060209050601f831160018114614340576000841561432e578287015190505b61433885826142ba565b8655506143a0565b601f19841661434e86614134565b60005b8281101561437657848901518255600182019150602085019450602081019050614351565b86831015614393578489015161438f601f89168261429c565b8355505b6001600288020188555050505b505050505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614404602683613387565b915061440f826143a8565b604082019050919050565b60006020820190508181036000830152614433816143f7565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614470602083613387565b915061447b8261443a565b602082019050919050565b6000602082019050818103600083015261449f81614463565b9050919050565b7f526563697069656e742073686f756c642062652070726573656e740000000000600082015250565b60006144dc601b83613387565b91506144e7826144a6565b602082019050919050565b6000602082019050818103600083015261450b816144cf565b9050919050565b7f526f79616c74792076616c75652073686f756c6420626520706f736974697665600082015250565b6000614548602083613387565b915061455382614512565b602082019050919050565b600060208201905081810360008301526145778161453b565b9050919050565b60006145898261342e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145bb576145ba613dec565b5b600182019050919050565b7f526f79616c747920746f74616c2076616c75652073686f756c64206265203c2060008201527f3130303030000000000000000000000000000000000000000000000000000000602082015250565b6000614622602583613387565b915061462d826145c6565b604082019050919050565b6000602082019050818103600083015261465181614615565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061468e601f83613387565b915061469982614658565b602082019050919050565b600060208201905081810360008301526146bd81614681565b9050919050565b7f746f6b656e4964206f66207a65726f206973206f7574206f662072616e676500600082015250565b60006146fa601f83613387565b9150614705826146c4565b602082019050919050565b60006020820190508181036000830152614729816146ed565b9050919050565b600061473b8261342e565b91506147468361342e565b925082820390508181111561475e5761475d613dec565b5b92915050565b7f6d697373696e67204349442076616c756520666f7220746f6b656e0000000000600082015250565b600061479a601b83613387565b91506147a582614764565b602082019050919050565b600060208201905081810360008301526147c98161478d565b9050919050565b60006040820190506147e56000830185613810565b81810360208301526147f78184613a41565b90509392505050565b600060808201905061481560008301876134c3565b61482260208301866134c3565b61482f6040830185613810565b81810360608301526148418184613ca9565b905095945050505050565b60008151905061485b81613294565b92915050565b6000602082840312156148775761487661325e565b5b60006148858482850161484c565b9150509291505056fea2646970667358221220a54fa0ae72a15494fc22efc8ddb9b17fa57cb1554149af36c8c090c40fb012cc64736f6c63430008110033

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

0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005068747470733a2f2f6d6179672e6d7970696e6174612e636c6f75642f697066732f516d646945314876506e6b4b655370633359334d673856544e545458447133365032364c687667545953644255352f00000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _cid (string): https://mayg.mypinata.cloud/ipfs/QmdiE1HvPnkKeSpc3Y3Mg8VTNTTXDq36P26LhvgTYSdBU5/

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000050
Arg [2] : 68747470733a2f2f6d6179672e6d7970696e6174612e636c6f75642f69706673
Arg [3] : 2f516d646945314876506e6b4b655370633359334d673856544e545458447133
Arg [4] : 365032364c687667545953644255352f00000000000000000000000000000000


Deployed Bytecode Sourcemap

748:6176:10:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4863:333;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5260:71;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9883:98:3;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11830:200;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11364:405;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3897:344:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2838:746;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4056:309:3;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1517:157:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;945:48;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4312:547;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;5774:271;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3588:161;;;:::i;:::-;;2061:443;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1678:165;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;914:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9679:142:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5639:231;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1824:101:15;;;:::i;:::-;;1194:85;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6450:138:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10045:102:3;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5335:109:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;12097:303:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1847:210:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2518:316;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;187:291:20;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;12466:162:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6327:119:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2074:198:15;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4863:333:10;4957:4;258:10:9;4989:38:10;;4974:53;;;:11;:53;;;;4971:90;;5048:4;5041:11;;;;4971:90;899:10;5087:21;;5072:36;;;:11;:36;;;;5069:71;;5127:4;5120:11;;;;5069:71;5155:36;5179:11;5155:23;:36::i;:::-;5148:43;;4863:333;;;;:::o;5260:71::-;1087:13:15;:11;:13::i;:::-;5320:6:10::1;5311;;:15;;;;;;;;;;;;;;;;;;5260:71:::0;:::o;9883:98:3:-;9937:13;9969:5;9962:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9883:98;:::o;11830:200::-;11898:7;11922:16;11930:7;11922;:16::i;:::-;11917:64;;11947:34;;;;;;;;;;;;;;11917:64;11999:15;:24;12015:7;11999:24;;;;;;;;;;;;;;;;;;;;;11992:31;;11830:200;;;:::o;11364:405::-;11436:13;11468:27;11487:7;11468:18;:27::i;:::-;11436:61;;11535:5;11512:28;;:19;:17;:19::i;:::-;:28;;;11508:172;;11559:44;11576:5;11583:19;:17;:19::i;:::-;11559:16;:44::i;:::-;11554:126;;11630:35;;;;;;;;;;;;;;11554:126;11508:172;11717:2;11690:15;:24;11706:7;11690:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;11754:7;11750:2;11734:28;;11743:5;11734:28;;;;;;;;;;;;11426:343;11364:405;;:::o;3897:344:10:-;1087:13:15;:11;:13::i;:::-;4032:32:10::1;4086:1;4067:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;4032:56;;4116:22;4094:10;4105:1;4094:13;;;;;;;;:::i;:::-;;;;;;;;:19;;:44;;;;;;;;;::::0;::::1;4168:26;4144:10;4155:1;4144:13;;;;;;;;:::i;:::-;;;;;;;;:21;;:50;;;;;;;;;::::0;::::1;4200:36;4215:8;4225:10;4200:14;:36::i;:::-;4026:215;3897:344:::0;;;:::o;2838:746::-;2985:6;3488:46;3497:8;3507:4;3513:7;3522:4;3528:5;3488:46;;;;;;;;;;:::i;:::-;;;;;;;;3549:30;;;3542:37;;2838:746;;;;;;:::o;4056:309:3:-;4109:7;4333:15;:13;:15::i;:::-;4318:12;;4302:13;;:28;:46;4295:53;;4056:309;:::o;1517:157:10:-;1618:4;1475:1:14;310:42;1429:43;;;:47;1425:683;;;1712:10;1704:18;;:4;:18;;;1700:82;;1632:37:10::1;1651:4;1657:2;1661:7;1632:18;:37::i;:::-;1761:7:14::0;;1700:82;310:42;1839:40;;;1888:4;1895:10;1839:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:156;;;;;310:42;1934:40;;;1983:4;1990;1934:61;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1839:156;1795:303;;2072:10;2053:30;;;;;;;;;;;:::i;:::-;;;;;;;;1795:303;1425:683;1632:37:10::1;1651:4;1657:2;1661:7;1632:18;:37::i;:::-;1517:157:::0;;;;;:::o;945:48::-;;;;;;;;;;;;;;;;;;;:::o;4312:547::-;4394:16;4412:21;4501:32;4536:9;:19;4546:8;4536:19;;;;;;;;;;;4501:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4584:1;4564:10;:17;:21;4561:115;;;4603:10;4614:1;4603:13;;;;;;;;:::i;:::-;;;;;;;;:21;;;4663:5;4640:10;4651:1;4640:13;;;;;;;;:::i;:::-;;;;;;;;:19;;;4627:32;;:10;:32;;;;:::i;:::-;4626:42;;;;:::i;:::-;4595:74;;;;;;;4561:115;4694:9;:12;4704:1;4694:12;;;;;;;;;;;4681:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4735:1;4715:10;:17;:21;4712:115;;;4754:10;4765:1;4754:13;;;;;;;;:::i;:::-;;;;;;;;:21;;;4814:5;4791:10;4802:1;4791:13;;;;;;;;:::i;:::-;;;;;;;;:19;;;4778:32;;:10;:32;;;;:::i;:::-;4777:42;;;;:::i;:::-;4746:74;;;;;;;4712:115;4848:1;4852;4832:22;;;;;4312:547;;;;;;:::o;5774:271::-;1087:13:15;:11;:13::i;:::-;5973:23:10::1;5946:24;:50;;;;6023:17;6002:18;:38;;;;5774:271:::0;;:::o;3588:161::-;1087:13:15;:11;:13::i;:::-;2261:21:18::1;:19;:21::i;:::-;3646:12:10::2;3672:10;3664:24;;3696:21;3664:58;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3645:77;;;3736:7;3728:16;;;::::0;::::2;;3638:111;2303:20:18::1;:18;:20::i;:::-;3588:161:10:o:0;2061:443::-;1087:13:15;:11;:13::i;:::-;2141:6:10::1;;;;;;;;;;;2140:7;2132:16;;;::::0;::::1;;2177:1;2165:9;:13;2157:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;2242:24;;2229:9;:37;;2221:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;2318:14;2335:13;:11;:13::i;:::-;2318:30;;2386:18;;2373:9;2364:6;:18;;;;:::i;:::-;:40;;2356:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;2472:25;2482:3;2487:9;2472;:25::i;:::-;2124:380;2061:443:::0;;:::o;1678:165::-;1783:4;1475:1:14;310:42;1429:43;;;:47;1425:683;;;1712:10;1704:18;;:4;:18;;;1700:82;;1797:41:10::1;1820:4;1826:2;1830:7;1797:22;:41::i;:::-;1761:7:14::0;;1700:82;310:42;1839:40;;;1888:4;1895:10;1839:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:156;;;;;310:42;1934:40;;;1983:4;1990;1934:61;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1839:156;1795:303;;2072:10;2053:30;;;;;;;;;;;:::i;:::-;;;;;;;;1795:303;1425:683;1797:41:10::1;1820:4;1826:2;1830:7;1797:22;:41::i;:::-;1678:165:::0;;;;;:::o;914:26::-;;;;;;;;;;;;;:::o;9679:142:3:-;9743:7;9785:27;9804:7;9785:18;:27::i;:::-;9762:52;;9679:142;;;:::o;5639:231::-;5703:7;5754:1;5726:24;5744:5;5726:17;:24::i;:::-;:29;5722:70;;5764:28;;;;;;;;;;;;;;5722:70;1116:13;5809:18;:25;5828:5;5809:25;;;;;;;;;;;;;;;;:54;5802:61;;5639:231;;;:::o;1824:101:15:-;1087:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;1194:85::-;1240:7;1266:6;;;;;;;;;;;1259:13;;1194:85;:::o;6450:138:10:-;6524:13;1087::15;:11;:13::i;:::-;6552:31:10::1;6575:7;6552:22;:31::i;:::-;6545:38;;6450:138:::0;;;:::o;10045:102:3:-;10101:13;10133:7;10126:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10045:102;:::o;5335:109:10:-;1087:13:15;:11;:13::i;:::-;5409:30:10::1;5416:7;5425:13;5409:5;:30::i;:::-;5335:109:::0;;:::o;12097:303:3:-;12207:19;:17;:19::i;:::-;12195:31;;:8;:31;;;12191:61;;12235:17;;;;;;;;;;;;;;12191:61;12315:8;12263:18;:39;12282:19;:17;:19::i;:::-;12263:39;;;;;;;;;;;;;;;:49;12303:8;12263:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;12374:8;12338:55;;12353:19;:17;:19::i;:::-;12338:55;;;12384:8;12338:55;;;;;;:::i;:::-;;;;;;;;12097:303;;:::o;1847:210:10:-;1989:4;1475:1:14;310:42;1429:43;;;:47;1425:683;;;1712:10;1704:18;;:4;:18;;;1700:82;;2005:47:10::1;2028:4;2034:2;2038:7;2047:4;2005:22;:47::i;:::-;1761:7:14::0;;1700:82;310:42;1839:40;;;1888:4;1895:10;1839:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:156;;;;;310:42;1934:40;;;1983:4;1990;1934:61;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1839:156;1795:303;;2072:10;2053:30;;;;;;;;;;;:::i;:::-;;;;;;;;1795:303;1425:683;2005:47:10::1;2028:4;2034:2;2038:7;2047:4;2005:22;:47::i;:::-;1847:210:::0;;;;;;:::o;2518:316::-;2600:13;2623:17;2643:32;2666:8;2643:22;:32::i;:::-;2623:52;;2681:24;2708:26;2725:8;2708:16;:26::i;:::-;2681:53;;2741:14;2775:3;2780:10;2792:14;;;;;;;;;;;;;;;;;2758:49;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2741:66;;2827:1;2813:16;;;;;2518:316;;;:::o;187:291:20:-;262:21;293:32;328:9;:13;338:2;328:13;;;;;;;;;;;293:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;372:1;352:10;:17;:21;349:65;;;392:9;:13;402:2;392:13;;;;;;;;;;;385:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;349:65;434:9;:12;444:1;434:12;;;;;;;;;;;421:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;461:10;454:17;;;187:291;;;;:::o;12466:162:3:-;12563:4;12586:18;:25;12605:5;12586:25;;;;;;;;;;;;;;;:35;12612:8;12586:35;;;;;;;;;;;;;;;;;;;;;;;;;12579:42;;12466:162;;;;:::o;6327:119:10:-;1087:13:15;:11;:13::i;:::-;6437:4:10::1;6413:11;6425:8;6413:21;;;;;;;:::i;:::-;;;:28;;;;;;:::i;:::-;;6327:119:::0;;:::o;2074:198:15:-;1087:13;:11;:13::i;:::-;2182:1:::1;2162:22;;:8;:22;;::::0;2154:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;2237:28;2256:8;2237:18;:28::i;:::-;2074:198:::0;:::o;4973:607:3:-;5058:4;5368:10;5353:25;;:11;:25;;;;:101;;;;5444:10;5429:25;;:11;:25;;;;5353:101;:177;;;;5520:10;5505:25;;:11;:25;;;;5353:177;5334:196;;4973:607;;;:::o;1352:130:15:-;1426:12;:10;:12::i;:::-;1415:23;;:7;:5;:7::i;:::-;:23;;;1407:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1352:130::o;13796:268:3:-;13853:4;13907:7;13888:15;:13;:15::i;:::-;:26;;:65;;;;;13940:13;;13930:7;:23;13888:65;:150;;;;;14037:1;1868:8;13990:17;:26;14008:7;13990:26;;;;;;;;;;;;:43;:48;13888:150;13869:169;;13796:268;;;:::o;7256:1105::-;7323:7;7342:12;7357:7;7342:22;;7422:4;7403:15;:13;:15::i;:::-;:23;7399:898;;7455:13;;7448:4;:20;7444:853;;;7492:14;7509:17;:23;7527:4;7509:23;;;;;;;;;;;;7492:40;;7623:1;1868:8;7596:6;:23;:28;7592:687;;8107:111;8124:1;8114:6;:11;8107:111;;8166:17;:25;8184:6;;;;;;;8166:25;;;;;;;;;;;;8157:34;;8107:111;;;8250:6;8243:13;;;;;;7592:687;7470:827;7444:853;7399:898;8323:31;;;;;;;;;;;;;;7256:1105;;;;:::o;26122:103::-;26182:7;26208:10;26201:17;;26122:103;:::o;186:566:0:-;275:18;308:6;317:1;308:10;;303:324;324:10;:17;320:1;:21;303:324;;;403:3;370:37;;:10;381:1;370:13;;;;;;;;:::i;:::-;;;;;;;;:21;;;:37;;;362:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;484:1;461:10;472:1;461:13;;;;;;;;:::i;:::-;;;;;;;;:19;;;:24;;;453:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;550:10;561:1;550:13;;;;;;;;:::i;:::-;;;;;;;;:19;;;536:33;;;;;;;:::i;:::-;;;583:9;:13;593:2;583:13;;;;;;;;;;;602:10;613:1;602:13;;;;;;;;:::i;:::-;;;;;;;;583:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;343:3;;;;;:::i;:::-;;;;303:324;;;;657:5;644:10;:18;636:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;714:31;730:2;734:10;714:15;:31::i;:::-;265:487;186:566;;:::o;5466:87:10:-;5523:7;5547:1;5540:8;;5466:87;:::o;12690:164:3:-;12819:28;12829:4;12835:2;12839:7;12819:9;:28::i;:::-;12690:164;;;:::o;2336:287:18:-;1759:1;2468:7;;:19;2460:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1759:1;2598:7;:18;;;;2336:287::o;2629:209::-;1716:1;2809:7;:22;;;;2629:209::o;14143:102:3:-;14211:27;14221:2;14225:8;14211:27;;;;;;;;;;;;:9;:27::i;:::-;14143:102;;:::o;12920:179::-;13053:39;13070:4;13076:2;13080:7;13053:39;;;;;;;;;;;;:16;:39::i;:::-;12920:179;;;:::o;10943:144::-;11007:14;11066:5;11056:15;;10943:144;;;:::o;2426:187:15:-;2499:16;2518:6;;;;;;;;;;;2499:25;;2543:8;2534:6;;:17;;;;;;;;;;;;;;;;;;2597:8;2566:40;;2587:8;2566:40;;;;;;;;;;;;2489:124;2426:187;:::o;6592:330:10:-;6666:13;6706:1;6696:7;:11;6688:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;6752:16;1237:3;6780:1;6772:7;:9;;;;:::i;:::-;6771:34;;;;:::i;:::-;6752:53;;1290:2;6821:8;:29;6812:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;6896:11;6908:8;6896:21;;;;;;;:::i;:::-;;;6889:28;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6592:330;;;:::o;20329:2870:3:-;20408:27;20438;20457:7;20438:18;:27::i;:::-;20408:57;;20476:12;20507:19;20476:52;;20538:23;20564:15;:24;20580:7;20564:24;;;;;;;;;;;;;;;;;;;;;20538:50;;20603:13;20599:300;;;20632:22;20681:4;20658:27;;:19;:17;:19::i;:::-;:27;;;:90;;;;20705:43;20722:4;20728:19;:17;:19::i;:::-;20705:16;:43::i;:::-;20658:90;:148;;;;20787:19;:17;:19::i;:::-;20768:38;;:15;:38;;;20658:148;20632:175;;20827:17;20822:66;;20853:35;;;;;;;;;;;;;;20822:66;20618:281;20599:300;20909:51;20931:4;20945:1;20949:7;20958:1;20909:21;:51::i;:::-;21065:1;21027:34;21045:15;21027:17;:34::i;:::-;:39;21023:101;;21089:15;:24;21105:7;21089:24;;;;;;;;;;;;21082:31;;;;;;;;;;;21023:101;21758:1;1373:3;21729:1;:25;;21728:31;21700:18;:24;21719:4;21700:24;;;;;;;;;;;;;;;;:59;;;;;;;;;;;2140:8;1868;1755:3;22078:15;:41;;22035:23;22053:4;22035:17;:23::i;:::-;:85;:118;:161;21990:17;:26;22008:7;21990:26;;;;;;;;;;;:206;;;;22363:1;2140:8;22313:19;:46;:51;22309:616;;22384:19;22416:1;22406:7;:11;22384:33;;22571:1;22537:17;:30;22555:11;22537:30;;;;;;;;;;;;:35;22533:378;;22673:13;;22658:11;:28;22654:239;;22851:19;22818:17;:30;22836:11;22818:30;;;;;;;;;;;:52;;;;22654:239;22533:378;22366:559;22309:616;22977:7;22973:1;22950:35;;22959:4;22950:35;;;;;;;;;;;;22995:50;23016:4;23030:1;23034:7;23043:1;22995:20;:50::i;:::-;23168:12;;:14;;;;;;;;;;;;;20398:2801;;;20329:2870;;:::o;13165:385::-;13326:28;13336:4;13342:2;13346:7;13326:9;:28::i;:::-;13386:1;13368:2;:14;;;:19;13364:180;;13406:56;13437:4;13443:2;13447:7;13456:5;13406:30;:56::i;:::-;13401:143;;13489:40;;;;;;;;;;;;;;13401:143;13364:180;13165:385;;;;:::o;410:696:21:-;466:13;515:14;552:1;532:17;543:5;532:10;:17::i;:::-;:21;515:38;;567:20;601:6;590:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;567:41;;622:11;748:6;744:2;740:15;732:6;728:28;721:35;;783:280;790:4;783:280;;;814:5;;;;;;;;953:8;948:2;941:5;937:14;932:30;927:3;919:44;1007:2;998:11;;;;;;:::i;:::-;;;;;1040:1;1031:5;:10;783:280;1027:21;783:280;1083:6;1076:13;;;;;410:696;;;:::o;640:96:1:-;693:7;719:10;712:17;;640:96;:::o;484:139:20:-;588:28;601:2;605:10;588:28;;;;;;;:::i;:::-;;;;;;;;484:139;;:::o;17357:2595:3:-;17467:27;17497;17516:7;17497:18;:27::i;:::-;17467:57;;17580:4;17539:45;;17555:19;17539:45;;;17535:86;;17593:28;;;;;;;;;;;;;;17535:86;17632:23;17658:15;:24;17674:7;17658:24;;;;;;;;;;;;;;;;;;;;;17632:50;;17693:22;17742:4;17719:27;;:19;:17;:19::i;:::-;:27;;;:86;;;;17762:43;17779:4;17785:19;:17;:19::i;:::-;17762:16;:43::i;:::-;17719:86;:140;;;;17840:19;:17;:19::i;:::-;17821:38;;:15;:38;;;17719:140;17693:167;;17876:17;17871:66;;17902:35;;;;;;;;;;;;;;17871:66;17976:1;17951:21;17969:2;17951:17;:21::i;:::-;:26;17947:62;;17986:23;;;;;;;;;;;;;;17947:62;18020:43;18042:4;18048:2;18052:7;18061:1;18020:21;:43::i;:::-;18168:1;18130:34;18148:15;18130:17;:34::i;:::-;:39;18126:101;;18192:15;:24;18208:7;18192:24;;;;;;;;;;;;18185:31;;;;;;;;;;;18126:101;18587:18;:24;18606:4;18587:24;;;;;;;;;;;;;;;;18585:26;;;;;;;;;;;;18655:18;:22;18674:2;18655:22;;;;;;;;;;;;;;;;18653:24;;;;;;;;;;;2140:8;1755:3;19027:15;:41;;18986:21;19004:2;18986:17;:21::i;:::-;:83;:126;18941:17;:26;18959:7;18941:26;;;;;;;;;;;:171;;;;19279:1;2140:8;19229:19;:46;:51;19225:616;;19300:19;19332:1;19322:7;:11;19300:33;;19487:1;19453:17;:30;19471:11;19453:30;;;;;;;;;;;;:35;19449:378;;19589:13;;19574:11;:28;19570:239;;19767:19;19734:17;:30;19752:11;19734:30;;;;;;;;;;;:52;;;;19570:239;19449:378;19282:559;19225:616;19885:7;19881:2;19866:27;;19875:4;19866:27;;;;;;;;;;;;19903:42;19924:4;19930:2;19934:7;19943:1;19903:20;:42::i;:::-;17457:2495;;;17357:2595;;;:::o;14619:661::-;14737:19;14743:2;14747:8;14737:5;:19::i;:::-;14813:1;14795:2;:14;;;:19;14791:473;;14834:11;14848:13;;14834:27;;14879:13;14901:8;14895:3;:14;14879:30;;14927:229;14957:62;14996:1;15000:2;15004:7;;;;;;15013:5;14957:30;:62::i;:::-;14952:165;;15054:40;;;;;;;;;;;;;;14952:165;15151:3;15143:5;:11;14927:229;;15236:3;15219:13;;:20;15215:34;;15241:8;;;15215:34;14816:448;;14791:473;14619:661;;;:::o;24990:154::-;;;;;:::o;25785:153::-;;;;;:::o;23680:679::-;23838:4;23874:2;23858:36;;;23895:19;:17;:19::i;:::-;23916:4;23922:7;23931:5;23858:79;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;23854:499;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24135:1;24118:6;:13;:18;24114:229;;24163:40;;;;;;;;;;;;;;24114:229;24303:6;24297:13;24288:6;24284:2;24280:15;24273:38;23854:499;24015:45;;;24005:55;;;:6;:55;;;;23998:62;;;23680:679;;;;;;:::o;9889:890:11:-;9942:7;9961:14;9978:1;9961:18;;10026:6;10017:5;:15;10013:99;;10061:6;10052:15;;;;;;:::i;:::-;;;;;10095:2;10085:12;;;;10013:99;10138:6;10129:5;:15;10125:99;;10173:6;10164:15;;;;;;:::i;:::-;;;;;10207:2;10197:12;;;;10125:99;10250:6;10241:5;:15;10237:99;;10285:6;10276:15;;;;;;:::i;:::-;;;;;10319:2;10309:12;;;;10237:99;10362:5;10353;:14;10349:96;;10396:5;10387:14;;;;;;:::i;:::-;;;;;10429:1;10419:11;;;;10349:96;10471:5;10462;:14;10458:96;;10505:5;10496:14;;;;;;:::i;:::-;;;;;10538:1;10528:11;;;;10458:96;10580:5;10571;:14;10567:96;;10614:5;10605:14;;;;;;:::i;:::-;;;;;10647:1;10637:11;;;;10567:96;10689:5;10680;:14;10676:64;;10724:1;10714:11;;;;10676:64;10766:6;10759:13;;;9889:890;;;:::o;15541:1574:3:-;15605:20;15628:13;;15605:36;;15680:1;15655:21;15673:2;15655:17;:21::i;:::-;:26;15651:58;;15690:19;;;;;;;;;;;;;;15651:58;15735:1;15723:8;:13;15719:44;;15745:18;;;;;;;;;;;;;;15719:44;15774:61;15804:1;15808:2;15812:12;15826:8;15774:21;:61::i;:::-;16367:1;1250:2;16338:1;:25;;16337:31;16325:8;:44;16299:18;:22;16318:2;16299:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;2008:3;16758:29;16785:1;16773:8;:13;16758:14;:29::i;:::-;:56;;1755:3;16696:15;:41;;16655:21;16673:2;16655:17;:21::i;:::-;:83;:160;16605:17;:31;16623:12;16605:31;;;;;;;;;;;:210;;;;16830:14;16858:117;16924:8;;;;;;16909:12;:23;16905:2;16884:49;;16901:1;16884:49;;;;;;;;;;;;16965:8;16956:6;:17;16858:117;;17020:8;17005:12;:23;16989:13;:39;;;;16082:957;17048:60;17077:1;17081:2;17085:12;17099:8;17048:20;:60::i;:::-;15595:1520;15541:1574;;:::o;11169:138::-;11227:14;11286:5;11276:15;;11169:138;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:22:-;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:116::-;1588:21;1603:5;1588:21;:::i;:::-;1581:5;1578:32;1568:60;;1624:1;1621;1614:12;1568:60;1518:116;:::o;1640:133::-;1683:5;1721:6;1708:20;1699:29;;1737:30;1761:5;1737:30;:::i;:::-;1640:133;;;;:::o;1779:323::-;1835:6;1884:2;1872:9;1863:7;1859:23;1855:32;1852:119;;;1890:79;;:::i;:::-;1852:119;2010:1;2035:50;2077:7;2068:6;2057:9;2053:22;2035:50;:::i;:::-;2025:60;;1981:114;1779:323;;;;:::o;2108:99::-;2160:6;2194:5;2188:12;2178:22;;2108:99;;;:::o;2213:169::-;2297:11;2331:6;2326:3;2319:19;2371:4;2366:3;2362:14;2347:29;;2213:169;;;;:::o;2388:246::-;2469:1;2479:113;2493:6;2490:1;2487:13;2479:113;;;2578:1;2573:3;2569:11;2563:18;2559:1;2554:3;2550:11;2543:39;2515:2;2512:1;2508:10;2503:15;;2479:113;;;2626:1;2617:6;2612:3;2608:16;2601:27;2450:184;2388:246;;;:::o;2640:102::-;2681:6;2732:2;2728:7;2723:2;2716:5;2712:14;2708:28;2698:38;;2640:102;;;:::o;2748:377::-;2836:3;2864:39;2897:5;2864:39;:::i;:::-;2919:71;2983:6;2978:3;2919:71;:::i;:::-;2912:78;;2999:65;3057:6;3052:3;3045:4;3038:5;3034:16;2999:65;:::i;:::-;3089:29;3111:6;3089:29;:::i;:::-;3084:3;3080:39;3073:46;;2840:285;2748:377;;;;:::o;3131:313::-;3244:4;3282:2;3271:9;3267:18;3259:26;;3331:9;3325:4;3321:20;3317:1;3306:9;3302:17;3295:47;3359:78;3432:4;3423:6;3359:78;:::i;:::-;3351:86;;3131:313;;;;:::o;3450:77::-;3487:7;3516:5;3505:16;;3450:77;;;:::o;3533:122::-;3606:24;3624:5;3606:24;:::i;:::-;3599:5;3596:35;3586:63;;3645:1;3642;3635:12;3586:63;3533:122;:::o;3661:139::-;3707:5;3745:6;3732:20;3723:29;;3761:33;3788:5;3761:33;:::i;:::-;3661:139;;;;:::o;3806:329::-;3865:6;3914:2;3902:9;3893:7;3889:23;3885:32;3882:119;;;3920:79;;:::i;:::-;3882:119;4040:1;4065:53;4110:7;4101:6;4090:9;4086:22;4065:53;:::i;:::-;4055:63;;4011:117;3806:329;;;;:::o;4141:126::-;4178:7;4218:42;4211:5;4207:54;4196:65;;4141:126;;;:::o;4273:96::-;4310:7;4339:24;4357:5;4339:24;:::i;:::-;4328:35;;4273:96;;;:::o;4375:118::-;4462:24;4480:5;4462:24;:::i;:::-;4457:3;4450:37;4375:118;;:::o;4499:222::-;4592:4;4630:2;4619:9;4615:18;4607:26;;4643:71;4711:1;4700:9;4696:17;4687:6;4643:71;:::i;:::-;4499:222;;;;:::o;4727:122::-;4800:24;4818:5;4800:24;:::i;:::-;4793:5;4790:35;4780:63;;4839:1;4836;4829:12;4780:63;4727:122;:::o;4855:139::-;4901:5;4939:6;4926:20;4917:29;;4955:33;4982:5;4955:33;:::i;:::-;4855:139;;;;:::o;5000:474::-;5068:6;5076;5125:2;5113:9;5104:7;5100:23;5096:32;5093:119;;;5131:79;;:::i;:::-;5093:119;5251:1;5276:53;5321:7;5312:6;5301:9;5297:22;5276:53;:::i;:::-;5266:63;;5222:117;5378:2;5404:53;5449:7;5440:6;5429:9;5425:22;5404:53;:::i;:::-;5394:63;;5349:118;5000:474;;;;;:::o;5480:104::-;5525:7;5554:24;5572:5;5554:24;:::i;:::-;5543:35;;5480:104;;;:::o;5590:138::-;5671:32;5697:5;5671:32;:::i;:::-;5664:5;5661:43;5651:71;;5718:1;5715;5708:12;5651:71;5590:138;:::o;5734:155::-;5788:5;5826:6;5813:20;5804:29;;5842:41;5877:5;5842:41;:::i;:::-;5734:155;;;;:::o;5895:109::-;5931:7;5971:26;5964:5;5960:38;5949:49;;5895:109;;;:::o;6010:120::-;6082:23;6099:5;6082:23;:::i;:::-;6075:5;6072:34;6062:62;;6120:1;6117;6110:12;6062:62;6010:120;:::o;6136:137::-;6181:5;6219:6;6206:20;6197:29;;6235:32;6261:5;6235:32;:::i;:::-;6136:137;;;;:::o;6279:633::-;6363:6;6371;6379;6428:2;6416:9;6407:7;6403:23;6399:32;6396:119;;;6434:79;;:::i;:::-;6396:119;6554:1;6579:53;6624:7;6615:6;6604:9;6600:22;6579:53;:::i;:::-;6569:63;;6525:117;6681:2;6707:61;6760:7;6751:6;6740:9;6736:22;6707:61;:::i;:::-;6697:71;;6652:126;6817:2;6843:52;6887:7;6878:6;6867:9;6863:22;6843:52;:::i;:::-;6833:62;;6788:117;6279:633;;;;;:::o;6918:117::-;7027:1;7024;7017:12;7041:117;7150:1;7147;7140:12;7164:180;7212:77;7209:1;7202:88;7309:4;7306:1;7299:15;7333:4;7330:1;7323:15;7350:281;7433:27;7455:4;7433:27;:::i;:::-;7425:6;7421:40;7563:6;7551:10;7548:22;7527:18;7515:10;7512:34;7509:62;7506:88;;;7574:18;;:::i;:::-;7506:88;7614:10;7610:2;7603:22;7393:238;7350:281;;:::o;7637:129::-;7671:6;7698:20;;:::i;:::-;7688:30;;7727:33;7755:4;7747:6;7727:33;:::i;:::-;7637:129;;;:::o;7772:307::-;7833:4;7923:18;7915:6;7912:30;7909:56;;;7945:18;;:::i;:::-;7909:56;7983:29;8005:6;7983:29;:::i;:::-;7975:37;;8067:4;8061;8057:15;8049:23;;7772:307;;;:::o;8085:146::-;8182:6;8177:3;8172;8159:30;8223:1;8214:6;8209:3;8205:16;8198:27;8085:146;;;:::o;8237:423::-;8314:5;8339:65;8355:48;8396:6;8355:48;:::i;:::-;8339:65;:::i;:::-;8330:74;;8427:6;8420:5;8413:21;8465:4;8458:5;8454:16;8503:3;8494:6;8489:3;8485:16;8482:25;8479:112;;;8510:79;;:::i;:::-;8479:112;8600:54;8647:6;8642:3;8637;8600:54;:::i;:::-;8320:340;8237:423;;;;;:::o;8679:338::-;8734:5;8783:3;8776:4;8768:6;8764:17;8760:27;8750:122;;8791:79;;:::i;:::-;8750:122;8908:6;8895:20;8933:78;9007:3;8999:6;8992:4;8984:6;8980:17;8933:78;:::i;:::-;8924:87;;8740:277;8679:338;;;;:::o;9023:943::-;9118:6;9126;9134;9142;9191:3;9179:9;9170:7;9166:23;9162:33;9159:120;;;9198:79;;:::i;:::-;9159:120;9318:1;9343:53;9388:7;9379:6;9368:9;9364:22;9343:53;:::i;:::-;9333:63;;9289:117;9445:2;9471:53;9516:7;9507:6;9496:9;9492:22;9471:53;:::i;:::-;9461:63;;9416:118;9573:2;9599:53;9644:7;9635:6;9624:9;9620:22;9599:53;:::i;:::-;9589:63;;9544:118;9729:2;9718:9;9714:18;9701:32;9760:18;9752:6;9749:30;9746:117;;;9782:79;;:::i;:::-;9746:117;9887:62;9941:7;9932:6;9921:9;9917:22;9887:62;:::i;:::-;9877:72;;9672:287;9023:943;;;;;;;:::o;9972:115::-;10057:23;10074:5;10057:23;:::i;:::-;10052:3;10045:36;9972:115;;:::o;10093:218::-;10184:4;10222:2;10211:9;10207:18;10199:26;;10235:69;10301:1;10290:9;10286:17;10277:6;10235:69;:::i;:::-;10093:218;;;;:::o;10317:118::-;10404:24;10422:5;10404:24;:::i;:::-;10399:3;10392:37;10317:118;;:::o;10441:222::-;10534:4;10572:2;10561:9;10557:18;10549:26;;10585:71;10653:1;10642:9;10638:17;10629:6;10585:71;:::i;:::-;10441:222;;;;:::o;10669:619::-;10746:6;10754;10762;10811:2;10799:9;10790:7;10786:23;10782:32;10779:119;;;10817:79;;:::i;:::-;10779:119;10937:1;10962:53;11007:7;10998:6;10987:9;10983:22;10962:53;:::i;:::-;10952:63;;10908:117;11064:2;11090:53;11135:7;11126:6;11115:9;11111:22;11090:53;:::i;:::-;11080:63;;11035:118;11192:2;11218:53;11263:7;11254:6;11243:9;11239:22;11218:53;:::i;:::-;11208:63;;11163:118;10669:619;;;;;:::o;11294:474::-;11362:6;11370;11419:2;11407:9;11398:7;11394:23;11390:32;11387:119;;;11425:79;;:::i;:::-;11387:119;11545:1;11570:53;11615:7;11606:6;11595:9;11591:22;11570:53;:::i;:::-;11560:63;;11516:117;11672:2;11698:53;11743:7;11734:6;11723:9;11719:22;11698:53;:::i;:::-;11688:63;;11643:118;11294:474;;;;;:::o;11774:332::-;11895:4;11933:2;11922:9;11918:18;11910:26;;11946:71;12014:1;12003:9;11999:17;11990:6;11946:71;:::i;:::-;12027:72;12095:2;12084:9;12080:18;12071:6;12027:72;:::i;:::-;11774:332;;;;;:::o;12112:329::-;12171:6;12220:2;12208:9;12199:7;12195:23;12191:32;12188:119;;;12226:79;;:::i;:::-;12188:119;12346:1;12371:53;12416:7;12407:6;12396:9;12392:22;12371:53;:::i;:::-;12361:63;;12317:117;12112:329;;;;:::o;12447:468::-;12512:6;12520;12569:2;12557:9;12548:7;12544:23;12540:32;12537:119;;;12575:79;;:::i;:::-;12537:119;12695:1;12720:53;12765:7;12756:6;12745:9;12741:22;12720:53;:::i;:::-;12710:63;;12666:117;12822:2;12848:50;12890:7;12881:6;12870:9;12866:22;12848:50;:::i;:::-;12838:60;;12793:115;12447:468;;;;;:::o;12921:::-;12986:6;12994;13043:2;13031:9;13022:7;13018:23;13014:32;13011:119;;;13049:79;;:::i;:::-;13011:119;13169:1;13194:53;13239:7;13230:6;13219:9;13215:22;13194:53;:::i;:::-;13184:63;;13140:117;13296:2;13322:50;13364:7;13355:6;13344:9;13340:22;13322:50;:::i;:::-;13312:60;;13267:115;12921:468;;;;;:::o;13395:136::-;13484:6;13518:5;13512:12;13502:22;;13395:136;;;:::o;13537:206::-;13658:11;13692:6;13687:3;13680:19;13732:4;13727:3;13723:14;13708:29;;13537:206;;;;:::o;13749:154::-;13838:4;13861:3;13853:11;;13891:4;13886:3;13882:14;13874:22;;13749:154;;;:::o;13909:132::-;14002:32;14028:5;14002:32;:::i;:::-;13997:3;13990:45;13909:132;;:::o;14047:105::-;14122:23;14139:5;14122:23;:::i;:::-;14117:3;14110:36;14047:105;;:::o;14208:509::-;14339:4;14334:3;14330:14;14429:4;14422:5;14418:16;14412:23;14448:79;14521:4;14516:3;14512:14;14498:12;14448:79;:::i;:::-;14354:183;14620:4;14613:5;14609:16;14603:23;14639:61;14694:4;14689:3;14685:14;14671:12;14639:61;:::i;:::-;14547:163;14308:409;14208:509;;:::o;14723:267::-;14836:10;14857:90;14943:3;14935:6;14857:90;:::i;:::-;14979:4;14974:3;14970:14;14956:28;;14723:267;;;;:::o;14996:135::-;15088:4;15120;15115:3;15111:14;15103:22;;14996:135;;;:::o;15191:908::-;15354:3;15383:76;15453:5;15383:76;:::i;:::-;15475:108;15576:6;15571:3;15475:108;:::i;:::-;15468:115;;15607:78;15679:5;15607:78;:::i;:::-;15708:7;15739:1;15724:350;15749:6;15746:1;15743:13;15724:350;;;15825:6;15819:13;15852:107;15955:3;15940:13;15852:107;:::i;:::-;15845:114;;15982:82;16057:6;15982:82;:::i;:::-;15972:92;;15784:290;15771:1;15768;15764:9;15759:14;;15724:350;;;15728:14;16090:3;16083:10;;15359:740;;;15191:908;;;;:::o;16105:461::-;16292:4;16330:2;16319:9;16315:18;16307:26;;16379:9;16373:4;16369:20;16365:1;16354:9;16350:17;16343:47;16407:152;16554:4;16545:6;16407:152;:::i;:::-;16399:160;;16105:461;;;;:::o;16572:474::-;16640:6;16648;16697:2;16685:9;16676:7;16672:23;16668:32;16665:119;;;16703:79;;:::i;:::-;16665:119;16823:1;16848:53;16893:7;16884:6;16873:9;16869:22;16848:53;:::i;:::-;16838:63;;16794:117;16950:2;16976:53;17021:7;17012:6;17001:9;16997:22;16976:53;:::i;:::-;16966:63;;16921:118;16572:474;;;;;:::o;17052:308::-;17114:4;17204:18;17196:6;17193:30;17190:56;;;17226:18;;:::i;:::-;17190:56;17264:29;17286:6;17264:29;:::i;:::-;17256:37;;17348:4;17342;17338:15;17330:23;;17052:308;;;:::o;17366:425::-;17444:5;17469:66;17485:49;17527:6;17485:49;:::i;:::-;17469:66;:::i;:::-;17460:75;;17558:6;17551:5;17544:21;17596:4;17589:5;17585:16;17634:3;17625:6;17620:3;17616:16;17613:25;17610:112;;;17641:79;;:::i;:::-;17610:112;17731:54;17778:6;17773:3;17768;17731:54;:::i;:::-;17450:341;17366:425;;;;;:::o;17811:340::-;17867:5;17916:3;17909:4;17901:6;17897:17;17893:27;17883:122;;17924:79;;:::i;:::-;17883:122;18041:6;18028:20;18066:79;18141:3;18133:6;18126:4;18118:6;18114:17;18066:79;:::i;:::-;18057:88;;17873:278;17811:340;;;;:::o;18157:654::-;18235:6;18243;18292:2;18280:9;18271:7;18267:23;18263:32;18260:119;;;18298:79;;:::i;:::-;18260:119;18446:1;18435:9;18431:17;18418:31;18476:18;18468:6;18465:30;18462:117;;;18498:79;;:::i;:::-;18462:117;18603:63;18658:7;18649:6;18638:9;18634:22;18603:63;:::i;:::-;18593:73;;18389:287;18715:2;18741:53;18786:7;18777:6;18766:9;18762:22;18741:53;:::i;:::-;18731:63;;18686:118;18157:654;;;;;:::o;18817:180::-;18865:77;18862:1;18855:88;18962:4;18959:1;18952:15;18986:4;18983:1;18976:15;19003:320;19047:6;19084:1;19078:4;19074:12;19064:22;;19131:1;19125:4;19121:12;19152:18;19142:81;;19208:4;19200:6;19196:17;19186:27;;19142:81;19270:2;19262:6;19259:14;19239:18;19236:38;19233:84;;19289:18;;:::i;:::-;19233:84;19054:269;19003:320;;;:::o;19329:180::-;19377:77;19374:1;19367:88;19474:4;19471:1;19464:15;19498:4;19495:1;19488:15;19515:98;19566:6;19600:5;19594:12;19584:22;;19515:98;;;:::o;19619:168::-;19702:11;19736:6;19731:3;19724:19;19776:4;19771:3;19767:14;19752:29;;19619:168;;;;:::o;19793:373::-;19879:3;19907:38;19939:5;19907:38;:::i;:::-;19961:70;20024:6;20019:3;19961:70;:::i;:::-;19954:77;;20040:65;20098:6;20093:3;20086:4;20079:5;20075:16;20040:65;:::i;:::-;20130:29;20152:6;20130:29;:::i;:::-;20125:3;20121:39;20114:46;;19883:283;19793:373;;;;:::o;20172:89::-;20221:7;20250:5;20239:16;;20172:89;;;:::o;20267:60::-;20295:3;20316:5;20309:12;;20267:60;;;:::o;20333:166::-;20395:9;20428:65;20446:46;20455:36;20485:5;20455:36;:::i;:::-;20446:46;:::i;:::-;20428:65;:::i;:::-;20415:78;;20333:166;;;:::o;20505:155::-;20604:49;20647:5;20604:49;:::i;:::-;20599:3;20592:62;20505:155;;:::o;20666:775::-;20901:4;20939:3;20928:9;20924:19;20916:27;;20953:71;21021:1;21010:9;21006:17;20997:6;20953:71;:::i;:::-;21034:72;21102:2;21091:9;21087:18;21078:6;21034:72;:::i;:::-;21116;21184:2;21173:9;21169:18;21160:6;21116:72;:::i;:::-;21235:9;21229:4;21225:20;21220:2;21209:9;21205:18;21198:48;21263:76;21334:4;21325:6;21263:76;:::i;:::-;21255:84;;21349:85;21429:3;21418:9;21414:19;21405:6;21349:85;:::i;:::-;20666:775;;;;;;;;:::o;21447:332::-;21568:4;21606:2;21595:9;21591:18;21583:26;;21619:71;21687:1;21676:9;21672:17;21663:6;21619:71;:::i;:::-;21700:72;21768:2;21757:9;21753:18;21744:6;21700:72;:::i;:::-;21447:332;;;;;:::o;21785:137::-;21839:5;21870:6;21864:13;21855:22;;21886:30;21910:5;21886:30;:::i;:::-;21785:137;;;;:::o;21928:345::-;21995:6;22044:2;22032:9;22023:7;22019:23;22015:32;22012:119;;;22050:79;;:::i;:::-;22012:119;22170:1;22195:61;22248:7;22239:6;22228:9;22224:22;22195:61;:::i;:::-;22185:71;;22141:125;21928:345;;;;:::o;22279:180::-;22327:77;22324:1;22317:88;22424:4;22421:1;22414:15;22448:4;22445:1;22438:15;22465:410;22505:7;22528:20;22546:1;22528:20;:::i;:::-;22523:25;;22562:20;22580:1;22562:20;:::i;:::-;22557:25;;22617:1;22614;22610:9;22639:30;22657:11;22639:30;:::i;:::-;22628:41;;22818:1;22809:7;22805:15;22802:1;22799:22;22779:1;22772:9;22752:83;22729:139;;22848:18;;:::i;:::-;22729:139;22513:362;22465:410;;;;:::o;22881:180::-;22929:77;22926:1;22919:88;23026:4;23023:1;23016:15;23050:4;23047:1;23040:15;23067:185;23107:1;23124:20;23142:1;23124:20;:::i;:::-;23119:25;;23158:20;23176:1;23158:20;:::i;:::-;23153:25;;23197:1;23187:35;;23202:18;;:::i;:::-;23187:35;23244:1;23241;23237:9;23232:14;;23067:185;;;;:::o;23258:147::-;23359:11;23396:3;23381:18;;23258:147;;;;:::o;23411:114::-;;:::o;23531:398::-;23690:3;23711:83;23792:1;23787:3;23711:83;:::i;:::-;23704:90;;23803:93;23892:3;23803:93;:::i;:::-;23921:1;23916:3;23912:11;23905:18;;23531:398;;;:::o;23935:379::-;24119:3;24141:147;24284:3;24141:147;:::i;:::-;24134:154;;24305:3;24298:10;;23935:379;;;:::o;24320:180::-;24460:32;24456:1;24448:6;24444:14;24437:56;24320:180;:::o;24506:366::-;24648:3;24669:67;24733:2;24728:3;24669:67;:::i;:::-;24662:74;;24745:93;24834:3;24745:93;:::i;:::-;24863:2;24858:3;24854:12;24847:19;;24506:366;;;:::o;24878:419::-;25044:4;25082:2;25071:9;25067:18;25059:26;;25131:9;25125:4;25121:20;25117:1;25106:9;25102:17;25095:47;25159:131;25285:4;25159:131;:::i;:::-;25151:139;;24878:419;;;:::o;25303:225::-;25443:34;25439:1;25431:6;25427:14;25420:58;25512:8;25507:2;25499:6;25495:15;25488:33;25303:225;:::o;25534:366::-;25676:3;25697:67;25761:2;25756:3;25697:67;:::i;:::-;25690:74;;25773:93;25862:3;25773:93;:::i;:::-;25891:2;25886:3;25882:12;25875:19;;25534:366;;;:::o;25906:419::-;26072:4;26110:2;26099:9;26095:18;26087:26;;26159:9;26153:4;26149:20;26145:1;26134:9;26130:17;26123:47;26187:131;26313:4;26187:131;:::i;:::-;26179:139;;25906:419;;;:::o;26331:191::-;26371:3;26390:20;26408:1;26390:20;:::i;:::-;26385:25;;26424:20;26442:1;26424:20;:::i;:::-;26419:25;;26467:1;26464;26460:9;26453:16;;26488:3;26485:1;26482:10;26479:36;;;26495:18;;:::i;:::-;26479:36;26331:191;;;;:::o;26528:241::-;26668:34;26664:1;26656:6;26652:14;26645:58;26737:24;26732:2;26724:6;26720:15;26713:49;26528:241;:::o;26775:366::-;26917:3;26938:67;27002:2;26997:3;26938:67;:::i;:::-;26931:74;;27014:93;27103:3;27014:93;:::i;:::-;27132:2;27127:3;27123:12;27116:19;;26775:366;;;:::o;27147:419::-;27313:4;27351:2;27340:9;27336:18;27328:26;;27400:9;27394:4;27390:20;27386:1;27375:9;27371:17;27364:47;27428:131;27554:4;27428:131;:::i;:::-;27420:139;;27147:419;;;:::o;27572:148::-;27674:11;27711:3;27696:18;;27572:148;;;;:::o;27726:390::-;27832:3;27860:39;27893:5;27860:39;:::i;:::-;27915:89;27997:6;27992:3;27915:89;:::i;:::-;27908:96;;28013:65;28071:6;28066:3;28059:4;28052:5;28048:16;28013:65;:::i;:::-;28103:6;28098:3;28094:16;28087:23;;27836:280;27726:390;;;;:::o;28122:595::-;28350:3;28372:95;28463:3;28454:6;28372:95;:::i;:::-;28365:102;;28484:95;28575:3;28566:6;28484:95;:::i;:::-;28477:102;;28596:95;28687:3;28678:6;28596:95;:::i;:::-;28589:102;;28708:3;28701:10;;28122:595;;;;;;:::o;28723:141::-;28772:4;28795:3;28787:11;;28818:3;28815:1;28808:14;28852:4;28849:1;28839:18;28831:26;;28723:141;;;:::o;28870:93::-;28907:6;28954:2;28949;28942:5;28938:14;28934:23;28924:33;;28870:93;;;:::o;28969:107::-;29013:8;29063:5;29057:4;29053:16;29032:37;;28969:107;;;;:::o;29082:393::-;29151:6;29201:1;29189:10;29185:18;29224:97;29254:66;29243:9;29224:97;:::i;:::-;29342:39;29372:8;29361:9;29342:39;:::i;:::-;29330:51;;29414:4;29410:9;29403:5;29399:21;29390:30;;29463:4;29453:8;29449:19;29442:5;29439:30;29429:40;;29158:317;;29082:393;;;;;:::o;29481:142::-;29531:9;29564:53;29582:34;29591:24;29609:5;29591:24;:::i;:::-;29582:34;:::i;:::-;29564:53;:::i;:::-;29551:66;;29481:142;;;:::o;29629:75::-;29672:3;29693:5;29686:12;;29629:75;;;:::o;29710:269::-;29820:39;29851:7;29820:39;:::i;:::-;29881:91;29930:41;29954:16;29930:41;:::i;:::-;29922:6;29915:4;29909:11;29881:91;:::i;:::-;29875:4;29868:105;29786:193;29710:269;;;:::o;29985:73::-;30030:3;29985:73;:::o;30064:189::-;30141:32;;:::i;:::-;30182:65;30240:6;30232;30226:4;30182:65;:::i;:::-;30117:136;30064:189;;:::o;30259:186::-;30319:120;30336:3;30329:5;30326:14;30319:120;;;30390:39;30427:1;30420:5;30390:39;:::i;:::-;30363:1;30356:5;30352:13;30343:22;;30319:120;;;30259:186;;:::o;30451:543::-;30552:2;30547:3;30544:11;30541:446;;;30586:38;30618:5;30586:38;:::i;:::-;30670:29;30688:10;30670:29;:::i;:::-;30660:8;30656:44;30853:2;30841:10;30838:18;30835:49;;;30874:8;30859:23;;30835:49;30897:80;30953:22;30971:3;30953:22;:::i;:::-;30943:8;30939:37;30926:11;30897:80;:::i;:::-;30556:431;;30541:446;30451:543;;;:::o;31000:117::-;31054:8;31104:5;31098:4;31094:16;31073:37;;31000:117;;;;:::o;31123:169::-;31167:6;31200:51;31248:1;31244:6;31236:5;31233:1;31229:13;31200:51;:::i;:::-;31196:56;31281:4;31275;31271:15;31261:25;;31174:118;31123:169;;;;:::o;31297:295::-;31373:4;31519:29;31544:3;31538:4;31519:29;:::i;:::-;31511:37;;31581:3;31578:1;31574:11;31568:4;31565:21;31557:29;;31297:295;;;;:::o;31597:1395::-;31714:37;31747:3;31714:37;:::i;:::-;31816:18;31808:6;31805:30;31802:56;;;31838:18;;:::i;:::-;31802:56;31882:38;31914:4;31908:11;31882:38;:::i;:::-;31967:67;32027:6;32019;32013:4;31967:67;:::i;:::-;32061:1;32085:4;32072:17;;32117:2;32109:6;32106:14;32134:1;32129:618;;;;32791:1;32808:6;32805:77;;;32857:9;32852:3;32848:19;32842:26;32833:35;;32805:77;32908:67;32968:6;32961:5;32908:67;:::i;:::-;32902:4;32895:81;32764:222;32099:887;;32129:618;32181:4;32177:9;32169:6;32165:22;32215:37;32247:4;32215:37;:::i;:::-;32274:1;32288:208;32302:7;32299:1;32296:14;32288:208;;;32381:9;32376:3;32372:19;32366:26;32358:6;32351:42;32432:1;32424:6;32420:14;32410:24;;32479:2;32468:9;32464:18;32451:31;;32325:4;32322:1;32318:12;32313:17;;32288:208;;;32524:6;32515:7;32512:19;32509:179;;;32582:9;32577:3;32573:19;32567:26;32625:48;32667:4;32659:6;32655:17;32644:9;32625:48;:::i;:::-;32617:6;32610:64;32532:156;32509:179;32734:1;32730;32722:6;32718:14;32714:22;32708:4;32701:36;32136:611;;;32099:887;;31689:1303;;;31597:1395;;:::o;32998:225::-;33138:34;33134:1;33126:6;33122:14;33115:58;33207:8;33202:2;33194:6;33190:15;33183:33;32998:225;:::o;33229:366::-;33371:3;33392:67;33456:2;33451:3;33392:67;:::i;:::-;33385:74;;33468:93;33557:3;33468:93;:::i;:::-;33586:2;33581:3;33577:12;33570:19;;33229:366;;;:::o;33601:419::-;33767:4;33805:2;33794:9;33790:18;33782:26;;33854:9;33848:4;33844:20;33840:1;33829:9;33825:17;33818:47;33882:131;34008:4;33882:131;:::i;:::-;33874:139;;33601:419;;;:::o;34026:182::-;34166:34;34162:1;34154:6;34150:14;34143:58;34026:182;:::o;34214:366::-;34356:3;34377:67;34441:2;34436:3;34377:67;:::i;:::-;34370:74;;34453:93;34542:3;34453:93;:::i;:::-;34571:2;34566:3;34562:12;34555:19;;34214:366;;;:::o;34586:419::-;34752:4;34790:2;34779:9;34775:18;34767:26;;34839:9;34833:4;34829:20;34825:1;34814:9;34810:17;34803:47;34867:131;34993:4;34867:131;:::i;:::-;34859:139;;34586:419;;;:::o;35011:177::-;35151:29;35147:1;35139:6;35135:14;35128:53;35011:177;:::o;35194:366::-;35336:3;35357:67;35421:2;35416:3;35357:67;:::i;:::-;35350:74;;35433:93;35522:3;35433:93;:::i;:::-;35551:2;35546:3;35542:12;35535:19;;35194:366;;;:::o;35566:419::-;35732:4;35770:2;35759:9;35755:18;35747:26;;35819:9;35813:4;35809:20;35805:1;35794:9;35790:17;35783:47;35847:131;35973:4;35847:131;:::i;:::-;35839:139;;35566:419;;;:::o;35991:182::-;36131:34;36127:1;36119:6;36115:14;36108:58;35991:182;:::o;36179:366::-;36321:3;36342:67;36406:2;36401:3;36342:67;:::i;:::-;36335:74;;36418:93;36507:3;36418:93;:::i;:::-;36536:2;36531:3;36527:12;36520:19;;36179:366;;;:::o;36551:419::-;36717:4;36755:2;36744:9;36740:18;36732:26;;36804:9;36798:4;36794:20;36790:1;36779:9;36775:17;36768:47;36832:131;36958:4;36832:131;:::i;:::-;36824:139;;36551:419;;;:::o;36976:233::-;37015:3;37038:24;37056:5;37038:24;:::i;:::-;37029:33;;37084:66;37077:5;37074:77;37071:103;;37154:18;;:::i;:::-;37071:103;37201:1;37194:5;37190:13;37183:20;;36976:233;;;:::o;37215:224::-;37355:34;37351:1;37343:6;37339:14;37332:58;37424:7;37419:2;37411:6;37407:15;37400:32;37215:224;:::o;37445:366::-;37587:3;37608:67;37672:2;37667:3;37608:67;:::i;:::-;37601:74;;37684:93;37773:3;37684:93;:::i;:::-;37802:2;37797:3;37793:12;37786:19;;37445:366;;;:::o;37817:419::-;37983:4;38021:2;38010:9;38006:18;37998:26;;38070:9;38064:4;38060:20;38056:1;38045:9;38041:17;38034:47;38098:131;38224:4;38098:131;:::i;:::-;38090:139;;37817:419;;;:::o;38242:181::-;38382:33;38378:1;38370:6;38366:14;38359:57;38242:181;:::o;38429:366::-;38571:3;38592:67;38656:2;38651:3;38592:67;:::i;:::-;38585:74;;38668:93;38757:3;38668:93;:::i;:::-;38786:2;38781:3;38777:12;38770:19;;38429:366;;;:::o;38801:419::-;38967:4;39005:2;38994:9;38990:18;38982:26;;39054:9;39048:4;39044:20;39040:1;39029:9;39025:17;39018:47;39082:131;39208:4;39082:131;:::i;:::-;39074:139;;38801:419;;;:::o;39226:181::-;39366:33;39362:1;39354:6;39350:14;39343:57;39226:181;:::o;39413:366::-;39555:3;39576:67;39640:2;39635:3;39576:67;:::i;:::-;39569:74;;39652:93;39741:3;39652:93;:::i;:::-;39770:2;39765:3;39761:12;39754:19;;39413:366;;;:::o;39785:419::-;39951:4;39989:2;39978:9;39974:18;39966:26;;40038:9;40032:4;40028:20;40024:1;40013:9;40009:17;40002:47;40066:131;40192:4;40066:131;:::i;:::-;40058:139;;39785:419;;;:::o;40210:194::-;40250:4;40270:20;40288:1;40270:20;:::i;:::-;40265:25;;40304:20;40322:1;40304:20;:::i;:::-;40299:25;;40348:1;40345;40341:9;40333:17;;40372:1;40366:4;40363:11;40360:37;;;40377:18;;:::i;:::-;40360:37;40210:194;;;;:::o;40410:177::-;40550:29;40546:1;40538:6;40534:14;40527:53;40410:177;:::o;40593:366::-;40735:3;40756:67;40820:2;40815:3;40756:67;:::i;:::-;40749:74;;40832:93;40921:3;40832:93;:::i;:::-;40950:2;40945:3;40941:12;40934:19;;40593:366;;;:::o;40965:419::-;41131:4;41169:2;41158:9;41154:18;41146:26;;41218:9;41212:4;41208:20;41204:1;41193:9;41189:17;41182:47;41246:131;41372:4;41246:131;:::i;:::-;41238:139;;40965:419;;;:::o;41390:571::-;41605:4;41643:2;41632:9;41628:18;41620:26;;41656:71;41724:1;41713:9;41709:17;41700:6;41656:71;:::i;:::-;41774:9;41768:4;41764:20;41759:2;41748:9;41744:18;41737:48;41802:152;41949:4;41940:6;41802:152;:::i;:::-;41794:160;;41390:571;;;;;:::o;41967:640::-;42162:4;42200:3;42189:9;42185:19;42177:27;;42214:71;42282:1;42271:9;42267:17;42258:6;42214:71;:::i;:::-;42295:72;42363:2;42352:9;42348:18;42339:6;42295:72;:::i;:::-;42377;42445:2;42434:9;42430:18;42421:6;42377:72;:::i;:::-;42496:9;42490:4;42486:20;42481:2;42470:9;42466:18;42459:48;42524:76;42595:4;42586:6;42524:76;:::i;:::-;42516:84;;41967:640;;;;;;;:::o;42613:141::-;42669:5;42700:6;42694:13;42685:22;;42716:32;42742:5;42716:32;:::i;:::-;42613:141;;;;:::o;42760:349::-;42829:6;42878:2;42866:9;42857:7;42853:23;42849:32;42846:119;;;42884:79;;:::i;:::-;42846:119;43004:1;43029:63;43084:7;43075:6;43064:9;43060:22;43029:63;:::i;:::-;43019:73;;42975:127;42760:349;;;;:::o

Swarm Source

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