ERC-721
Overview
Max Total Supply
1,000 KLDSCP
Holders
180
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
20 KLDSCPLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Kaleidoscopes
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import "erc721a/contracts/ERC721A.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "./Utilities.sol"; import "./Renderer.sol"; import "svgnft/contracts/Base64.sol"; contract Kaleidoscopes is ERC721A, Ownable { uint256 public price; uint256 public maxSupply; uint256 public constant maxMintPerWallet = 20; Renderer public renderer; bytes32 public merkleRoot; uint256 public allowListMintStartBlock; uint256 public publicMintOffsetBlocks; // 3 hours /** * @dev Constructs a new instance of the contract. * @param _name Name of the ERC721 token. * @param _symbol Symbol of the ERC721 token. * @param _price Price of each token in wei. * @param _maxSupply Maximum supply of tokens. */ constructor( string memory _name, string memory _symbol, uint256 _price, uint256 _maxSupply, bytes32 _merkleRoot, uint256 _allowListMintStartBlock, uint256 _publicMintOffsetBlocks, address _renderer ) ERC721A(_name, _symbol) { price = _price; maxSupply = _maxSupply; merkleRoot = _merkleRoot; allowListMintStartBlock = _allowListMintStartBlock; publicMintOffsetBlocks = _publicMintOffsetBlocks; renderer = Renderer(_renderer); } /** * @notice Checks if public sale has started. */ function hasPublicSaleStarted() public view returns (bool) { return block.number >= allowListMintStartBlock + publicMintOffsetBlocks; } /** * @notice Checks if allow list sale has started. */ function hasAllowlistSaleStarted() public view returns (bool) { return block.number >= allowListMintStartBlock; } /** * @notice Sets the block at which the allowlist mint starts. * @param _allowListMintStartBlock Block at which the allowlist mint starts. */ function setAllowListMintStartBlock(uint256 _allowListMintStartBlock) external onlyOwner { allowListMintStartBlock = _allowListMintStartBlock; } /** * @notice Sets the number of blocks after which the public sale starts. * @param _publicMintOffsetBlocks Number of blocks. */ function setPublicMintOffsetBlocks(uint256 _publicMintOffsetBlocks) external onlyOwner { publicMintOffsetBlocks = _publicMintOffsetBlocks; } /** * @notice Sets the price of each token in wei. * @param _price Price of each token in wei. */ function setPrice(uint256 _price) external onlyOwner { price = _price; } /** * @notice Returns the token URI for a given token ID. * @param _tokenId ID of the token to get the URI for. * @return Token URI. */ function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { if (!_exists(_tokenId)) revert URIQueryForNonexistentToken(); string memory name = string(abi.encodePacked("Kaleidoscope #", utils.uint2str(_tokenId))); string memory description = "Fully on-chain, procedurally generated, animated kaleidoscopes."; Renderer.Kaleidoscope memory kaleidoscope = renderer.kaleidoscopeForTokenId(_tokenId); kaleidoscope.hasHalo = _tokenId <= 50; Renderer.ColorPalette memory palette = renderer.colorPaletteForKaleidescope(kaleidoscope); string memory svg = renderer.getKaleidoscopeSVG(kaleidoscope, palette); string memory attributes = string.concat( '"attributes": [', '{"trait_type": "Mirrors", "value": ', utils.uint2str(kaleidoscope.repetitions), "},", '{"trait_type": "Outside Artifacts", "value": ', utils.uint2str(kaleidoscope.numOutsideArtifacts), "},", '{"trait_type": "Inside Artifacts", "value": ', utils.uint2str(kaleidoscope.numInsideArtifacts), "},", '{"trait_type": "Gradient", "value": "', kaleidoscope.hasGradient ? "Yes" : "No", '"},', '{"trait_type": "Primary Color", "value": "', utils.getHueName(palette.primaryHue), '"}' ); if (kaleidoscope.hasSecondaryColor) { attributes = string.concat( attributes, ',{"trait_type": "Secondary Color", "value": "', utils.getHueName(palette.secondaryHue), '"}' ); } if (kaleidoscope.hasHalo) { attributes = string.concat(attributes, ',{"trait_type": "Halo", "value": "Yes"}'); } attributes = string.concat(attributes, "]"); string memory json = string( abi.encodePacked( '{"name":"', name, '","description":"', description, '",', attributes, ', "image": "data:image/svg+xml;base64,', Base64.encode(bytes(svg)), '"}' ) ); return string(abi.encodePacked("data:application/json;base64,", Base64.encode(bytes(json)))); } /** * @notice Mints new tokens for the caller. * @param _quantity Quantity of tokens to mint. */ function mint(uint256 _quantity) internal { require(msg.value >= price * _quantity, "Insufficient fee"); require(totalSupply() + _quantity <= maxSupply, "Exceeds max supply"); require(_numberMinted(msg.sender) + _quantity <= 20, "Exceeds max quantity"); _mint(msg.sender, _quantity); // Refund any extra ETH sent if (msg.value > price * _quantity) { (bool status, ) = payable(msg.sender).call{value: msg.value - price * _quantity}(""); require(status, "Refund failed"); } } /** * @notice Airdrops tokens to a list of recipients. Only callable by the contract owner. * @param _recipients List of recipients to receive the airdrop. * @param _quantity Quantity of tokens to airdrop to each recipient. */ function airdrop(address[] memory _recipients, uint256 _quantity) external payable onlyOwner { require(totalSupply() + _quantity * _recipients.length <= maxSupply, "Exceeds max supply"); for (uint256 i = 0; i < _recipients.length; i++) { _mint(_recipients[i], _quantity); } } /** * @notice Withdraws the contract's balance. Only callable by the contract owner. */ function withdraw() external onlyOwner { require(payable(msg.sender).send(address(this).balance)); } /** * @notice Checks if a wallet is on the allowlist given a Merkle proof. * @param _wallet Wallet to check. * @param _proof Merkle proof. */ function allowListed(address _wallet, bytes32[] calldata _proof) public view returns (bool) { return MerkleProof.verify(_proof, merkleRoot, keccak256(abi.encodePacked(_wallet))); } /** * @notice Mints tokens for the caller if they are on the allowlist. * @param _quantity Quantity of tokens to mint. * @param _proof Merkle proof. */ function mintAllowList(uint256 _quantity, bytes32[] calldata _proof) external payable { require(allowListed(msg.sender, _proof), "You are not on the allowlist"); require(hasAllowlistSaleStarted(), "Allowlist sale has not started yet"); mint(_quantity); } /** * @notice Mints tokens for the caller if public sale has started. * @param _quantity Quantity of tokens to mint. */ function mintPublic(uint256 _quantity) external payable { require(hasPublicSaleStarted(), "Public sale has not started yet"); mint(_quantity); } function mintQuotaRemaining(address _wallet) external view returns (uint256) { return maxMintPerWallet - _numberMinted(_wallet); } function _startTokenId() internal view virtual override returns (uint256) { return 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import "./Trigonometry.sol"; import "./Utilities.sol"; import "hardhat/console.sol"; contract Renderer { uint256 constant SIZE = 500; uint256 constant RADIUS = 200; uint256 constant PRECISION_DEGREE = 7; uint256 constant PRECISION = 10**PRECISION_DEGREE; struct ColorPalette { uint256 primaryHue; uint256 secondaryHue; utils.HSL primaryColorHsl; utils.HSL secondaryColorHsl; utils.HSL backgroundColorHsl; utils.HSL darkerSecondaryHsl; utils.HSL[] primaryColorsHsl; utils.HSL[] secondaryColorsHsl; } struct Kaleidoscope { uint256 tokenId; uint256 repetitions; uint256 numInsideArtifacts; uint256 numOutsideArtifacts; uint256 centerX_precise; uint256 centerY_precise; bool hasGradient; bool hasSecondaryColor; bool hasHalo; } struct AnimatedCircle { // Start position int256 x1; int256 y1; // End position int256 x2; int256 y2; uint256 radius1; uint256 radius2; uint256 alternatingClass; uint256 duration; utils.HSL color; } struct AnimatedTriangle { uint256 x1; uint256 y1; uint256 centerX; uint256 centerY; uint256 duration; utils.HSL color; } struct AnimatedRectangle { uint256 width; uint256 height; uint256 x; uint256 y; uint256 duration; utils.HSL color; } function colorPaletteForKaleidescope(Kaleidoscope memory _kaleidoscope) public pure returns (ColorPalette memory palette) { palette.primaryHue = utils.randomRange(_kaleidoscope.tokenId, "primaryHue", 0, 360); palette.secondaryHue = _kaleidoscope.hasSecondaryColor ? (palette.primaryHue + 240) % 360 : palette.primaryHue; palette.primaryColorHsl = utils.HSL(palette.primaryHue, 100, 30); palette.secondaryColorHsl = utils.HSL(palette.secondaryHue, 100, 70); palette.backgroundColorHsl = utils.HSL(palette.primaryHue, 100, 10); palette.darkerSecondaryHsl = utils.HSL((palette.primaryHue + 10) % 360, 100, 10); palette.primaryColorsHsl = utils.generateColors(palette.primaryHue, _kaleidoscope.numInsideArtifacts + 1); palette.secondaryColorsHsl = utils.generateColors(palette.secondaryHue, _kaleidoscope.numInsideArtifacts + 1); return palette; } function kaleidoscopeForTokenId(uint256 _tokenId) public pure returns (Kaleidoscope memory kaleidoscope) { kaleidoscope.tokenId = _tokenId; kaleidoscope.repetitions = utils.randomRange(_tokenId, "repetitions", 3, 20); kaleidoscope.numInsideArtifacts = utils.randomRange(_tokenId, "numInsideArtifacts", 3, 10); kaleidoscope.numOutsideArtifacts = utils.randomRange(_tokenId, "numOutsideArtifacts", 1, 4); kaleidoscope.hasGradient = utils.randomRange(_tokenId, "hasGradient", 1, 10) == 5; kaleidoscope.hasSecondaryColor = utils.randomRange(_tokenId, "secondaryColor", 1, 8) == 8; uint256 angle = (((180 - 360 / kaleidoscope.repetitions) / 2) * Trigonometry.PI) / 180; kaleidoscope.centerX_precise = uint256( (int256(RADIUS) * Trigonometry.cos(angle)) / int256(10**(18 - PRECISION_DEGREE)) ); kaleidoscope.centerY_precise = uint256( (int256(RADIUS) * Trigonometry.sin(angle)) / int256(10**(18 - PRECISION_DEGREE)) ); return kaleidoscope; } function circleAtIndexForKaleidescope( Kaleidoscope memory _kaleidoscope, ColorPalette memory _palette, uint256 _index ) public pure returns (AnimatedCircle memory circle) { uint256 yUpperBound = (_kaleidoscope.centerY_precise / PRECISION) + RADIUS / 8; circle.y1 = int256( utils.randomRange(_kaleidoscope.tokenId, string.concat("y1", utils.uint2str(_index)), 20, yUpperBound) ); circle.y2 = int256( utils.randomRange(_kaleidoscope.tokenId, string.concat("y2", utils.uint2str(_index)), 20, yUpperBound) ); circle.alternatingClass = utils.randomRange( _kaleidoscope.tokenId, string.concat("alternatingClass", utils.uint2str(_index)), 0, 3 ); if (circle.y1 > circle.y2 && circle.alternatingClass % 2 == 0) { int256 temp = circle.y1; circle.y1 = circle.y2; circle.y2 = temp; } int256 gradient_1000 = int256((_kaleidoscope.centerY_precise * 1000) / _kaleidoscope.centerX_precise); uint256 radiusUB = (_kaleidoscope.centerX_precise / PRECISION) * 2; circle.radius1 = uint256( utils.min((radiusUB * (1000 - (uint256(circle.y1) * 1000) / yUpperBound)) / 1000, radiusUB) ); circle.radius2 = uint256( utils.min((radiusUB * (1000 - (uint256(circle.y2) * 1000) / yUpperBound)) / 1000, radiusUB) ); // x1 should be within bounds of triangular path int256 lb1 = (circle.y1 * 1000) / gradient_1000; circle.x1 = int256(lb1 - int256(circle.radius1) * 2); // x2 should be within bounds of triangular path int256 lb2 = (circle.y2 * 1000) / gradient_1000; circle.x2 = int256(2 * int256(_kaleidoscope.centerX_precise / PRECISION) - lb2 + int256(circle.radius2) * 2); circle.duration = utils.randomRange(_kaleidoscope.tokenId, string.concat("duration", utils.uint2str(_index)), 3, 7); circle.color = _index % 2 == 0 ? _palette.primaryColorsHsl[_index + 1] : _palette.secondaryColorsHsl[_index + 1]; return circle; } function rectangleAtIndexForKaleidescope( Kaleidoscope memory _kaleidoscope, ColorPalette memory _palette, uint256 _index ) public pure returns (AnimatedRectangle memory rectangle) { rectangle.width = utils.randomRange( _kaleidoscope.tokenId, string.concat("rectwidth", utils.uint2str(_index)), (_kaleidoscope.centerY_precise / PRECISION) / 2, (_kaleidoscope.centerY_precise / PRECISION) ); rectangle.height = utils.randomRange( _kaleidoscope.tokenId, string.concat("rectheight", utils.uint2str(_index)), (_kaleidoscope.centerY_precise / PRECISION), _kaleidoscope.centerY_precise * 2 + RADIUS / 8 ); rectangle.x = 0; rectangle.y = _kaleidoscope.centerY_precise / PRECISION; rectangle.duration = utils.randomRange( _kaleidoscope.tokenId, string.concat("rectduration", utils.uint2str(_index)), 5, 10 ); rectangle.color = _index % 2 == 0 ? _palette.primaryColorsHsl[0] : _palette.secondaryColorsHsl[0]; return rectangle; } function getCircleSVG(AnimatedCircle memory _circle) public pure returns (string memory) { string memory animations = string.concat( '<animate attributeName="r" values="', utils.uint2str(_circle.radius1), ";", utils.uint2str(_circle.radius2), ";", utils.uint2str(_circle.radius1), ";", utils.uint2str(_circle.radius2), '" calcMode="linear" dur="', utils.uint2str(_circle.duration * 2), 's" repeatCount="indefinite"/>' ); animations = string.concat( animations, '<animate attributeName="cy" values="', utils.int2str(_circle.y1), ";", utils.int2str(_circle.y2), ";", utils.int2str(_circle.y1), ";", utils.int2str(_circle.y2), '" calcMode="linear" dur="', utils.uint2str(_circle.duration * 2), 's" repeatCount="indefinite"/>' ); animations = string.concat( animations, '<animate attributeName="cx" values="', utils.int2str(_circle.x1), ";", utils.int2str(_circle.x2), ";", utils.int2str(_circle.x1), ";", utils.int2str(_circle.x2), '" calcMode="linear" dur="', utils.uint2str(_circle.duration * 2), 's" repeatCount="indefinite"/>' ); return string.concat( '<circle cx="', utils.int2str((_circle.x1 + _circle.x2) / 2), '" cy="', utils.int2str((_circle.y1 + _circle.y2) / 2), '" r="', utils.uint2str((_circle.radius1 + _circle.radius2) / 2), '" fill="', utils.getHslString(_circle.color), '">', animations, "</circle>" ); } function getRectangleSVG(AnimatedRectangle memory _rectangle) public pure returns (string memory) { string memory animations = string.concat( '<animateTransform attributeName="transform" type="rotate" from="0 0 -', utils.uint2str(_rectangle.y), '" to="-360 0 -', utils.uint2str(_rectangle.y), '" begin="0s" dur="', utils.uint2str(_rectangle.duration), 's" repeatCount="indefinite" />' ); return string.concat( '<rect rx="3" ry="3" x="0" y="-', utils.uint2str(_rectangle.y), '" width="', utils.uint2str(_rectangle.width), '" height="', utils.uint2str(_rectangle.height), '" fill="', utils.getHslString(_rectangle.color), '">', animations, "</rect>" ); } function linearGradient(string memory _stop1Color, string memory _stop2Color) internal pure returns (string memory) { return string.concat( '<linearGradient id="gradient">', '<stop offset="0%" stop-color="', _stop1Color, '"/>', '<stop offset="100%" stop-color="', _stop2Color, '"/>', "</linearGradient>" ); } function getKaleidoscopeSVG(Kaleidoscope memory _kaleidoscope, ColorPalette memory _palette) public pure returns (string memory) { // Get outer artifacts string memory outerArtifacts = ""; for (uint256 i = 0; i < _kaleidoscope.numOutsideArtifacts; i++) { // Rectangle AnimatedRectangle memory rectangle = rectangleAtIndexForKaleidescope(_kaleidoscope, _palette, i); outerArtifacts = string.concat(outerArtifacts, getRectangleSVG(rectangle)); } string memory innerArtifacts = ""; for (uint256 i = 0; i < _kaleidoscope.numInsideArtifacts; i++) { AnimatedCircle memory circle = circleAtIndexForKaleidescope(_kaleidoscope, _palette, i); innerArtifacts = string.concat(innerArtifacts, getCircleSVG(circle)); } string memory paths = ""; uint256 angleInterval = (360 * 10**7) / _kaleidoscope.repetitions; for (uint256 i = 0; i < _kaleidoscope.repetitions; i++) { paths = string.concat( paths, '<use href="#tile" transform="rotate(', utils.uint2floatstr(angleInterval * i, PRECISION_DEGREE), ",", utils.uint2floatstr(_kaleidoscope.centerX_precise, PRECISION_DEGREE), ",", utils.uint2floatstr(_kaleidoscope.centerY_precise, PRECISION_DEGREE), ')" />' ); } string memory clipPath = string.concat( '<clipPath id="clip">', '<path d="M0,0L', utils.uint2floatstr(_kaleidoscope.centerX_precise, PRECISION_DEGREE), ",", utils.uint2floatstr(_kaleidoscope.centerY_precise, PRECISION_DEGREE), "L", utils.uint2floatstr(_kaleidoscope.centerX_precise * 2, PRECISION_DEGREE), ",0A", utils.uint2str(RADIUS), ",", utils.uint2str(RADIUS), ',0,0,0,0,0Z" />', "</clipPath>" ); string memory svg = string.concat( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ', utils.uint2str(SIZE), " ", utils.uint2str(SIZE), '" width="', utils.uint2str(SIZE), '" height="', utils.uint2str(SIZE), '"><defs>', linearGradient(utils.getHslString(_palette.primaryColorHsl), utils.getHslString(_palette.darkerSecondaryHsl)), clipPath, '<g id="tile" clip-path="url(#clip)">', '<rect x="0" y="-', utils.uint2str(RADIUS), '" width="', utils.uint2str(RADIUS * 2), '" height="', utils.uint2str(RADIUS * 2), '" fill="' ); svg = string.concat( svg, _kaleidoscope.hasGradient ? "url(#gradient)" : utils.getHslString(_palette.primaryColorHsl), '"></rect>', outerArtifacts, innerArtifacts, "</g>" ); svg = string.concat( svg, "</defs>", '<rect width="', utils.uint2str(SIZE), '" height="', utils.uint2str(SIZE), '" fill="', utils.getHslString(_palette.backgroundColorHsl), '"></rect>', '<g id="kaleidoscopeTile" transform="translate(', utils.uint2str(SIZE / 2 - _kaleidoscope.centerX_precise / PRECISION) // "0" ); string memory backgroundCircleBase = string.concat( '<circle cx="', utils.uint2floatstr(_kaleidoscope.centerX_precise, PRECISION_DEGREE), '" cy="', utils.uint2floatstr(_kaleidoscope.centerY_precise, PRECISION_DEGREE), '" r="' ); string memory haloTrait = string.concat( backgroundCircleBase, utils.uint2str(RADIUS + 8), '" fill="none"', _kaleidoscope.hasHalo ? ' stroke="#EBA947" stroke-width="4"' : "", "/>" ); svg = string.concat( svg, ",", utils.uint2str(SIZE / 2 - _kaleidoscope.centerY_precise / PRECISION), // "0", ')">', backgroundCircleBase, utils.uint2str(RADIUS), '" fill="', utils.getHslString(_palette.primaryColorHsl), '" />', _kaleidoscope.hasHalo ? haloTrait : "" ); svg = string.concat(svg, paths, "</g>", "</svg>"); return svg; } function render(uint256 _tokenId) public pure returns (string memory) { Kaleidoscope memory kaleidoscope = kaleidoscopeForTokenId(_tokenId); ColorPalette memory palette = colorPaletteForKaleidescope(kaleidoscope); string memory svg = getKaleidoscopeSVG(kaleidoscope, palette); return svg; } function metadata(uint256 _tokenId) public pure returns (Kaleidoscope memory) { Kaleidoscope memory kaleidoscope = kaleidoscopeForTokenId(_tokenId); return kaleidoscope; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; /** * @notice Solidity library offering basic trigonometry functions where inputs and outputs are * integers. Inputs are specified in radians scaled by 1e18, and similarly outputs are scaled by 1e18. * * This implementation is based off the Solidity trigonometry library written by Lefteris Karapetsas * which can be found here: https://github.com/Sikorkaio/sikorka/blob/e75c91925c914beaedf4841c0336a806f2b5f66d/contracts/trigonometry.sol * * Compared to Lefteris' implementation, this version makes the following changes: * - Uses a 32 bits instead of 16 bits for improved accuracy * - Updated for Solidity 0.8.x * - Various gas optimizations * - Change inputs/outputs to standard trig format (scaled by 1e18) instead of requiring the * integer format used by the algorithm * * Lefertis' implementation is based off Dave Dribin's trigint C library * http://www.dribin.org/dave/trigint/ * * Which in turn is based from a now deleted article which can be found in the Wayback Machine: * http://web.archive.org/web/20120301144605/http://www.dattalo.com/technical/software/pic/picsine.html */ library Trigonometry { // Table index into the trigonometric table uint256 constant INDEX_WIDTH = 8; // Interpolation between successive entries in the table uint256 constant INTERP_WIDTH = 16; uint256 constant INDEX_OFFSET = 28 - INDEX_WIDTH; uint256 constant INTERP_OFFSET = INDEX_OFFSET - INTERP_WIDTH; uint32 constant ANGLES_IN_CYCLE = 1073741824; uint32 constant QUADRANT_HIGH_MASK = 536870912; uint32 constant QUADRANT_LOW_MASK = 268435456; uint256 constant SINE_TABLE_SIZE = 256; // Pi as an 18 decimal value, which is plenty of accuracy: "For JPL's highest accuracy calculations, which are for // interplanetary navigation, we use 3.141592653589793: https://www.jpl.nasa.gov/edu/news/2016/3/16/how-many-decimals-of-pi-do-we-really-need/ uint256 constant PI = 3141592653589793238; uint256 constant TWO_PI = 2 * PI; uint256 constant PI_OVER_TWO = PI / 2; // The constant sine lookup table was generated by generate_trigonometry.py. We must use a constant // bytes array because constant arrays are not supported in Solidity. Each entry in the lookup // table is 4 bytes. Since we're using 32-bit parameters for the lookup table, we get a table size // of 2^(32/4) + 1 = 257, where the first and last entries are equivalent (hence the table size of // 256 defined above) uint8 constant entry_bytes = 4; // each entry in the lookup table is 4 bytes uint256 constant entry_mask = ((1 << (8 * entry_bytes)) - 1); // mask used to cast bytes32 -> lookup table entry bytes constant sin_table = hex"00_00_00_00_00_c9_0f_88_01_92_1d_20_02_5b_26_d7_03_24_2a_bf_03_ed_26_e6_04_b6_19_5d_05_7f_00_35_06_47_d9_7c_07_10_a3_45_07_d9_5b_9e_08_a2_00_9a_09_6a_90_49_0a_33_08_bc_0a_fb_68_05_0b_c3_ac_35_0c_8b_d3_5e_0d_53_db_92_0e_1b_c2_e4_0e_e3_87_66_0f_ab_27_2b_10_72_a0_48_11_39_f0_cf_12_01_16_d5_12_c8_10_6e_13_8e_db_b1_14_55_76_b1_15_1b_df_85_15_e2_14_44_16_a8_13_05_17_6d_d9_de_18_33_66_e8_18_f8_b8_3c_19_bd_cb_f3_1a_82_a0_25_1b_47_32_ef_1c_0b_82_6a_1c_cf_8c_b3_1d_93_4f_e5_1e_56_ca_1e_1f_19_f9_7b_1f_dc_dc_1b_20_9f_70_1c_21_61_b3_9f_22_23_a4_c5_22_e5_41_af_23_a6_88_7e_24_67_77_57_25_28_0c_5d_25_e8_45_b6_26_a8_21_85_27_67_9d_f4_28_26_b9_28_28_e5_71_4a_29_a3_c4_85_2a_61_b1_01_2b_1f_34_eb_2b_dc_4e_6f_2c_98_fb_ba_2d_55_3a_fb_2e_11_0a_62_2e_cc_68_1e_2f_87_52_62_30_41_c7_60_30_fb_c5_4d_31_b5_4a_5d_32_6e_54_c7_33_26_e2_c2_33_de_f2_87_34_96_82_4f_35_4d_90_56_36_04_1a_d9_36_ba_20_13_37_6f_9e_46_38_24_93_b0_38_d8_fe_93_39_8c_dd_32_3a_40_2d_d1_3a_f2_ee_b7_3b_a5_1e_29_3c_56_ba_70_3d_07_c1_d5_3d_b8_32_a5_3e_68_0b_2c_3f_17_49_b7_3f_c5_ec_97_40_73_f2_1d_41_21_58_9a_41_ce_1e_64_42_7a_41_d0_43_25_c1_35_43_d0_9a_ec_44_7a_cd_50_45_24_56_bc_45_cd_35_8f_46_75_68_27_47_1c_ec_e6_47_c3_c2_2e_48_69_e6_64_49_0f_57_ee_49_b4_15_33_4a_58_1c_9d_4a_fb_6c_97_4b_9e_03_8f_4c_3f_df_f3_4c_e1_00_34_4d_81_62_c3_4e_21_06_17_4e_bf_e8_a4_4f_5e_08_e2_4f_fb_65_4c_50_97_fc_5e_51_33_cc_94_51_ce_d4_6e_52_69_12_6e_53_02_85_17_53_9b_2a_ef_54_33_02_7d_54_ca_0a_4a_55_60_40_e2_55_f5_a4_d2_56_8a_34_a9_57_1d_ee_f9_57_b0_d2_55_58_42_dd_54_58_d4_0e_8c_59_64_64_97_59_f3_de_12_5a_82_79_99_5b_10_35_ce_5b_9d_11_53_5c_29_0a_cc_5c_b4_20_df_5d_3e_52_36_5d_c7_9d_7b_5e_50_01_5d_5e_d7_7c_89_5f_5e_0d_b2_5f_e3_b3_8d_60_68_6c_ce_60_ec_38_2f_61_6f_14_6b_61_f1_00_3e_62_71_fa_68_62_f2_01_ac_63_71_14_cc_63_ef_32_8f_64_6c_59_bf_64_e8_89_25_65_63_bf_91_65_dd_fb_d2_66_57_3c_bb_66_cf_81_1f_67_46_c7_d7_67_bd_0f_bc_68_32_57_aa_68_a6_9e_80_69_19_e3_1f_69_8c_24_6b_69_fd_61_4a_6a_6d_98_a3_6a_dc_c9_64_6b_4a_f2_78_6b_b8_12_d0_6c_24_29_5f_6c_8f_35_1b_6c_f9_34_fb_6d_62_27_f9_6d_ca_0d_14_6e_30_e3_49_6e_96_a9_9c_6e_fb_5f_11_6f_5f_02_b1_6f_c1_93_84_70_23_10_99_70_83_78_fe_70_e2_cb_c5_71_41_08_04_71_9e_2c_d1_71_fa_39_48_72_55_2c_84_72_af_05_a6_73_07_c3_cf_73_5f_66_25_73_b5_eb_d0_74_0b_53_fa_74_5f_9d_d0_74_b2_c8_83_75_04_d3_44_75_55_bd_4b_75_a5_85_ce_75_f4_2c_0a_76_41_af_3c_76_8e_0e_a5_76_d9_49_88_77_23_5f_2c_77_6c_4e_da_77_b4_17_df_77_fa_b9_88_78_40_33_28_78_84_84_13_78_c7_ab_a1_79_09_a9_2c_79_4a_7c_11_79_8a_23_b0_79_c8_9f_6d_7a_05_ee_ac_7a_42_10_d8_7a_7d_05_5a_7a_b6_cb_a3_7a_ef_63_23_7b_26_cb_4e_7b_5d_03_9d_7b_92_0b_88_7b_c5_e2_8f_7b_f8_88_2f_7c_29_fb_ed_7c_5a_3d_4f_7c_89_4b_dd_7c_b7_27_23_7c_e3_ce_b1_7d_0f_42_17_7d_39_80_eb_7d_62_8a_c5_7d_8a_5f_3f_7d_b0_fd_f7_7d_d6_66_8e_7d_fa_98_a7_7e_1d_93_e9_7e_3f_57_fe_7e_5f_e4_92_7e_7f_39_56_7e_9d_55_fb_7e_ba_3a_38_7e_d5_e5_c5_7e_f0_58_5f_7f_09_91_c3_7f_21_91_b3_7f_38_57_f5_7f_4d_e4_50_7f_62_36_8e_7f_75_4e_7f_7f_87_2b_f2_7f_97_ce_bc_7f_a7_36_b3_7f_b5_63_b2_7f_c2_55_95_7f_ce_0c_3d_7f_d8_87_8d_7f_e1_c7_6a_7f_e9_cb_bf_7f_f0_94_77_7f_f6_21_81_7f_fa_72_d0_7f_fd_88_59_7f_ff_62_15_7f_ff_ff_ff"; /** * @notice Return the sine of a value, specified in radians scaled by 1e18 * @dev This algorithm for converting sine only uses integer values, and it works by dividing the * circle into 30 bit angles, i.e. there are 1,073,741,824 (2^30) angle units, instead of the * standard 360 degrees (2pi radians). From there, we get an output in range -2,147,483,647 to * 2,147,483,647, (which is the max value of an int32) which is then converted back to the standard * range of -1 to 1, again scaled by 1e18 * @param _angle Angle to convert * @return Result scaled by 1e18 */ function sin(uint256 _angle) internal pure returns (int256) { unchecked { // Convert angle from from arbitrary radian value (range of 0 to 2pi) to the algorithm's range // of 0 to 1,073,741,824 _angle = (ANGLES_IN_CYCLE * (_angle % TWO_PI)) / TWO_PI; // Apply a mask on an integer to extract a certain number of bits, where angle is the integer // whose bits we want to get, the width is the width of the bits (in bits) we want to extract, // and the offset is the offset of the bits (in bits) we want to extract. The result is an // integer containing _width bits of _value starting at the offset bit uint256 interp = (_angle >> INTERP_OFFSET) & ((1 << INTERP_WIDTH) - 1); uint256 index = (_angle >> INDEX_OFFSET) & ((1 << INDEX_WIDTH) - 1); // The lookup table only contains data for one quadrant (since sin is symmetric around both // axes), so here we figure out which quadrant we're in, then we lookup the values in the // table then modify values accordingly bool is_odd_quadrant = (_angle & QUADRANT_LOW_MASK) == 0; bool is_negative_quadrant = (_angle & QUADRANT_HIGH_MASK) != 0; if (!is_odd_quadrant) { index = SINE_TABLE_SIZE - 1 - index; } bytes memory table = sin_table; // We are looking for two consecutive indices in our lookup table // Since EVM is left aligned, to read n bytes of data from idx i, we must read from `i * data_len` + `n` // therefore, to read two entries of size entry_bytes `index * entry_bytes` + `entry_bytes * 2` uint256 offset1_2 = (index + 2) * entry_bytes; // This following snippet will function for any entry_bytes <= 15 uint256 x1_2; assembly { // mload will grab one word worth of bytes (32), as that is the minimum size in EVM x1_2 := mload(add(table, offset1_2)) } // We now read the last two numbers of size entry_bytes from x1_2 // in example: entry_bytes = 4; x1_2 = 0x00...12345678abcdefgh // therefore: entry_mask = 0xFFFFFFFF // 0x00...12345678abcdefgh >> 8*4 = 0x00...12345678 // 0x00...12345678 & 0xFFFFFFFF = 0x12345678 uint256 x1 = (x1_2 >> (8 * entry_bytes)) & entry_mask; // 0x00...12345678abcdefgh & 0xFFFFFFFF = 0xabcdefgh uint256 x2 = x1_2 & entry_mask; // Approximate angle by interpolating in the table, accounting for the quadrant uint256 approximation = ((x2 - x1) * interp) >> INTERP_WIDTH; int256 sine = is_odd_quadrant ? int256(x1) + int256(approximation) : int256(x2) - int256(approximation); if (is_negative_quadrant) { sine *= -1; } // Bring result from the range of -2,147,483,647 through 2,147,483,647 to -1e18 through 1e18. // This can never overflow because sine is bounded by the above values return (sine * 1e18) / 2_147_483_647; } } /** * @notice Return the cosine of a value, specified in radians scaled by 1e18 * @dev This is identical to the sin() method, and just computes the value by delegating to the * sin() method using the identity cos(x) = sin(x + pi/2) * @dev Overflow when `angle + PI_OVER_TWO > type(uint256).max` is ok, results are still accurate * @param _angle Angle to convert * @return Result scaled by 1e18 */ function cos(uint256 _angle) internal pure returns (int256) { unchecked { return sin(_angle + PI_OVER_TWO); } } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.12; // Core utils used extensively to format CSS and numbers. library utils { struct HSL { uint256 h; uint256 s; uint256 l; } function random(string memory input) internal pure returns (uint256) { return uint256(keccak256(abi.encodePacked(input))); } function randomRange( uint256 tokenId, string memory keyPrefix, uint256 lower, uint256 upper ) internal pure returns (uint256) { uint256 rand = random(string(abi.encodePacked(keyPrefix, uint2str(tokenId)))); return (rand % (upper - lower + 1)) + lower; } function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } function generateColors(uint256 _hue, uint256 _numColors) public pure returns (HSL[] memory) { HSL[] memory colors = new HSL[](_numColors); for (uint256 i = 0; i < _numColors; i++) { colors[i] = HSL(_hue, 100 - ((i * 50) / _numColors), 70 - ((i * 30) / _numColors)); } return colors; } function getHueName(uint256 _hue) public pure returns (string memory) { _hue = _hue % 360; string[12] memory colors = [ "Red", "Orange", "Yellow", "Chartreuse", "Green", "Spring green", "Turquoise", "Teal", "Blue", "Violet", "Magenta", "Rose" ]; uint256 colorIndex = (_hue / 30) % colors.length; return colors[colorIndex]; } function getHslString(HSL memory _hsl) public pure returns (string memory) { return string(abi.encodePacked("hsl(", uint2str(_hsl.h), ",", uint2str(_hsl.s), "%,", uint2str(_hsl.l), "%)")); } function uint2floatstr(uint256 _i_scaled, uint256 _decimals) internal pure returns (string memory) { return string.concat(uint2str(_i_scaled / (10**_decimals)), ".", uint2str(_i_scaled % (10**_decimals))); } function int2str(int256 _i) internal pure returns (string memory _uintAsString) { if (_i < 0) { return string.concat("-", uint2str(uint256(-_i))); } else { return uint2str(uint256(_i)); } } // converts an unsigned integer to a string function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k - 1; uint8 temp = (48 + uint8(_i - (_i / 10) * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: MIT pragma solidity >= 0.4.22 <0.9.0; library console { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function _sendLogPayload(bytes memory payload) private view { uint256 payloadLength = payload.length; address consoleAddress = CONSOLE_ADDRESS; assembly { let payloadStart := add(payload, 32) let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) } } function log() internal view { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); } function logUint(uint256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function logString(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function log(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint256 p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); } function log(uint256 p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); } function log(uint256 p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); } function log(uint256 p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); } function log(string memory p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); } function log(string memory p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); } function log(bool p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); } function log(address p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint256 p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); } function log(uint256 p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); } function log(uint256 p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); } function log(uint256 p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); } function log(uint256 p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); } function log(uint256 p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); } function log(uint256 p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); } function log(uint256 p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); } function log(uint256 p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); } function log(uint256 p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); } function log(uint256 p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); } function log(uint256 p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); } function log(uint256 p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); } function log(string memory p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); } function log(string memory p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); } function log(string memory p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); } function log(string memory p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); } function log(bool p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); } function log(bool p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); } function log(bool p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); } function log(address p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); } function log(address p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); } function log(address p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.2; /// [MIT License] /// @title Base64 /// @notice Provides a function for encoding some bytes in base64 /// @author Brecht Devos <[email protected]> library Base64 { bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /// @notice Encodes some bytes to the base64 representation function encode(bytes memory data) internal pure returns (string memory) { uint256 len = data.length; if (len == 0) return ""; // multiply by 4/3 rounded up uint256 encodedLen = 4 * ((len + 2) / 3); // Add some extra buffer at the end bytes memory result = new bytes(encodedLen + 32); bytes memory table = TABLE; assembly { let tablePtr := add(table, 1) let resultPtr := add(result, 32) for { let i := 0 } lt(i, len) { } { i := add(i, 3) let input := and(mload(add(data, i)), 0xffffff) let out := mload(add(tablePtr, and(shr(18, input), 0x3F))) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)) out := shl(224, out) mstore(resultPtr, out) resultPtr := add(resultPtr, 4) } switch mod(len, 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } mstore(result, encodedLen) } return string(result); } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": { "contracts/Utilities.sol": { "utils": "0x01e833cf8c115bb859a8e16a72d5ff298f834413" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"_allowListMintStartBlock","type":"uint256"},{"internalType":"uint256","name":"_publicMintOffsetBlocks","type":"uint256"},{"internalType":"address","name":"_renderer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"allowListMintStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"allowListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasAllowlistSaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasPublicSaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"mintAllowList","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"mintPublic","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"mintQuotaRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMintOffsetBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renderer","outputs":[{"internalType":"contract Renderer","name":"","type":"address"}],"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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allowListMintStartBlock","type":"uint256"}],"name":"setAllowListMintStartBlock","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":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_publicMintOffsetBlocks","type":"uint256"}],"name":"setPublicMintOffsetBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620051393803806200513983398181016040528101906200003791906200044c565b878781600290816200004a919062000794565b5080600390816200005c919062000794565b506200006d6200010760201b60201c565b600081905550505062000095620000896200011060201b60201c565b6200011860201b60201c565b8560098190555084600a8190555083600c8190555082600d8190555081600e8190555080600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050506200087b565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200024782620001fc565b810181811067ffffffffffffffff821117156200026957620002686200020d565b5b80604052505050565b60006200027e620001de565b90506200028c82826200023c565b919050565b600067ffffffffffffffff821115620002af57620002ae6200020d565b5b620002ba82620001fc565b9050602081019050919050565b60005b83811015620002e7578082015181840152602081019050620002ca565b60008484015250505050565b60006200030a620003048462000291565b62000272565b905082815260208101848484011115620003295762000328620001f7565b5b62000336848285620002c7565b509392505050565b600082601f830112620003565762000355620001f2565b5b815162000368848260208601620002f3565b91505092915050565b6000819050919050565b620003868162000371565b81146200039257600080fd5b50565b600081519050620003a6816200037b565b92915050565b6000819050919050565b620003c181620003ac565b8114620003cd57600080fd5b50565b600081519050620003e181620003b6565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200041482620003e7565b9050919050565b620004268162000407565b81146200043257600080fd5b50565b60008151905062000446816200041b565b92915050565b600080600080600080600080610100898b03121562000470576200046f620001e8565b5b600089015167ffffffffffffffff811115620004915762000490620001ed565b5b6200049f8b828c016200033e565b985050602089015167ffffffffffffffff811115620004c357620004c2620001ed565b5b620004d18b828c016200033e565b9750506040620004e48b828c0162000395565b9650506060620004f78b828c0162000395565b95505060806200050a8b828c01620003d0565b94505060a06200051d8b828c0162000395565b93505060c0620005308b828c0162000395565b92505060e0620005438b828c0162000435565b9150509295985092959890939650565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620005a657607f821691505b602082108103620005bc57620005bb6200055e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620006267fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620005e7565b620006328683620005e7565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620006756200066f620006698462000371565b6200064a565b62000371565b9050919050565b6000819050919050565b620006918362000654565b620006a9620006a0826200067c565b848454620005f4565b825550505050565b600090565b620006c0620006b1565b620006cd81848462000686565b505050565b5b81811015620006f557620006e9600082620006b6565b600181019050620006d3565b5050565b601f82111562000744576200070e81620005c2565b6200071984620005d7565b8101602085101562000729578190505b620007416200073885620005d7565b830182620006d2565b50505b505050565b600082821c905092915050565b6000620007696000198460080262000749565b1980831691505092915050565b600062000784838362000756565b9150826002028217905092915050565b6200079f8262000553565b67ffffffffffffffff811115620007bb57620007ba6200020d565b5b620007c782546200058d565b620007d4828285620006f9565b600060209050601f8311600181146200080c5760008415620007f7578287015190505b62000803858262000776565b86555062000873565b601f1984166200081c86620005c2565b60005b8281101562000846578489015182556001820191506020850194506020810190506200081f565b8683101562000866578489015162000862601f89168262000756565b8355505b6001600288020188555050505b505050505050565b6148ae806200088b6000396000f3fe6080604052600436106102045760003560e01c80638da5cb5b11610118578063c87b56dd116100a0578063efd0cbf91161006f578063efd0cbf91461072a578063f2fde38b14610746578063f764561d1461076f578063fa05a65714610798578063fdd4b0f0146107b457610204565b8063c87b56dd1461065a578063d0e59d5a14610697578063d5abeb01146106c2578063e985e9c5146106ed57610204565b8063a22cb465116100e7578063a22cb465146105a3578063afc1cad3146105cc578063b228d925146105f7578063b88d4fde14610622578063c204642c1461063e57610204565b80638da5cb5b146104f957806391b7f5ed1461052457806395d89b411461054d578063a035b1fe1461057857610204565b806323b872dd1161019b57806342842e0e1161016a57806342842e0e146104215780636352211e1461043d57806370a082311461047a578063715018a6146104b75780638ada6b0f146104ce57610204565b806323b872dd14610386578063247155ff146103a25780632eb4a7ab146103df5780633ccfd60b1461040a57610204565b80630bf02d87116101d75780630bf02d87146102ca5780630e2a1448146102f5578063170a78cc1461033257806318160ddd1461035b57610204565b806301ffc9a71461020957806306fdde0314610246578063081812fc14610271578063095ea7b3146102ae575b600080fd5b34801561021557600080fd5b50610230600480360381019061022b91906127a8565b6107df565b60405161023d91906127f0565b60405180910390f35b34801561025257600080fd5b5061025b610871565b604051610268919061289b565b60405180910390f35b34801561027d57600080fd5b50610298600480360381019061029391906128f3565b610903565b6040516102a59190612961565b60405180910390f35b6102c860048036038101906102c391906129a8565b610982565b005b3480156102d657600080fd5b506102df610ac6565b6040516102ec91906127f0565b60405180910390f35b34801561030157600080fd5b5061031c600480360381019061031791906129e8565b610ad3565b6040516103299190612a24565b60405180910390f35b34801561033e57600080fd5b50610359600480360381019061035491906128f3565b610af1565b005b34801561036757600080fd5b50610370610b03565b60405161037d9190612a24565b60405180910390f35b6103a0600480360381019061039b9190612a3f565b610b1a565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190612af7565b610e3c565b6040516103d691906127f0565b60405180910390f35b3480156103eb57600080fd5b506103f4610ebb565b6040516104019190612b70565b60405180910390f35b34801561041657600080fd5b5061041f610ec1565b005b61043b60048036038101906104369190612a3f565b610f09565b005b34801561044957600080fd5b50610464600480360381019061045f91906128f3565b610f29565b6040516104719190612961565b60405180910390f35b34801561048657600080fd5b506104a1600480360381019061049c91906129e8565b610f3b565b6040516104ae9190612a24565b60405180910390f35b3480156104c357600080fd5b506104cc610ff3565b005b3480156104da57600080fd5b506104e3611007565b6040516104f09190612bea565b60405180910390f35b34801561050557600080fd5b5061050e61102d565b60405161051b9190612961565b60405180910390f35b34801561053057600080fd5b5061054b600480360381019061054691906128f3565b611057565b005b34801561055957600080fd5b50610562611069565b60405161056f919061289b565b60405180910390f35b34801561058457600080fd5b5061058d6110fb565b60405161059a9190612a24565b60405180910390f35b3480156105af57600080fd5b506105ca60048036038101906105c59190612c31565b611101565b005b3480156105d857600080fd5b506105e161120c565b6040516105ee9190612a24565b60405180910390f35b34801561060357600080fd5b5061060c611212565b6040516106199190612a24565b60405180910390f35b61063c60048036038101906106379190612da1565b611217565b005b61065860048036038101906106539190612ee7565b61128a565b005b34801561066657600080fd5b50610681600480360381019061067c91906128f3565b61133d565b60405161068e919061289b565b60405180910390f35b3480156106a357600080fd5b506106ac61187a565b6040516106b99190612a24565b60405180910390f35b3480156106ce57600080fd5b506106d7611880565b6040516106e49190612a24565b60405180910390f35b3480156106f957600080fd5b50610714600480360381019061070f9190612f43565b611886565b60405161072191906127f0565b60405180910390f35b610744600480360381019061073f91906128f3565b61191a565b005b34801561075257600080fd5b5061076d600480360381019061076891906129e8565b61196d565b005b34801561077b57600080fd5b50610796600480360381019061079191906128f3565b6119f0565b005b6107b260048036038101906107ad9190612f83565b611a02565b005b3480156107c057600080fd5b506107c9611aa1565b6040516107d691906127f0565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083a57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061086a5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461088090613012565b80601f01602080910402602001604051908101604052809291908181526020018280546108ac90613012565b80156108f95780601f106108ce576101008083540402835291602001916108f9565b820191906000526020600020905b8154815290600101906020018083116108dc57829003601f168201915b5050505050905090565b600061090e82611abb565b610944576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061098d82610f29565b90508073ffffffffffffffffffffffffffffffffffffffff166109ae611b1a565b73ffffffffffffffffffffffffffffffffffffffff1614610a11576109da816109d5611b1a565b611886565b610a10576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000600d54431015905090565b6000610ade82611b22565b6014610aea9190613072565b9050919050565b610af9611b79565b80600e8190555050565b6000610b0d611bf7565b6001546000540303905090565b6000610b2582611c00565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b8c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610b9884611ccc565b91509150610bae8187610ba9611b1a565b611cf3565b610bfa57610bc386610bbe611b1a565b611886565b610bf9576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c60576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c6d8686866001611d37565b8015610c7857600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610d4685610d22888887611d3d565b7c020000000000000000000000000000000000000000000000000000000017611d65565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610dcc5760006001850190506000600460008381526020019081526020016000205403610dca576000548114610dc9578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e348686866001611d90565b505050505050565b6000610eb2838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600c5486604051602001610e9791906130ee565b60405160208183030381529060405280519060200120611d96565b90509392505050565b600c5481565b610ec9611b79565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050610f0757600080fd5b565b610f2483838360405180602001604052806000815250611217565b505050565b6000610f3482611c00565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fa2576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610ffb611b79565b6110056000611dad565b565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61105f611b79565b8060098190555050565b60606003805461107890613012565b80601f01602080910402602001604051908101604052809291908181526020018280546110a490613012565b80156110f15780601f106110c6576101008083540402835291602001916110f1565b820191906000526020600020905b8154815290600101906020018083116110d457829003601f168201915b5050505050905090565b60095481565b806007600061110e611b1a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166111bb611b1a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161120091906127f0565b60405180910390a35050565b600e5481565b601481565b611222848484610b1a565b60008373ffffffffffffffffffffffffffffffffffffffff163b146112845761124d84848484611e73565b611283576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611292611b79565b600a548251826112a29190613109565b6112aa610b03565b6112b49190613163565b11156112f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ec906131e3565b60405180910390fd5b60005b82518110156113385761132583828151811061131757611316613203565b5b602002602001015183611fc3565b808061133090613232565b9150506112f8565b505050565b606061134882611abb565b61137e576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006113898361217e565b6040516020016113999190613302565b604051602081830303815290604052905060006040518060600160405280603f815260200161483a603f913990506000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6cf5f55866040518263ffffffff1660e01b81526004016114249190612a24565b61012060405180830381865afa158015611442573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114669190613438565b90506032851115816101000190151590811515815250506000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166391b078a4836040518263ffffffff1660e01b81526004016114da919061353b565b600060405180830381865afa1580156114f7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906115209190613784565b90506000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637d11e69c84846040518363ffffffff1660e01b8152600401611581929190613979565b600060405180830381865afa15801561159e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906115c79190613a4c565b905060006115d8846020015161217e565b6115e5856060015161217e565b6115f2866040015161217e565b8660c00151611636576040518060400160405280600281526020017f4e6f00000000000000000000000000000000000000000000000000000000000081525061166d565b6040518060400160405280600381526020017f59657300000000000000000000000000000000000000000000000000000000008152505b7301e833cf8c115bb859a8e16a72d5ff298f8344136375f5696d88600001516040518263ffffffff1660e01b81526004016116a89190613aa4565b600060405180830381865af41580156116c5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906116ee9190613a4c565b604051602001611702959493929190613d91565b60405160208183030381529060405290508360e00151156117c257807301e833cf8c115bb859a8e16a72d5ff298f8344136375f5696d85602001516040518263ffffffff1660e01b81526004016117599190613aa4565b600060405180830381865af4158015611776573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061179f9190613a4c565b6040516020016117b0929190613edf565b60405160208183030381529060405290505b836101000151156117f057806040516020016117de9190613f8f565b60405160208183030381529060405290505b806040516020016118019190613fd7565b6040516020818303038152906040529050600086868361182086612306565b604051602001611833949392919061419f565b604051602081830303815290604052905061184d81612306565b60405160200161185d9190614260565b604051602081830303815290604052975050505050505050919050565b600d5481565b600a5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611922611aa1565b611961576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611958906142ce565b60405180910390fd5b61196a8161249d565b50565b611975611b79565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119db90614360565b60405180910390fd5b6119ed81611dad565b50565b6119f8611b79565b80600d8190555050565b611a0d338383610e3c565b611a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a43906143cc565b60405180910390fd5b611a54610ac6565b611a93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8a9061445e565b60405180910390fd5b611a9c8361249d565b505050565b6000600e54600d54611ab39190613163565b431015905090565b600081611ac6611bf7565b11158015611ad5575060005482105b8015611b13575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b611b81612683565b73ffffffffffffffffffffffffffffffffffffffff16611b9f61102d565b73ffffffffffffffffffffffffffffffffffffffff1614611bf5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bec906144ca565b60405180910390fd5b565b60006001905090565b60008082905080611c0f611bf7565b11611c9557600054811015611c945760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611c92575b60008103611c88576004600083600190039350838152602001908152602001600020549050611c5e565b8092505050611cc7565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611d5486868461268b565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600082611da38584612694565b1490509392505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611e99611b1a565b8786866040518563ffffffff1660e01b8152600401611ebb949392919061453f565b6020604051808303816000875af1925050508015611ef757506040513d601f19601f82011682018060405250810190611ef491906145a0565b60015b611f70573d8060008114611f27576040519150601f19603f3d011682016040523d82523d6000602084013e611f2c565b606091505b506000815103611f68576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60008054905060008203612003576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120106000848385611d37565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612087836120786000866000611d3d565b612081856126ea565b17611d65565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461212857808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506120ed565b5060008203612163576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506121796000848385611d90565b505050565b6060600082036121c5576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612301565b600082905060005b600082146121f75780806121e090613232565b915050600a826121f091906145fc565b91506121cd565b60008167ffffffffffffffff81111561221357612212612c76565b5b6040519080825280601f01601f1916602001820160405280156122455781602001600182028036833780820191505090505b50905060008290505b600086146122f9576001816122639190613072565b90506000600a808861227591906145fc565b61227f9190613109565b8761228a9190613072565b6030612296919061463a565b905060008160f81b9050808484815181106122b4576122b3613203565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a886122f091906145fc565b9750505061224e565b819450505050505b919050565b60606000825190506000810361232e5760405180602001604052806000815250915050612498565b6000600360028361233f9190613163565b61234991906145fc565b60046123559190613109565b905060006020826123669190613163565b67ffffffffffffffff81111561237f5761237e612c76565b5b6040519080825280601f01601f1916602001820160405280156123b15781602001600182028036833780820191505090505b50905060006040518060600160405280604081526020016147fa604091399050600181016020830160005b868110156124555760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b905080845260048401935050506123dc565b50600386066001811461246f576002811461247f5761248a565b613d3d60f01b600283035261248a565b603d60f81b60018303525b508484525050819450505050505b919050565b806009546124ab9190613109565b3410156124ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e4906146bb565b60405180910390fd5b600a54816124f9610b03565b6125039190613163565b1115612544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161253b906131e3565b60405180910390fd5b60148161255033611b22565b61255a9190613163565b111561259b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259290614727565b60405180910390fd5b6125a53382611fc3565b806009546125b39190613109565b3411156126805760003373ffffffffffffffffffffffffffffffffffffffff16826009546125e19190613109565b346125ec9190613072565b6040516125f890614778565b60006040518083038185875af1925050503d8060008114612635576040519150601f19603f3d011682016040523d82523d6000602084013e61263a565b606091505b505090508061267e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612675906147d9565b60405180910390fd5b505b50565b600033905090565b60009392505050565b60008082905060005b84518110156126df576126ca828683815181106126bd576126bc613203565b5b60200260200101516126fa565b915080806126d790613232565b91505061269d565b508091505092915050565b60006001821460e11b9050919050565b60008183106127125761270d8284612725565b61271d565b61271c8383612725565b5b905092915050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61278581612750565b811461279057600080fd5b50565b6000813590506127a28161277c565b92915050565b6000602082840312156127be576127bd612746565b5b60006127cc84828501612793565b91505092915050565b60008115159050919050565b6127ea816127d5565b82525050565b600060208201905061280560008301846127e1565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561284557808201518184015260208101905061282a565b60008484015250505050565b6000601f19601f8301169050919050565b600061286d8261280b565b6128778185612816565b9350612887818560208601612827565b61289081612851565b840191505092915050565b600060208201905081810360008301526128b58184612862565b905092915050565b6000819050919050565b6128d0816128bd565b81146128db57600080fd5b50565b6000813590506128ed816128c7565b92915050565b60006020828403121561290957612908612746565b5b6000612917848285016128de565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061294b82612920565b9050919050565b61295b81612940565b82525050565b60006020820190506129766000830184612952565b92915050565b61298581612940565b811461299057600080fd5b50565b6000813590506129a28161297c565b92915050565b600080604083850312156129bf576129be612746565b5b60006129cd85828601612993565b92505060206129de858286016128de565b9150509250929050565b6000602082840312156129fe576129fd612746565b5b6000612a0c84828501612993565b91505092915050565b612a1e816128bd565b82525050565b6000602082019050612a396000830184612a15565b92915050565b600080600060608486031215612a5857612a57612746565b5b6000612a6686828701612993565b9350506020612a7786828701612993565b9250506040612a88868287016128de565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f840112612ab757612ab6612a92565b5b8235905067ffffffffffffffff811115612ad457612ad3612a97565b5b602083019150836020820283011115612af057612aef612a9c565b5b9250929050565b600080600060408486031215612b1057612b0f612746565b5b6000612b1e86828701612993565b935050602084013567ffffffffffffffff811115612b3f57612b3e61274b565b5b612b4b86828701612aa1565b92509250509250925092565b6000819050919050565b612b6a81612b57565b82525050565b6000602082019050612b856000830184612b61565b92915050565b6000819050919050565b6000612bb0612bab612ba684612920565b612b8b565b612920565b9050919050565b6000612bc282612b95565b9050919050565b6000612bd482612bb7565b9050919050565b612be481612bc9565b82525050565b6000602082019050612bff6000830184612bdb565b92915050565b612c0e816127d5565b8114612c1957600080fd5b50565b600081359050612c2b81612c05565b92915050565b60008060408385031215612c4857612c47612746565b5b6000612c5685828601612993565b9250506020612c6785828601612c1c565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cae82612851565b810181811067ffffffffffffffff82111715612ccd57612ccc612c76565b5b80604052505050565b6000612ce061273c565b9050612cec8282612ca5565b919050565b600067ffffffffffffffff821115612d0c57612d0b612c76565b5b612d1582612851565b9050602081019050919050565b82818337600083830152505050565b6000612d44612d3f84612cf1565b612cd6565b905082815260208101848484011115612d6057612d5f612c71565b5b612d6b848285612d22565b509392505050565b600082601f830112612d8857612d87612a92565b5b8135612d98848260208601612d31565b91505092915050565b60008060008060808587031215612dbb57612dba612746565b5b6000612dc987828801612993565b9450506020612dda87828801612993565b9350506040612deb878288016128de565b925050606085013567ffffffffffffffff811115612e0c57612e0b61274b565b5b612e1887828801612d73565b91505092959194509250565b600067ffffffffffffffff821115612e3f57612e3e612c76565b5b602082029050602081019050919050565b6000612e63612e5e84612e24565b612cd6565b90508083825260208201905060208402830185811115612e8657612e85612a9c565b5b835b81811015612eaf5780612e9b8882612993565b845260208401935050602081019050612e88565b5050509392505050565b600082601f830112612ece57612ecd612a92565b5b8135612ede848260208601612e50565b91505092915050565b60008060408385031215612efe57612efd612746565b5b600083013567ffffffffffffffff811115612f1c57612f1b61274b565b5b612f2885828601612eb9565b9250506020612f39858286016128de565b9150509250929050565b60008060408385031215612f5a57612f59612746565b5b6000612f6885828601612993565b9250506020612f7985828601612993565b9150509250929050565b600080600060408486031215612f9c57612f9b612746565b5b6000612faa868287016128de565b935050602084013567ffffffffffffffff811115612fcb57612fca61274b565b5b612fd786828701612aa1565b92509250509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061302a57607f821691505b60208210810361303d5761303c612fe3565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061307d826128bd565b9150613088836128bd565b92508282039050818111156130a05761309f613043565b5b92915050565b60008160601b9050919050565b60006130be826130a6565b9050919050565b60006130d0826130b3565b9050919050565b6130e86130e382612940565b6130c5565b82525050565b60006130fa82846130d7565b60148201915081905092915050565b6000613114826128bd565b915061311f836128bd565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561315857613157613043565b5b828202905092915050565b600061316e826128bd565b9150613179836128bd565b925082820190508082111561319157613190613043565b5b92915050565b7f45786365656473206d617820737570706c790000000000000000000000000000600082015250565b60006131cd601283612816565b91506131d882613197565b602082019050919050565b600060208201905081810360008301526131fc816131c0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061323d826128bd565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361326f5761326e613043565b5b600182019050919050565b600081905092915050565b7f4b616c6569646f73636f70652023000000000000000000000000000000000000600082015250565b60006132bb600e8361327a565b91506132c682613285565b600e82019050919050565b60006132dc8261280b565b6132e6818561327a565b93506132f6818560208601612827565b80840191505092915050565b600061330d826132ae565b915061331982846132d1565b915081905092915050565b600080fd5b600080fd5b60008151905061333d816128c7565b92915050565b60008151905061335281612c05565b92915050565b6000610120828403121561336f5761336e613324565b5b61337a610120612cd6565b9050600061338a8482850161332e565b600083015250602061339e8482850161332e565b60208301525060406133b28482850161332e565b60408301525060606133c68482850161332e565b60608301525060806133da8482850161332e565b60808301525060a06133ee8482850161332e565b60a08301525060c061340284828501613343565b60c08301525060e061341684828501613343565b60e08301525061010061342b84828501613343565b6101008301525092915050565b6000610120828403121561344f5761344e612746565b5b600061345d84828501613358565b91505092915050565b61346f816128bd565b82525050565b61347e816127d5565b82525050565b6101208201600082015161349b6000850182613466565b5060208201516134ae6020850182613466565b5060408201516134c16040850182613466565b5060608201516134d46060850182613466565b5060808201516134e76080850182613466565b5060a08201516134fa60a0850182613466565b5060c082015161350d60c0850182613475565b5060e082015161352060e0850182613475565b50610100820151613535610100850182613475565b50505050565b6000610120820190506135516000830184613484565b92915050565b60006060828403121561356d5761356c613324565b5b6135776060612cd6565b905060006135878482850161332e565b600083015250602061359b8482850161332e565b60208301525060406135af8482850161332e565b60408301525092915050565b600067ffffffffffffffff8211156135d6576135d5612c76565b5b602082029050602081019050919050565b60006135fa6135f5846135bb565b612cd6565b9050808382526020820190506060840283018581111561361d5761361c612a9c565b5b835b8181101561364657806136328882613557565b84526020840193505060608101905061361f565b5050509392505050565b600082601f83011261366557613664612a92565b5b81516136758482602086016135e7565b91505092915050565b6000610200828403121561369557613694613324565b5b6136a0610100612cd6565b905060006136b08482850161332e565b60008301525060206136c48482850161332e565b60208301525060406136d884828501613557565b60408301525060a06136ec84828501613557565b60608301525061010061370184828501613557565b60808301525061016061371684828501613557565b60a0830152506101c082015167ffffffffffffffff81111561373b5761373a613329565b5b61374784828501613650565b60c0830152506101e082015167ffffffffffffffff81111561376c5761376b613329565b5b61377884828501613650565b60e08301525092915050565b60006020828403121561379a57613799612746565b5b600082015167ffffffffffffffff8111156137b8576137b761274b565b5b6137c48482850161367e565b91505092915050565b6060820160008201516137e36000850182613466565b5060208201516137f66020850182613466565b5060408201516138096040850182613466565b50505050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061384783836137cd565b60608301905092915050565b6000602082019050919050565b600061386b8261380f565b613875818561381a565b93506138808361382b565b8060005b838110156138b1578151613898888261383b565b97506138a383613853565b925050600181019050613884565b5085935050505092915050565b6000610200830160008301516138d76000860182613466565b5060208301516138ea6020860182613466565b5060408301516138fd60408601826137cd565b50606083015161391060a08601826137cd565b5060808301516139246101008601826137cd565b5060a08301516139386101608601826137cd565b5060c08301518482036101c08601526139518282613860565b91505060e08301518482036101e086015261396c8282613860565b9150508091505092915050565b60006101408201905061398f6000830185613484565b8181036101208301526139a281846138be565b90509392505050565b600067ffffffffffffffff8211156139c6576139c5612c76565b5b6139cf82612851565b9050602081019050919050565b60006139ef6139ea846139ab565b612cd6565b905082815260208101848484011115613a0b57613a0a612c71565b5b613a16848285612827565b509392505050565b600082601f830112613a3357613a32612a92565b5b8151613a438482602086016139dc565b91505092915050565b600060208284031215613a6257613a61612746565b5b600082015167ffffffffffffffff811115613a8057613a7f61274b565b5b613a8c84828501613a1e565b91505092915050565b613a9e816128bd565b82525050565b6000602082019050613ab96000830184613a95565b92915050565b7f2261747472696275746573223a205b0000000000000000000000000000000000815250565b7f7b2274726169745f74797065223a20224d6972726f7273222c202276616c756560008201527f223a200000000000000000000000000000000000000000000000000000000000602082015250565b6000613b4160238361327a565b9150613b4c82613ae5565b602382019050919050565b7f7d2c000000000000000000000000000000000000000000000000000000000000815250565b7f7b2274726169745f74797065223a20224f75747369646520417274696661637460008201527f73222c202276616c7565223a2000000000000000000000000000000000000000602082015250565b6000613bd9602d8361327a565b9150613be482613b7d565b602d82019050919050565b7f7b2274726169745f74797065223a2022496e736964652041727469666163747360008201527f222c202276616c7565223a200000000000000000000000000000000000000000602082015250565b6000613c4b602c8361327a565b9150613c5682613bef565b602c82019050919050565b7f7b2274726169745f74797065223a20224772616469656e74222c202276616c7560008201527f65223a2022000000000000000000000000000000000000000000000000000000602082015250565b6000613cbd60258361327a565b9150613cc882613c61565b602582019050919050565b7f227d2c0000000000000000000000000000000000000000000000000000000000815250565b7f7b2274726169745f74797065223a20225072696d61727920436f6c6f72222c2060008201527f2276616c7565223a202200000000000000000000000000000000000000000000602082015250565b6000613d55602a8361327a565b9150613d6082613cf9565b602a82019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000815250565b6000613d9c82613abf565b600f82019150613dab82613b34565b9150613db782886132d1565b9150613dc282613b57565b600282019150613dd182613bcc565b9150613ddd82876132d1565b9150613de882613b57565b600282019150613df782613c3e565b9150613e0382866132d1565b9150613e0e82613b57565b600282019150613e1d82613cb0565b9150613e2982856132d1565b9150613e3482613cd3565b600382019150613e4382613d48565b9150613e4f82846132d1565b9150613e5a82613d6b565b6002820191508190509695505050505050565b7f2c7b2274726169745f74797065223a20225365636f6e6461727920436f6c6f7260008201527f222c202276616c7565223a202200000000000000000000000000000000000000602082015250565b6000613ec9602d8361327a565b9150613ed482613e6d565b602d82019050919050565b6000613eeb82856132d1565b9150613ef682613ebc565b9150613f0282846132d1565b9150613f0d82613d6b565b6002820191508190509392505050565b7f2c7b2274726169745f74797065223a202248616c6f222c202276616c7565223a60008201527f2022596573227d00000000000000000000000000000000000000000000000000602082015250565b6000613f7960278361327a565b9150613f8482613f1d565b602782019050919050565b6000613f9b82846132d1565b9150613fa682613f6c565b915081905092915050565b7f5d00000000000000000000000000000000000000000000000000000000000000815250565b6000613fe382846132d1565b9150613fee82613fb1565b60018201915081905092915050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000600082015250565b600061403360098361327a565b915061403e82613ffd565b600982019050919050565b7f222c226465736372697074696f6e223a22000000000000000000000000000000600082015250565b600061407f60118361327a565b915061408a82614049565b601182019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b60006140cb60028361327a565b91506140d682614095565b600282019050919050565b7f2c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6260008201527f61736536342c0000000000000000000000000000000000000000000000000000602082015250565b600061413d60268361327a565b9150614148826140e1565b602682019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b600061418960028361327a565b915061419482614153565b600282019050919050565b60006141aa82614026565b91506141b682876132d1565b91506141c182614072565b91506141cd82866132d1565b91506141d8826140be565b91506141e482856132d1565b91506141ef82614130565b91506141fb82846132d1565b91506142068261417c565b915081905095945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b600061424a601d8361327a565b915061425582614214565b601d82019050919050565b600061426b8261423d565b915061427782846132d1565b915081905092915050565b7f5075626c69632073616c6520686173206e6f7420737461727465642079657400600082015250565b60006142b8601f83612816565b91506142c382614282565b602082019050919050565b600060208201905081810360008301526142e7816142ab565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061434a602683612816565b9150614355826142ee565b604082019050919050565b600060208201905081810360008301526143798161433d565b9050919050565b7f596f7520617265206e6f74206f6e2074686520616c6c6f776c69737400000000600082015250565b60006143b6601c83612816565b91506143c182614380565b602082019050919050565b600060208201905081810360008301526143e5816143a9565b9050919050565b7f416c6c6f776c6973742073616c6520686173206e6f742073746172746564207960008201527f6574000000000000000000000000000000000000000000000000000000000000602082015250565b6000614448602283612816565b9150614453826143ec565b604082019050919050565b600060208201905081810360008301526144778161443b565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006144b4602083612816565b91506144bf8261447e565b602082019050919050565b600060208201905081810360008301526144e3816144a7565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614511826144ea565b61451b81856144f5565b935061452b818560208601612827565b61453481612851565b840191505092915050565b60006080820190506145546000830187612952565b6145616020830186612952565b61456e6040830185612a15565b81810360608301526145808184614506565b905095945050505050565b60008151905061459a8161277c565b92915050565b6000602082840312156145b6576145b5612746565b5b60006145c48482850161458b565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614607826128bd565b9150614612836128bd565b925082614622576146216145cd565b5b828204905092915050565b600060ff82169050919050565b60006146458261462d565b91506146508361462d565b9250828201905060ff81111561466957614668613043565b5b92915050565b7f496e73756666696369656e742066656500000000000000000000000000000000600082015250565b60006146a5601083612816565b91506146b08261466f565b602082019050919050565b600060208201905081810360008301526146d481614698565b9050919050565b7f45786365656473206d6178207175616e74697479000000000000000000000000600082015250565b6000614711601483612816565b915061471c826146db565b602082019050919050565b6000602082019050818103600083015261474081614704565b9050919050565b600081905092915050565b50565b6000614762600083614747565b915061476d82614752565b600082019050919050565b600061478382614755565b9150819050919050565b7f526566756e64206661696c656400000000000000000000000000000000000000600082015250565b60006147c3600d83612816565b91506147ce8261478d565b602082019050919050565b600060208201905081810360008301526147f2816147b6565b905091905056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f46756c6c79206f6e2d636861696e2c2070726f6365647572616c6c792067656e6572617465642c20616e696d61746564206b616c6569646f73636f7065732ea264697066735822122052abef236944e932101b30fe89aa13017f608c9ba9c850189986d5776b62cea064736f6c6343000810003300000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000003e81a803dbdfb3d0c0c775bc03f7e858f42eac3ccf7aae62a18b498e8dcced2b2240000000000000000000000000000000000000000000000000000000000fa3afc000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000834a227ec86776292601d298de4a767677950a55000000000000000000000000000000000000000000000000000000000000000d4b616c6569646f73636f7065730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064b4c445343500000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102045760003560e01c80638da5cb5b11610118578063c87b56dd116100a0578063efd0cbf91161006f578063efd0cbf91461072a578063f2fde38b14610746578063f764561d1461076f578063fa05a65714610798578063fdd4b0f0146107b457610204565b8063c87b56dd1461065a578063d0e59d5a14610697578063d5abeb01146106c2578063e985e9c5146106ed57610204565b8063a22cb465116100e7578063a22cb465146105a3578063afc1cad3146105cc578063b228d925146105f7578063b88d4fde14610622578063c204642c1461063e57610204565b80638da5cb5b146104f957806391b7f5ed1461052457806395d89b411461054d578063a035b1fe1461057857610204565b806323b872dd1161019b57806342842e0e1161016a57806342842e0e146104215780636352211e1461043d57806370a082311461047a578063715018a6146104b75780638ada6b0f146104ce57610204565b806323b872dd14610386578063247155ff146103a25780632eb4a7ab146103df5780633ccfd60b1461040a57610204565b80630bf02d87116101d75780630bf02d87146102ca5780630e2a1448146102f5578063170a78cc1461033257806318160ddd1461035b57610204565b806301ffc9a71461020957806306fdde0314610246578063081812fc14610271578063095ea7b3146102ae575b600080fd5b34801561021557600080fd5b50610230600480360381019061022b91906127a8565b6107df565b60405161023d91906127f0565b60405180910390f35b34801561025257600080fd5b5061025b610871565b604051610268919061289b565b60405180910390f35b34801561027d57600080fd5b50610298600480360381019061029391906128f3565b610903565b6040516102a59190612961565b60405180910390f35b6102c860048036038101906102c391906129a8565b610982565b005b3480156102d657600080fd5b506102df610ac6565b6040516102ec91906127f0565b60405180910390f35b34801561030157600080fd5b5061031c600480360381019061031791906129e8565b610ad3565b6040516103299190612a24565b60405180910390f35b34801561033e57600080fd5b50610359600480360381019061035491906128f3565b610af1565b005b34801561036757600080fd5b50610370610b03565b60405161037d9190612a24565b60405180910390f35b6103a0600480360381019061039b9190612a3f565b610b1a565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190612af7565b610e3c565b6040516103d691906127f0565b60405180910390f35b3480156103eb57600080fd5b506103f4610ebb565b6040516104019190612b70565b60405180910390f35b34801561041657600080fd5b5061041f610ec1565b005b61043b60048036038101906104369190612a3f565b610f09565b005b34801561044957600080fd5b50610464600480360381019061045f91906128f3565b610f29565b6040516104719190612961565b60405180910390f35b34801561048657600080fd5b506104a1600480360381019061049c91906129e8565b610f3b565b6040516104ae9190612a24565b60405180910390f35b3480156104c357600080fd5b506104cc610ff3565b005b3480156104da57600080fd5b506104e3611007565b6040516104f09190612bea565b60405180910390f35b34801561050557600080fd5b5061050e61102d565b60405161051b9190612961565b60405180910390f35b34801561053057600080fd5b5061054b600480360381019061054691906128f3565b611057565b005b34801561055957600080fd5b50610562611069565b60405161056f919061289b565b60405180910390f35b34801561058457600080fd5b5061058d6110fb565b60405161059a9190612a24565b60405180910390f35b3480156105af57600080fd5b506105ca60048036038101906105c59190612c31565b611101565b005b3480156105d857600080fd5b506105e161120c565b6040516105ee9190612a24565b60405180910390f35b34801561060357600080fd5b5061060c611212565b6040516106199190612a24565b60405180910390f35b61063c60048036038101906106379190612da1565b611217565b005b61065860048036038101906106539190612ee7565b61128a565b005b34801561066657600080fd5b50610681600480360381019061067c91906128f3565b61133d565b60405161068e919061289b565b60405180910390f35b3480156106a357600080fd5b506106ac61187a565b6040516106b99190612a24565b60405180910390f35b3480156106ce57600080fd5b506106d7611880565b6040516106e49190612a24565b60405180910390f35b3480156106f957600080fd5b50610714600480360381019061070f9190612f43565b611886565b60405161072191906127f0565b60405180910390f35b610744600480360381019061073f91906128f3565b61191a565b005b34801561075257600080fd5b5061076d600480360381019061076891906129e8565b61196d565b005b34801561077b57600080fd5b50610796600480360381019061079191906128f3565b6119f0565b005b6107b260048036038101906107ad9190612f83565b611a02565b005b3480156107c057600080fd5b506107c9611aa1565b6040516107d691906127f0565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083a57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061086a5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461088090613012565b80601f01602080910402602001604051908101604052809291908181526020018280546108ac90613012565b80156108f95780601f106108ce576101008083540402835291602001916108f9565b820191906000526020600020905b8154815290600101906020018083116108dc57829003601f168201915b5050505050905090565b600061090e82611abb565b610944576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061098d82610f29565b90508073ffffffffffffffffffffffffffffffffffffffff166109ae611b1a565b73ffffffffffffffffffffffffffffffffffffffff1614610a11576109da816109d5611b1a565b611886565b610a10576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000600d54431015905090565b6000610ade82611b22565b6014610aea9190613072565b9050919050565b610af9611b79565b80600e8190555050565b6000610b0d611bf7565b6001546000540303905090565b6000610b2582611c00565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b8c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610b9884611ccc565b91509150610bae8187610ba9611b1a565b611cf3565b610bfa57610bc386610bbe611b1a565b611886565b610bf9576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c60576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c6d8686866001611d37565b8015610c7857600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610d4685610d22888887611d3d565b7c020000000000000000000000000000000000000000000000000000000017611d65565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610dcc5760006001850190506000600460008381526020019081526020016000205403610dca576000548114610dc9578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e348686866001611d90565b505050505050565b6000610eb2838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600c5486604051602001610e9791906130ee565b60405160208183030381529060405280519060200120611d96565b90509392505050565b600c5481565b610ec9611b79565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050610f0757600080fd5b565b610f2483838360405180602001604052806000815250611217565b505050565b6000610f3482611c00565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fa2576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610ffb611b79565b6110056000611dad565b565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61105f611b79565b8060098190555050565b60606003805461107890613012565b80601f01602080910402602001604051908101604052809291908181526020018280546110a490613012565b80156110f15780601f106110c6576101008083540402835291602001916110f1565b820191906000526020600020905b8154815290600101906020018083116110d457829003601f168201915b5050505050905090565b60095481565b806007600061110e611b1a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166111bb611b1a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161120091906127f0565b60405180910390a35050565b600e5481565b601481565b611222848484610b1a565b60008373ffffffffffffffffffffffffffffffffffffffff163b146112845761124d84848484611e73565b611283576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611292611b79565b600a548251826112a29190613109565b6112aa610b03565b6112b49190613163565b11156112f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ec906131e3565b60405180910390fd5b60005b82518110156113385761132583828151811061131757611316613203565b5b602002602001015183611fc3565b808061133090613232565b9150506112f8565b505050565b606061134882611abb565b61137e576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006113898361217e565b6040516020016113999190613302565b604051602081830303815290604052905060006040518060600160405280603f815260200161483a603f913990506000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6cf5f55866040518263ffffffff1660e01b81526004016114249190612a24565b61012060405180830381865afa158015611442573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114669190613438565b90506032851115816101000190151590811515815250506000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166391b078a4836040518263ffffffff1660e01b81526004016114da919061353b565b600060405180830381865afa1580156114f7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906115209190613784565b90506000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637d11e69c84846040518363ffffffff1660e01b8152600401611581929190613979565b600060405180830381865afa15801561159e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906115c79190613a4c565b905060006115d8846020015161217e565b6115e5856060015161217e565b6115f2866040015161217e565b8660c00151611636576040518060400160405280600281526020017f4e6f00000000000000000000000000000000000000000000000000000000000081525061166d565b6040518060400160405280600381526020017f59657300000000000000000000000000000000000000000000000000000000008152505b7301e833cf8c115bb859a8e16a72d5ff298f8344136375f5696d88600001516040518263ffffffff1660e01b81526004016116a89190613aa4565b600060405180830381865af41580156116c5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906116ee9190613a4c565b604051602001611702959493929190613d91565b60405160208183030381529060405290508360e00151156117c257807301e833cf8c115bb859a8e16a72d5ff298f8344136375f5696d85602001516040518263ffffffff1660e01b81526004016117599190613aa4565b600060405180830381865af4158015611776573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061179f9190613a4c565b6040516020016117b0929190613edf565b60405160208183030381529060405290505b836101000151156117f057806040516020016117de9190613f8f565b60405160208183030381529060405290505b806040516020016118019190613fd7565b6040516020818303038152906040529050600086868361182086612306565b604051602001611833949392919061419f565b604051602081830303815290604052905061184d81612306565b60405160200161185d9190614260565b604051602081830303815290604052975050505050505050919050565b600d5481565b600a5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611922611aa1565b611961576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611958906142ce565b60405180910390fd5b61196a8161249d565b50565b611975611b79565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119db90614360565b60405180910390fd5b6119ed81611dad565b50565b6119f8611b79565b80600d8190555050565b611a0d338383610e3c565b611a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a43906143cc565b60405180910390fd5b611a54610ac6565b611a93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8a9061445e565b60405180910390fd5b611a9c8361249d565b505050565b6000600e54600d54611ab39190613163565b431015905090565b600081611ac6611bf7565b11158015611ad5575060005482105b8015611b13575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b611b81612683565b73ffffffffffffffffffffffffffffffffffffffff16611b9f61102d565b73ffffffffffffffffffffffffffffffffffffffff1614611bf5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bec906144ca565b60405180910390fd5b565b60006001905090565b60008082905080611c0f611bf7565b11611c9557600054811015611c945760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611c92575b60008103611c88576004600083600190039350838152602001908152602001600020549050611c5e565b8092505050611cc7565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611d5486868461268b565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600082611da38584612694565b1490509392505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611e99611b1a565b8786866040518563ffffffff1660e01b8152600401611ebb949392919061453f565b6020604051808303816000875af1925050508015611ef757506040513d601f19601f82011682018060405250810190611ef491906145a0565b60015b611f70573d8060008114611f27576040519150601f19603f3d011682016040523d82523d6000602084013e611f2c565b606091505b506000815103611f68576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60008054905060008203612003576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120106000848385611d37565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612087836120786000866000611d3d565b612081856126ea565b17611d65565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461212857808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506120ed565b5060008203612163576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506121796000848385611d90565b505050565b6060600082036121c5576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612301565b600082905060005b600082146121f75780806121e090613232565b915050600a826121f091906145fc565b91506121cd565b60008167ffffffffffffffff81111561221357612212612c76565b5b6040519080825280601f01601f1916602001820160405280156122455781602001600182028036833780820191505090505b50905060008290505b600086146122f9576001816122639190613072565b90506000600a808861227591906145fc565b61227f9190613109565b8761228a9190613072565b6030612296919061463a565b905060008160f81b9050808484815181106122b4576122b3613203565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a886122f091906145fc565b9750505061224e565b819450505050505b919050565b60606000825190506000810361232e5760405180602001604052806000815250915050612498565b6000600360028361233f9190613163565b61234991906145fc565b60046123559190613109565b905060006020826123669190613163565b67ffffffffffffffff81111561237f5761237e612c76565b5b6040519080825280601f01601f1916602001820160405280156123b15781602001600182028036833780820191505090505b50905060006040518060600160405280604081526020016147fa604091399050600181016020830160005b868110156124555760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b905080845260048401935050506123dc565b50600386066001811461246f576002811461247f5761248a565b613d3d60f01b600283035261248a565b603d60f81b60018303525b508484525050819450505050505b919050565b806009546124ab9190613109565b3410156124ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e4906146bb565b60405180910390fd5b600a54816124f9610b03565b6125039190613163565b1115612544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161253b906131e3565b60405180910390fd5b60148161255033611b22565b61255a9190613163565b111561259b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259290614727565b60405180910390fd5b6125a53382611fc3565b806009546125b39190613109565b3411156126805760003373ffffffffffffffffffffffffffffffffffffffff16826009546125e19190613109565b346125ec9190613072565b6040516125f890614778565b60006040518083038185875af1925050503d8060008114612635576040519150601f19603f3d011682016040523d82523d6000602084013e61263a565b606091505b505090508061267e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612675906147d9565b60405180910390fd5b505b50565b600033905090565b60009392505050565b60008082905060005b84518110156126df576126ca828683815181106126bd576126bc613203565b5b60200260200101516126fa565b915080806126d790613232565b91505061269d565b508091505092915050565b60006001821460e11b9050919050565b60008183106127125761270d8284612725565b61271d565b61271c8383612725565b5b905092915050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61278581612750565b811461279057600080fd5b50565b6000813590506127a28161277c565b92915050565b6000602082840312156127be576127bd612746565b5b60006127cc84828501612793565b91505092915050565b60008115159050919050565b6127ea816127d5565b82525050565b600060208201905061280560008301846127e1565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561284557808201518184015260208101905061282a565b60008484015250505050565b6000601f19601f8301169050919050565b600061286d8261280b565b6128778185612816565b9350612887818560208601612827565b61289081612851565b840191505092915050565b600060208201905081810360008301526128b58184612862565b905092915050565b6000819050919050565b6128d0816128bd565b81146128db57600080fd5b50565b6000813590506128ed816128c7565b92915050565b60006020828403121561290957612908612746565b5b6000612917848285016128de565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061294b82612920565b9050919050565b61295b81612940565b82525050565b60006020820190506129766000830184612952565b92915050565b61298581612940565b811461299057600080fd5b50565b6000813590506129a28161297c565b92915050565b600080604083850312156129bf576129be612746565b5b60006129cd85828601612993565b92505060206129de858286016128de565b9150509250929050565b6000602082840312156129fe576129fd612746565b5b6000612a0c84828501612993565b91505092915050565b612a1e816128bd565b82525050565b6000602082019050612a396000830184612a15565b92915050565b600080600060608486031215612a5857612a57612746565b5b6000612a6686828701612993565b9350506020612a7786828701612993565b9250506040612a88868287016128de565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f840112612ab757612ab6612a92565b5b8235905067ffffffffffffffff811115612ad457612ad3612a97565b5b602083019150836020820283011115612af057612aef612a9c565b5b9250929050565b600080600060408486031215612b1057612b0f612746565b5b6000612b1e86828701612993565b935050602084013567ffffffffffffffff811115612b3f57612b3e61274b565b5b612b4b86828701612aa1565b92509250509250925092565b6000819050919050565b612b6a81612b57565b82525050565b6000602082019050612b856000830184612b61565b92915050565b6000819050919050565b6000612bb0612bab612ba684612920565b612b8b565b612920565b9050919050565b6000612bc282612b95565b9050919050565b6000612bd482612bb7565b9050919050565b612be481612bc9565b82525050565b6000602082019050612bff6000830184612bdb565b92915050565b612c0e816127d5565b8114612c1957600080fd5b50565b600081359050612c2b81612c05565b92915050565b60008060408385031215612c4857612c47612746565b5b6000612c5685828601612993565b9250506020612c6785828601612c1c565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cae82612851565b810181811067ffffffffffffffff82111715612ccd57612ccc612c76565b5b80604052505050565b6000612ce061273c565b9050612cec8282612ca5565b919050565b600067ffffffffffffffff821115612d0c57612d0b612c76565b5b612d1582612851565b9050602081019050919050565b82818337600083830152505050565b6000612d44612d3f84612cf1565b612cd6565b905082815260208101848484011115612d6057612d5f612c71565b5b612d6b848285612d22565b509392505050565b600082601f830112612d8857612d87612a92565b5b8135612d98848260208601612d31565b91505092915050565b60008060008060808587031215612dbb57612dba612746565b5b6000612dc987828801612993565b9450506020612dda87828801612993565b9350506040612deb878288016128de565b925050606085013567ffffffffffffffff811115612e0c57612e0b61274b565b5b612e1887828801612d73565b91505092959194509250565b600067ffffffffffffffff821115612e3f57612e3e612c76565b5b602082029050602081019050919050565b6000612e63612e5e84612e24565b612cd6565b90508083825260208201905060208402830185811115612e8657612e85612a9c565b5b835b81811015612eaf5780612e9b8882612993565b845260208401935050602081019050612e88565b5050509392505050565b600082601f830112612ece57612ecd612a92565b5b8135612ede848260208601612e50565b91505092915050565b60008060408385031215612efe57612efd612746565b5b600083013567ffffffffffffffff811115612f1c57612f1b61274b565b5b612f2885828601612eb9565b9250506020612f39858286016128de565b9150509250929050565b60008060408385031215612f5a57612f59612746565b5b6000612f6885828601612993565b9250506020612f7985828601612993565b9150509250929050565b600080600060408486031215612f9c57612f9b612746565b5b6000612faa868287016128de565b935050602084013567ffffffffffffffff811115612fcb57612fca61274b565b5b612fd786828701612aa1565b92509250509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061302a57607f821691505b60208210810361303d5761303c612fe3565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061307d826128bd565b9150613088836128bd565b92508282039050818111156130a05761309f613043565b5b92915050565b60008160601b9050919050565b60006130be826130a6565b9050919050565b60006130d0826130b3565b9050919050565b6130e86130e382612940565b6130c5565b82525050565b60006130fa82846130d7565b60148201915081905092915050565b6000613114826128bd565b915061311f836128bd565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561315857613157613043565b5b828202905092915050565b600061316e826128bd565b9150613179836128bd565b925082820190508082111561319157613190613043565b5b92915050565b7f45786365656473206d617820737570706c790000000000000000000000000000600082015250565b60006131cd601283612816565b91506131d882613197565b602082019050919050565b600060208201905081810360008301526131fc816131c0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061323d826128bd565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361326f5761326e613043565b5b600182019050919050565b600081905092915050565b7f4b616c6569646f73636f70652023000000000000000000000000000000000000600082015250565b60006132bb600e8361327a565b91506132c682613285565b600e82019050919050565b60006132dc8261280b565b6132e6818561327a565b93506132f6818560208601612827565b80840191505092915050565b600061330d826132ae565b915061331982846132d1565b915081905092915050565b600080fd5b600080fd5b60008151905061333d816128c7565b92915050565b60008151905061335281612c05565b92915050565b6000610120828403121561336f5761336e613324565b5b61337a610120612cd6565b9050600061338a8482850161332e565b600083015250602061339e8482850161332e565b60208301525060406133b28482850161332e565b60408301525060606133c68482850161332e565b60608301525060806133da8482850161332e565b60808301525060a06133ee8482850161332e565b60a08301525060c061340284828501613343565b60c08301525060e061341684828501613343565b60e08301525061010061342b84828501613343565b6101008301525092915050565b6000610120828403121561344f5761344e612746565b5b600061345d84828501613358565b91505092915050565b61346f816128bd565b82525050565b61347e816127d5565b82525050565b6101208201600082015161349b6000850182613466565b5060208201516134ae6020850182613466565b5060408201516134c16040850182613466565b5060608201516134d46060850182613466565b5060808201516134e76080850182613466565b5060a08201516134fa60a0850182613466565b5060c082015161350d60c0850182613475565b5060e082015161352060e0850182613475565b50610100820151613535610100850182613475565b50505050565b6000610120820190506135516000830184613484565b92915050565b60006060828403121561356d5761356c613324565b5b6135776060612cd6565b905060006135878482850161332e565b600083015250602061359b8482850161332e565b60208301525060406135af8482850161332e565b60408301525092915050565b600067ffffffffffffffff8211156135d6576135d5612c76565b5b602082029050602081019050919050565b60006135fa6135f5846135bb565b612cd6565b9050808382526020820190506060840283018581111561361d5761361c612a9c565b5b835b8181101561364657806136328882613557565b84526020840193505060608101905061361f565b5050509392505050565b600082601f83011261366557613664612a92565b5b81516136758482602086016135e7565b91505092915050565b6000610200828403121561369557613694613324565b5b6136a0610100612cd6565b905060006136b08482850161332e565b60008301525060206136c48482850161332e565b60208301525060406136d884828501613557565b60408301525060a06136ec84828501613557565b60608301525061010061370184828501613557565b60808301525061016061371684828501613557565b60a0830152506101c082015167ffffffffffffffff81111561373b5761373a613329565b5b61374784828501613650565b60c0830152506101e082015167ffffffffffffffff81111561376c5761376b613329565b5b61377884828501613650565b60e08301525092915050565b60006020828403121561379a57613799612746565b5b600082015167ffffffffffffffff8111156137b8576137b761274b565b5b6137c48482850161367e565b91505092915050565b6060820160008201516137e36000850182613466565b5060208201516137f66020850182613466565b5060408201516138096040850182613466565b50505050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061384783836137cd565b60608301905092915050565b6000602082019050919050565b600061386b8261380f565b613875818561381a565b93506138808361382b565b8060005b838110156138b1578151613898888261383b565b97506138a383613853565b925050600181019050613884565b5085935050505092915050565b6000610200830160008301516138d76000860182613466565b5060208301516138ea6020860182613466565b5060408301516138fd60408601826137cd565b50606083015161391060a08601826137cd565b5060808301516139246101008601826137cd565b5060a08301516139386101608601826137cd565b5060c08301518482036101c08601526139518282613860565b91505060e08301518482036101e086015261396c8282613860565b9150508091505092915050565b60006101408201905061398f6000830185613484565b8181036101208301526139a281846138be565b90509392505050565b600067ffffffffffffffff8211156139c6576139c5612c76565b5b6139cf82612851565b9050602081019050919050565b60006139ef6139ea846139ab565b612cd6565b905082815260208101848484011115613a0b57613a0a612c71565b5b613a16848285612827565b509392505050565b600082601f830112613a3357613a32612a92565b5b8151613a438482602086016139dc565b91505092915050565b600060208284031215613a6257613a61612746565b5b600082015167ffffffffffffffff811115613a8057613a7f61274b565b5b613a8c84828501613a1e565b91505092915050565b613a9e816128bd565b82525050565b6000602082019050613ab96000830184613a95565b92915050565b7f2261747472696275746573223a205b0000000000000000000000000000000000815250565b7f7b2274726169745f74797065223a20224d6972726f7273222c202276616c756560008201527f223a200000000000000000000000000000000000000000000000000000000000602082015250565b6000613b4160238361327a565b9150613b4c82613ae5565b602382019050919050565b7f7d2c000000000000000000000000000000000000000000000000000000000000815250565b7f7b2274726169745f74797065223a20224f75747369646520417274696661637460008201527f73222c202276616c7565223a2000000000000000000000000000000000000000602082015250565b6000613bd9602d8361327a565b9150613be482613b7d565b602d82019050919050565b7f7b2274726169745f74797065223a2022496e736964652041727469666163747360008201527f222c202276616c7565223a200000000000000000000000000000000000000000602082015250565b6000613c4b602c8361327a565b9150613c5682613bef565b602c82019050919050565b7f7b2274726169745f74797065223a20224772616469656e74222c202276616c7560008201527f65223a2022000000000000000000000000000000000000000000000000000000602082015250565b6000613cbd60258361327a565b9150613cc882613c61565b602582019050919050565b7f227d2c0000000000000000000000000000000000000000000000000000000000815250565b7f7b2274726169745f74797065223a20225072696d61727920436f6c6f72222c2060008201527f2276616c7565223a202200000000000000000000000000000000000000000000602082015250565b6000613d55602a8361327a565b9150613d6082613cf9565b602a82019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000815250565b6000613d9c82613abf565b600f82019150613dab82613b34565b9150613db782886132d1565b9150613dc282613b57565b600282019150613dd182613bcc565b9150613ddd82876132d1565b9150613de882613b57565b600282019150613df782613c3e565b9150613e0382866132d1565b9150613e0e82613b57565b600282019150613e1d82613cb0565b9150613e2982856132d1565b9150613e3482613cd3565b600382019150613e4382613d48565b9150613e4f82846132d1565b9150613e5a82613d6b565b6002820191508190509695505050505050565b7f2c7b2274726169745f74797065223a20225365636f6e6461727920436f6c6f7260008201527f222c202276616c7565223a202200000000000000000000000000000000000000602082015250565b6000613ec9602d8361327a565b9150613ed482613e6d565b602d82019050919050565b6000613eeb82856132d1565b9150613ef682613ebc565b9150613f0282846132d1565b9150613f0d82613d6b565b6002820191508190509392505050565b7f2c7b2274726169745f74797065223a202248616c6f222c202276616c7565223a60008201527f2022596573227d00000000000000000000000000000000000000000000000000602082015250565b6000613f7960278361327a565b9150613f8482613f1d565b602782019050919050565b6000613f9b82846132d1565b9150613fa682613f6c565b915081905092915050565b7f5d00000000000000000000000000000000000000000000000000000000000000815250565b6000613fe382846132d1565b9150613fee82613fb1565b60018201915081905092915050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000600082015250565b600061403360098361327a565b915061403e82613ffd565b600982019050919050565b7f222c226465736372697074696f6e223a22000000000000000000000000000000600082015250565b600061407f60118361327a565b915061408a82614049565b601182019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b60006140cb60028361327a565b91506140d682614095565b600282019050919050565b7f2c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6260008201527f61736536342c0000000000000000000000000000000000000000000000000000602082015250565b600061413d60268361327a565b9150614148826140e1565b602682019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b600061418960028361327a565b915061419482614153565b600282019050919050565b60006141aa82614026565b91506141b682876132d1565b91506141c182614072565b91506141cd82866132d1565b91506141d8826140be565b91506141e482856132d1565b91506141ef82614130565b91506141fb82846132d1565b91506142068261417c565b915081905095945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b600061424a601d8361327a565b915061425582614214565b601d82019050919050565b600061426b8261423d565b915061427782846132d1565b915081905092915050565b7f5075626c69632073616c6520686173206e6f7420737461727465642079657400600082015250565b60006142b8601f83612816565b91506142c382614282565b602082019050919050565b600060208201905081810360008301526142e7816142ab565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061434a602683612816565b9150614355826142ee565b604082019050919050565b600060208201905081810360008301526143798161433d565b9050919050565b7f596f7520617265206e6f74206f6e2074686520616c6c6f776c69737400000000600082015250565b60006143b6601c83612816565b91506143c182614380565b602082019050919050565b600060208201905081810360008301526143e5816143a9565b9050919050565b7f416c6c6f776c6973742073616c6520686173206e6f742073746172746564207960008201527f6574000000000000000000000000000000000000000000000000000000000000602082015250565b6000614448602283612816565b9150614453826143ec565b604082019050919050565b600060208201905081810360008301526144778161443b565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006144b4602083612816565b91506144bf8261447e565b602082019050919050565b600060208201905081810360008301526144e3816144a7565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614511826144ea565b61451b81856144f5565b935061452b818560208601612827565b61453481612851565b840191505092915050565b60006080820190506145546000830187612952565b6145616020830186612952565b61456e6040830185612a15565b81810360608301526145808184614506565b905095945050505050565b60008151905061459a8161277c565b92915050565b6000602082840312156145b6576145b5612746565b5b60006145c48482850161458b565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614607826128bd565b9150614612836128bd565b925082614622576146216145cd565b5b828204905092915050565b600060ff82169050919050565b60006146458261462d565b91506146508361462d565b9250828201905060ff81111561466957614668613043565b5b92915050565b7f496e73756666696369656e742066656500000000000000000000000000000000600082015250565b60006146a5601083612816565b91506146b08261466f565b602082019050919050565b600060208201905081810360008301526146d481614698565b9050919050565b7f45786365656473206d6178207175616e74697479000000000000000000000000600082015250565b6000614711601483612816565b915061471c826146db565b602082019050919050565b6000602082019050818103600083015261474081614704565b9050919050565b600081905092915050565b50565b6000614762600083614747565b915061476d82614752565b600082019050919050565b600061478382614755565b9150819050919050565b7f526566756e64206661696c656400000000000000000000000000000000000000600082015250565b60006147c3600d83612816565b91506147ce8261478d565b602082019050919050565b600060208201905081810360008301526147f2816147b6565b905091905056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f46756c6c79206f6e2d636861696e2c2070726f6365647572616c6c792067656e6572617465642c20616e696d61746564206b616c6569646f73636f7065732ea264697066735822122052abef236944e932101b30fe89aa13017f608c9ba9c850189986d5776b62cea064736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000003e81a803dbdfb3d0c0c775bc03f7e858f42eac3ccf7aae62a18b498e8dcced2b2240000000000000000000000000000000000000000000000000000000000fa3afc000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000834a227ec86776292601d298de4a767677950a55000000000000000000000000000000000000000000000000000000000000000d4b616c6569646f73636f7065730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064b4c445343500000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Kaleidoscopes
Arg [1] : _symbol (string): KLDSCP
Arg [2] : _price (uint256): 10000000000000000
Arg [3] : _maxSupply (uint256): 1000
Arg [4] : _merkleRoot (bytes32): 0x1a803dbdfb3d0c0c775bc03f7e858f42eac3ccf7aae62a18b498e8dcced2b224
Arg [5] : _allowListMintStartBlock (uint256): 16399100
Arg [6] : _publicMintOffsetBlocks (uint256): 300
Arg [7] : _renderer (address): 0x834A227Ec86776292601D298DE4a767677950a55
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [3] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [4] : 1a803dbdfb3d0c0c775bc03f7e858f42eac3ccf7aae62a18b498e8dcced2b224
Arg [5] : 0000000000000000000000000000000000000000000000000000000000fa3afc
Arg [6] : 000000000000000000000000000000000000000000000000000000000000012c
Arg [7] : 000000000000000000000000834a227ec86776292601d298de4a767677950a55
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [9] : 4b616c6569646f73636f70657300000000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [11] : 4b4c445343500000000000000000000000000000000000000000000000000000
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.