ETH Price: $2,520.85 (+3.16%)
Gas: 0.94 Gwei

Token

Mutant Forest (MForest)
 

Overview

Max Total Supply

665 MForest

Holders

77

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
4 MForest
0x6C69AfCe8a5D7851CA1f7D5D549d4c78C5953bcB
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:
Woolf

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 21 of 21: Woolf.sol
// SPDX-License-Identifier: MIT LICENSE

pragma solidity ^0.8.0;
import "./Ownable.sol";
import "./Pausable.sol";
import "./ERC721Enumerable.sol";
import "./ERC20.sol";
import "./IWoolf.sol";
import "./IForest.sol";
import "./ITraits.sol";
import "./MutantPeach.sol";

interface ISuperShibaBAMC {
	function balanceOf(address owner) external view returns (uint256);

	function ownerOf(uint256 index) external view returns (address);
}

interface ISuperShibaClub {
	function balanceOf(address owner) external view returns (uint256);

	function ownerOf(uint256 index) external view returns (address);
}

interface Pool {
	function balanceOf(address owner) external view returns (uint256);
}

interface RandomPick {
	function random(uint256 seed) external view returns (uint256);
}

contract Woolf is ERC721Enumerable, Ownable, Pausable {
	RandomPick private randomPick;
	ISuperShibaBAMC public bamc;
	ISuperShibaClub public club;
	Pool public pool;
	// reference to the Forest for choosing random Wolf thieves
	IForest public forest;
	// reference to $MutantPeach for burning on mint
	MutantPeach public mutantPeach;
	// reference to Traits
	ITraits public traits;

	// mint price
	// uint256 public MINT_PRICE = 0.06942 ether;
	uint256 public MINT_PRICE = 0.000001 ether;
	// max number of tokens that can be minted - 50000 in production
	uint256 public immutable MAX_TOKENS;
	// number of tokens that can be claimed for free - 20% of MAX_TOKENS
	uint256 public PAID_TOKENS;
	// number of tokens have been minted so far
	uint16 public minted = 0;

	bool public openFreeMint = false;
	bool public openPublicMint = false;

	uint256 public LP = 0.5 ether;

	// mapping from tokenId to a struct containing the token's traits
	mapping(uint256 => IWoolf.ApeWolf) public tokenTraits;
	// mapping from hashed(tokenTrait) to the tokenId it's associated with
	// used to ensure there are no duplicates
	mapping(uint256 => uint256) public existingCombinations;

	mapping(uint256 => address) public superShibaBAMCTokensMint;
	mapping(uint256 => address) public superShibaClubTokensMint;

	// list of probabilities for each trait type
	// 0 - 5 are associated with Ape, 6 - 11 are associated with Wolves
	uint8[][12] public rarities;
	// list of aliases for Walker's Alias algorithm
	// 0 - 5 are associated with Ape, 6 - 11 are associated with Wolves
	uint8[][12] public aliases;

	address private wolfGameTreasury;

	/**
	 * instantiates contract and rarity tables
	 */
	constructor(
		address _peach,
		address _traits,
		address _bamc,
		address _club,
		address _treasury,
		uint256 _maxTokens
	) ERC721("Mutant Forest", "MForest") {
		mutantPeach = MutantPeach(_peach);
		traits = ITraits(_traits);
		bamc = ISuperShibaBAMC(_bamc);
		club = ISuperShibaClub(_club);
		wolfGameTreasury = _treasury;
		MAX_TOKENS = _maxTokens;
		PAID_TOKENS = _maxTokens / 5;

		// I know this looks weird but it saves users gas by making lookup O(1)
		// A.J. Walker's Alias Algorithm
		// ape
		// skin 22
		rarities[0] = [50, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128];
		aliases[0] = [17, 17, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21];
		// eyes 19
		rarities[1] = [50, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128];
		aliases[1] = [18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18];
		// mouth 22
		rarities[2] = [50, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128];
		aliases[2] = [21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21];
		// clothing 0
		rarities[3] = [255];
		aliases[3] = [0];

		// headwear 43
		rarities[4] = [
			50,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128
		];
		aliases[4] = [
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42,
			42
		];

		// alphaIndex
		rarities[5] = [255];
		aliases[5] = [0];

		// wolf
		// skin 4
		rarities[6] = [255];
		aliases[6] = [0];
		// eyes 11
		rarities[7] = [50, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128];
		aliases[7] = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10];
		// mouth 11
		rarities[8] = [50, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128];
		aliases[8] = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10];
		// clothing 26
		rarities[9] = [
			50,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128,
			128
		];
		aliases[9] = [25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25];

		// headwear 21
		rarities[10] = [50, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128];
		aliases[10] = [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20];

		// alphaIndex 0
		rarities[11] = [9, 161, 74, 255];
		aliases[11] = [2, 3, 3, 3];
	}

	/** EXTERNAL */

	/**
	 * mint a token - 90% Ape, 10% Wolves
	 * The first 20% are free to claim, the remaining cost $MutantPeach
	 */
	function mint(uint256 amount) external payable whenNotPaused {
		require(tx.origin == _msgSender(), "Only EOA");
		require(openPublicMint, "not open free mint");
		require(minted + amount <= MAX_TOKENS, "All tokens minted");
		require(amount > 0 && amount <= 10, "Invalid mint amount");
		if (minted < PAID_TOKENS) {
			require(minted + amount <= PAID_TOKENS, "All tokens on-sale already sold");
			require(amount * MINT_PRICE == msg.value, "Invalid payment amount");
		} else {
			require(msg.value == 0);
		}

		uint256 totalWoolCost = 0;

		uint256 seed;
		for (uint256 i = 0; i < amount; i++) {
			minted++;
			seed = randomPick.random(minted);
			address recipient = selectRecipient(seed);
			_safeMint(recipient, minted);
			generate(minted, seed);
			totalWoolCost += mintCost(minted);
		}

		if (totalWoolCost > 0) mutantPeach.burn(_msgSender(), totalWoolCost);
	}

	function freeMint(uint256[] memory bamcIds, uint256[] memory clubIds) external whenNotPaused {
		require(tx.origin == _msgSender(), "Only EOA");
		require(openFreeMint, "not open free mint");
		require((bamcIds.length + clubIds.length) <= 10, "Invalid mint amount");
		require((minted + bamcIds.length + clubIds.length) <= MAX_TOKENS, "All tokens minted");

		uint256 mintCount = 0;
		for (uint256 i = 0; i < bamcIds.length; i++) {
			uint256 tokenId = bamcIds[i];
			if (bamc.ownerOf(tokenId) == _msgSender()) {
				if (superShibaBAMCTokensMint[tokenId] == address(0)) {
					mintCount++;
					superShibaBAMCTokensMint[tokenId] = _msgSender();
				}
			}
		}

		for (uint256 i = 0; i < clubIds.length; i++) {
			uint256 tokenId = clubIds[i];
			if (club.ownerOf(tokenId) == _msgSender()) {
				if (superShibaClubTokensMint[tokenId] == address(0)) {
					mintCount++;
					superShibaClubTokensMint[tokenId] = _msgSender();
				}
			}
		}

		require(mintCount > 0, "The shiba in your wallet has been mint");

		_freeMint(mintCount);
	}

	function _freeMint(uint256 amount) private whenNotPaused {
		uint256 seed;
		for (uint256 i = 0; i < amount; i++) {
			minted++;
			seed = randomPick.random(minted);

			_safeMint(_msgSender(), minted);

			generate(minted, seed);
		}
	}

	/**
	 * the first 20% are paid in ETH
	 * the next 20% are 20000 $MutantPeach
	 * the next 40% are 40000 $MutantPeach
	 * the final 20% are 80000 $MutantPeach
	 * @param tokenId the ID to check the cost of to mint
	 * @return the cost of the given token ID
	 */
	function mintCost(uint256 tokenId) public view returns (uint256) {
		if (tokenId <= PAID_TOKENS) return 0;
		if (tokenId <= (MAX_TOKENS * 2) / 5) return 20000 ether;
		if (tokenId <= (MAX_TOKENS * 4) / 5) return 40000 ether;
		return 80000 ether;
	}

	function transferFrom(
		address from,
		address to,
		uint256 tokenId
	) public virtual override {
		// Hardcode the Forest's approval so that users don't have to waste gas approving
		if (_msgSender() != address(forest))
			require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
		_transfer(from, to, tokenId);
	}

	/** INTERNAL */

	/**
	 * generates traits for a specific token, checking to make sure it's unique
	 * @param tokenId the id of the token to generate traits for
	 * @param seed a pseudorandom 256 bit number to derive traits from
	 * @return t - a struct of traits for the given token ID
	 */
	function generate(uint256 tokenId, uint256 seed) internal returns (IWoolf.ApeWolf memory t) {
		t = selectTraits(seed);
		if (existingCombinations[structToHash(t)] == 0) {
			tokenTraits[tokenId] = t;
			existingCombinations[structToHash(t)] = tokenId;
			return t;
		}
		return generate(tokenId, randomPick.random(seed));
	}

	/**
	 * uses A.J. Walker's Alias algorithm for O(1) rarity table lookup
	 * ensuring O(1) instead of O(n) reduces mint cost by more than 50%
	 * probability & alias tables are generated off-chain beforehand
	 * @param seed portion of the 256 bit seed to remove trait correlation
	 * @param traitType the trait type to select a trait for
	 * @return the ID of the randomly selected trait
	 */
	function selectTrait(uint16 seed, uint8 traitType) internal view returns (uint8) {
		uint8 trait = uint8(seed) % uint8(rarities[traitType].length);
		if (seed >> 8 < rarities[traitType][trait]) return trait;
		return aliases[traitType][trait];
	}

	/**
	 * the first 20% (ETH purchases) go to the minter
	 * the remaining 80% have a 10% chance to be given to a random staked wolf
	 * @param seed a random value to select a recipient from
	 * @return the address of the recipient (either the minter or the Wolf thief's owner)
	 */
	function selectRecipient(uint256 seed) internal view returns (address) {
		uint16 num = 10;
		uint256 count = pool.balanceOf(_msgSender());
		if (count >= LP) {
			num = 5;
		}
		if (minted <= PAID_TOKENS || ((seed >> 245) % 100) > num) return _msgSender(); // top 10 bits haven't been used
		address thief = forest.randomWolfOwner(seed >> 144); // 144 bits reserved for trait selection
		if (thief == address(0x0)) return _msgSender();
		return thief;
	}

	/**
	 * selects the species and all of its traits based on the seed value
	 * @param seed a pseudorandom 256 bit number to derive traits from
	 * @return t -  a struct of randomly selected traits
	 */
	function selectTraits(uint256 seed) internal view returns (IWoolf.ApeWolf memory t) {
		t.isApe = (seed & 0xFFFF) % 10 != 0;
		uint8 shift = t.isApe ? 0 : 6;
		seed >>= 16;
		t.skin = selectTrait(uint16(seed & 0xFFFF), 0 + shift);
		seed >>= 16;
		t.eyes = selectTrait(uint16(seed & 0xFFFF), 1 + shift);
		seed >>= 16;
		t.mouth = selectTrait(uint16(seed & 0xFFFF), 2 + shift);
		seed >>= 16;
		t.clothing = selectTrait(uint16(seed & 0xFFFF), 3 + shift);
		seed >>= 16;
		t.headwear = selectTrait(uint16(seed & 0xFFFF), 4 + shift);
		seed >>= 16;
		t.alphaIndex = selectTrait(uint16(seed & 0xFFFF), 5 + shift);
	}

	/**
	 * converts a struct to a 256 bit hash to check for uniqueness
	 * @param s the struct to pack into a hash
	 * @return the 256 bit hash of the struct
	 */
	function structToHash(IWoolf.ApeWolf memory s) internal pure returns (uint256) {
		return uint256(bytes32(abi.encodePacked(s.isApe, s.skin, s.eyes, s.mouth, s.clothing, s.headwear, s.alphaIndex)));
	}

	/** READ */

	function getTokenTraits(uint256 tokenId) external view returns (IWoolf.ApeWolf memory) {
		return tokenTraits[tokenId];
	}

	function getPaidTokens() external view returns (uint256) {
		return PAID_TOKENS;
	}

	/** ADMIN */

	/**
	 * called after deployment so that the contract can get random wolf thieves
	 * @param _forest the address of the Forest
	 */
	function setForest(address _forest) external onlyOwner {
		forest = IForest(_forest);
	}

	function setMPeach(address _MPeach) external onlyOwner {
		mutantPeach = MutantPeach(_MPeach);
	}

	function setPool(address _pool) external onlyOwner {
		pool = Pool(_pool);
	}

	function setRandomPick(address _address) external onlyOwner {
		randomPick = RandomPick(_address);
	}

	function setSuperShibaBAMCAddress(address _address) external onlyOwner {
		bamc = ISuperShibaBAMC(_address);
	}

	function setSuperShibaClubAddress(address _address) external onlyOwner {
		club = ISuperShibaClub(_address);
	}

	function setTraits(address _address) external onlyOwner {
		traits = ITraits(_address);
	}

	/**
	 * allows owner to withdraw funds from minting
	 */
	function withdraw() external onlyOwner {
		payable(wolfGameTreasury).transfer(address(this).balance);
	}

	function getTreasure() external view onlyOwner returns (address) {
		return wolfGameTreasury;
	}

	/**
	 * updates the number of tokens for sale
	 */
	function setPaidTokens(uint256 _paidTokens) external onlyOwner {
		PAID_TOKENS = _paidTokens;
	}

	function setLP(uint256 _lp) external onlyOwner {
		LP = _lp;
	}

	function setMint(bool _free, bool _public) external onlyOwner {
		openFreeMint = _free;
		openPublicMint = _public;
	}

	/**
	 * enables owner to pause / unpause minting
	 */
	function setPaused(bool _paused) external onlyOwner {
		if (_paused) _pause();
		else _unpause();
	}

	/** RENDER */

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

	function tokenURI(uint256 tokenId) public view override returns (string memory) {
		require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
		return traits.tokenURI(tokenId);
	}

	function setTreasury(address _treasury) external onlyOwner {
		wolfGameTreasury = _treasury;
	}
}

File 1 of 21: Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
	/**
	 * @dev Returns true if `account` is a contract.
	 *
	 * [IMPORTANT]
	 * ====
	 * It is unsafe to assume that an address for which this function returns
	 * false is an externally-owned account (EOA) and not a contract.
	 *
	 * Among others, `isContract` will return false for the following
	 * types of addresses:
	 *
	 *  - an externally-owned account
	 *  - a contract in construction
	 *  - an address where a contract will be created
	 *  - an address where a contract lived, but was destroyed
	 * ====
	 */
	function isContract(address account) internal view returns (bool) {
		// This method relies on extcodesize, which returns 0 for contracts in
		// construction, since the code is only stored at the end of the
		// constructor execution.

		uint256 size;
		assembly {
			size := extcodesize(account)
		}
		return size > 0;
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 21: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 4 of 21: ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./IERC20Metadata.sol";
import "./Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
	mapping(address => uint256) private _balances;

	mapping(address => mapping(address => uint256)) private _allowances;

	uint256 private _totalSupply;

	string private _name;
	string private _symbol;

	/**
	 * @dev Sets the values for {name} and {symbol}.
	 *
	 * The default value of {decimals} is 18. To select a different value for
	 * {decimals} you should overload it.
	 *
	 * All two of these values are immutable: they can only be set once during
	 * construction.
	 */
	constructor(string memory name_, string memory symbol_) {
		_name = name_;
		_symbol = symbol_;
	}

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

	/**
	 * @dev Returns the symbol of the token, usually a shorter version of the
	 * name.
	 */
	function symbol() public view virtual override returns (string memory) {
		return _symbol;
	}

	/**
	 * @dev Returns the number of decimals used to get its user representation.
	 * For example, if `decimals` equals `2`, a balance of `505` tokens should
	 * be displayed to a user as `5.05` (`505 / 10 ** 2`).
	 *
	 * Tokens usually opt for a value of 18, imitating the relationship between
	 * Ether and Wei. This is the value {ERC20} uses, unless this function is
	 * overridden;
	 *
	 * NOTE: This information is only used for _display_ purposes: it in
	 * no way affects any of the arithmetic of the contract, including
	 * {IERC20-balanceOf} and {IERC20-transfer}.
	 */
	function decimals() public view virtual override returns (uint8) {
		return 18;
	}

	/**
	 * @dev See {IERC20-totalSupply}.
	 */
	function totalSupply() public view virtual override returns (uint256) {
		return _totalSupply;
	}

	/**
	 * @dev See {IERC20-balanceOf}.
	 */
	function balanceOf(address account) public view virtual override returns (uint256) {
		return _balances[account];
	}

	/**
	 * @dev See {IERC20-transfer}.
	 *
	 * Requirements:
	 *
	 * - `recipient` cannot be the zero address.
	 * - the caller must have a balance of at least `amount`.
	 */
	function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
		_transfer(_msgSender(), recipient, amount);
		return true;
	}

	/**
	 * @dev See {IERC20-allowance}.
	 */
	function allowance(address owner, address spender) public view virtual override returns (uint256) {
		return _allowances[owner][spender];
	}

	/**
	 * @dev See {IERC20-approve}.
	 *
	 * Requirements:
	 *
	 * - `spender` cannot be the zero address.
	 */
	function approve(address spender, uint256 amount) public virtual override returns (bool) {
		_approve(_msgSender(), spender, amount);
		return true;
	}

	/**
	 * @dev See {IERC20-transferFrom}.
	 *
	 * Emits an {Approval} event indicating the updated allowance. This is not
	 * required by the EIP. See the note at the beginning of {ERC20}.
	 *
	 * Requirements:
	 *
	 * - `sender` and `recipient` cannot be the zero address.
	 * - `sender` must have a balance of at least `amount`.
	 * - the caller must have allowance for ``sender``'s tokens of at least
	 * `amount`.
	 */
	function transferFrom(
		address sender,
		address recipient,
		uint256 amount
	) public virtual override returns (bool) {
		_transfer(sender, recipient, amount);

		uint256 currentAllowance = _allowances[sender][_msgSender()];
		require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
		unchecked {
			_approve(sender, _msgSender(), currentAllowance - amount);
		}

		return true;
	}

	/**
	 * @dev Atomically increases the allowance granted to `spender` by the caller.
	 *
	 * This is an alternative to {approve} that can be used as a mitigation for
	 * problems described in {IERC20-approve}.
	 *
	 * Emits an {Approval} event indicating the updated allowance.
	 *
	 * Requirements:
	 *
	 * - `spender` cannot be the zero address.
	 */
	function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
		_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
		return true;
	}

	/**
	 * @dev Atomically decreases the allowance granted to `spender` by the caller.
	 *
	 * This is an alternative to {approve} that can be used as a mitigation for
	 * problems described in {IERC20-approve}.
	 *
	 * Emits an {Approval} event indicating the updated allowance.
	 *
	 * Requirements:
	 *
	 * - `spender` cannot be the zero address.
	 * - `spender` must have allowance for the caller of at least
	 * `subtractedValue`.
	 */
	function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
		uint256 currentAllowance = _allowances[_msgSender()][spender];
		require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
		unchecked {
			_approve(_msgSender(), spender, currentAllowance - subtractedValue);
		}

		return true;
	}

	/**
	 * @dev Moves `amount` of tokens from `sender` to `recipient`.
	 *
	 * This internal function is equivalent to {transfer}, and can be used to
	 * e.g. implement automatic token fees, slashing mechanisms, etc.
	 *
	 * Emits a {Transfer} event.
	 *
	 * Requirements:
	 *
	 * - `sender` cannot be the zero address.
	 * - `recipient` cannot be the zero address.
	 * - `sender` must have a balance of at least `amount`.
	 */
	function _transfer(
		address sender,
		address recipient,
		uint256 amount
	) internal virtual {
		require(sender != address(0), "ERC20: transfer from the zero address");
		require(recipient != address(0), "ERC20: transfer to the zero address");

		_beforeTokenTransfer(sender, recipient, amount);

		uint256 senderBalance = _balances[sender];
		require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
		unchecked {
			_balances[sender] = senderBalance - amount;
		}
		_balances[recipient] += amount;

		emit Transfer(sender, recipient, amount);

		_afterTokenTransfer(sender, recipient, amount);
	}

	/** @dev Creates `amount` tokens and assigns them to `account`, increasing
	 * the total supply.
	 *
	 * Emits a {Transfer} event with `from` set to the zero address.
	 *
	 * Requirements:
	 *
	 * - `account` cannot be the zero address.
	 */
	function _mint(address account, uint256 amount) internal virtual {
		require(account != address(0), "ERC20: mint to the zero address");

		_beforeTokenTransfer(address(0), account, amount);

		_totalSupply += amount;
		_balances[account] += amount;
		emit Transfer(address(0), account, amount);

		_afterTokenTransfer(address(0), account, amount);
	}

	/**
	 * @dev Destroys `amount` tokens from `account`, reducing the
	 * total supply.
	 *
	 * Emits a {Transfer} event with `to` set to the zero address.
	 *
	 * Requirements:
	 *
	 * - `account` cannot be the zero address.
	 * - `account` must have at least `amount` tokens.
	 */
	function _burn(address account, uint256 amount) internal virtual {
		require(account != address(0), "ERC20: burn from the zero address");

		_beforeTokenTransfer(account, address(0), amount);

		uint256 accountBalance = _balances[account];
		require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
		unchecked {
			_balances[account] = accountBalance - amount;
		}
		_totalSupply -= amount;

		emit Transfer(account, address(0), amount);

		_afterTokenTransfer(account, address(0), amount);
	}

	/**
	 * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
	 *
	 * This internal function is equivalent to `approve`, and can be used to
	 * e.g. set automatic allowances for certain subsystems, etc.
	 *
	 * Emits an {Approval} event.
	 *
	 * Requirements:
	 *
	 * - `owner` cannot be the zero address.
	 * - `spender` cannot be the zero address.
	 */
	function _approve(
		address owner,
		address spender,
		uint256 amount
	) internal virtual {
		require(owner != address(0), "ERC20: approve from the zero address");
		require(spender != address(0), "ERC20: approve to the zero address");

		_allowances[owner][spender] = amount;
		emit Approval(owner, spender, amount);
	}

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

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

File 5 of 21: ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./Context.sol";
import "./Strings.sol";
import "./ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
	using Address for address;
	using Strings for uint256;

	// Token name
	string private _name;

	// Token symbol
	string private _symbol;

	// Mapping from token ID to owner address
	mapping(uint256 => address) private _owners;

	// Mapping owner address to token count
	mapping(address => uint256) private _balances;

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

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

	/**
	 * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
	 */
	constructor(string memory name_, string memory symbol_) {
		_name = name_;
		_symbol = symbol_;
	}

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

	/**
	 * @dev See {IERC721-balanceOf}.
	 */
	function balanceOf(address owner) public view virtual override returns (uint256) {
		require(owner != address(0), "ERC721: balance query for the zero address");
		return _balances[owner];
	}

	/**
	 * @dev See {IERC721-ownerOf}.
	 */
	function ownerOf(uint256 tokenId) public view virtual override returns (address) {
		address owner = _owners[tokenId];
		require(owner != address(0), "ERC721: owner query for nonexistent token");
		return owner;
	}

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

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

	/**
	 * @dev See {IERC721Metadata-tokenURI}.
	 */
	function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
		require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

		string memory baseURI = _baseURI();
		return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
	}

	/**
	 * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
	 * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
	 * by default, can be overriden in child contracts.
	 */
	function _baseURI() internal view virtual returns (string memory) {
		return "";
	}

	/**
	 * @dev See {IERC721-approve}.
	 */
	function approve(address to, uint256 tokenId) public virtual override {
		address owner = ERC721.ownerOf(tokenId);
		require(to != owner, "ERC721: approval to current owner");

		require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all");

		_approve(to, tokenId);
	}

	/**
	 * @dev See {IERC721-getApproved}.
	 */
	function getApproved(uint256 tokenId) public view virtual override returns (address) {
		require(_exists(tokenId), "ERC721: approved query for nonexistent token");

		return _tokenApprovals[tokenId];
	}

	/**
	 * @dev See {IERC721-setApprovalForAll}.
	 */
	function setApprovalForAll(address operator, bool approved) public virtual override {
		require(operator != _msgSender(), "ERC721: approve to caller");

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

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

	/**
	 * @dev See {IERC721-transferFrom}.
	 */
	function transferFrom(
		address from,
		address to,
		uint256 tokenId
	) public virtual override {
		//solhint-disable-next-line max-line-length
		require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

		_transfer(from, to, tokenId);
	}

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

	/**
	 * @dev See {IERC721-safeTransferFrom}.
	 */
	function safeTransferFrom(
		address from,
		address to,
		uint256 tokenId,
		bytes memory _data
	) public virtual override {
		require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
		_safeTransfer(from, to, tokenId, _data);
	}

	/**
	 * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
	 * are aware of the ERC721 protocol to prevent tokens from being forever locked.
	 *
	 * `_data` is additional data, it has no specified format and it is sent in call to `to`.
	 *
	 * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
	 * implement alternative mechanisms to perform token transfer, such as signature-based.
	 *
	 * Requirements:
	 *
	 * - `from` cannot be the zero address.
	 * - `to` cannot be the zero address.
	 * - `tokenId` token must exist and be owned by `from`.
	 * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
	 *
	 * Emits a {Transfer} event.
	 */
	function _safeTransfer(
		address from,
		address to,
		uint256 tokenId,
		bytes memory _data
	) internal virtual {
		_transfer(from, to, tokenId);
		require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
	}

	/**
	 * @dev Returns whether `tokenId` exists.
	 *
	 * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
	 *
	 * Tokens start existing when they are minted (`_mint`),
	 * and stop existing when they are burned (`_burn`).
	 */
	function _exists(uint256 tokenId) internal view virtual returns (bool) {
		return _owners[tokenId] != address(0);
	}

	/**
	 * @dev Returns whether `spender` is allowed to manage `tokenId`.
	 *
	 * Requirements:
	 *
	 * - `tokenId` must exist.
	 */
	function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
		require(_exists(tokenId), "ERC721: operator query for nonexistent token");
		address owner = ERC721.ownerOf(tokenId);
		return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
	}

	/**
	 * @dev Safely mints `tokenId` and transfers it to `to`.
	 *
	 * Requirements:
	 *
	 * - `tokenId` must not exist.
	 * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
	 *
	 * Emits a {Transfer} event.
	 */
	function _safeMint(address to, uint256 tokenId) internal virtual {
		_safeMint(to, tokenId, "");
	}

	/**
	 * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
	 * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
	 */
	function _safeMint(
		address to,
		uint256 tokenId,
		bytes memory _data
	) internal virtual {
		_mint(to, tokenId);
		require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
	}

	/**
	 * @dev Mints `tokenId` and transfers it to `to`.
	 *
	 * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
	 *
	 * Requirements:
	 *
	 * - `tokenId` must not exist.
	 * - `to` cannot be the zero address.
	 *
	 * Emits a {Transfer} event.
	 */
	function _mint(address to, uint256 tokenId) internal virtual {
		require(to != address(0), "ERC721: mint to the zero address");
		require(!_exists(tokenId), "ERC721: token already minted");

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

		_balances[to] += 1;
		_owners[tokenId] = to;

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

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

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

		// Clear approvals
		_approve(address(0), tokenId);

		_balances[owner] -= 1;
		delete _owners[tokenId];

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

	/**
	 * @dev Transfers `tokenId` from `from` to `to`.
	 *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
	 *
	 * Requirements:
	 *
	 * - `to` cannot be the zero address.
	 * - `tokenId` token must be owned by `from`.
	 *
	 * Emits a {Transfer} event.
	 */
	function _transfer(
		address from,
		address to,
		uint256 tokenId
	) internal virtual {
		require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
		require(to != address(0), "ERC721: transfer to the zero address");

		_beforeTokenTransfer(from, to, tokenId);

		// Clear approvals from the previous owner
		_approve(address(0), tokenId);

		_balances[from] -= 1;
		_balances[to] += 1;
		_owners[tokenId] = to;

		emit Transfer(from, to, tokenId);
	}

	/**
	 * @dev Approve `to` to operate on `tokenId`
	 *
	 * Emits a {Approval} event.
	 */
	function _approve(address to, uint256 tokenId) internal virtual {
		_tokenApprovals[tokenId] = to;
		emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
	}

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

	/**
	 * @dev Hook that is called before any token transfer. This includes minting
	 * and burning.
	 *
	 * Calling conditions:
	 *
	 * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
	 * transferred to `to`.
	 * - When `from` is zero, `tokenId` will be minted for `to`.
	 * - When `to` is zero, ``from``'s `tokenId` will be burned.
	 * - `from` and `to` are never both zero.
	 *
	 * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
	 */
	function _beforeTokenTransfer(
		address from,
		address to,
		uint256 tokenId
	) internal virtual {}
}

File 6 of 21: ERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ERC721.sol";
import "./IERC721Enumerable.sol";

/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
	// Mapping from owner to list of owned token IDs
	mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

	// Mapping from token ID to index of the owner tokens list
	mapping(uint256 => uint256) private _ownedTokensIndex;

	// Array with all token ids, used for enumeration
	uint256[] private _allTokens;

	// Mapping from token id to position in the allTokens array
	mapping(uint256 => uint256) private _allTokensIndex;

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

	/**
	 * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
	 */
	function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
		require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
		return _ownedTokens[owner][index];
	}

	/**
	 * @dev See {IERC721Enumerable-totalSupply}.
	 */
	function totalSupply() public view virtual override returns (uint256) {
		return _allTokens.length;
	}

	/**
	 * @dev See {IERC721Enumerable-tokenByIndex}.
	 */
	function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
		require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
		return _allTokens[index];
	}

	/**
	 * @dev Hook that is called before any token transfer. This includes minting
	 * and burning.
	 *
	 * Calling conditions:
	 *
	 * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
	 * transferred to `to`.
	 * - When `from` is zero, `tokenId` will be minted for `to`.
	 * - When `to` is zero, ``from``'s `tokenId` will be burned.
	 * - `from` cannot be the zero address.
	 * - `to` cannot be the zero address.
	 *
	 * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
	 */
	function _beforeTokenTransfer(
		address from,
		address to,
		uint256 tokenId
	) internal virtual override {
		super._beforeTokenTransfer(from, to, tokenId);

		if (from == address(0)) {
			_addTokenToAllTokensEnumeration(tokenId);
		} else if (from != to) {
			_removeTokenFromOwnerEnumeration(from, tokenId);
		}
		if (to == address(0)) {
			_removeTokenFromAllTokensEnumeration(tokenId);
		} else if (to != from) {
			_addTokenToOwnerEnumeration(to, tokenId);
		}
	}

	/**
	 * @dev Private function to add a token to this extension's ownership-tracking data structures.
	 * @param to address representing the new owner of the given token ID
	 * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
	 */
	function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
		uint256 length = ERC721.balanceOf(to);
		_ownedTokens[to][length] = tokenId;
		_ownedTokensIndex[tokenId] = length;
	}

	/**
	 * @dev Private function to add a token to this extension's token tracking data structures.
	 * @param tokenId uint256 ID of the token to be added to the tokens list
	 */
	function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
		_allTokensIndex[tokenId] = _allTokens.length;
		_allTokens.push(tokenId);
	}

	/**
	 * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
	 * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
	 * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
	 * This has O(1) time complexity, but alters the order of the _ownedTokens array.
	 * @param from address representing the previous owner of the given token ID
	 * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
	 */
	function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
		// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
		// then delete the last slot (swap and pop).

		uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
		uint256 tokenIndex = _ownedTokensIndex[tokenId];

		// When the token to delete is the last token, the swap operation is unnecessary
		if (tokenIndex != lastTokenIndex) {
			uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

			_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
			_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
		}

		// This also deletes the contents at the last position of the array
		delete _ownedTokensIndex[tokenId];
		delete _ownedTokens[from][lastTokenIndex];
	}

	/**
	 * @dev Private function to remove a token from this extension's token tracking data structures.
	 * This has O(1) time complexity, but alters the order of the _allTokens array.
	 * @param tokenId uint256 ID of the token to be removed from the tokens list
	 */
	function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
		// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
		// then delete the last slot (swap and pop).

		uint256 lastTokenIndex = _allTokens.length - 1;
		uint256 tokenIndex = _allTokensIndex[tokenId];

		// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
		// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
		// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
		uint256 lastTokenId = _allTokens[lastTokenIndex];

		_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
		_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

		// This also deletes the contents at the last position of the array
		delete _allTokensIndex[tokenId];
		_allTokens.pop();
	}
}

File 7 of 21: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 8 of 21: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
	/**
	 * @dev Returns the amount of tokens in existence.
	 */
	function totalSupply() external view returns (uint256);

	/**
	 * @dev Returns the amount of tokens owned by `account`.
	 */
	function balanceOf(address account) external view returns (uint256);

	/**
	 * @dev Moves `amount` tokens from the caller's account to `recipient`.
	 *
	 * Returns a boolean value indicating whether the operation succeeded.
	 *
	 * Emits a {Transfer} event.
	 */
	function transfer(address recipient, uint256 amount) external returns (bool);

	/**
	 * @dev Returns the remaining number of tokens that `spender` will be
	 * allowed to spend on behalf of `owner` through {transferFrom}. This is
	 * zero by default.
	 *
	 * This value changes when {approve} or {transferFrom} are called.
	 */
	function allowance(address owner, address spender) external view returns (uint256);

	/**
	 * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
	 *
	 * Returns a boolean value indicating whether the operation succeeded.
	 *
	 * IMPORTANT: Beware that changing an allowance with this method brings the risk
	 * that someone may use both the old and the new allowance by unfortunate
	 * transaction ordering. One possible solution to mitigate this race
	 * condition is to first reduce the spender's allowance to 0 and set the
	 * desired value afterwards:
	 * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
	 *
	 * Emits an {Approval} event.
	 */
	function approve(address spender, uint256 amount) external returns (bool);

	/**
	 * @dev Moves `amount` tokens from `sender` to `recipient` using the
	 * allowance mechanism. `amount` is then deducted from the caller's
	 * allowance.
	 *
	 * Returns a boolean value indicating whether the operation succeeded.
	 *
	 * Emits a {Transfer} event.
	 */
	function transferFrom(
		address sender,
		address recipient,
		uint256 amount
	) external returns (bool);

	/**
	 * @dev Emitted when `value` tokens are moved from one account (`from`) to
	 * another (`to`).
	 *
	 * Note that `value` may be zero.
	 */
	event Transfer(address indexed from, address indexed to, uint256 value);

	/**
	 * @dev Emitted when the allowance of a `spender` for an `owner` is set by
	 * a call to {approve}. `value` is the new allowance.
	 */
	event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 9 of 21: IERC20Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
	/**
	 * @dev Returns the name of the token.
	 */
	function name() external view returns (string memory);

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

	/**
	 * @dev Returns the decimals places of the token.
	 */
	function decimals() external view returns (uint8);
}

File 10 of 21: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 11 of 21: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
	/**
	 * @dev Returns the total amount of tokens stored by the contract.
	 */
	function totalSupply() external view returns (uint256);

	/**
	 * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
	 * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
	 */
	function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

	/**
	 * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
	 * Use along with {totalSupply} to enumerate all tokens.
	 */
	function tokenByIndex(uint256 index) external view returns (uint256);
}

File 12 of 21: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 13 of 21: IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 14 of 21: IForest.sol
// SPDX-License-Identifier: MIT LICENSE

pragma solidity ^0.8.0;

interface IForest {
	function addManyToForestAndPack(address account, uint16[] calldata tokenIds) external;

	function randomWolfOwner(uint256 seed) external view returns (address);
}

File 15 of 21: ITraits.sol
// SPDX-License-Identifier: MIT LICENSE

pragma solidity ^0.8.0;

interface ITraits {
	function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 16 of 21: IWoolf.sol
// SPDX-License-Identifier: MIT LICENSE

pragma solidity ^0.8.0;

import "./IERC721.sol";

interface IWoolf is IERC721 {
	// struct to store each token's traits
	struct ApeWolf {
		bool isApe;
		uint8 skin;
		uint8 eyes;
		uint8 mouth;
		uint8 clothing;
		uint8 headwear;
		uint8 alphaIndex;
	}

	function getPaidTokens() external view returns (uint256);

	function getTokenTraits(uint256 tokenId) external view returns (ApeWolf memory);
	
	function transferFrom(
		address from,
		address to,
		uint256 tokenId
	) external;
}

File 17 of 21: MutantPeach.sol
// SPDX-License-Identifier: MIT LICENSE

pragma solidity ^0.8.0;
import "./ERC20.sol";
import "./Ownable.sol";

contract MutantPeach is ERC20, Ownable {
	// a mapping from an address to whether or not it can mint / burn
	mapping(address => bool) controllers;

	constructor() ERC20("MutantPeach", "MutantPeach") {}

	/**
	 * mints $MutantPeach to a recipient
	 * @param to the recipient of the $MutantPeach
	 * @param amount the amount of $MutantPeach to mint
	 */
	function mint(address to, uint256 amount) external {
		require(controllers[msg.sender], "Only controllers can mint");
		_mint(to, amount);
	}

	/**
	 * burns $MutantPeach from a holder
	 * @param from the holder of the $MutantPeach
	 * @param amount the amount of $MutantPeach to burn
	 */
	function burn(address from, uint256 amount) external {
		require(controllers[msg.sender], "Only controllers can burn");
		_burn(from, amount);
	}

	/**
	 * enables an address to mint / burn
	 * @param controller the address to enable
	 */
	function addController(address controller) external onlyOwner {
		controllers[controller] = true;
	}

	/**
	 * disables an address from minting / burning
	 * @param controller the address to disbale
	 */
	function removeController(address controller) external onlyOwner {
		controllers[controller] = false;
	}
}

File 18 of 21: Ownable.sol
// SPDX-License-Identifier: MIT

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() {
		_setOwner(_msgSender());
	}

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

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

	/**
	 * @dev Leaves the contract without owner. It will not be possible to call
	 * `onlyOwner` functions anymore. Can only be called by the current owner.
	 *
	 * NOTE: Renouncing ownership will leave the contract without an owner,
	 * thereby removing any functionality that is only available to the owner.
	 */
	function renounceOwnership() public virtual onlyOwner {
		_setOwner(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");
		_setOwner(newOwner);
	}

	function _setOwner(address newOwner) private {
		address oldOwner = _owner;
		_owner = newOwner;
		emit OwnershipTransferred(oldOwner, newOwner);
	}
}

File 19 of 21: Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
	/**
	 * @dev Emitted when the pause is triggered by `account`.
	 */
	event Paused(address account);

	/**
	 * @dev Emitted when the pause is lifted by `account`.
	 */
	event Unpaused(address account);

	bool private _paused;

	/**
	 * @dev Initializes the contract in unpaused state.
	 */
	constructor() {
		_paused = false;
	}

	/**
	 * @dev Returns true if the contract is paused, and false otherwise.
	 */
	function paused() public view virtual returns (bool) {
		return _paused;
	}

	/**
	 * @dev Modifier to make a function callable only when the contract is not paused.
	 *
	 * Requirements:
	 *
	 * - The contract must not be paused.
	 */
	modifier whenNotPaused() {
		require(!paused(), "Pausable: paused");
		_;
	}

	/**
	 * @dev Modifier to make a function callable only when the contract is paused.
	 *
	 * Requirements:
	 *
	 * - The contract must be paused.
	 */
	modifier whenPaused() {
		require(paused(), "Pausable: not paused");
		_;
	}

	/**
	 * @dev Triggers stopped state.
	 *
	 * Requirements:
	 *
	 * - The contract must not be paused.
	 */
	function _pause() internal virtual whenNotPaused {
		_paused = true;
		emit Paused(_msgSender());
	}

	/**
	 * @dev Returns to normal state.
	 *
	 * Requirements:
	 *
	 * - The contract must be paused.
	 */
	function _unpause() internal virtual whenPaused {
		_paused = false;
		emit Unpaused(_msgSender());
	}
}

File 20 of 21: Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_peach","type":"address"},{"internalType":"address","name":"_traits","type":"address"},{"internalType":"address","name":"_bamc","type":"address"},{"internalType":"address","name":"_club","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"uint256","name":"_maxTokens","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"account","type":"address"}],"name":"Paused","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"LP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAID_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"aliases","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"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":[],"name":"bamc","outputs":[{"internalType":"contract ISuperShibaBAMC","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"club","outputs":[{"internalType":"contract ISuperShibaClub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"existingCombinations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"forest","outputs":[{"internalType":"contract IForest","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"bamcIds","type":"uint256[]"},{"internalType":"uint256[]","name":"clubIds","type":"uint256[]"}],"name":"freeMint","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":[],"name":"getPaidTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenTraits","outputs":[{"components":[{"internalType":"bool","name":"isApe","type":"bool"},{"internalType":"uint8","name":"skin","type":"uint8"},{"internalType":"uint8","name":"eyes","type":"uint8"},{"internalType":"uint8","name":"mouth","type":"uint8"},{"internalType":"uint8","name":"clothing","type":"uint8"},{"internalType":"uint8","name":"headwear","type":"uint8"},{"internalType":"uint8","name":"alphaIndex","type":"uint8"}],"internalType":"struct IWoolf.ApeWolf","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasure","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minted","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mutantPeach","outputs":[{"internalType":"contract MutantPeach","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openFreeMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openPublicMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract Pool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rarities","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_forest","type":"address"}],"name":"setForest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lp","type":"uint256"}],"name":"setLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_MPeach","type":"address"}],"name":"setMPeach","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_free","type":"bool"},{"internalType":"bool","name":"_public","type":"bool"}],"name":"setMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_paidTokens","type":"uint256"}],"name":"setPaidTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"setPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setRandomPick","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setSuperShibaBAMCAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setSuperShibaClubAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setTraits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"superShibaBAMCTokensMint","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"superShibaClubTokensMint","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenTraits","outputs":[{"internalType":"bool","name":"isApe","type":"bool"},{"internalType":"uint8","name":"skin","type":"uint8"},{"internalType":"uint8","name":"eyes","type":"uint8"},{"internalType":"uint8","name":"mouth","type":"uint8"},{"internalType":"uint8","name":"clothing","type":"uint8"},{"internalType":"uint8","name":"headwear","type":"uint8"},{"internalType":"uint8","name":"alphaIndex","type":"uint8"}],"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":[],"name":"traits","outputs":[{"internalType":"contract ITraits","name":"","type":"address"}],"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"}]

60a060405264e8d4a510006012556014805463ffffffff191690556706f05b59d3b200006015553480156200003357600080fd5b5060405162004bed38038062004bed833981016040819052620000569162001055565b604080518082018252600d81526c135d5d185b9d08119bdc995cdd609a1b60208083019182528351808501909452600784526613519bdc995cdd60ca1b908401528151919291620000aa9160009162000eef565b508051620000c090600190602084019062000eef565b505050620000dd620000d762000e9960201b60201c565b62000e9d565b600a805460ff60a01b19169055601080546001600160a01b03199081166001600160a01b0389811691909117909255601180548216888416179055600c80548216878416179055600d8054821686841617905560328054909116918416919091179055608081905262000152600582620010cd565b601355604080516102c081018252603281526080602082018190529181018290526060810182905281810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a08101919091526200021690601a90601662000f7e565b50604080516102c081018252601180825260208201526012918101829052606081018290526080810182905260a0810182905260c0810191909152601360e08201819052610100820181905261012082018190526101408201819052610160820152601461018082018190526101a082018190526101c082018190526101e08201819052610200820152601561022082018190526102408201819052610260820181905261028082018190526102a0820152620002d890602690601662000f7e565b506040805161026081018252603281526080602082018190529181018290526060810182905281810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101919091526200038290601b90601362000f7e565b506040805161026081018252601280825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101919091526200042c90602790601362000f7e565b50604080516102c081018252603281526080602082018190529181018290526060810182905281810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a0810191909152620004ee90601c90601662000f7e565b50604080516102c081018252601580825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a0810191909152620005b090602890601662000f7e565b50604080516020810190915260ff8152620005d090601d90600162000f7e565b50604080516020810190915260008152620005f090602990600162000f7e565b506040805161056081018252603281526080602082018190529181018290526060810182905281810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a081018290526102c081018290526102e08101829052610300810182905261032081018290526103408101829052610360810182905261038081018290526103a081018290526103c081018290526103e08101829052610400810182905261042081018290526104408101829052610460810182905261048081018290526104a081018290526104c081018290526104e08101829052610500810182905261052081018290526105408101919091526200075a90601e90602b62000f7e565b506040805161056081018252602a80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a081018290526102c081018290526102e08101829052610300810182905261032081018290526103408101829052610360810182905261038081018290526103a081018290526103c081018290526103e08101829052610400810182905261042081018290526104408101829052610460810182905261048081018290526104a081018290526104c081018290526104e08101829052610500810182905261052081018290526105408101829052620008c19190602b62000f7e565b50604080516020810190915260ff8152620008e190601f90600162000f7e565b506040805160208101909152600081526200090190602b90600162000f7e565b5060408051602080820190925260ff8152620009209190600162000f7e565b506040805160208101909152600081526200094090602c90600162000f7e565b506040805161016081018252603281526080602082018190529181018290526060810182905281810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152620009aa90602190600b62000f7e565b506040805161016081018252600a80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915262000a1490602d90600b62000f7e565b506040805161016081018252603281526080602082018190529181018290526060810182905281810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915262000a7e90602290600b62000f7e565b506040805161016081018252600a80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915262000ae890602e90600b62000f7e565b506040805161034081018252603281526080602082018190529181018290526060810182905281810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a081018290526102c081018290526102e08101829052610300810182905261032081019190915262000bca90602390601a62000f7e565b506040805161034081018252601980825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a081018290526102c081018290526102e08101829052610300810182905261032081019190915262000cac90602f90601a62000f7e565b50604080516102a081018252603281526080602082018190529181018290526060810182905281810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081019190915262000d6690602490601562000f7e565b50604080516102a081018252601480825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081019190915262000e2090603090601562000f7e565b50604080516080810182526009815260a16020820152604a9181019190915260ff606082015262000e5690602590600462000f7e565b506040805160808101825260028152600360208201819052918101829052606081019190915262000e8c90603190600462000f7e565b505050505050506200112d565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805462000efd90620010f0565b90600052602060002090601f01602090048101928262000f21576000855562000f6c565b82601f1062000f3c57805160ff191683800117855562000f6c565b8280016001018555821562000f6c579182015b8281111562000f6c57825182559160200191906001019062000f4f565b5062000f7a92915062001021565b5090565b82805482825590600052602060002090601f0160209004810192821562000f6c5791602002820160005b8382111562000fe857835183826101000a81548160ff021916908360ff160217905550926020019260010160208160000104928301926001030262000fa8565b8015620010175782816101000a81549060ff021916905560010160208160000104928301926001030262000fe8565b505062000f7a9291505b5b8082111562000f7a576000815560010162001022565b80516001600160a01b03811681146200105057600080fd5b919050565b60008060008060008060c087890312156200106f57600080fd5b6200107a8762001038565b95506200108a6020880162001038565b94506200109a6040880162001038565b9350620010aa6060880162001038565b9250620010ba6080880162001038565b915060a087015190509295509295509295565b600082620010eb57634e487b7160e01b600052601260045260246000fd5b500490565b600181811c908216806200110557607f821691505b602082108114156200112757634e487b7160e01b600052602260045260246000fd5b50919050565b608051613a886200116560003960008181610c0901528181610fea01528181611038015281816116bb0152611d6a0152613a886000f3fe60806040526004361061038c5760003560e01c80636f4f7366116101dc578063c002d23d11610102578063e05c57bf116100a0578063f0f442601161006f578063f0f4426014610bb7578063f2fde38b14610bd7578063f47c84c514610bf7578063f4a0a52814610c2b57600080fd5b8063e05c57bf14610a7f578063e1fc334f14610b2e578063e985e9c514610b4e578063ed0b0e1314610b9757600080fd5b8063d289ce70116100dc578063d289ce70146109e9578063d51f39b914610a09578063d59f08b314610a3f578063de0e408a14610a5f57600080fd5b8063c002d23d1461099d578063c084f540146109b3578063c87b56dd146109c957600080fd5b806394e568471161017a578063a22cb46511610149578063a22cb46514610911578063b6fccf8a14610931578063b88d4fde14610947578063bb71f6ba1461096757600080fd5b806394e568471461083357806395d89b41146108bc578063a0712d68146108d1578063a1b8f374146108e457600080fd5b80637e64c8fb116101b65780637e64c8fb146107b55780637ffc42a6146107d55780638466ee01146107f55780638da5cb5b1461081557600080fd5b80636f4f73661461076057806370a0823114610780578063715018a6146107a057600080fd5b80632f745c59116102c15780634437152a1161025f578063562349951161022e57806356234995146106e15780635c975abb146107015780636352211e146107205780636c7b09b21461074057600080fd5b80634437152a1461065257806345f7e06e146106725780634f02c420146106935780634f6ccce7146106c157600080fd5b8063368383911161029b57806336838391146105e85780633ccfd60b146106085780634018b1f81461061d57806342842e0e1461063257600080fd5b80632f745c591461057657806333df4b2c146105965780633431a753146105c857600080fd5b806316f0115b1161032e578063215a416311610308578063215a4163146104f657806323b872dd1461051657806327de8f27146105365780632af177bc1461055657600080fd5b806316f0115b146104a257806318160ddd146104c25780631e71ccb1146104e157600080fd5b8063092576761161036a5780630925767614610420578063095ea7b3146104425780630efd09731461046257806316c38b3c1461048257600080fd5b806301ffc9a71461039157806306fdde03146103c6578063081812fc146103e8575b600080fd5b34801561039d57600080fd5b506103b16103ac366004613283565b610c4b565b60405190151581526020015b60405180910390f35b3480156103d257600080fd5b506103db610c76565b6040516103bd91906132f8565b3480156103f457600080fd5b5061040861040336600461330b565b610d08565b6040516001600160a01b0390911681526020016103bd565b34801561042c57600080fd5b5061044061043b366004613339565b610da2565b005b34801561044e57600080fd5b5061044061045d366004613356565b610dee565b34801561046e57600080fd5b50600d54610408906001600160a01b031681565b34801561048e57600080fd5b5061044061049d366004613397565b610f04565b3480156104ae57600080fd5b50600e54610408906001600160a01b031681565b3480156104ce57600080fd5b506008545b6040519081526020016103bd565b3480156104ed57600080fd5b50610408610f47565b34801561050257600080fd5b506014546103b19062010000900460ff1681565b34801561052257600080fd5b506104406105313660046133b2565b610f84565b34801561054257600080fd5b506104d361055136600461330b565b610fd0565b34801561056257600080fd5b50610440610571366004613339565b611090565b34801561058257600080fd5b506104d3610591366004613356565b6110dc565b3480156105a257600080fd5b506105b66105b13660046133f3565b611172565b60405160ff90911681526020016103bd565b3480156105d457600080fd5b506104406105e336600461330b565b6111b8565b3480156105f457600080fd5b506105b66106033660046133f3565b6111e7565b34801561061457600080fd5b506104406111f7565b34801561062957600080fd5b506013546104d3565b34801561063e57600080fd5b5061044061064d3660046133b2565b61125a565b34801561065e57600080fd5b5061044061066d366004613339565b611275565b34801561067e57600080fd5b506014546103b1906301000000900460ff1681565b34801561069f57600080fd5b506014546106ae9061ffff1681565b60405161ffff90911681526020016103bd565b3480156106cd57600080fd5b506104d36106dc36600461330b565b6112c1565b3480156106ed57600080fd5b506104406106fc366004613339565b611354565b34801561070d57600080fd5b50600a54600160a01b900460ff166103b1565b34801561072c57600080fd5b5061040861073b36600461330b565b6113a0565b34801561074c57600080fd5b5061044061075b366004613339565b611417565b34801561076c57600080fd5b5061044061077b366004613339565b611463565b34801561078c57600080fd5b506104d361079b366004613339565b6114af565b3480156107ac57600080fd5b50610440611536565b3480156107c157600080fd5b50600f54610408906001600160a01b031681565b3480156107e157600080fd5b50600c54610408906001600160a01b031681565b34801561080157600080fd5b50601054610408906001600160a01b031681565b34801561082157600080fd5b50600a546001600160a01b0316610408565b34801561083f57600080fd5b5061085361084e36600461330b565b61156c565b6040516103bd9190600060e082019050825115158252602083015160ff80821660208501528060408601511660408501528060608601511660608501528060808601511660808501528060a08601511660a08501528060c08601511660c0850152505092915050565b3480156108c857600080fd5b506103db6115f5565b6104406108df36600461330b565b611604565b3480156108f057600080fd5b506104d36108ff36600461330b565b60176020526000908152604090205481565b34801561091d57600080fd5b5061044061092c366004613415565b6119e4565b34801561093d57600080fd5b506104d360155481565b34801561095357600080fd5b506104406109623660046134b9565b611aa9565b34801561097357600080fd5b5061040861098236600461330b565b6019602052600090815260409020546001600160a01b031681565b3480156109a957600080fd5b506104d360125481565b3480156109bf57600080fd5b506104d360135481565b3480156109d557600080fd5b506103db6109e436600461330b565b611ae1565b3480156109f557600080fd5b50610440610a0436600461330b565b611bd1565b348015610a1557600080fd5b50610408610a2436600461330b565b6018602052600090815260409020546001600160a01b031681565b348015610a4b57600080fd5b50610440610a5a366004613568565b611c00565b348015610a6b57600080fd5b50610440610a7a366004613604565b611c5c565b348015610a8b57600080fd5b50610aed610a9a36600461330b565b60166020526000908152604090205460ff808216916101008104821691620100008204811691630100000081048216916401000000008204811691650100000000008104821691600160301b9091041687565b60408051971515885260ff968716602089015294861694870194909452918416606086015283166080850152821660a08401521660c082015260e0016103bd565b348015610b3a57600080fd5b50601154610408906001600160a01b031681565b348015610b5a57600080fd5b506103b1610b69366004613668565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610ba357600080fd5b50610440610bb2366004613339565b612091565b348015610bc357600080fd5b50610440610bd2366004613339565b6120dd565b348015610be357600080fd5b50610440610bf2366004613339565b612129565b348015610c0357600080fd5b506104d37f000000000000000000000000000000000000000000000000000000000000000081565b348015610c3757600080fd5b50610440610c4636600461330b565b6121c1565b60006001600160e01b0319821663780e9d6360e01b1480610c705750610c70826121f0565b92915050565b606060008054610c85906136a1565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb1906136a1565b8015610cfe5780601f10610cd357610100808354040283529160200191610cfe565b820191906000526020600020905b815481529060010190602001808311610ce157829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610d865760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600a546001600160a01b03163314610dcc5760405162461bcd60e51b8152600401610d7d906136dc565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610df9826113a0565b9050806001600160a01b0316836001600160a01b03161415610e675760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610d7d565b336001600160a01b0382161480610e835750610e838133610b69565b610ef55760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610d7d565b610eff8383612240565b505050565b600a546001600160a01b03163314610f2e5760405162461bcd60e51b8152600401610d7d906136dc565b8015610f3f57610f3c6122ae565b50565b610f3c612330565b600a546000906001600160a01b03163314610f745760405162461bcd60e51b8152600401610d7d906136dc565b506032546001600160a01b031690565b600f546001600160a01b0316336001600160a01b031614610fc557610fa933826123b4565b610fc55760405162461bcd60e51b8152600401610d7d90613711565b610eff8383836124ab565b60006013548211610fe357506000919050565b60056110107f00000000000000000000000000000000000000000000000000000000000000006002613778565b61101a91906137ad565b8211611031575069043c33c1937564800000919050565b600561105e7f00000000000000000000000000000000000000000000000000000000000000006004613778565b61106891906137ad565b821161107f5750690878678326eac9000000919050565b506910f0cf064dd592000000919050565b600a546001600160a01b031633146110ba5760405162461bcd60e51b8152600401610d7d906136dc565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60006110e7836114af565b82106111495760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610d7d565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b601a82600c811061118257600080fd5b01818154811061119157600080fd5b9060005260206000209060209182820401919006915091509054906101000a900460ff1681565b600a546001600160a01b031633146111e25760405162461bcd60e51b8152600401610d7d906136dc565b601355565b602682600c811061118257600080fd5b600a546001600160a01b031633146112215760405162461bcd60e51b8152600401610d7d906136dc565b6032546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610f3c573d6000803e3d6000fd5b610eff83838360405180602001604052806000815250611aa9565b600a546001600160a01b0316331461129f5760405162461bcd60e51b8152600401610d7d906136dc565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b60006112cc60085490565b821061132f5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610d7d565b60088281548110611342576113426137c1565b90600052602060002001549050919050565b600a546001600160a01b0316331461137e5760405162461bcd60e51b8152600401610d7d906136dc565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600260205260408120546001600160a01b031680610c705760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610d7d565b600a546001600160a01b031633146114415760405162461bcd60e51b8152600401610d7d906136dc565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b0316331461148d5760405162461bcd60e51b8152600401610d7d906136dc565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b03821661151a5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610d7d565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146115605760405162461bcd60e51b8152600401610d7d906136dc565b61156a6000612656565b565b611574613231565b50600090815260166020908152604091829020825160e081018452905460ff8082161515835261010082048116938301939093526201000081048316938201939093526301000000830482166060820152640100000000830482166080820152650100000000008304821660a0820152600160301b9092041660c082015290565b606060018054610c85906136a1565b600a54600160a01b900460ff161561162e5760405162461bcd60e51b8152600401610d7d906137d7565b3233146116685760405162461bcd60e51b81526020600482015260086024820152674f6e6c7920454f4160c01b6044820152606401610d7d565b6014546301000000900460ff166116b65760405162461bcd60e51b81526020600482015260126024820152711b9bdd081bdc195b88199c9959481b5a5b9d60721b6044820152606401610d7d565b6014547f0000000000000000000000000000000000000000000000000000000000000000906116ea90839061ffff16613801565b111561172c5760405162461bcd60e51b8152602060048201526011602482015270105b1b081d1bdad95b9cc81b5a5b9d1959607a1b6044820152606401610d7d565b60008111801561173d5750600a8111155b61177f5760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610d7d565b60135460145461ffff16101561184c576013546014546117a490839061ffff16613801565b11156117f25760405162461bcd60e51b815260206004820152601f60248201527f416c6c20746f6b656e73206f6e2d73616c6520616c726561647920736f6c64006044820152606401610d7d565b34601254826118019190613778565b146118475760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c185e5b595b9d08185b5bdd5b9d60521b6044820152606401610d7d565b611857565b341561185757600080fd5b600080805b83811015611966576014805461ffff1690600061187883613819565b82546101009290920a61ffff818102199093169183160217909155600b5460145460405163b863bd3760e01b8152921660048301526001600160a01b0316915063b863bd3790602401602060405180830381865afa1580156118de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611902919061383b565b9150600061190f836126a8565b60145490915061192490829061ffff166127fc565b6014546119359061ffff168461281a565b506014546119469061ffff16610fd0565b6119509085613801565b935050808061195e90613854565b91505061185c565b508115610eff576010546001600160a01b0316639dc29fac336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401600060405180830381600087803b1580156119c757600080fd5b505af11580156119db573d6000803e3d6000fd5b50505050505050565b6001600160a01b038216331415611a3d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d7d565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611ab333836123b4565b611acf5760405162461bcd60e51b8152600401610d7d90613711565b611adb848484846129b8565b50505050565b6000818152600260205260409020546060906001600160a01b0316611b605760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610d7d565b60115460405163c87b56dd60e01b8152600481018490526001600160a01b039091169063c87b56dd90602401600060405180830381865afa158015611ba9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c70919081019061386f565b600a546001600160a01b03163314611bfb5760405162461bcd60e51b8152600401610d7d906136dc565b601555565b600a546001600160a01b03163314611c2a5760405162461bcd60e51b8152600401610d7d906136dc565b6014805463ffff00001916620100009315159390930263ff000000191692909217630100000091151591909102179055565b600a54600160a01b900460ff1615611c865760405162461bcd60e51b8152600401610d7d906137d7565b323314611cc05760405162461bcd60e51b81526020600482015260086024820152674f6e6c7920454f4160c01b6044820152606401610d7d565b60145462010000900460ff16611d0d5760405162461bcd60e51b81526020600482015260126024820152711b9bdd081bdc195b88199c9959481b5a5b9d60721b6044820152606401610d7d565b600a81518351611d1d9190613801565b1115611d615760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610d7d565b805182516014547f00000000000000000000000000000000000000000000000000000000000000009291611d989161ffff16613801565b611da29190613801565b1115611de45760405162461bcd60e51b8152602060048201526011602482015270105b1b081d1bdad95b9cc81b5a5b9d1959607a1b6044820152606401610d7d565b6000805b8351811015611f06576000848281518110611e0557611e056137c1565b60200260200101519050611e163390565b600c546040516331a9108f60e11b8152600481018490526001600160a01b039283169290911690636352211e90602401602060405180830381865afa158015611e63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8791906138dd565b6001600160a01b03161415611ef3576000818152601860205260409020546001600160a01b0316611ef35782611ebc81613854565b935050611ec63390565b600082815260186020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b5080611efe81613854565b915050611de8565b5060005b8251811015612028576000838281518110611f2757611f276137c1565b60200260200101519050611f383390565b600d546040516331a9108f60e11b8152600481018490526001600160a01b039283169290911690636352211e90602401602060405180830381865afa158015611f85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa991906138dd565b6001600160a01b03161415612015576000818152601960205260409020546001600160a01b03166120155782611fde81613854565b935050611fe83390565b600082815260196020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b508061202081613854565b915050611f0a565b50600081116120885760405162461bcd60e51b815260206004820152602660248201527f54686520736869626120696e20796f75722077616c6c657420686173206265656044820152651b881b5a5b9d60d21b6064820152608401610d7d565b610eff816129eb565b600a546001600160a01b031633146120bb5760405162461bcd60e51b8152600401610d7d906136dc565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b031633146121075760405162461bcd60e51b8152600401610d7d906136dc565b603280546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b031633146121535760405162461bcd60e51b8152600401610d7d906136dc565b6001600160a01b0381166121b85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d7d565b610f3c81612656565b600a546001600160a01b031633146121eb5760405162461bcd60e51b8152600401610d7d906136dc565b601255565b60006001600160e01b031982166380ac58cd60e01b148061222157506001600160e01b03198216635b5e139f60e01b145b80610c7057506301ffc9a760e01b6001600160e01b0319831614610c70565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612275826113a0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600160a01b900460ff16156122d85760405162461bcd60e51b8152600401610d7d906137d7565b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586123133390565b6040516001600160a01b03909116815260200160405180910390a1565b600a54600160a01b900460ff166123805760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610d7d565b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33612313565b6000818152600260205260408120546001600160a01b031661242d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610d7d565b6000612438836113a0565b9050806001600160a01b0316846001600160a01b031614806124735750836001600160a01b031661246884610d08565b6001600160a01b0316145b806124a357506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166124be826113a0565b6001600160a01b0316146125265760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610d7d565b6001600160a01b0382166125885760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d7d565b612593838383612af5565b61259e600082612240565b6001600160a01b03831660009081526003602052604081208054600192906125c79084906138fa565b90915550506001600160a01b03821660009081526003602052604081208054600192906125f5908490613801565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600e54600090600a9082906001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061272a919061383b565b9050601554811061273a57600591505b60135460145461ffff16111580612762575061ffff8216612760606460f587901c613911565b115b156127705733949350505050565b600f54604051631e4c4f3560e11b8152609086901c60048201526000916001600160a01b031690633c989e6a90602401602060405180830381865afa1580156127bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e191906138dd565b90506001600160a01b0381166124a357335b95945050505050565b612816828260405180602001604052806000815250612bad565b5050565b612822613231565b61282b82612be0565b90506017600061283a83612ce6565b815260200190815260200160002054600014156129395760008381526016602090815260408083208451815493860151928601516060870151608088015160a089015160c08a015161ffff1990981694151561ff0019169490941761010060ff978816021763ffff00001916620100009387169390930263ff0000001916929092176301000000918616919091021765ffff0000000019166401000000009185169190910265ff000000000019161765010000000000918416919091021766ff0000000000001916600160301b9290931691909102919091179055839060179061292384612ce6565b8152602081019190915260400160002055610c70565b600b5460405163b863bd3760e01b8152600481018490526129b19185916001600160a01b039091169063b863bd3790602401602060405180830381865afa158015612988573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ac919061383b565b61281a565b9392505050565b6129c38484846124ab565b6129cf84848484612d79565b611adb5760405162461bcd60e51b8152600401610d7d90613925565b600a54600160a01b900460ff1615612a155760405162461bcd60e51b8152600401610d7d906137d7565b6000805b82811015610eff576014805461ffff16906000612a3583613819565b82546101009290920a61ffff818102199093169183160217909155600b5460145460405163b863bd3760e01b8152921660048301526001600160a01b0316915063b863bd3790602401602060405180830381865afa158015612a9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612abf919061383b565b9150612ad13360145461ffff166127fc565b601454612ae29061ffff168361281a565b5080612aed81613854565b915050612a19565b6001600160a01b038316612b5057612b4b81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612b73565b816001600160a01b0316836001600160a01b031614612b7357612b738382612e77565b6001600160a01b038216612b8a57610eff81612f14565b826001600160a01b0316826001600160a01b031614610eff57610eff8282612fc3565b612bb78383613007565b612bc46000848484612d79565b610eff5760405162461bcd60e51b8152600401610d7d90613925565b612be8613231565b612bf7600a61ffff8416613911565b1515808252600090612c0a576006612c0d565b60005b60109390931c929050612c2e61ffff8416612c29836000613977565b613155565b60ff16602083015260109290921c91612c5061ffff8416612c29836001613977565b60ff16604083015260109290921c91612c7261ffff8416612c29836002613977565b60ff16606083015260109290921c91612c9461ffff8416612c29836003613977565b60ff16608083015260109290921c91612cb661ffff8416612c29836004613977565b60ff1660a083015260109290921c91612cd861ffff8416612c29836005613977565b60ff1660c083015250919050565b80516020808301516040808501516060860151608087015160a088015160c0890151945197151560f890811b978901979097526001600160f81b031995871b8616602189015292861b8516602288015290851b84166023870152841b83166024860152831b8216602585015290911b166026820152600090602701604051602081830303815290604052610c709061399c565b60006001600160a01b0384163b15612e6c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612dbd9033908990889088906004016139c0565b6020604051808303816000875af1925050508015612df8575060408051601f3d908101601f19168201909252612df5918101906139fd565b60015b612e52573d808015612e26576040519150601f19603f3d011682016040523d82523d6000602084013e612e2b565b606091505b508051612e4a5760405162461bcd60e51b8152600401610d7d90613925565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506124a3565b506001949350505050565b60006001612e84846114af565b612e8e91906138fa565b600083815260076020526040902054909150808214612ee1576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612f26906001906138fa565b60008381526009602052604081205460088054939450909284908110612f4e57612f4e6137c1565b906000526020600020015490508060088381548110612f6f57612f6f6137c1565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612fa757612fa7613a1a565b6001900381819060005260206000200160009055905550505050565b6000612fce836114af565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b03821661305d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d7d565b6000818152600260205260409020546001600160a01b0316156130c25760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d7d565b6130ce60008383612af5565b6001600160a01b03821660009081526003602052604081208054600192906130f7908490613801565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600080601a8360ff16600c811061316e5761316e6137c1565b015461317a9085613a30565b9050601a8360ff16600c8110613192576131926137c1565b018160ff16815481106131a7576131a76137c1565b60009182526020918290209181049091015460ff601f9092166101000a90048116600886901c90911610156131dd579050610c70565b60268360ff16600c81106131f3576131f36137c1565b018160ff1681548110613208576132086137c1565b90600052602060002090602091828204019190069054906101000a900460ff1691505092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b6001600160e01b031981168114610f3c57600080fd5b60006020828403121561329557600080fd5b81356129b18161326d565b60005b838110156132bb5781810151838201526020016132a3565b83811115611adb5750506000910152565b600081518084526132e48160208601602086016132a0565b601f01601f19169290920160200192915050565b6020815260006129b160208301846132cc565b60006020828403121561331d57600080fd5b5035919050565b6001600160a01b0381168114610f3c57600080fd5b60006020828403121561334b57600080fd5b81356129b181613324565b6000806040838503121561336957600080fd5b823561337481613324565b946020939093013593505050565b8035801515811461339257600080fd5b919050565b6000602082840312156133a957600080fd5b6129b182613382565b6000806000606084860312156133c757600080fd5b83356133d281613324565b925060208401356133e281613324565b929592945050506040919091013590565b6000806040838503121561340657600080fd5b50508035926020909101359150565b6000806040838503121561342857600080fd5b823561343381613324565b915061344160208401613382565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156134895761348961344a565b604052919050565b600067ffffffffffffffff8211156134ab576134ab61344a565b50601f01601f191660200190565b600080600080608085870312156134cf57600080fd5b84356134da81613324565b935060208501356134ea81613324565b925060408501359150606085013567ffffffffffffffff81111561350d57600080fd5b8501601f8101871361351e57600080fd5b803561353161352c82613491565b613460565b81815288602083850101111561354657600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000806040838503121561357b57600080fd5b61343383613382565b600082601f83011261359557600080fd5b8135602067ffffffffffffffff8211156135b1576135b161344a565b8160051b6135c0828201613460565b92835284810182019282810190878511156135da57600080fd5b83870192505b848310156135f9578235825291830191908301906135e0565b979650505050505050565b6000806040838503121561361757600080fd5b823567ffffffffffffffff8082111561362f57600080fd5b61363b86838701613584565b9350602085013591508082111561365157600080fd5b5061365e85828601613584565b9150509250929050565b6000806040838503121561367b57600080fd5b823561368681613324565b9150602083013561369681613324565b809150509250929050565b600181811c908216806136b557607f821691505b602082108114156136d657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561379257613792613762565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826137bc576137bc613797565b500490565b634e487b7160e01b600052603260045260246000fd5b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6000821982111561381457613814613762565b500190565b600061ffff8083168181141561383157613831613762565b6001019392505050565b60006020828403121561384d57600080fd5b5051919050565b600060001982141561386857613868613762565b5060010190565b60006020828403121561388157600080fd5b815167ffffffffffffffff81111561389857600080fd5b8201601f810184136138a957600080fd5b80516138b761352c82613491565b8181528560208385010111156138cc57600080fd5b6127f38260208301602086016132a0565b6000602082840312156138ef57600080fd5b81516129b181613324565b60008282101561390c5761390c613762565b500390565b60008261392057613920613797565b500690565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600060ff821660ff84168060ff0382111561399457613994613762565b019392505050565b805160208083015191908110156136d65760001960209190910360031b1b16919050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906139f3908301846132cc565b9695505050505050565b600060208284031215613a0f57600080fd5b81516129b18161326d565b634e487b7160e01b600052603160045260246000fd5b600060ff831680613a4357613a43613797565b8060ff8416069150509291505056fea26469706673582212203003fa8fe352f01d73828bcc2dbc78ea147e00f0a18d2670d205e5960c602de864736f6c634300080a00330000000000000000000000006fd2ba29a23e61759035b4b28b245c7dbd6e00b90000000000000000000000006fd2ba29a23e61759035b4b28b245c7dbd6e00b9000000000000000000000000df7cafb1449e62aa6ba35afb8f692feb67356e2500000000000000000000000048c58b8496642bc4c860c7efc13813b73aa674f7000000000000000000000000edf8efa1e46c8a76535d0498ecf2751f99320902000000000000000000000000000000000000000000000000000000000000c350

Deployed Bytecode

0x60806040526004361061038c5760003560e01c80636f4f7366116101dc578063c002d23d11610102578063e05c57bf116100a0578063f0f442601161006f578063f0f4426014610bb7578063f2fde38b14610bd7578063f47c84c514610bf7578063f4a0a52814610c2b57600080fd5b8063e05c57bf14610a7f578063e1fc334f14610b2e578063e985e9c514610b4e578063ed0b0e1314610b9757600080fd5b8063d289ce70116100dc578063d289ce70146109e9578063d51f39b914610a09578063d59f08b314610a3f578063de0e408a14610a5f57600080fd5b8063c002d23d1461099d578063c084f540146109b3578063c87b56dd146109c957600080fd5b806394e568471161017a578063a22cb46511610149578063a22cb46514610911578063b6fccf8a14610931578063b88d4fde14610947578063bb71f6ba1461096757600080fd5b806394e568471461083357806395d89b41146108bc578063a0712d68146108d1578063a1b8f374146108e457600080fd5b80637e64c8fb116101b65780637e64c8fb146107b55780637ffc42a6146107d55780638466ee01146107f55780638da5cb5b1461081557600080fd5b80636f4f73661461076057806370a0823114610780578063715018a6146107a057600080fd5b80632f745c59116102c15780634437152a1161025f578063562349951161022e57806356234995146106e15780635c975abb146107015780636352211e146107205780636c7b09b21461074057600080fd5b80634437152a1461065257806345f7e06e146106725780634f02c420146106935780634f6ccce7146106c157600080fd5b8063368383911161029b57806336838391146105e85780633ccfd60b146106085780634018b1f81461061d57806342842e0e1461063257600080fd5b80632f745c591461057657806333df4b2c146105965780633431a753146105c857600080fd5b806316f0115b1161032e578063215a416311610308578063215a4163146104f657806323b872dd1461051657806327de8f27146105365780632af177bc1461055657600080fd5b806316f0115b146104a257806318160ddd146104c25780631e71ccb1146104e157600080fd5b8063092576761161036a5780630925767614610420578063095ea7b3146104425780630efd09731461046257806316c38b3c1461048257600080fd5b806301ffc9a71461039157806306fdde03146103c6578063081812fc146103e8575b600080fd5b34801561039d57600080fd5b506103b16103ac366004613283565b610c4b565b60405190151581526020015b60405180910390f35b3480156103d257600080fd5b506103db610c76565b6040516103bd91906132f8565b3480156103f457600080fd5b5061040861040336600461330b565b610d08565b6040516001600160a01b0390911681526020016103bd565b34801561042c57600080fd5b5061044061043b366004613339565b610da2565b005b34801561044e57600080fd5b5061044061045d366004613356565b610dee565b34801561046e57600080fd5b50600d54610408906001600160a01b031681565b34801561048e57600080fd5b5061044061049d366004613397565b610f04565b3480156104ae57600080fd5b50600e54610408906001600160a01b031681565b3480156104ce57600080fd5b506008545b6040519081526020016103bd565b3480156104ed57600080fd5b50610408610f47565b34801561050257600080fd5b506014546103b19062010000900460ff1681565b34801561052257600080fd5b506104406105313660046133b2565b610f84565b34801561054257600080fd5b506104d361055136600461330b565b610fd0565b34801561056257600080fd5b50610440610571366004613339565b611090565b34801561058257600080fd5b506104d3610591366004613356565b6110dc565b3480156105a257600080fd5b506105b66105b13660046133f3565b611172565b60405160ff90911681526020016103bd565b3480156105d457600080fd5b506104406105e336600461330b565b6111b8565b3480156105f457600080fd5b506105b66106033660046133f3565b6111e7565b34801561061457600080fd5b506104406111f7565b34801561062957600080fd5b506013546104d3565b34801561063e57600080fd5b5061044061064d3660046133b2565b61125a565b34801561065e57600080fd5b5061044061066d366004613339565b611275565b34801561067e57600080fd5b506014546103b1906301000000900460ff1681565b34801561069f57600080fd5b506014546106ae9061ffff1681565b60405161ffff90911681526020016103bd565b3480156106cd57600080fd5b506104d36106dc36600461330b565b6112c1565b3480156106ed57600080fd5b506104406106fc366004613339565b611354565b34801561070d57600080fd5b50600a54600160a01b900460ff166103b1565b34801561072c57600080fd5b5061040861073b36600461330b565b6113a0565b34801561074c57600080fd5b5061044061075b366004613339565b611417565b34801561076c57600080fd5b5061044061077b366004613339565b611463565b34801561078c57600080fd5b506104d361079b366004613339565b6114af565b3480156107ac57600080fd5b50610440611536565b3480156107c157600080fd5b50600f54610408906001600160a01b031681565b3480156107e157600080fd5b50600c54610408906001600160a01b031681565b34801561080157600080fd5b50601054610408906001600160a01b031681565b34801561082157600080fd5b50600a546001600160a01b0316610408565b34801561083f57600080fd5b5061085361084e36600461330b565b61156c565b6040516103bd9190600060e082019050825115158252602083015160ff80821660208501528060408601511660408501528060608601511660608501528060808601511660808501528060a08601511660a08501528060c08601511660c0850152505092915050565b3480156108c857600080fd5b506103db6115f5565b6104406108df36600461330b565b611604565b3480156108f057600080fd5b506104d36108ff36600461330b565b60176020526000908152604090205481565b34801561091d57600080fd5b5061044061092c366004613415565b6119e4565b34801561093d57600080fd5b506104d360155481565b34801561095357600080fd5b506104406109623660046134b9565b611aa9565b34801561097357600080fd5b5061040861098236600461330b565b6019602052600090815260409020546001600160a01b031681565b3480156109a957600080fd5b506104d360125481565b3480156109bf57600080fd5b506104d360135481565b3480156109d557600080fd5b506103db6109e436600461330b565b611ae1565b3480156109f557600080fd5b50610440610a0436600461330b565b611bd1565b348015610a1557600080fd5b50610408610a2436600461330b565b6018602052600090815260409020546001600160a01b031681565b348015610a4b57600080fd5b50610440610a5a366004613568565b611c00565b348015610a6b57600080fd5b50610440610a7a366004613604565b611c5c565b348015610a8b57600080fd5b50610aed610a9a36600461330b565b60166020526000908152604090205460ff808216916101008104821691620100008204811691630100000081048216916401000000008204811691650100000000008104821691600160301b9091041687565b60408051971515885260ff968716602089015294861694870194909452918416606086015283166080850152821660a08401521660c082015260e0016103bd565b348015610b3a57600080fd5b50601154610408906001600160a01b031681565b348015610b5a57600080fd5b506103b1610b69366004613668565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610ba357600080fd5b50610440610bb2366004613339565b612091565b348015610bc357600080fd5b50610440610bd2366004613339565b6120dd565b348015610be357600080fd5b50610440610bf2366004613339565b612129565b348015610c0357600080fd5b506104d37f000000000000000000000000000000000000000000000000000000000000c35081565b348015610c3757600080fd5b50610440610c4636600461330b565b6121c1565b60006001600160e01b0319821663780e9d6360e01b1480610c705750610c70826121f0565b92915050565b606060008054610c85906136a1565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb1906136a1565b8015610cfe5780601f10610cd357610100808354040283529160200191610cfe565b820191906000526020600020905b815481529060010190602001808311610ce157829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610d865760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600a546001600160a01b03163314610dcc5760405162461bcd60e51b8152600401610d7d906136dc565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610df9826113a0565b9050806001600160a01b0316836001600160a01b03161415610e675760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610d7d565b336001600160a01b0382161480610e835750610e838133610b69565b610ef55760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610d7d565b610eff8383612240565b505050565b600a546001600160a01b03163314610f2e5760405162461bcd60e51b8152600401610d7d906136dc565b8015610f3f57610f3c6122ae565b50565b610f3c612330565b600a546000906001600160a01b03163314610f745760405162461bcd60e51b8152600401610d7d906136dc565b506032546001600160a01b031690565b600f546001600160a01b0316336001600160a01b031614610fc557610fa933826123b4565b610fc55760405162461bcd60e51b8152600401610d7d90613711565b610eff8383836124ab565b60006013548211610fe357506000919050565b60056110107f000000000000000000000000000000000000000000000000000000000000c3506002613778565b61101a91906137ad565b8211611031575069043c33c1937564800000919050565b600561105e7f000000000000000000000000000000000000000000000000000000000000c3506004613778565b61106891906137ad565b821161107f5750690878678326eac9000000919050565b506910f0cf064dd592000000919050565b600a546001600160a01b031633146110ba5760405162461bcd60e51b8152600401610d7d906136dc565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60006110e7836114af565b82106111495760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610d7d565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b601a82600c811061118257600080fd5b01818154811061119157600080fd5b9060005260206000209060209182820401919006915091509054906101000a900460ff1681565b600a546001600160a01b031633146111e25760405162461bcd60e51b8152600401610d7d906136dc565b601355565b602682600c811061118257600080fd5b600a546001600160a01b031633146112215760405162461bcd60e51b8152600401610d7d906136dc565b6032546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610f3c573d6000803e3d6000fd5b610eff83838360405180602001604052806000815250611aa9565b600a546001600160a01b0316331461129f5760405162461bcd60e51b8152600401610d7d906136dc565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b60006112cc60085490565b821061132f5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610d7d565b60088281548110611342576113426137c1565b90600052602060002001549050919050565b600a546001600160a01b0316331461137e5760405162461bcd60e51b8152600401610d7d906136dc565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600260205260408120546001600160a01b031680610c705760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610d7d565b600a546001600160a01b031633146114415760405162461bcd60e51b8152600401610d7d906136dc565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b0316331461148d5760405162461bcd60e51b8152600401610d7d906136dc565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b03821661151a5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610d7d565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146115605760405162461bcd60e51b8152600401610d7d906136dc565b61156a6000612656565b565b611574613231565b50600090815260166020908152604091829020825160e081018452905460ff8082161515835261010082048116938301939093526201000081048316938201939093526301000000830482166060820152640100000000830482166080820152650100000000008304821660a0820152600160301b9092041660c082015290565b606060018054610c85906136a1565b600a54600160a01b900460ff161561162e5760405162461bcd60e51b8152600401610d7d906137d7565b3233146116685760405162461bcd60e51b81526020600482015260086024820152674f6e6c7920454f4160c01b6044820152606401610d7d565b6014546301000000900460ff166116b65760405162461bcd60e51b81526020600482015260126024820152711b9bdd081bdc195b88199c9959481b5a5b9d60721b6044820152606401610d7d565b6014547f000000000000000000000000000000000000000000000000000000000000c350906116ea90839061ffff16613801565b111561172c5760405162461bcd60e51b8152602060048201526011602482015270105b1b081d1bdad95b9cc81b5a5b9d1959607a1b6044820152606401610d7d565b60008111801561173d5750600a8111155b61177f5760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610d7d565b60135460145461ffff16101561184c576013546014546117a490839061ffff16613801565b11156117f25760405162461bcd60e51b815260206004820152601f60248201527f416c6c20746f6b656e73206f6e2d73616c6520616c726561647920736f6c64006044820152606401610d7d565b34601254826118019190613778565b146118475760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c185e5b595b9d08185b5bdd5b9d60521b6044820152606401610d7d565b611857565b341561185757600080fd5b600080805b83811015611966576014805461ffff1690600061187883613819565b82546101009290920a61ffff818102199093169183160217909155600b5460145460405163b863bd3760e01b8152921660048301526001600160a01b0316915063b863bd3790602401602060405180830381865afa1580156118de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611902919061383b565b9150600061190f836126a8565b60145490915061192490829061ffff166127fc565b6014546119359061ffff168461281a565b506014546119469061ffff16610fd0565b6119509085613801565b935050808061195e90613854565b91505061185c565b508115610eff576010546001600160a01b0316639dc29fac336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401600060405180830381600087803b1580156119c757600080fd5b505af11580156119db573d6000803e3d6000fd5b50505050505050565b6001600160a01b038216331415611a3d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d7d565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611ab333836123b4565b611acf5760405162461bcd60e51b8152600401610d7d90613711565b611adb848484846129b8565b50505050565b6000818152600260205260409020546060906001600160a01b0316611b605760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610d7d565b60115460405163c87b56dd60e01b8152600481018490526001600160a01b039091169063c87b56dd90602401600060405180830381865afa158015611ba9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c70919081019061386f565b600a546001600160a01b03163314611bfb5760405162461bcd60e51b8152600401610d7d906136dc565b601555565b600a546001600160a01b03163314611c2a5760405162461bcd60e51b8152600401610d7d906136dc565b6014805463ffff00001916620100009315159390930263ff000000191692909217630100000091151591909102179055565b600a54600160a01b900460ff1615611c865760405162461bcd60e51b8152600401610d7d906137d7565b323314611cc05760405162461bcd60e51b81526020600482015260086024820152674f6e6c7920454f4160c01b6044820152606401610d7d565b60145462010000900460ff16611d0d5760405162461bcd60e51b81526020600482015260126024820152711b9bdd081bdc195b88199c9959481b5a5b9d60721b6044820152606401610d7d565b600a81518351611d1d9190613801565b1115611d615760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610d7d565b805182516014547f000000000000000000000000000000000000000000000000000000000000c3509291611d989161ffff16613801565b611da29190613801565b1115611de45760405162461bcd60e51b8152602060048201526011602482015270105b1b081d1bdad95b9cc81b5a5b9d1959607a1b6044820152606401610d7d565b6000805b8351811015611f06576000848281518110611e0557611e056137c1565b60200260200101519050611e163390565b600c546040516331a9108f60e11b8152600481018490526001600160a01b039283169290911690636352211e90602401602060405180830381865afa158015611e63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8791906138dd565b6001600160a01b03161415611ef3576000818152601860205260409020546001600160a01b0316611ef35782611ebc81613854565b935050611ec63390565b600082815260186020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b5080611efe81613854565b915050611de8565b5060005b8251811015612028576000838281518110611f2757611f276137c1565b60200260200101519050611f383390565b600d546040516331a9108f60e11b8152600481018490526001600160a01b039283169290911690636352211e90602401602060405180830381865afa158015611f85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa991906138dd565b6001600160a01b03161415612015576000818152601960205260409020546001600160a01b03166120155782611fde81613854565b935050611fe83390565b600082815260196020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b508061202081613854565b915050611f0a565b50600081116120885760405162461bcd60e51b815260206004820152602660248201527f54686520736869626120696e20796f75722077616c6c657420686173206265656044820152651b881b5a5b9d60d21b6064820152608401610d7d565b610eff816129eb565b600a546001600160a01b031633146120bb5760405162461bcd60e51b8152600401610d7d906136dc565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b031633146121075760405162461bcd60e51b8152600401610d7d906136dc565b603280546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b031633146121535760405162461bcd60e51b8152600401610d7d906136dc565b6001600160a01b0381166121b85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d7d565b610f3c81612656565b600a546001600160a01b031633146121eb5760405162461bcd60e51b8152600401610d7d906136dc565b601255565b60006001600160e01b031982166380ac58cd60e01b148061222157506001600160e01b03198216635b5e139f60e01b145b80610c7057506301ffc9a760e01b6001600160e01b0319831614610c70565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612275826113a0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600160a01b900460ff16156122d85760405162461bcd60e51b8152600401610d7d906137d7565b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586123133390565b6040516001600160a01b03909116815260200160405180910390a1565b600a54600160a01b900460ff166123805760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610d7d565b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33612313565b6000818152600260205260408120546001600160a01b031661242d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610d7d565b6000612438836113a0565b9050806001600160a01b0316846001600160a01b031614806124735750836001600160a01b031661246884610d08565b6001600160a01b0316145b806124a357506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166124be826113a0565b6001600160a01b0316146125265760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610d7d565b6001600160a01b0382166125885760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d7d565b612593838383612af5565b61259e600082612240565b6001600160a01b03831660009081526003602052604081208054600192906125c79084906138fa565b90915550506001600160a01b03821660009081526003602052604081208054600192906125f5908490613801565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600e54600090600a9082906001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061272a919061383b565b9050601554811061273a57600591505b60135460145461ffff16111580612762575061ffff8216612760606460f587901c613911565b115b156127705733949350505050565b600f54604051631e4c4f3560e11b8152609086901c60048201526000916001600160a01b031690633c989e6a90602401602060405180830381865afa1580156127bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e191906138dd565b90506001600160a01b0381166124a357335b95945050505050565b612816828260405180602001604052806000815250612bad565b5050565b612822613231565b61282b82612be0565b90506017600061283a83612ce6565b815260200190815260200160002054600014156129395760008381526016602090815260408083208451815493860151928601516060870151608088015160a089015160c08a015161ffff1990981694151561ff0019169490941761010060ff978816021763ffff00001916620100009387169390930263ff0000001916929092176301000000918616919091021765ffff0000000019166401000000009185169190910265ff000000000019161765010000000000918416919091021766ff0000000000001916600160301b9290931691909102919091179055839060179061292384612ce6565b8152602081019190915260400160002055610c70565b600b5460405163b863bd3760e01b8152600481018490526129b19185916001600160a01b039091169063b863bd3790602401602060405180830381865afa158015612988573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ac919061383b565b61281a565b9392505050565b6129c38484846124ab565b6129cf84848484612d79565b611adb5760405162461bcd60e51b8152600401610d7d90613925565b600a54600160a01b900460ff1615612a155760405162461bcd60e51b8152600401610d7d906137d7565b6000805b82811015610eff576014805461ffff16906000612a3583613819565b82546101009290920a61ffff818102199093169183160217909155600b5460145460405163b863bd3760e01b8152921660048301526001600160a01b0316915063b863bd3790602401602060405180830381865afa158015612a9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612abf919061383b565b9150612ad13360145461ffff166127fc565b601454612ae29061ffff168361281a565b5080612aed81613854565b915050612a19565b6001600160a01b038316612b5057612b4b81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612b73565b816001600160a01b0316836001600160a01b031614612b7357612b738382612e77565b6001600160a01b038216612b8a57610eff81612f14565b826001600160a01b0316826001600160a01b031614610eff57610eff8282612fc3565b612bb78383613007565b612bc46000848484612d79565b610eff5760405162461bcd60e51b8152600401610d7d90613925565b612be8613231565b612bf7600a61ffff8416613911565b1515808252600090612c0a576006612c0d565b60005b60109390931c929050612c2e61ffff8416612c29836000613977565b613155565b60ff16602083015260109290921c91612c5061ffff8416612c29836001613977565b60ff16604083015260109290921c91612c7261ffff8416612c29836002613977565b60ff16606083015260109290921c91612c9461ffff8416612c29836003613977565b60ff16608083015260109290921c91612cb661ffff8416612c29836004613977565b60ff1660a083015260109290921c91612cd861ffff8416612c29836005613977565b60ff1660c083015250919050565b80516020808301516040808501516060860151608087015160a088015160c0890151945197151560f890811b978901979097526001600160f81b031995871b8616602189015292861b8516602288015290851b84166023870152841b83166024860152831b8216602585015290911b166026820152600090602701604051602081830303815290604052610c709061399c565b60006001600160a01b0384163b15612e6c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612dbd9033908990889088906004016139c0565b6020604051808303816000875af1925050508015612df8575060408051601f3d908101601f19168201909252612df5918101906139fd565b60015b612e52573d808015612e26576040519150601f19603f3d011682016040523d82523d6000602084013e612e2b565b606091505b508051612e4a5760405162461bcd60e51b8152600401610d7d90613925565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506124a3565b506001949350505050565b60006001612e84846114af565b612e8e91906138fa565b600083815260076020526040902054909150808214612ee1576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612f26906001906138fa565b60008381526009602052604081205460088054939450909284908110612f4e57612f4e6137c1565b906000526020600020015490508060088381548110612f6f57612f6f6137c1565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612fa757612fa7613a1a565b6001900381819060005260206000200160009055905550505050565b6000612fce836114af565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b03821661305d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d7d565b6000818152600260205260409020546001600160a01b0316156130c25760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d7d565b6130ce60008383612af5565b6001600160a01b03821660009081526003602052604081208054600192906130f7908490613801565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600080601a8360ff16600c811061316e5761316e6137c1565b015461317a9085613a30565b9050601a8360ff16600c8110613192576131926137c1565b018160ff16815481106131a7576131a76137c1565b60009182526020918290209181049091015460ff601f9092166101000a90048116600886901c90911610156131dd579050610c70565b60268360ff16600c81106131f3576131f36137c1565b018160ff1681548110613208576132086137c1565b90600052602060002090602091828204019190069054906101000a900460ff1691505092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b6001600160e01b031981168114610f3c57600080fd5b60006020828403121561329557600080fd5b81356129b18161326d565b60005b838110156132bb5781810151838201526020016132a3565b83811115611adb5750506000910152565b600081518084526132e48160208601602086016132a0565b601f01601f19169290920160200192915050565b6020815260006129b160208301846132cc565b60006020828403121561331d57600080fd5b5035919050565b6001600160a01b0381168114610f3c57600080fd5b60006020828403121561334b57600080fd5b81356129b181613324565b6000806040838503121561336957600080fd5b823561337481613324565b946020939093013593505050565b8035801515811461339257600080fd5b919050565b6000602082840312156133a957600080fd5b6129b182613382565b6000806000606084860312156133c757600080fd5b83356133d281613324565b925060208401356133e281613324565b929592945050506040919091013590565b6000806040838503121561340657600080fd5b50508035926020909101359150565b6000806040838503121561342857600080fd5b823561343381613324565b915061344160208401613382565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156134895761348961344a565b604052919050565b600067ffffffffffffffff8211156134ab576134ab61344a565b50601f01601f191660200190565b600080600080608085870312156134cf57600080fd5b84356134da81613324565b935060208501356134ea81613324565b925060408501359150606085013567ffffffffffffffff81111561350d57600080fd5b8501601f8101871361351e57600080fd5b803561353161352c82613491565b613460565b81815288602083850101111561354657600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000806040838503121561357b57600080fd5b61343383613382565b600082601f83011261359557600080fd5b8135602067ffffffffffffffff8211156135b1576135b161344a565b8160051b6135c0828201613460565b92835284810182019282810190878511156135da57600080fd5b83870192505b848310156135f9578235825291830191908301906135e0565b979650505050505050565b6000806040838503121561361757600080fd5b823567ffffffffffffffff8082111561362f57600080fd5b61363b86838701613584565b9350602085013591508082111561365157600080fd5b5061365e85828601613584565b9150509250929050565b6000806040838503121561367b57600080fd5b823561368681613324565b9150602083013561369681613324565b809150509250929050565b600181811c908216806136b557607f821691505b602082108114156136d657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561379257613792613762565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826137bc576137bc613797565b500490565b634e487b7160e01b600052603260045260246000fd5b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6000821982111561381457613814613762565b500190565b600061ffff8083168181141561383157613831613762565b6001019392505050565b60006020828403121561384d57600080fd5b5051919050565b600060001982141561386857613868613762565b5060010190565b60006020828403121561388157600080fd5b815167ffffffffffffffff81111561389857600080fd5b8201601f810184136138a957600080fd5b80516138b761352c82613491565b8181528560208385010111156138cc57600080fd5b6127f38260208301602086016132a0565b6000602082840312156138ef57600080fd5b81516129b181613324565b60008282101561390c5761390c613762565b500390565b60008261392057613920613797565b500690565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600060ff821660ff84168060ff0382111561399457613994613762565b019392505050565b805160208083015191908110156136d65760001960209190910360031b1b16919050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906139f3908301846132cc565b9695505050505050565b600060208284031215613a0f57600080fd5b81516129b18161326d565b634e487b7160e01b600052603160045260246000fd5b600060ff831680613a4357613a43613797565b8060ff8416069150509291505056fea26469706673582212203003fa8fe352f01d73828bcc2dbc78ea147e00f0a18d2670d205e5960c602de864736f6c634300080a0033

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

0000000000000000000000006fd2ba29a23e61759035b4b28b245c7dbd6e00b90000000000000000000000006fd2ba29a23e61759035b4b28b245c7dbd6e00b9000000000000000000000000df7cafb1449e62aa6ba35afb8f692feb67356e2500000000000000000000000048c58b8496642bc4c860c7efc13813b73aa674f7000000000000000000000000edf8efa1e46c8a76535d0498ecf2751f99320902000000000000000000000000000000000000000000000000000000000000c350

-----Decoded View---------------
Arg [0] : _peach (address): 0x6fd2BA29A23e61759035B4b28B245C7dbd6e00b9
Arg [1] : _traits (address): 0x6fd2BA29A23e61759035B4b28B245C7dbd6e00b9
Arg [2] : _bamc (address): 0xdf7cafB1449e62aA6bA35afB8F692Feb67356E25
Arg [3] : _club (address): 0x48C58B8496642Bc4C860c7eFC13813B73aA674F7
Arg [4] : _treasury (address): 0xedF8eFA1E46c8A76535D0498ecf2751F99320902
Arg [5] : _maxTokens (uint256): 50000

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000006fd2ba29a23e61759035b4b28b245c7dbd6e00b9
Arg [1] : 0000000000000000000000006fd2ba29a23e61759035b4b28b245c7dbd6e00b9
Arg [2] : 000000000000000000000000df7cafb1449e62aa6ba35afb8f692feb67356e25
Arg [3] : 00000000000000000000000048c58b8496642bc4c860c7efc13813b73aa674f7
Arg [4] : 000000000000000000000000edf8efa1e46c8a76535d0498ecf2751f99320902
Arg [5] : 000000000000000000000000000000000000000000000000000000000000c350


Deployed Bytecode Sourcemap

779:13365:20:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;873:213:5;;;;;;;;;;-1:-1:-1;873:213:5;;;;;:::i;:::-;;:::i;:::-;;;565:14:21;;558:22;540:41;;528:2;513:18;873:213:5;;;;;;;;2160:89:4;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3496:202::-;;;;;;;;;;-1:-1:-1;3496:202:4;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:21;;;1674:51;;1662:2;1647:18;3496:202:4;1528:203:21;12775:111:20;;;;;;;;;;-1:-1:-1;12775:111:20;;;;;:::i;:::-;;:::i;:::-;;3107:340:4;;;;;;;;;;-1:-1:-1;3107:340:4;;;;;:::i;:::-;;:::i;898:27:20:-;;;;;;;;;;-1:-1:-1;898:27:20;;;;-1:-1:-1;;;;;898:27:20;;;13639:100;;;;;;;;;;-1:-1:-1;13639:100:20;;;;;:::i;:::-;;:::i;928:16::-;;;;;;;;;;-1:-1:-1;928:16:20;;;;-1:-1:-1;;;;;928:16:20;;;1450:102:5;;;;;;;;;;-1:-1:-1;1531:10:5;:17;1450:102;;;3393:25:21;;;3381:2;3366:18;1450:102:5;3247:177:21;13147:96:20;;;;;;;;;;;;;:::i;1547:32::-;;;;;;;;;;-1:-1:-1;1547:32:20;;;;;;;;;;;8361:365;;;;;;;;;;-1:-1:-1;8361:365:20;;;;;:::i;:::-;;:::i;8109:249::-;;;;;;;;;;-1:-1:-1;8109:249:20;;;;;:::i;:::-;;:::i;12557:101::-;;;;;;;;;;-1:-1:-1;12557:101:20;;;;;:::i;:::-;;:::i;1153:238:5:-;;;;;;;;;;-1:-1:-1;1153:238:5;;;;;:::i;:::-;;:::i;2190:27:20:-;;;;;;;;;;-1:-1:-1;2190:27:20;;;;;:::i;:::-;;:::i;:::-;;;4315:4:21;4303:17;;;4285:36;;4273:2;4258:18;2190:27:20;4143:184:21;13298:96:20;;;;;;;;;;-1:-1:-1;13298:96:20;;;;;:::i;:::-;;:::i;2338:26::-;;;;;;;;;;-1:-1:-1;2338:26:20;;;;;:::i;:::-;;:::i;13040:104::-;;;;;;;;;;;;;:::i;12053:83::-;;;;;;;;;;-1:-1:-1;12121:11:20;;12053:83;;4621:149:4;;;;;;;;;;-1:-1:-1;4621:149:4;;;;;:::i;:::-;;:::i;12477:77:20:-;;;;;;;;;;-1:-1:-1;12477:77:20;;;;;:::i;:::-;;:::i;1582:34::-;;;;;;;;;;-1:-1:-1;1582:34:20;;;;;;;;;;;1519:24;;;;;;;;;;-1:-1:-1;1519:24:20;;;;;;;;;;;4506:6:21;4494:19;;;4476:38;;4464:2;4449:18;1519:24:20;4332:188:21;1612:215:5;;;;;;;;;;-1:-1:-1;1612:215:5;;;;;:::i;:::-;;:::i;12661:111:20:-;;;;;;;;;;-1:-1:-1;12661:111:20;;;;;:::i;:::-;;:::i;974:75:18:-;;;;;;;;;;-1:-1:-1;1038:7:18;;-1:-1:-1;;;1038:7:18;;;;974:75;;1896:214:4;;;;;;;;;;-1:-1:-1;1896:214:4;;;;;:::i;:::-;;:::i;12377:97:20:-;;;;;;;;;;-1:-1:-1;12377:97:20;;;;;:::i;:::-;;:::i;12889:90::-;;;;;;;;;;-1:-1:-1;12889:90:20;;;;;:::i;:::-;;:::i;1661:190:4:-;;;;;;;;;;-1:-1:-1;1661:190:4;;;;;:::i;:::-;;:::i;1499:83:17:-;;;;;;;;;;;;;:::i;1008:21:20:-;;;;;;;;;;-1:-1:-1;1008:21:20;;;;-1:-1:-1;;;;;1008:21:20;;;868:27;;;;;;;;;;-1:-1:-1;868:27:20;;;;-1:-1:-1;;;;;868:27:20;;;1082:30;;;;;;;;;;-1:-1:-1;1082:30:20;;;;-1:-1:-1;;;;;1082:30:20;;;927:76:17;;;;;;;;;;-1:-1:-1;993:6:17;;-1:-1:-1;;;;;993:6:17;927:76;;11928:122:20;;;;;;;;;;-1:-1:-1;11928:122:20;;;;;:::i;:::-;;:::i;:::-;;;;;;5351:4:21;5393:3;5382:9;5378:19;5370:27;;5444:6;5438:13;5431:21;5424:29;5413:9;5406:48;5501:4;5493:6;5489:17;5483:24;5526:4;5586:2;5572:12;5568:21;5561:4;5550:9;5546:20;5539:51;5658:2;5650:4;5642:6;5638:17;5632:24;5628:33;5621:4;5610:9;5606:20;5599:63;5730:2;5722:4;5714:6;5710:17;5704:24;5700:33;5693:4;5682:9;5678:20;5671:63;5802:2;5794:4;5786:6;5782:17;5776:24;5772:33;5765:4;5754:9;5750:20;5743:63;5874:2;5866:4;5858:6;5854:17;5848:24;5844:33;5837:4;5826:9;5822:20;5815:63;5946:2;5938:4;5930:6;5926:17;5920:24;5916:33;5909:4;5898:9;5894:20;5887:63;;;5209:747;;;;;2301:93:4;;;;;;;;;;;;;:::i;5694:872:20:-;;;;;;:::i;:::-;;:::i;1891:55::-;;;;;;;;;;-1:-1:-1;1891:55:20;;;;;:::i;:::-;;;;;;;;;;;;;;3753:269:4;;;;;;;;;;-1:-1:-1;3753:269:4;;;;;:::i;:::-;;:::i;1620:29:20:-;;;;;;;;;;;;;;;;4824:278:4;;;;;;;;;;-1:-1:-1;4824:278:4;;;;;:::i;:::-;;:::i;2012:59:20:-;;;;;;;;;;-1:-1:-1;2012:59:20;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;2012:59:20;;;1226:42;;;;;;;;;;;;;;;;1445:26;;;;;;;;;;;;;;;;13845:199;;;;;;;;;;-1:-1:-1;13845:199:20;;;;;:::i;:::-;;:::i;13397:63::-;;;;;;;;;;-1:-1:-1;13397:63:20;;;;;:::i;:::-;;:::i;1950:59::-;;;;;;;;;;-1:-1:-1;1950:59:20;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;1950:59:20;;;13463:118;;;;;;;;;;-1:-1:-1;13463:118:20;;;;;:::i;:::-;;:::i;6569:1034::-;;;;;;;;;;-1:-1:-1;6569:1034:20;;;;;:::i;:::-;;:::i;1720:53::-;;;;;;;;;;-1:-1:-1;1720:53:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1720:53:20;;;;;;;;;;9785:14:21;;9778:22;9760:41;;9820:4;9860:15;;;9855:2;9840:18;;9833:43;9912:15;;;9892:18;;;9885:43;;;;9964:15;;;9959:2;9944:18;;9937:43;10017:15;;10011:3;9996:19;;9989:44;10070:15;;10064:3;10049:19;;10042:44;10123:15;10117:3;10102:19;;10095:44;9747:3;9732:19;1720:53:20;9475:670:21;1139:21:20;;;;;;;;;;-1:-1:-1;1139:21:20;;;;-1:-1:-1;;;;;1139:21:20;;;4076:153:4;;;;;;;;;;-1:-1:-1;4076:153:4;;;;;:::i;:::-;-1:-1:-1;;;;;4190:25:4;;;4173:4;4190:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4076:153;12286:88:20;;;;;;;;;;-1:-1:-1;12286:88:20;;;;;:::i;:::-;;:::i;14047:95::-;;;;;;;;;;-1:-1:-1;14047:95:20;;;;;:::i;:::-;;:::i;1716:174:17:-;;;;;;;;;;-1:-1:-1;1716:174:17;;;;;:::i;:::-;;:::i;1337:35:20:-;;;;;;;;;;;;;;;13758:84;;;;;;;;;;-1:-1:-1;13758:84:20;;;;;:::i;:::-;;:::i;873:213:5:-;975:4;-1:-1:-1;;;;;;992:50:5;;-1:-1:-1;;;992:50:5;;:90;;;1046:36;1070:11;1046:23;:36::i;:::-;985:97;873:213;-1:-1:-1;;873:213:5:o;2160:89:4:-;2214:13;2240:5;2233:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2160:89;:::o;3496:202::-;3572:7;6530:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6530:16:4;3585:73;;;;-1:-1:-1;;;3585:73:4;;11354:2:21;3585:73:4;;;11336:21:21;11393:2;11373:18;;;11366:30;11432:34;11412:18;;;11405:62;-1:-1:-1;;;11483:18:21;;;11476:42;11535:19;;3585:73:4;;;;;;;;;-1:-1:-1;3670:24:4;;;;:15;:24;;;;;;-1:-1:-1;;;;;3670:24:4;;3496:202::o;12775:111:20:-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;12850:4:20::1;:32:::0;;-1:-1:-1;;;;;;12850:32:20::1;-1:-1:-1::0;;;;;12850:32:20;;;::::1;::::0;;;::::1;::::0;;12775:111::o;3107:340:4:-;3181:13;3197:23;3212:7;3197:14;:23::i;:::-;3181:39;;3238:5;-1:-1:-1;;;;;3232:11:4;:2;-1:-1:-1;;;;;3232:11:4;;;3224:57;;;;-1:-1:-1;;;3224:57:4;;12128:2:21;3224:57:4;;;12110:21:21;12167:2;12147:18;;;12140:30;12206:34;12186:18;;;12179:62;-1:-1:-1;;;12257:18:21;;;12250:31;12298:19;;3224:57:4;11926:397:21;3224:57:4;657:10:1;-1:-1:-1;;;;;3294:21:4;;;;:62;;-1:-1:-1;3319:37:4;3336:5;657:10:1;4076:153:4;:::i;3319:37::-;3286:131;;;;-1:-1:-1;;;3286:131:4;;12530:2:21;3286:131:4;;;12512:21:21;12569:2;12549:18;;;12542:30;12608:34;12588:18;;;12581:62;12679:26;12659:18;;;12652:54;12723:19;;3286:131:4;12328:420:21;3286:131:4;3422:21;3431:2;3435:7;3422:8;:21::i;:::-;3177:270;3107:340;;:::o;13639:100:20:-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;13699:7:20::1;13695:40;;;13708:8;:6;:8::i;:::-;13639:100:::0;:::o;13695:40::-:1;13725:10;:8;:10::i;13147:96::-:0;993:6:17;;13203:7:20;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;-1:-1:-1;13223:16:20::1;::::0;-1:-1:-1;;;;;13223:16:20::1;13147:96:::0;:::o;8361:365::-;8575:6;;-1:-1:-1;;;;;8575:6:20;657:10:1;-1:-1:-1;;;;;8551:31:20;;8547:143;;8595:41;657:10:1;8628:7:20;8595:18;:41::i;:::-;8587:103;;;;-1:-1:-1;;;8587:103:20;;;;;;;:::i;:::-;8694:28;8704:4;8710:2;8714:7;8694:9;:28::i;8109:249::-;8165:7;8193:11;;8182:7;:22;8178:36;;-1:-1:-1;8213:1:20;;8109:249;-1:-1:-1;8109:249:20:o;8178:36::-;8252:1;8234:14;:10;8247:1;8234:14;:::i;:::-;8233:20;;;;:::i;:::-;8222:7;:31;8218:55;;-1:-1:-1;8262:11:20;;8109:249;-1:-1:-1;8109:249:20:o;8218:55::-;8311:1;8293:14;:10;8306:1;8293:14;:::i;:::-;8292:20;;;;:::i;:::-;8281:7;:31;8277:55;;-1:-1:-1;8321:11:20;;8109:249;-1:-1:-1;8109:249:20:o;8277:55::-;-1:-1:-1;8343:11:20;;8109:249;-1:-1:-1;8109:249:20:o;12557:101::-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;12621:10:20::1;:33:::0;;-1:-1:-1;;;;;;12621:33:20::1;-1:-1:-1::0;;;;;12621:33:20;;;::::1;::::0;;;::::1;::::0;;12557:101::o;1153:238:5:-;1250:7;1279:23;1296:5;1279:16;:23::i;:::-;1271:5;:31;1263:87;;;;-1:-1:-1;;;1263:87:5;;13935:2:21;1263:87:5;;;13917:21:21;13974:2;13954:18;;;13947:30;14013:34;13993:18;;;13986:62;-1:-1:-1;;;14064:18:21;;;14057:41;14115:19;;1263:87:5;13733:407:21;1263:87:5;-1:-1:-1;;;;;;1361:19:5;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;1153:238::o;2190:27:20:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;13298:96::-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;13365:11:20::1;:25:::0;13298:96::o;2338:26::-;;;;;;;;;;;13040:104;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;13091:16:20::1;::::0;13083:57:::1;::::0;-1:-1:-1;;;;;13091:16:20;;::::1;::::0;13118:21:::1;13083:57:::0;::::1;;;::::0;13091:16:::1;13083:57:::0;13091:16;13083:57;13118:21;13091:16;13083:57;::::1;;;;;;;;;;;;;::::0;::::1;;;;4621:149:4::0;4727:39;4744:4;4750:2;4754:7;4727:39;;;;;;;;;;;;:16;:39::i;12477:77:20:-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;12532:4:20::1;:18:::0;;-1:-1:-1;;;;;;12532:18:20::1;-1:-1:-1::0;;;;;12532:18:20;;;::::1;::::0;;;::::1;::::0;;12477:77::o;1612:215:5:-;1687:7;1716:30;1531:10;:17;;1450:102;1716:30;1708:5;:38;1700:95;;;;-1:-1:-1;;;1700:95:5;;14347:2:21;1700:95:5;;;14329:21:21;14386:2;14366:18;;;14359:30;14425:34;14405:18;;;14398:62;-1:-1:-1;;;14476:18:21;;;14469:42;14528:19;;1700:95:5;14145:408:21;1700:95:5;1806:10;1817:5;1806:17;;;;;;;;:::i;:::-;;;;;;;;;1799:24;;1612:215;;;:::o;12661:111:20:-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;12736:4:20::1;:32:::0;;-1:-1:-1;;;;;;12736:32:20::1;-1:-1:-1::0;;;;;12736:32:20;;;::::1;::::0;;;::::1;::::0;;12661:111::o;1896:214:4:-;1968:7;1997:16;;;:7;:16;;;;;;-1:-1:-1;;;;;1997:16:4;2025:19;2017:73;;;;-1:-1:-1;;;2017:73:4;;14892:2:21;2017:73:4;;;14874:21:21;14931:2;14911:18;;;14904:30;14970:34;14950:18;;;14943:62;-1:-1:-1;;;15021:18:21;;;15014:39;15070:19;;2017:73:4;14690:405:21;12377:97:20;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;12436:11:20::1;:34:::0;;-1:-1:-1;;;;;;12436:34:20::1;-1:-1:-1::0;;;;;12436:34:20;;;::::1;::::0;;;::::1;::::0;;12377:97::o;12889:90::-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;12949:6:20::1;:26:::0;;-1:-1:-1;;;;;;12949:26:20::1;-1:-1:-1::0;;;;;12949:26:20;;;::::1;::::0;;;::::1;::::0;;12889:90::o;1661:190:4:-;1733:7;-1:-1:-1;;;;;1754:19:4;;1746:74;;;;-1:-1:-1;;;1746:74:4;;15302:2:21;1746:74:4;;;15284:21:21;15341:2;15321:18;;;15314:30;15380:34;15360:18;;;15353:62;-1:-1:-1;;;15431:18:21;;;15424:40;15481:19;;1746:74:4;15100:406:21;1746:74:4;-1:-1:-1;;;;;;1831:16:4;;;;;:9;:16;;;;;;;1661:190::o;1499:83:17:-;993:6;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;1557:21:::1;1575:1;1557:9;:21::i;:::-;1499:83::o:0;11928:122:20:-;11992:21;;:::i;:::-;-1:-1:-1;12026:20:20;;;;:11;:20;;;;;;;;;12019:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;12019:27:20;;;;;;;;;11928:122::o;2301:93:4:-;2357:13;2383:7;2376:14;;;;;:::i;5694:872:20:-;1038:7:18;;-1:-1:-1;;;1038:7:18;;;;1248:9;1240:38;;;;-1:-1:-1;;;1240:38:18;;;;;;;:::i;:::-;5767:9:20::1;657:10:1::0;5767:25:20::1;5759:46;;;::::0;-1:-1:-1;;;5759:46:20;;16058:2:21;5759:46:20::1;::::0;::::1;16040:21:21::0;16097:1;16077:18;;;16070:29;-1:-1:-1;;;16115:18:21;;;16108:38;16163:18;;5759:46:20::1;15856:331:21::0;5759:46:20::1;5817:14;::::0;;;::::1;;;5809:45;;;::::0;-1:-1:-1;;;5809:45:20;;16394:2:21;5809:45:20::1;::::0;::::1;16376:21:21::0;16433:2;16413:18;;;16406:30;-1:-1:-1;;;16452:18:21;;;16445:48;16510:18;;5809:45:20::1;16192:342:21::0;5809:45:20::1;5866:6;::::0;5885:10:::1;::::0;5866:15:::1;::::0;5875:6;;5866::::1;;:15;:::i;:::-;:29;;5858:59;;;::::0;-1:-1:-1;;;5858:59:20;;16874:2:21;5858:59:20::1;::::0;::::1;16856:21:21::0;16913:2;16893:18;;;16886:30;-1:-1:-1;;;16932:18:21;;;16925:47;16989:18;;5858:59:20::1;16672:341:21::0;5858:59:20::1;5938:1;5929:6;:10;:26;;;;;5953:2;5943:6;:12;;5929:26;5921:58;;;::::0;-1:-1:-1;;;5921:58:20;;17220:2:21;5921:58:20::1;::::0;::::1;17202:21:21::0;17259:2;17239:18;;;17232:30;-1:-1:-1;;;17278:18:21;;;17271:49;17337:18;;5921:58:20::1;17018:343:21::0;5921:58:20::1;5996:11;::::0;5987:6:::1;::::0;::::1;;:20;5983:221;;;6041:11;::::0;6022:6:::1;::::0;:15:::1;::::0;6031:6;;6022::::1;;:15;:::i;:::-;:30;;6014:74;;;::::0;-1:-1:-1;;;6014:74:20;;17568:2:21;6014:74:20::1;::::0;::::1;17550:21:21::0;17607:2;17587:18;;;17580:30;17646:33;17626:18;;;17619:61;17697:18;;6014:74:20::1;17366:355:21::0;6014:74:20::1;6124:9;6110:10;;6101:6;:19;;;;:::i;:::-;:32;6093:67;;;::::0;-1:-1:-1;;;6093:67:20;;17928:2:21;6093:67:20::1;::::0;::::1;17910:21:21::0;17967:2;17947:18;;;17940:30;-1:-1:-1;;;17986:18:21;;;17979:52;18048:18;;6093:67:20::1;17726:346:21::0;6093:67:20::1;5983:221;;;6184:9;:14:::0;6176:23:::1;;;::::0;::::1;;6208:21;::::0;;6254:236:::1;6278:6;6274:1;:10;6254:236;;;6296:6;:8:::0;;::::1;;::::0;:6:::1;:8;::::0;::::1;:::i;:::-;::::0;;::::1;::::0;;;::::1;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;;;::::0;;;6316:10:::1;::::0;6334:6:::1;::::0;6316:25:::1;::::0;-1:-1:-1;;;6316:25:20;;6334:6;::::1;6316:25;::::0;::::1;4476:38:21::0;-1:-1:-1;;;;;6316:10:20::1;::::0;-1:-1:-1;6316:17:20::1;::::0;4449:18:21;;6316:25:20::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6309:32;;6346:17;6366:21;6382:4;6366:15;:21::i;:::-;6413:6;::::0;6346:41;;-1:-1:-1;6392:28:20::1;::::0;6346:41;;6413:6:::1;;6392:9;:28::i;:::-;6434:6;::::0;6425:22:::1;::::0;6434:6:::1;;6442:4:::0;6425:8:::1;:22::i;:::-;-1:-1:-1::0;6478:6:20::1;::::0;6469:16:::1;::::0;6478:6:::1;;6469:8;:16::i;:::-;6452:33;::::0;;::::1;:::i;:::-;;;6291:199;6286:3;;;;;:::i;:::-;;;;6254:236;;;-1:-1:-1::0;6498:17:20;;6494:68:::1;;6517:11;::::0;-1:-1:-1;;;;;6517:11:20::1;:16;657:10:1::0;6517:45:20::1;::::0;-1:-1:-1;;;;;;6517:45:20::1;::::0;;;;;;-1:-1:-1;;;;;18994:32:21;;;6517:45:20::1;::::0;::::1;18976:51:21::0;19043:18;;;19036:34;;;18949:18;;6517:45:20::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;5755:811;;5694:872:::0;:::o;3753:269:4:-;-1:-1:-1;;;;;3849:24:4;;657:10:1;3849:24:4;;3841:62;;;;-1:-1:-1;;;3841:62:4;;19283:2:21;3841:62:4;;;19265:21:21;19322:2;19302:18;;;19295:30;19361:27;19341:18;;;19334:55;19406:18;;3841:62:4;19081:349:21;3841:62:4;657:10:1;3908:32:4;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;3908:42:4;;;;;;;;;;;;:53;;-1:-1:-1;;3908:53:4;;;;;;;;;;3970:48;;540:41:21;;;3908:42:4;;657:10:1;3970:48:4;;513:18:21;3970:48:4;;;;;;;3753:269;;:::o;4824:278::-;4960:41;657:10:1;4993:7:4;4960:18;:41::i;:::-;4952:103;;;;-1:-1:-1;;;4952:103:4;;;;;;;:::i;:::-;5059:39;5073:4;5079:2;5083:7;5092:5;5059:13;:39::i;:::-;4824:278;;;;:::o;13845:199:20:-;6513:4:4;6530:16;;;:7;:16;;;;;;13910:13:20;;-1:-1:-1;;;;;6530:16:4;13929:76:20;;;;-1:-1:-1;;;13929:76:20;;19637:2:21;13929:76:20;;;19619:21:21;19676:2;19656:18;;;19649:30;19715:34;19695:18;;;19688:62;-1:-1:-1;;;19766:18:21;;;19759:45;19821:19;;13929:76:20;19435:411:21;13929:76:20;14016:6;;:24;;-1:-1:-1;;;14016:24:20;;;;;3393:25:21;;;-1:-1:-1;;;;;14016:6:20;;;;:15;;3366:18:21;;14016:24:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14016:24:20;;;;;;;;;;;;:::i;13397:63::-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;13448:2:20::1;:8:::0;13397:63::o;13463:118::-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;13529:12:20::1;:20:::0;;-1:-1:-1;;13553:24:20;13529:20;;::::1;;::::0;;;::::1;-1:-1:-1::0;;13553:24:20;;;;;;;::::1;;::::0;;;::::1;;::::0;;13463:118::o;6569:1034::-;1038:7:18;;-1:-1:-1;;;1038:7:18;;;;1248:9;1240:38;;;;-1:-1:-1;;;1240:38:18;;;;;;;:::i;:::-;6674:9:20::1;657:10:1::0;6674:25:20::1;6666:46;;;::::0;-1:-1:-1;;;6666:46:20;;16058:2:21;6666:46:20::1;::::0;::::1;16040:21:21::0;16097:1;16077:18;;;16070:29;-1:-1:-1;;;16115:18:21;;;16108:38;16163:18;;6666:46:20::1;15856:331:21::0;6666:46:20::1;6724:12;::::0;;;::::1;;;6716:43;;;::::0;-1:-1:-1;;;6716:43:20;;16394:2:21;6716:43:20::1;::::0;::::1;16376:21:21::0;16433:2;16413:18;;;16406:30;-1:-1:-1;;;16452:18:21;;;16445:48;16510:18;;6716:43:20::1;16192:342:21::0;6716:43:20::1;6808:2;6789:7;:14;6772:7;:14;:31;;;;:::i;:::-;6771:39;;6763:71;;;::::0;-1:-1:-1;;;6763:71:20;;17220:2:21;6763:71:20::1;::::0;::::1;17202:21:21::0;17259:2;17239:18;;;17232:30;-1:-1:-1;;;17278:18:21;;;17271:49;17337:18;;6763:71:20::1;17018:343:21::0;6763:71:20::1;6873:14:::0;;6856;;6847:6:::1;::::0;6892:10:::1;::::0;6873:14;6847:23:::1;::::0;:6:::1;;:23;:::i;:::-;:40;;;;:::i;:::-;6846:56;;6838:86;;;::::0;-1:-1:-1;;;6838:86:20;;16874:2:21;6838:86:20::1;::::0;::::1;16856:21:21::0;16913:2;16893:18;;;16886:30;-1:-1:-1;;;16932:18:21;;;16925:47;16989:18;;6838:86:20::1;16672:341:21::0;6838:86:20::1;6929:17;6959:9:::0;6954:274:::1;6978:7;:14;6974:1;:18;6954:274;;;7004:15;7022:7;7030:1;7022:10;;;;;;;;:::i;:::-;;;;;;;7004:28;;7066:12;657:10:1::0;;584:87;7066:12:20::1;7041:4;::::0;:21:::1;::::0;-1:-1:-1;;;7041:21:20;;::::1;::::0;::::1;3393:25:21::0;;;-1:-1:-1;;;;;7041:37:20;;::::1;::::0;:4;;::::1;::::0;:12:::1;::::0;3366:18:21;;7041:21:20::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;7041:37:20::1;;7037:187;;;7135:1;7090:33:::0;;;:24:::1;:33;::::0;;;;;-1:-1:-1;;;;;7090:33:20::1;7086:133;;7146:11:::0;::::1;::::0;::::1;:::i;:::-;;;;7200:12;657:10:1::0;;584:87;7200:12:20::1;7164:33;::::0;;;:24:::1;:33;::::0;;;;:48;;-1:-1:-1;;;;;;7164:48:20::1;-1:-1:-1::0;;;;;7164:48:20;;;::::1;::::0;;;::::1;::::0;;7086:133:::1;-1:-1:-1::0;6994:3:20;::::1;::::0;::::1;:::i;:::-;;;;6954:274;;;;7237:9;7232:274;7256:7;:14;7252:1;:18;7232:274;;;7282:15;7300:7;7308:1;7300:10;;;;;;;;:::i;:::-;;;;;;;7282:28;;7344:12;657:10:1::0;;584:87;7344:12:20::1;7319:4;::::0;:21:::1;::::0;-1:-1:-1;;;7319:21:20;;::::1;::::0;::::1;3393:25:21::0;;;-1:-1:-1;;;;;7319:37:20;;::::1;::::0;:4;;::::1;::::0;:12:::1;::::0;3366:18:21;;7319:21:20::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;7319:37:20::1;;7315:187;;;7413:1;7368:33:::0;;;:24:::1;:33;::::0;;;;;-1:-1:-1;;;;;7368:33:20::1;7364:133;;7424:11:::0;::::1;::::0;::::1;:::i;:::-;;;;7478:12;657:10:1::0;;584:87;7478:12:20::1;7442:33;::::0;;;:24:::1;:33;::::0;;;;:48;;-1:-1:-1;;;;;;7442:48:20::1;-1:-1:-1::0;;;;;7442:48:20;;;::::1;::::0;;;::::1;::::0;;7364:133:::1;-1:-1:-1::0;7272:3:20;::::1;::::0;::::1;:::i;:::-;;;;7232:274;;;;7530:1;7518:9;:13;7510:64;;;::::0;-1:-1:-1;;;7510:64:20;;20949:2:21;7510:64:20::1;::::0;::::1;20931:21:21::0;20988:2;20968:18;;;20961:30;21027:34;21007:18;;;21000:62;-1:-1:-1;;;21078:18:21;;;21071:36;21124:19;;7510:64:20::1;20747:402:21::0;7510:64:20::1;7579:20;7589:9;7579;:20::i;12286:88::-:0;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;12345:6:20::1;:25:::0;;-1:-1:-1;;;;;;12345:25:20::1;-1:-1:-1::0;;;;;12345:25:20;;;::::1;::::0;;;::::1;::::0;;12286:88::o;14047:95::-;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;14110:16:20::1;:28:::0;;-1:-1:-1;;;;;;14110:28:20::1;-1:-1:-1::0;;;;;14110:28:20;;;::::1;::::0;;;::::1;::::0;;14047:95::o;1716:174:17:-;993:6;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;-1:-1:-1;;;;;1798:22:17;::::1;1790:73;;;::::0;-1:-1:-1;;;1790:73:17;;21356:2:21;1790:73:17::1;::::0;::::1;21338:21:21::0;21395:2;21375:18;;;21368:30;21434:34;21414:18;;;21407:62;-1:-1:-1;;;21485:18:21;;;21478:36;21531:19;;1790:73:17::1;21154:402:21::0;1790:73:17::1;1867:19;1877:8;1867:9;:19::i;13758:84:20:-:0;993:6:17;;-1:-1:-1;;;;;993:6:17;657:10:1;1112:23:17;1104:68;;;;-1:-1:-1;;;1104:68:17;;;;;;;:::i;:::-;13819:10:20::1;:19:::0;13758:84::o;1350:264:4:-;1452:4;-1:-1:-1;;;;;;1472:40:4;;-1:-1:-1;;;1472:40:4;;:95;;-1:-1:-1;;;;;;;1519:48:4;;-1:-1:-1;;;1519:48:4;1472:95;:138;;;-1:-1:-1;;;;;;;;;;853:40:2;;;1574:36:4;751:146:2;9830:156:4;9898:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;9898:29:4;-1:-1:-1;;;;;9898:29:4;;;;;;;;:24;;9945:23;9898:24;9945:14;:23::i;:::-;-1:-1:-1;;;;;9936:46:4;;;;;;;;;;;9830:156;;:::o;1628:100:18:-;1038:7;;-1:-1:-1;;;1038:7:18;;;;1248:9;1240:38;;;;-1:-1:-1;;;1240:38:18;;;;;;;:::i;:::-;1681:7:::1;:14:::0;;-1:-1:-1;;;;1681:14:18::1;-1:-1:-1::0;;;1681:14:18::1;::::0;;1704:20:::1;1711:12;657:10:1::0;;584:87;1711:12:18::1;1704:20;::::0;-1:-1:-1;;;;;1692:32:21;;;1674:51;;1662:2;1647:18;1704:20:18::1;;;;;;;1628:100::o:0;1836:102::-;1038:7;;-1:-1:-1;;;1038:7:18;;;;1467:41;;;;-1:-1:-1;;;1467:41:18;;21763:2:21;1467:41:18;;;21745:21:21;21802:2;21782:18;;;21775:30;-1:-1:-1;;;21821:18:21;;;21814:50;21881:18;;1467:41:18;21561:344:21;1467:41:18;1888:7:::1;:15:::0;;-1:-1:-1;;;;1888:15:18::1;::::0;;1912:22:::1;657:10:1::0;1921:12:18::1;584:87:1::0;6698:323:4;6791:4;6530:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6530:16:4;6801:73;;;;-1:-1:-1;;;6801:73:4;;22112:2:21;6801:73:4;;;22094:21:21;22151:2;22131:18;;;22124:30;22190:34;22170:18;;;22163:62;-1:-1:-1;;;22241:18:21;;;22234:42;22293:19;;6801:73:4;21910:408:21;6801:73:4;6878:13;6894:23;6909:7;6894:14;:23::i;:::-;6878:39;;6940:5;-1:-1:-1;;;;;6929:16:4;:7;-1:-1:-1;;;;;6929:16:4;;:51;;;;6973:7;-1:-1:-1;;;;;6949:31:4;:20;6961:7;6949:11;:20::i;:::-;-1:-1:-1;;;;;6949:31:4;;6929:51;:87;;;-1:-1:-1;;;;;;4190:25:4;;;4173:4;4190:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;6984:32;6921:96;6698:323;-1:-1:-1;;;;6698:323:4:o;9255:482::-;9382:4;-1:-1:-1;;;;;9355:31:4;:23;9370:7;9355:14;:23::i;:::-;-1:-1:-1;;;;;9355:31:4;;9347:85;;;;-1:-1:-1;;;9347:85:4;;22525:2:21;9347:85:4;;;22507:21:21;22564:2;22544:18;;;22537:30;22603:34;22583:18;;;22576:62;-1:-1:-1;;;22654:18:21;;;22647:39;22703:19;;9347:85:4;22323:405:21;9347:85:4;-1:-1:-1;;;;;9444:16:4;;9436:65;;;;-1:-1:-1;;;9436:65:4;;22935:2:21;9436:65:4;;;22917:21:21;22974:2;22954:18;;;22947:30;23013:34;22993:18;;;22986:62;-1:-1:-1;;;23064:18:21;;;23057:34;23108:19;;9436:65:4;22733:400:21;9436:65:4;9506:39;9527:4;9533:2;9537:7;9506:20;:39::i;:::-;9595:29;9612:1;9616:7;9595:8;:29::i;:::-;-1:-1:-1;;;;;9629:15:4;;;;;;:9;:15;;;;;:20;;9648:1;;9629:15;:20;;9648:1;;9629:20;:::i;:::-;;;;-1:-1:-1;;;;;;;9653:13:4;;;;;;:9;:13;;;;;:18;;9670:1;;9653:13;:18;;9670:1;;9653:18;:::i;:::-;;;;-1:-1:-1;;9675:16:4;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9675:21:4;-1:-1:-1;;;;;9675:21:4;;;;;;;;;9706:27;;9675:16;;9706:27;;;;;;;9255:482;;;:::o;1893:148:17:-;1961:6;;;-1:-1:-1;;;;;1971:17:17;;;-1:-1:-1;;;;;;1971:17:17;;;;;;;1997:40;;1961:6;;;1971:17;1961:6;;1997:40;;1942:16;;1997:40;1938:103;1893:148;:::o;10274:455:20:-;10384:4;;10336:7;;10362:2;;10336:7;;-1:-1:-1;;;;;10384:4:20;:14;657:10:1;10384:28:20;;-1:-1:-1;;;;;;10384:28:20;;;;;;;-1:-1:-1;;;;;1692:32:21;;;10384:28:20;;;1674:51:21;1647:18;;10384:28:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10368:44;;10429:2;;10420:5;:11;10416:34;;10444:1;10438:7;;10416:34;10467:11;;10457:6;;;;:21;;;:52;;-1:-1:-1;10482:27:20;;;10483:19;10499:3;10492;10484:11;;;10483:19;:::i;:::-;10482:27;10457:52;10453:77;;;657:10:1;10511:19:20;10274:455;-1:-1:-1;;;;10274:455:20:o;10453:77::-;10583:6;;:35;;-1:-1:-1;;;10583:35:20;;10614:3;10606:11;;;10583:35;;;3393:25:21;10567:13:20;;-1:-1:-1;;;;;10583:6:20;;:22;;3366:18:21;;10583:35:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10567:51;-1:-1:-1;;;;;;10667:21:20;;10663:46;;657:10:1;10697:12:20;10690:19;10274:455;-1:-1:-1;;;;;10274:455:20:o;7318:99:4:-;7387:26;7397:2;7401:7;7387:26;;;;;;;;;;;;:9;:26::i;:::-;7318:99;;:::o;9022:325:20:-;9089:23;;:::i;:::-;9122:18;9135:4;9122:12;:18::i;:::-;9118:22;;9148:20;:37;9169:15;9182:1;9169:12;:15::i;:::-;9148:37;;;;;;;;;;;;9189:1;9148:42;9144:147;;;9197:20;;;;:11;:20;;;;;;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9197:24:20;;;;;;-1:-1:-1;;9197:24:20;;;;;;;;;;;;-1:-1:-1;;9197:24:20;;;;;;;;;-1:-1:-1;;9197:24:20;;;;;;;;;;;;;;-1:-1:-1;;9197:24:20;;;;;;;;;-1:-1:-1;;9197:24:20;;;;;;;;;;;-1:-1:-1;;9197:24:20;-1:-1:-1;;;9197:24:20;;;;;;;;;;;;;;:20;;9226;;9247:15;9197:24;9247:12;:15::i;:::-;9226:37;;;;;;;;;;;-1:-1:-1;9226:37:20;:47;9278:8;;9144:147;9319:10;;:23;;-1:-1:-1;;;9319:23:20;;;;;3393:25:21;;;9301:42:20;;9310:7;;-1:-1:-1;;;;;9319:10:20;;;;:17;;3366:18:21;;9319:23:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9301:8;:42::i;:::-;9294:49;9022:325;-1:-1:-1;;;9022:325:20:o;5907:265:4:-;6025:28;6035:4;6041:2;6045:7;6025:9;:28::i;:::-;6065:48;6088:4;6094:2;6098:7;6107:5;6065:22;:48::i;:::-;6057:111;;;;-1:-1:-1;;;6057:111:4;;;;;;;:::i;7606:237:20:-;1038:7:18;;-1:-1:-1;;;1038:7:18;;;;1248:9;1240:38;;;;-1:-1:-1;;;1240:38:18;;;;;;;:::i;:::-;7667:12:20::1;::::0;7683:157:::1;7707:6;7703:1;:10;7683:157;;;7725:6;:8:::0;;::::1;;::::0;:6:::1;:8;::::0;::::1;:::i;:::-;::::0;;::::1;::::0;;;::::1;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;;;::::0;;;7745:10:::1;::::0;7763:6:::1;::::0;7745:25:::1;::::0;-1:-1:-1;;;7745:25:20;;7763:6;::::1;7745:25;::::0;::::1;4476:38:21::0;-1:-1:-1;;;;;7745:10:20::1;::::0;-1:-1:-1;7745:17:20::1;::::0;4449:18:21;;7745:25:20::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7738:32:::0;-1:-1:-1;7776:31:20::1;657:10:1::0;7800:6:20::1;::::0;::::1;;7776:9;:31::i;:::-;7822:6;::::0;7813:22:::1;::::0;7822:6:::1;;7830:4:::0;7813:8:::1;:22::i;:::-;-1:-1:-1::0;7715:3:20;::::1;::::0;::::1;:::i;:::-;;;;7683:157;;2375:470:5::0;-1:-1:-1;;;;;2541:18:5;;2537:153;;2566:40;2598:7;3594:10;:17;;3567:24;;;;:15;:24;;;;;:44;;;3615:24;;;;;;;;;;;;3497:146;2566:40;2537:153;;;2629:2;-1:-1:-1;;;;;2621:10:5;:4;-1:-1:-1;;;;;2621:10:5;;2617:73;;2638:47;2671:4;2677:7;2638:32;:47::i;:::-;-1:-1:-1;;;;;2697:16:5;;2693:149;;2720:45;2757:7;2720:36;:45::i;2693:149::-;2786:4;-1:-1:-1;;;;;2780:10:5;:2;-1:-1:-1;;;;;2780:10:5;;2776:66;;2797:40;2825:2;2829:7;2797:27;:40::i;7623:241:4:-;7721:18;7727:2;7731:7;7721:5;:18::i;:::-;7751:54;7782:1;7786:2;7790:7;7799:5;7751:22;:54::i;:::-;7743:117;;;;-1:-1:-1;;;7743:117:4;;;;;;;:::i;10934:613:20:-;10993:23;;:::i;:::-;11032:20;11050:2;11040:6;11033:13;;11032:20;:::i;:::-;:25;;11022:35;;;11056:1;;11075:15;;11089:1;11075:15;;;11085:1;11075:15;11103:2;11094:11;;;;;11061:29;-1:-1:-1;11118:45:20;11144:6;11137:13;;11153:9;11061:29;11153:1;:9;:::i;:::-;11118:11;:45::i;:::-;11109:54;;:6;;;:54;11176:2;11167:11;;;;;11191:45;11217:6;11210:13;;11226:9;11230:5;11226:1;:9;:::i;11191:45::-;11182:54;;:6;;;:54;11249:2;11240:11;;;;;11265:45;11291:6;11284:13;;11300:9;11304:5;11300:1;:9;:::i;11265:45::-;11255:55;;:7;;;:55;11323:2;11314:11;;;;;11342:45;11368:6;11361:13;;11377:9;11381:5;11377:1;:9;:::i;11342:45::-;11329:58;;:10;;;:58;11400:2;11391:11;;;;;11419:45;11445:6;11438:13;;11454:9;11458:5;11454:1;:9;:::i;11419:45::-;11406:58;;:10;;;:58;11477:2;11468:11;;;;;11498:45;11524:6;11517:13;;11533:9;11537:5;11533:1;:9;:::i;11498:45::-;11483:60;;:12;;;:60;-1:-1:-1;11483:1:20;10934:613;-1:-1:-1;10934:613:20:o;11711:200::-;11834:7;;11843:6;;;;;11851;;;;;11859:7;;;;11868:10;;;;11880;;;;11892:12;;;;11817:88;;24329:14:21;;24322:22;24290:3;24314:31;;;11817:88:20;;;24302:44:21;;;;-1:-1:-1;;;;;;24411:15:21;;;24407:24;;24394:11;;;24387:45;24465:15;;;24461:24;;24448:11;;;24441:45;24519:15;;;24515:24;;24502:11;;;24495:45;24573:15;;24569:24;;24556:11;;;24549:45;24627:15;;24623:24;;24610:11;;;24603:45;24681:15;;;24677:24;24664:11;;;24657:45;11781:7:20;;24718:11:21;;11817:88:20;;;;;;;;;;;;11809:97;;;:::i;10506:583:4:-;10629:4;-1:-1:-1;;;;;10643:13:4;;941:20:0;975:8;10639:447:4;;10669:72;;-1:-1:-1;;;10669:72:4;;-1:-1:-1;;;;;10669:36:4;;;;;:72;;657:10:1;;10720:4:4;;10726:7;;10735:5;;10669:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10669:72:4;;;;;;;;-1:-1:-1;;10669:72:4;;;;;;;;;;;;:::i;:::-;;;10665:390;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10875:13:4;;10871:179;;10902:60;;-1:-1:-1;;;10902:60:4;;;;;;;:::i;10871:179::-;11029:6;11023:13;11014:6;11010:2;11006:15;10999:38;10665:390;-1:-1:-1;;;;;;10779:51:4;-1:-1:-1;;;10779:51:4;;-1:-1:-1;10772:58:4;;10639:447;-1:-1:-1;11077:4:4;10506:583;;;;;;:::o;4233:880:5:-;4477:22;4527:1;4502:22;4519:4;4502:16;:22::i;:::-;:26;;;;:::i;:::-;4532:18;4553:26;;;:17;:26;;;;;;4477:51;;-1:-1:-1;4671:28:5;;;4667:290;;-1:-1:-1;;;;;4728:18:5;;4706:19;4728:18;;;:12;:18;;;;;;;;:34;;;;;;;;;4768:30;;;;;;:44;;;4875:30;;:17;:30;;;;;:43;;;4667:290;-1:-1:-1;5038:26:5;;;;:17;:26;;;;;;;;5031:33;;;-1:-1:-1;;;;;5075:18:5;;;;;:12;:18;;;;;:34;;;;;;;5068:41;4233:880::o;5383:980::-;5639:10;:17;5614:22;;5639:21;;5659:1;;5639:21;:::i;:::-;5664:18;5685:24;;;:15;:24;;;;;;6029:10;:26;;5614:46;;-1:-1:-1;5685:24:5;;5614:46;;6029:26;;;;;;:::i;:::-;;;;;;;;;6007:48;;6085:11;6060:10;6071;6060:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;6158:28;;;:15;:28;;;;;;;:41;;;6315:24;;;;;6308:31;6343:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;5454:909;;;5383:980;:::o;3121:196::-;3199:14;3216:20;3233:2;3216:16;:20::i;:::-;-1:-1:-1;;;;;3240:16:5;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;3278:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;3121:196:5:o;8147:333:4:-;-1:-1:-1;;;;;8220:16:4;;8212:61;;;;-1:-1:-1;;;8212:61:4;;26124:2:21;8212:61:4;;;26106:21:21;;;26143:18;;;26136:30;26202:34;26182:18;;;26175:62;26254:18;;8212:61:4;25922:356:21;8212:61:4;6513:4;6530:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6530:16:4;:30;8277:58;;;;-1:-1:-1;;;8277:58:4;;26485:2:21;8277:58:4;;;26467:21:21;26524:2;26504:18;;;26497:30;26563;26543:18;;;26536:58;26611:18;;8277:58:4;26283:352:21;8277:58:4;8340:45;8369:1;8373:2;8377:7;8340:20;:45::i;:::-;-1:-1:-1;;;;;8390:13:4;;;;;;:9;:13;;;;;:18;;8407:1;;8390:13;:18;;8407:1;;8390:18;:::i;:::-;;;;-1:-1:-1;;8412:16:4;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;8412:21:4;-1:-1:-1;;;;;8412:21:4;;;;;;;;8443:33;;8412:16;;;8443:33;;8412:16;;8443:33;8147:333;;:::o;9743:246:20:-;9817:5;9828:11;9862:8;9871:9;9862:19;;;;;;;;;:::i;:::-;;:26;9842:47;;9848:4;9842:47;:::i;:::-;9828:61;;9909:8;9918:9;9909:19;;;;;;;;;:::i;:::-;;9929:5;9909:26;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;9905:1;9897:9;;;;;;:38;9893:56;;;9944:5;-1:-1:-1;9937:12:20;;9893:56;9960:7;9968:9;9960:18;;;;;;;;;:::i;:::-;;9979:5;9960:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;9953:32;;;9743:246;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:21:-;-1:-1:-1;;;;;;88:32:21;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:21;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:21;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:21:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:21;;1343:180;-1:-1:-1;1343:180:21:o;1736:131::-;-1:-1:-1;;;;;1811:31:21;;1801:42;;1791:70;;1857:1;1854;1847:12;1872:247;1931:6;1984:2;1972:9;1963:7;1959:23;1955:32;1952:52;;;2000:1;1997;1990:12;1952:52;2039:9;2026:23;2058:31;2083:5;2058:31;:::i;2124:315::-;2192:6;2200;2253:2;2241:9;2232:7;2228:23;2224:32;2221:52;;;2269:1;2266;2259:12;2221:52;2308:9;2295:23;2327:31;2352:5;2327:31;:::i;:::-;2377:5;2429:2;2414:18;;;;2401:32;;-1:-1:-1;;;2124:315:21:o;2676:160::-;2741:20;;2797:13;;2790:21;2780:32;;2770:60;;2826:1;2823;2816:12;2770:60;2676:160;;;:::o;2841:180::-;2897:6;2950:2;2938:9;2929:7;2925:23;2921:32;2918:52;;;2966:1;2963;2956:12;2918:52;2989:26;3005:9;2989:26;:::i;3429:456::-;3506:6;3514;3522;3575:2;3563:9;3554:7;3550:23;3546:32;3543:52;;;3591:1;3588;3581:12;3543:52;3630:9;3617:23;3649:31;3674:5;3649:31;:::i;:::-;3699:5;-1:-1:-1;3756:2:21;3741:18;;3728:32;3769:33;3728:32;3769:33;:::i;:::-;3429:456;;3821:7;;-1:-1:-1;;;3875:2:21;3860:18;;;;3847:32;;3429:456::o;3890:248::-;3958:6;3966;4019:2;4007:9;3998:7;3994:23;3990:32;3987:52;;;4035:1;4032;4025:12;3987:52;-1:-1:-1;;4058:23:21;;;4128:2;4113:18;;;4100:32;;-1:-1:-1;3890:248:21:o;5961:315::-;6026:6;6034;6087:2;6075:9;6066:7;6062:23;6058:32;6055:52;;;6103:1;6100;6093:12;6055:52;6142:9;6129:23;6161:31;6186:5;6161:31;:::i;:::-;6211:5;-1:-1:-1;6235:35:21;6266:2;6251:18;;6235:35;:::i;:::-;6225:45;;5961:315;;;;;:::o;6281:127::-;6342:10;6337:3;6333:20;6330:1;6323:31;6373:4;6370:1;6363:15;6397:4;6394:1;6387:15;6413:275;6484:2;6478:9;6549:2;6530:13;;-1:-1:-1;;6526:27:21;6514:40;;6584:18;6569:34;;6605:22;;;6566:62;6563:88;;;6631:18;;:::i;:::-;6667:2;6660:22;6413:275;;-1:-1:-1;6413:275:21:o;6693:186::-;6741:4;6774:18;6766:6;6763:30;6760:56;;;6796:18;;:::i;:::-;-1:-1:-1;6862:2:21;6841:15;-1:-1:-1;;6837:29:21;6868:4;6833:40;;6693:186::o;6884:1016::-;6979:6;6987;6995;7003;7056:3;7044:9;7035:7;7031:23;7027:33;7024:53;;;7073:1;7070;7063:12;7024:53;7112:9;7099:23;7131:31;7156:5;7131:31;:::i;:::-;7181:5;-1:-1:-1;7238:2:21;7223:18;;7210:32;7251:33;7210:32;7251:33;:::i;:::-;7303:7;-1:-1:-1;7357:2:21;7342:18;;7329:32;;-1:-1:-1;7412:2:21;7397:18;;7384:32;7439:18;7428:30;;7425:50;;;7471:1;7468;7461:12;7425:50;7494:22;;7547:4;7539:13;;7535:27;-1:-1:-1;7525:55:21;;7576:1;7573;7566:12;7525:55;7612:2;7599:16;7637:48;7653:31;7681:2;7653:31;:::i;:::-;7637:48;:::i;:::-;7708:2;7701:5;7694:17;7748:7;7743:2;7738;7734;7730:11;7726:20;7723:33;7720:53;;;7769:1;7766;7759:12;7720:53;7824:2;7819;7815;7811:11;7806:2;7799:5;7795:14;7782:45;7868:1;7863:2;7858;7851:5;7847:14;7843:23;7836:34;7889:5;7879:15;;;;;6884:1016;;;;;;;:::o;7905:248::-;7967:6;7975;8028:2;8016:9;8007:7;8003:23;7999:32;7996:52;;;8044:1;8041;8034:12;7996:52;8067:26;8083:9;8067:26;:::i;8158:712::-;8212:5;8265:3;8258:4;8250:6;8246:17;8242:27;8232:55;;8283:1;8280;8273:12;8232:55;8319:6;8306:20;8345:4;8368:18;8364:2;8361:26;8358:52;;;8390:18;;:::i;:::-;8436:2;8433:1;8429:10;8459:28;8483:2;8479;8475:11;8459:28;:::i;:::-;8521:15;;;8591;;;8587:24;;;8552:12;;;;8623:15;;;8620:35;;;8651:1;8648;8641:12;8620:35;8687:2;8679:6;8675:15;8664:26;;8699:142;8715:6;8710:3;8707:15;8699:142;;;8781:17;;8769:30;;8732:12;;;;8819;;;;8699:142;;;8859:5;8158:712;-1:-1:-1;;;;;;;8158:712:21:o;8875:595::-;8993:6;9001;9054:2;9042:9;9033:7;9029:23;9025:32;9022:52;;;9070:1;9067;9060:12;9022:52;9110:9;9097:23;9139:18;9180:2;9172:6;9169:14;9166:34;;;9196:1;9193;9186:12;9166:34;9219:61;9272:7;9263:6;9252:9;9248:22;9219:61;:::i;:::-;9209:71;;9333:2;9322:9;9318:18;9305:32;9289:48;;9362:2;9352:8;9349:16;9346:36;;;9378:1;9375;9368:12;9346:36;;9401:63;9456:7;9445:8;9434:9;9430:24;9401:63;:::i;:::-;9391:73;;;8875:595;;;;;:::o;10374:388::-;10442:6;10450;10503:2;10491:9;10482:7;10478:23;10474:32;10471:52;;;10519:1;10516;10509:12;10471:52;10558:9;10545:23;10577:31;10602:5;10577:31;:::i;:::-;10627:5;-1:-1:-1;10684:2:21;10669:18;;10656:32;10697:33;10656:32;10697:33;:::i;:::-;10749:7;10739:17;;;10374:388;;;;;:::o;10767:380::-;10846:1;10842:12;;;;10889;;;10910:61;;10964:4;10956:6;10952:17;10942:27;;10910:61;11017:2;11009:6;11006:14;10986:18;10983:38;10980:161;;;11063:10;11058:3;11054:20;11051:1;11044:31;11098:4;11095:1;11088:15;11126:4;11123:1;11116:15;10980:161;;10767:380;;;:::o;11565:356::-;11767:2;11749:21;;;11786:18;;;11779:30;11845:34;11840:2;11825:18;;11818:62;11912:2;11897:18;;11565:356::o;12753:413::-;12955:2;12937:21;;;12994:2;12974:18;;;12967:30;13033:34;13028:2;13013:18;;13006:62;-1:-1:-1;;;13099:2:21;13084:18;;13077:47;13156:3;13141:19;;12753:413::o;13171:127::-;13232:10;13227:3;13223:20;13220:1;13213:31;13263:4;13260:1;13253:15;13287:4;13284:1;13277:15;13303:168;13343:7;13409:1;13405;13401:6;13397:14;13394:1;13391:21;13386:1;13379:9;13372:17;13368:45;13365:71;;;13416:18;;:::i;:::-;-1:-1:-1;13456:9:21;;13303:168::o;13476:127::-;13537:10;13532:3;13528:20;13525:1;13518:31;13568:4;13565:1;13558:15;13592:4;13589:1;13582:15;13608:120;13648:1;13674;13664:35;;13679:18;;:::i;:::-;-1:-1:-1;13713:9:21;;13608:120::o;14558:127::-;14619:10;14614:3;14610:20;14607:1;14600:31;14650:4;14647:1;14640:15;14674:4;14671:1;14664:15;15511:340;15713:2;15695:21;;;15752:2;15732:18;;;15725:30;-1:-1:-1;;;15786:2:21;15771:18;;15764:46;15842:2;15827:18;;15511:340::o;16539:128::-;16579:3;16610:1;16606:6;16603:1;16600:13;16597:39;;;16616:18;;:::i;:::-;-1:-1:-1;16652:9:21;;16539:128::o;18077:197::-;18115:3;18143:6;18184:2;18177:5;18173:14;18211:2;18202:7;18199:15;18196:41;;;18217:18;;:::i;:::-;18266:1;18253:15;;18077:197;-1:-1:-1;;;18077:197:21:o;18473:184::-;18543:6;18596:2;18584:9;18575:7;18571:23;18567:32;18564:52;;;18612:1;18609;18602:12;18564:52;-1:-1:-1;18635:16:21;;18473:184;-1:-1:-1;18473:184:21:o;18662:135::-;18701:3;-1:-1:-1;;18722:17:21;;18719:43;;;18742:18;;:::i;:::-;-1:-1:-1;18789:1:21;18778:13;;18662:135::o;19851:635::-;19931:6;19984:2;19972:9;19963:7;19959:23;19955:32;19952:52;;;20000:1;19997;19990:12;19952:52;20033:9;20027:16;20066:18;20058:6;20055:30;20052:50;;;20098:1;20095;20088:12;20052:50;20121:22;;20174:4;20166:13;;20162:27;-1:-1:-1;20152:55:21;;20203:1;20200;20193:12;20152:55;20232:2;20226:9;20257:48;20273:31;20301:2;20273:31;:::i;20257:48::-;20328:2;20321:5;20314:17;20368:7;20363:2;20358;20354;20350:11;20346:20;20343:33;20340:53;;;20389:1;20386;20379:12;20340:53;20402:54;20453:2;20448;20441:5;20437:14;20432:2;20428;20424:11;20402:54;:::i;20491:251::-;20561:6;20614:2;20602:9;20593:7;20589:23;20585:32;20582:52;;;20630:1;20627;20620:12;20582:52;20662:9;20656:16;20681:31;20706:5;20681:31;:::i;23138:125::-;23178:4;23206:1;23203;23200:8;23197:34;;;23211:18;;:::i;:::-;-1:-1:-1;23248:9:21;;23138:125::o;23268:112::-;23300:1;23326;23316:35;;23331:18;;:::i;:::-;-1:-1:-1;23365:9:21;;23268:112::o;23385:414::-;23587:2;23569:21;;;23626:2;23606:18;;;23599:30;23665:34;23660:2;23645:18;;23638:62;-1:-1:-1;;;23731:2:21;23716:18;;23709:48;23789:3;23774:19;;23385:414::o;23804:204::-;23842:3;23878:4;23875:1;23871:12;23910:4;23907:1;23903:12;23945:3;23939:4;23935:14;23930:3;23927:23;23924:49;;;23953:18;;:::i;:::-;23989:13;;23804:204;-1:-1:-1;;;23804:204:21:o;24740:297::-;24858:12;;24905:4;24894:16;;;24888:23;;24858:12;24923:16;;24920:111;;;-1:-1:-1;;24997:4:21;24993:17;;;;24990:1;24986:25;24982:38;24971:50;;24740:297;-1:-1:-1;24740:297:21:o;25042:489::-;-1:-1:-1;;;;;25311:15:21;;;25293:34;;25363:15;;25358:2;25343:18;;25336:43;25410:2;25395:18;;25388:34;;;25458:3;25453:2;25438:18;;25431:31;;;25236:4;;25479:46;;25505:19;;25497:6;25479:46;:::i;:::-;25471:54;25042:489;-1:-1:-1;;;;;;25042:489:21:o;25536:249::-;25605:6;25658:2;25646:9;25637:7;25633:23;25629:32;25626:52;;;25674:1;25671;25664:12;25626:52;25706:9;25700:16;25725:30;25749:5;25725:30;:::i;25790:127::-;25851:10;25846:3;25842:20;25839:1;25832:31;25882:4;25879:1;25872:15;25906:4;25903:1;25896:15;26640:157;26670:1;26704:4;26701:1;26697:12;26728:3;26718:37;;26735:18;;:::i;:::-;26787:3;26780:4;26777:1;26773:12;26769:22;26764:27;;;26640:157;;;;:::o

Swarm Source

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