ETH Price: $2,593.82 (-2.42%)

Token

The GOAT (GOAT)
 

Overview

Max Total Supply

167 GOAT

Holders

54

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3 GOAT
0xa73827d96540e1d8cacd48017a2eb08b0e073e27
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
TheGoat

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion
File 1 of 33 : TheGoat.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/draft-ERC721Votes.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "./libraries/Base64.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IWETH} from "./interfaces/IWETH.sol";

contract TheGoat is ERC721, ERC721Enumerable, Ownable, EIP712, ERC721Votes {
    using Counters for Counters.Counter;
    using Strings for uint256;
    Counters.Counter private _tokenIdCounter;
    uint256 public deploymentTimestamp;
    using Base64 for *;
    address private constant dev2 = 0xCC44A5Feb6Ee172dAaa31c1Fee3FC1Ce1654057F;
    address public weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    event Bid(address indexed bidder, uint256 amount, uint256 day);

    struct Day {
        address winner;
        uint256 highestBid;
        bool minted;
    }

    mapping(uint256 => Day) public day;
    mapping(uint256 => uint256) private dayReward;
    mapping(uint256 => uint256) private claimed;

    enum ItemType {
        Head,
        Horn,
        Eye,
        Body
    }

    struct Item {
        string name;
        string svg;
        string json;
    }

    struct Art {
        Item[] heads;
        Item[] horns;
        Item[] bodies;
        Item[] eyes;
        uint8[3][2][4] skins;
    }

    Art private art;

    bool public artComplete = false;

    function addItems(
        ItemType _itemType,
        string[] memory _names,
        string[] memory _svgs,
        string[] memory _jsons
    ) public onlyOwner {
        require(
            _names.length == _svgs.length && _names.length == _jsons.length,
            "Array lengths must match"
        );

        require(!artComplete, "Art is already complete");

        for (uint256 i = 0; i < _names.length; i++) {
            if (_itemType == ItemType.Head) {
                art.heads.push(Item(_names[i], _svgs[i], _jsons[i]));
            } else if (_itemType == ItemType.Horn) {
                art.horns.push(Item(_names[i], _svgs[i], _jsons[i]));
            } else if (_itemType == ItemType.Eye) {
                art.eyes.push(Item(_names[i], _svgs[i], _jsons[i]));
            } else if (_itemType == ItemType.Body) {
                art.bodies.push(Item(_names[i], _svgs[i], _jsons[i]));
            }
        }
    }

    function lockArt() public onlyOwner {
        require(!artComplete, "Art is already complete");
        artComplete = true;
    }

    constructor() ERC721("The GOAT", "GOAT") EIP712("TheGoat", "1") {
        deploymentTimestamp = 1696706771;
        art.skins = [
            [[102, 72, 33], [135, 103, 46]],
            [[98, 98, 98], [160, 160, 160]],
            [[119, 39, 23], [162, 70, 28]],
            [[153, 133, 67], [191, 171, 105]]
        ];
        safeMint(owner(), 0);
        safeMint(0x0e802Eef59d855375e4826123a4145B829Bc3F83, 1);
        safeMint(0x895FAC7783C70d48E464a639ee3Cb453Dc8997E0, 2);
        safeMint(0xf728Ce79C82BB99335e0A781CAc0254B6a9AEb37, 3);
        safeMint(0xD3678054aeD0c09616684563f145318AccFF56a2, 4);
        safeMint(0xa73827D96540E1d8CAcd48017a2eb08B0e073e27, 5);
        safeMint(0xc2B35534e47cdF3D787e01630129631d8270abFb, 6);
        safeMint(0x0e802Eef59d855375e4826123a4145B829Bc3F83, 7);
        safeMint(0x5D2A610dfCFF2B38e82DF7F2C3C100CF6332527D, 8);
        safeMint(0x957Db774E28701A6e04C9d9Ec43De1bCfaEEb176, 9);
        safeMint(0x50f461F471e7dCe973e27f0e319eBe868135D764, 10);
        safeMint(0x2b6D02F088Fd0B2fC521F6D034F4C93164125851, 11);
    }

    function getDayId() public view returns (uint256) {
        return (block.timestamp - deploymentTimestamp) / 1 days + 1;
    }

    function getGoatsSinceDeployment() public view returns (uint256) {
        return getDayId() + (getDayId() - 1) / 9;
    }


    function bid() public payable {
        require(
            msg.value > 0,
            "You must send some ether to participate in the auction."
        );
        uint256 currentDay = getGoatsSinceDeployment();
        require(
            msg.value > day[currentDay].highestBid + 1000000 gwei,
            "Your bid is too low."
        );
        require(
            day[currentDay].winner != msg.sender,
            "You are already the winner."
        );

        address payable lastBidder = payable(day[currentDay].winner);
        uint256 lastBid = day[currentDay].highestBid;

        day[currentDay].highestBid = msg.value;
        day[currentDay].winner = msg.sender;
        calculateRewards(currentDay);
        emit Bid(msg.sender, msg.value, currentDay);
        if (lastBidder != address(0)) {
            _safeTransferETHWithFallback(lastBidder, lastBid);
        }
    }

    function mint(uint256 goatId) public {
        require(day[goatId].winner == msg.sender, "You are not the winner.");
        require(day[goatId].minted == false, "You already minted your NFT.");
        require(goatId < getGoatsSinceDeployment(), "Day not reached yet.");
        safeMint(msg.sender, goatId);
    }

    function mintUnminted(uint256 goatId) public {
        require(day[goatId].minted == false, "You already minted your NFT.");
        require(
            goatId + 10 < getGoatsSinceDeployment(),
            "Day not reached yet."
        );
        if (goatId % 20 == 0) {
            safeMint(dev2, goatId);
        } else {
            safeMint(owner(), goatId);
        }
    }

    function safeMint(address to, uint256 id) internal {
        day[id].minted = true;
        claimed[id] += dayReward[id];
        _safeMint(to, id);
    }

    function dna(uint256 _tokenId) internal pure returns (uint256) {
        return uint256(keccak256(abi.encodePacked(_tokenId, "TheGoat")));
    }

    function claim(uint256 _tokenId) public {
        require(_exists(_tokenId));
        require(_msgSender() == ownerOf(_tokenId));
        require(_tokenId < getGoatsSinceDeployment());

        uint256 amount = claimable(_tokenId);

        if (amount > 0) {
            claimed[_tokenId] += amount;
            payable(_msgSender()).transfer(amount);
        }
    }

    function claimMultiple(uint256[] calldata ownedNfts) public {
        for (uint256 i = 0; i < ownedNfts.length; ) {
            claim(ownedNfts[i]);
            unchecked {
                i++;
            }
        }
    }

    function claimable(uint256 tokenId) public view returns (uint256) {
        uint256 yesterday = getGoatsSinceDeployment() - 1;
        while (dayReward[yesterday] == 0 && yesterday > 0) {
            yesterday--;
        }
        return dayReward[yesterday] - claimed[tokenId];
    }

    function calculateRewards(uint256 _day) public {
        require(_day <= getGoatsSinceDeployment());
        require(_day > 0);
        if (dayReward[_day - 1] == 0 && _day > 1) {
            calculateRewards(_day - 1);
        }
        dayReward[_day] = dayReward[_day - 1] + day[_day].highestBid / _day;
    }

    function getWinningDays(
        address user
    ) public view returns (uint256[] memory) {
        uint256 goatsSinceDeployment = getGoatsSinceDeployment();
        uint256[] memory winningDays = new uint256[](goatsSinceDeployment);
        uint256 count = 0;

        for (uint256 i = 0; i < goatsSinceDeployment; i++) {
            if (day[i].winner == user && day[i].minted == false) {
                winningDays[count] = i;
                count++;
            }
        }
        uint256[] memory result = new uint256[](count);
        for (uint256 i = 0; i < count; i++) {
            result[i] = winningDays[i];
        }

        return result;
    }

    // image

    function imageData(uint256 _tokenId) public view returns (string memory) {
        require(_tokenId <= getGoatsSinceDeployment(), "Day not reached yet.");

        uint8[4] memory tdna = splitNumber(dna(_tokenId));

        require(tdna[0] < art.heads.length, "Invalid index for art.heads");
        require(tdna[1] < art.horns.length, "Invalid index for art.horns");
        require(tdna[2] < art.bodies.length, "Invalid index for art.bodies");
        require(tdna[3] < art.eyes.length, "Invalid index for art.eyes");
        uint8[3][9] memory colors = magicColors(_tokenId);

        return
            string(
                abi.encodePacked(
                    "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 -0.5 28 28' shape-rendering='crispEdges'><style> .c1{stroke:",
                    rgbToString(colors[0]),
                    ";} .c2{stroke:",
                    rgbToString(colors[1]),
                    ";} .c3{stroke:",
                    rgbToString(colors[2]),
                    ";} .c5{stroke:",
                    rgbToString(colors[3]),
                    ";} .c6{stroke:",
                    rgbToString(colors[4]),
                    ";} .d2{stroke:",
                    rgbToString(colors[5]),
                    ";} .d3{stroke:",
                    rgbToString(colors[6]),
                    ";} .d4{stroke:",
                    rgbToString(colors[7]),
                    ";} .d6{stroke:",
                    rgbToString(colors[8]),
                    ";} .s1{stroke:",
                    rgbToString(art.skins[tdna[0]][0]),
                    ";} .s2{stroke:",
                    rgbToString(art.skins[tdna[0]][1]),
                    ';} </style><path class="c1" d="M0 0h28M0 1h28M0 2h28M0 3h28M0 4h28M0 5h28M0 6h28M0 7h28M0 8h28M0 9h28M0 10h28M0 11h28M0 12h28M0 13h28M0 14h28M0 15h28M0 16h28M0 17h28M0 18h28M0 19h28M0 20h28M0 21h28M0 22h28M0 23h28M0 24h28M0 25h28M0 26h28M0 27h28"/>',
                    art.bodies[tdna[2]].svg,
                    art.heads[tdna[0]].svg,
                    art.horns[tdna[1]].svg,
                    art.eyes[tdna[3]].svg,
                    "</svg>"
                )
            );
    }

    function splitNumber(
        uint256 _number
    ) internal view returns (uint8[4] memory) {
        uint8[4] memory numbers;
        numbers[0] = uint8(_number % art.heads.length); // head
        _number /= art.heads.length;
        numbers[1] = uint8(_number % art.horns.length); // horns
        _number /= art.horns.length;
        numbers[2] = uint8(_number % art.bodies.length); // body
        _number /= art.bodies.length;
        numbers[3] = uint8(_number % art.eyes.length); // eyes

        return numbers;
    }

    function tokenURI(
        uint256 _tokenId
    ) public view virtual override returns (string memory) {
        require(
            _exists(_tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );
        uint8[4] memory tdna = splitNumber(dna(_tokenId));
        bytes memory baseURI = (
            abi.encodePacked(
                '{ "attributes": [',
                art.heads[tdna[0]].json,
                ",",
                art.horns[tdna[1]].json,
                ",",
                art.bodies[tdna[2]].json,
                ",",
                art.eyes[tdna[3]].json,
                ",",
                '{"trait_type": "Color", "value": "',
                rgbToString(getRandomColor(_tokenId)),
                '"}',
                "],",
                '"description": "Created by thegoat.wtf","external_url": "https://thegoat.wtf","image": "data:image/svg+xml;base64,',
                bytes(imageData(_tokenId)).encode(),
                '","name": "The Goat #',
                _tokenId.toString(),
                '"}'
            )
        );

        return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    baseURI.encode()
                )
            );
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId,
        uint256 batchSize
    ) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
    }

    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId,
        uint256 batchSize
    ) internal override(ERC721, ERC721Votes) {
        super._afterTokenTransfer(from, to, tokenId, batchSize);
    }

    function supportsInterface(
        bytes4 interfaceId
    ) public view override(ERC721, ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
    }

    function magicColors(
        uint256 _tokenId
    ) public pure returns (uint8[3][9] memory) {
        uint8[3] memory c = getRandomColor(_tokenId);
        uint8[3] memory d = getCColor(c);
        return (
            [
                adjustColor(c, 210, 253),
                adjustColor(c, 128, 240),
                adjustColor(c, 64, 200),
                adjustColor(c, 64, 128),
                adjustColor(c, 20, 64),
                adjustColor(d, 128, 240),
                adjustColor(d, 64, 200),
                adjustColor(d, 64, 128),
                adjustColor(d, 20, 64)
            ]
        );
    }

    function getRandomColor(uint id) internal pure returns (uint8[3] memory) {
        return [
            getRandomNumber(id),
            getRandomNumber(id + 1337),
            getRandomNumber(id + 13371337)
        ];
    }

    function getRandomNumber(uint256 nonce) internal pure returns (uint8) {
        return uint8(uint256(keccak256(abi.encodePacked(nonce))) % 256);
    }

    function getCColor(
        uint8[3] memory color
    ) internal pure returns (uint8[3] memory) {
        uint8[3] memory complementary;

        complementary[0] = 255 - color[0];
        complementary[1] = 255 - color[1];
        complementary[2] = 255 - color[2];

        return complementary;
    }

    function adjustColor(
        uint8[3] memory input,
        uint8 minOutput,
        uint8 maxOutput
    ) internal pure returns (uint8[3] memory) {
        uint256 inputRange = 255;
        uint256 outputRange = uint256(maxOutput) - uint256(minOutput);

        uint8[3] memory adjustedColor;
        adjustedColor[0] = uint8(
            (uint256(input[0]) * outputRange) / inputRange + uint256(minOutput)
        );
        adjustedColor[1] = uint8(
            (uint256(input[1]) * outputRange) / inputRange + uint256(minOutput)
        );
        adjustedColor[2] = uint8(
            (uint256(input[2]) * outputRange) / inputRange + uint256(minOutput)
        );

        return adjustedColor;
    }

    function rgbToString(
        uint8[3] memory color
    ) internal pure returns (string memory) {
        return
            string(
                abi.encodePacked(
                    "rgb(",
                    Strings.toString(color[0]),
                    ",",
                    Strings.toString(color[1]),
                    ",",
                    Strings.toString(color[2]),
                    ")"
                )
            );
    }

    function _safeTransferETHWithFallback(address to, uint256 amount) internal {
        if (!_safeTransferETH(to, amount)) {
            IWETH(weth).deposit{value: amount}();
            IERC20(weth).transfer(to, amount);
        }
    }

    /**
     * @notice Transfer ETH and return the success status.
     * @dev This function only forwards 30,000 gas to the callee.
     */
    function _safeTransferETH(
        address to,
        uint256 value
    ) internal returns (bool) {
        (bool success, ) = to.call{value: value, gas: 30_000}(new bytes(0));
        return success;
    }
}

File 2 of 33 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

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

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

File 3 of 33 : IVotes.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/IVotes.sol)
pragma solidity ^0.8.0;

/**
 * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.
 *
 * _Available since v4.5._
 */
interface IVotes {
    /**
     * @dev Emitted when an account changes their delegate.
     */
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /**
     * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.
     */
    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) external view returns (uint256);

    /**
     * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is
     * configured to use block numbers, this will return the value at the end of the corresponding block.
     */
    function getPastVotes(address account, uint256 timepoint) external view returns (uint256);

    /**
     * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is
     * configured to use block numbers, this will return the value at the end of the corresponding block.
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     */
    function getPastTotalSupply(uint256 timepoint) external view returns (uint256);

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) external view returns (address);

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) external;

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;
}

File 4 of 33 : Votes.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/Votes.sol)
pragma solidity ^0.8.0;

import "../../interfaces/IERC5805.sol";
import "../../utils/Context.sol";
import "../../utils/Counters.sol";
import "../../utils/Checkpoints.sol";
import "../../utils/cryptography/EIP712.sol";

/**
 * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be
 * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of
 * "representative" that will pool delegated voting units from different accounts and can then use it to vote in
 * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to
 * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative.
 *
 * This contract is often combined with a token contract such that voting units correspond to token units. For an
 * example, see {ERC721Votes}.
 *
 * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed
 * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the
 * cost of this history tracking optional.
 *
 * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return
 * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the
 * previous example, it would be included in {ERC721-_beforeTokenTransfer}).
 *
 * _Available since v4.5._
 */
abstract contract Votes is Context, EIP712, IERC5805 {
    using Checkpoints for Checkpoints.Trace224;
    using Counters for Counters.Counter;

    bytes32 private constant _DELEGATION_TYPEHASH =
        keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    mapping(address => address) private _delegation;

    /// @custom:oz-retyped-from mapping(address => Checkpoints.History)
    mapping(address => Checkpoints.Trace224) private _delegateCheckpoints;

    /// @custom:oz-retyped-from Checkpoints.History
    Checkpoints.Trace224 private _totalCheckpoints;

    mapping(address => Counters.Counter) private _nonces;

    /**
     * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based
     * checkpoints (and voting), in which case {CLOCK_MODE} should be overridden as well to match.
     */
    function clock() public view virtual override returns (uint48) {
        return SafeCast.toUint48(block.number);
    }

    /**
     * @dev Machine-readable description of the clock as specified in EIP-6372.
     */
    // solhint-disable-next-line func-name-mixedcase
    function CLOCK_MODE() public view virtual override returns (string memory) {
        // Check that the clock was not modified
        require(clock() == block.number, "Votes: broken clock mode");
        return "mode=blocknumber&from=default";
    }

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) public view virtual override returns (uint256) {
        return _delegateCheckpoints[account].latest();
    }

    /**
     * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is
     * configured to use block numbers, this will return the value at the end of the corresponding block.
     *
     * Requirements:
     *
     * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined.
     */
    function getPastVotes(address account, uint256 timepoint) public view virtual override returns (uint256) {
        require(timepoint < clock(), "Votes: future lookup");
        return _delegateCheckpoints[account].upperLookupRecent(SafeCast.toUint32(timepoint));
    }

    /**
     * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is
     * configured to use block numbers, this will return the value at the end of the corresponding block.
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     *
     * Requirements:
     *
     * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined.
     */
    function getPastTotalSupply(uint256 timepoint) public view virtual override returns (uint256) {
        require(timepoint < clock(), "Votes: future lookup");
        return _totalCheckpoints.upperLookupRecent(SafeCast.toUint32(timepoint));
    }

    /**
     * @dev Returns the current total supply of votes.
     */
    function _getTotalSupply() internal view virtual returns (uint256) {
        return _totalCheckpoints.latest();
    }

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) public view virtual override returns (address) {
        return _delegation[account];
    }

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) public virtual override {
        address account = _msgSender();
        _delegate(account, delegatee);
    }

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= expiry, "Votes: signature expired");
        address signer = ECDSA.recover(
            _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
            v,
            r,
            s
        );
        require(nonce == _useNonce(signer), "Votes: invalid nonce");
        _delegate(signer, delegatee);
    }

    /**
     * @dev Delegate all of `account`'s voting units to `delegatee`.
     *
     * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.
     */
    function _delegate(address account, address delegatee) internal virtual {
        address oldDelegate = delegates(account);
        _delegation[account] = delegatee;

        emit DelegateChanged(account, oldDelegate, delegatee);
        _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account));
    }

    /**
     * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to`
     * should be zero. Total supply of voting units will be adjusted with mints and burns.
     */
    function _transferVotingUnits(address from, address to, uint256 amount) internal virtual {
        if (from == address(0)) {
            _push(_totalCheckpoints, _add, SafeCast.toUint224(amount));
        }
        if (to == address(0)) {
            _push(_totalCheckpoints, _subtract, SafeCast.toUint224(amount));
        }
        _moveDelegateVotes(delegates(from), delegates(to), amount);
    }

    /**
     * @dev Moves delegated votes from one delegate to another.
     */
    function _moveDelegateVotes(address from, address to, uint256 amount) private {
        if (from != to && amount > 0) {
            if (from != address(0)) {
                (uint256 oldValue, uint256 newValue) = _push(
                    _delegateCheckpoints[from],
                    _subtract,
                    SafeCast.toUint224(amount)
                );
                emit DelegateVotesChanged(from, oldValue, newValue);
            }
            if (to != address(0)) {
                (uint256 oldValue, uint256 newValue) = _push(
                    _delegateCheckpoints[to],
                    _add,
                    SafeCast.toUint224(amount)
                );
                emit DelegateVotesChanged(to, oldValue, newValue);
            }
        }
    }

    function _push(
        Checkpoints.Trace224 storage store,
        function(uint224, uint224) view returns (uint224) op,
        uint224 delta
    ) private returns (uint224, uint224) {
        return store.push(SafeCast.toUint32(clock()), op(store.latest(), delta));
    }

    function _add(uint224 a, uint224 b) private pure returns (uint224) {
        return a + b;
    }

    function _subtract(uint224 a, uint224 b) private pure returns (uint224) {
        return a - b;
    }

    /**
     * @dev Consumes a nonce.
     *
     * Returns the current value and increments nonce.
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }

    /**
     * @dev Returns an address nonce.
     */
    function nonces(address owner) public view virtual returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev Returns the contract's {EIP712} domain separator.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev Must return the voting units held by an account.
     */
    function _getVotingUnits(address) internal view virtual returns (uint256);
}

File 5 of 33 : IERC5267.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.0;

interface IERC5267 {
    /**
     * @dev MAY be emitted to signal that the domain could have changed.
     */
    event EIP712DomainChanged();

    /**
     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
     * signature.
     */
    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );
}

File 6 of 33 : IERC5805.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5805.sol)

pragma solidity ^0.8.0;

import "../governance/utils/IVotes.sol";
import "./IERC6372.sol";

interface IERC5805 is IERC6372, IVotes {}

File 7 of 33 : IERC6372.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC6372.sol)

pragma solidity ^0.8.0;

interface IERC6372 {
    /**
     * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).
     */
    function clock() external view returns (uint48);

    /**
     * @dev Description of the clock
     */
    // solhint-disable-next-line func-name-mixedcase
    function CLOCK_MODE() external view returns (string memory);
}

File 8 of 33 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

File 9 of 33 : ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

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

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

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

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

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

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

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

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

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

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

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

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

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

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

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
     * that `ownerOf(tokenId)` is `a`.
     */
    // solhint-disable-next-line func-name-mixedcase
    function __unsafe_increaseBalance(address account, uint256 amount) internal {
        _balances[account] += amount;
    }
}

File 10 of 33 : draft-ERC721Votes.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/draft-ERC721Votes.sol)

pragma solidity ^0.8.0;

// ERC721Votes was marked as draft due to the EIP-712 dependency.
// EIP-712 is Final as of 2022-08-11. This file is deprecated.

import "./ERC721Votes.sol";

File 11 of 33 : ERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

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

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

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

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

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

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

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

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

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

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

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

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

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

File 12 of 33 : ERC721Votes.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/extensions/ERC721Votes.sol)

pragma solidity ^0.8.0;

import "../ERC721.sol";
import "../../../governance/utils/Votes.sol";

/**
 * @dev Extension of ERC721 to support voting and delegation as implemented by {Votes}, where each individual NFT counts
 * as 1 vote unit.
 *
 * Tokens do not count as votes until they are delegated, because votes must be tracked which incurs an additional cost
 * on every transfer. Token holders can either delegate to a trusted representative who will decide how to make use of
 * the votes in governance decisions, or they can delegate to themselves to be their own representative.
 *
 * _Available since v4.5._
 */
abstract contract ERC721Votes is ERC721, Votes {
    /**
     * @dev See {ERC721-_afterTokenTransfer}. Adjusts votes when tokens are transferred.
     *
     * Emits a {IVotes-DelegateVotesChanged} event.
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        _transferVotingUnits(from, to, batchSize);
        super._afterTokenTransfer(from, to, firstTokenId, batchSize);
    }

    /**
     * @dev Returns the balance of `account`.
     *
     * WARNING: Overriding this function will likely result in incorrect vote tracking.
     */
    function _getVotingUnits(address account) internal view virtual override returns (uint256) {
        return balanceOf(account);
    }
}

File 13 of 33 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

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

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

File 15 of 33 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

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

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

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

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

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

pragma solidity ^0.8.0;

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

File 17 of 33 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 18 of 33 : Checkpoints.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Checkpoints.sol)
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SafeCast.sol";

/**
 * @dev This library defines the `History` struct, for checkpointing values as they change at different points in
 * time, and later looking up past values by block number. See {Votes} as an example.
 *
 * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new
 * checkpoint for the current transaction block using the {push} function.
 *
 * _Available since v4.5._
 */
library Checkpoints {
    struct History {
        Checkpoint[] _checkpoints;
    }

    struct Checkpoint {
        uint32 _blockNumber;
        uint224 _value;
    }

    /**
     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
     * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the
     * block, the requested block number must be in the past, excluding the current block.
     */
    function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
        require(blockNumber < block.number, "Checkpoints: block not yet mined");
        uint32 key = SafeCast.toUint32(blockNumber);

        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
     * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched
     * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of
     * checkpoints.
     */
    function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
        require(blockNumber < block.number, "Checkpoints: block not yet mined");
        uint32 key = SafeCast.toUint32(blockNumber);

        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.
     *
     * Returns previous value and new value.
     */
    function push(History storage self, uint256 value) internal returns (uint256, uint256) {
        return _insert(self._checkpoints, SafeCast.toUint32(block.number), SafeCast.toUint224(value));
    }

    /**
     * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will
     * be set to `op(latest, delta)`.
     *
     * Returns previous value and new value.
     */
    function push(
        History storage self,
        function(uint256, uint256) view returns (uint256) op,
        uint256 delta
    ) internal returns (uint256, uint256) {
        return push(self, op(latest(self), delta));
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(History storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(
        History storage self
    ) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._blockNumber, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(History storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            require(last._blockNumber <= key, "Checkpoint: decreasing keys");

            // Update or push new checkpoint
            if (last._blockNumber == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint({_blockNumber: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint({_blockNumber: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._blockNumber > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._blockNumber < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace224 {
        Checkpoint224[] _checkpoints;
    }

    struct Checkpoint224 {
        uint32 _key;
        uint224 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     */
    function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.
     */
    function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
     */
    function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
     *
     * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys).
     */
    function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace224 storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace224 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint224 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            require(last._key <= key, "Checkpoint: decreasing keys");

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint224({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint224({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(
        Checkpoint224[] storage self,
        uint256 pos
    ) private pure returns (Checkpoint224 storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace160 {
        Checkpoint160[] _checkpoints;
    }

    struct Checkpoint160 {
        uint96 _key;
        uint160 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     */
    function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.
     */
    function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
     */
    function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
     *
     * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys).
     */
    function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace160 storage self) internal view returns (uint160) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace160 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint160 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            require(last._key <= key, "Checkpoint: decreasing keys");

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint160({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint160({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(
        Checkpoint160[] storage self,
        uint256 pos
    ) private pure returns (Checkpoint160 storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }
}

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

pragma solidity ^0.8.0;

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

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

File 20 of 33 : Counters.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

File 21 of 33 : draft-EIP712.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/draft-EIP712.sol)

pragma solidity ^0.8.0;

// EIP-712 is Final as of 2022-08-11. This file is deprecated.

import "./EIP712.sol";

File 22 of 33 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32")
            mstore(0x1c, hash)
            message := keccak256(0x00, 0x3c)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, "\x19\x01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            data := keccak256(ptr, 0x42)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Data with intended validator, created from a
     * `validator` and `data` according to the version 0 of EIP-191.
     *
     * See {recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x00", validator, data));
    }
}

File 23 of 33 : EIP712.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.8;

import "./ECDSA.sol";
import "../ShortStrings.sol";
import "../../interfaces/IERC5267.sol";

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
 * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the
 * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
 *
 * _Available since v3.4._
 *
 * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
 */
abstract contract EIP712 is IERC5267 {
    using ShortStrings for *;

    bytes32 private constant _TYPE_HASH =
        keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _cachedDomainSeparator;
    uint256 private immutable _cachedChainId;
    address private immutable _cachedThis;

    bytes32 private immutable _hashedName;
    bytes32 private immutable _hashedVersion;

    ShortString private immutable _name;
    ShortString private immutable _version;
    string private _nameFallback;
    string private _versionFallback;

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        _name = name.toShortStringWithFallback(_nameFallback);
        _version = version.toShortStringWithFallback(_versionFallback);
        _hashedName = keccak256(bytes(name));
        _hashedVersion = keccak256(bytes(version));

        _cachedChainId = block.chainid;
        _cachedDomainSeparator = _buildDomainSeparator();
        _cachedThis = address(this);
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
            return _cachedDomainSeparator;
        } else {
            return _buildDomainSeparator();
        }
    }

    function _buildDomainSeparator() private view returns (bytes32) {
        return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }

    /**
     * @dev See {EIP-5267}.
     *
     * _Available since v4.9._
     */
    function eip712Domain()
        public
        view
        virtual
        override
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        return (
            hex"0f", // 01111
            _name.toStringWithFallback(_nameFallback),
            _version.toStringWithFallback(_versionFallback),
            block.chainid,
            address(this),
            bytes32(0),
            new uint256[](0)
        );
    }
}

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

pragma solidity ^0.8.0;

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

File 26 of 33 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 27 of 33 : SafeCast.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.2._
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v2.5._
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.2._
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v2.5._
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v2.5._
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v2.5._
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v2.5._
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     *
     * _Available since v3.0._
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.7._
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
     * Counterpart to Solidity's `int152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toInt152(int256 value) internal pure returns (int152 downcasted) {
        downcasted = int152(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
    }

    /**
     * @dev Returns the downcasted int144 from int256, reverting on
     * overflow (when the input is less than smallest int144 or
     * greater than largest int144).
     *
     * Counterpart to Solidity's `int144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toInt144(int256 value) internal pure returns (int144 downcasted) {
        downcasted = int144(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
    }

    /**
     * @dev Returns the downcasted int136 from int256, reverting on
     * overflow (when the input is less than smallest int136 or
     * greater than largest int136).
     *
     * Counterpart to Solidity's `int136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toInt136(int256 value) internal pure returns (int136 downcasted) {
        downcasted = int136(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128 downcasted) {
        downcasted = int128(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
    }

    /**
     * @dev Returns the downcasted int120 from int256, reverting on
     * overflow (when the input is less than smallest int120 or
     * greater than largest int120).
     *
     * Counterpart to Solidity's `int120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toInt120(int256 value) internal pure returns (int120 downcasted) {
        downcasted = int120(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
    }

    /**
     * @dev Returns the downcasted int112 from int256, reverting on
     * overflow (when the input is less than smallest int112 or
     * greater than largest int112).
     *
     * Counterpart to Solidity's `int112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toInt112(int256 value) internal pure returns (int112 downcasted) {
        downcasted = int112(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
    }

    /**
     * @dev Returns the downcasted int104 from int256, reverting on
     * overflow (when the input is less than smallest int104 or
     * greater than largest int104).
     *
     * Counterpart to Solidity's `int104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toInt104(int256 value) internal pure returns (int104 downcasted) {
        downcasted = int104(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
    }

    /**
     * @dev Returns the downcasted int96 from int256, reverting on
     * overflow (when the input is less than smallest int96 or
     * greater than largest int96).
     *
     * Counterpart to Solidity's `int96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.7._
     */
    function toInt96(int256 value) internal pure returns (int96 downcasted) {
        downcasted = int96(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
    }

    /**
     * @dev Returns the downcasted int88 from int256, reverting on
     * overflow (when the input is less than smallest int88 or
     * greater than largest int88).
     *
     * Counterpart to Solidity's `int88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toInt88(int256 value) internal pure returns (int88 downcasted) {
        downcasted = int88(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
    }

    /**
     * @dev Returns the downcasted int80 from int256, reverting on
     * overflow (when the input is less than smallest int80 or
     * greater than largest int80).
     *
     * Counterpart to Solidity's `int80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toInt80(int256 value) internal pure returns (int80 downcasted) {
        downcasted = int80(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
    }

    /**
     * @dev Returns the downcasted int72 from int256, reverting on
     * overflow (when the input is less than smallest int72 or
     * greater than largest int72).
     *
     * Counterpart to Solidity's `int72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toInt72(int256 value) internal pure returns (int72 downcasted) {
        downcasted = int72(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64 downcasted) {
        downcasted = int64(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
    }

    /**
     * @dev Returns the downcasted int56 from int256, reverting on
     * overflow (when the input is less than smallest int56 or
     * greater than largest int56).
     *
     * Counterpart to Solidity's `int56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toInt56(int256 value) internal pure returns (int56 downcasted) {
        downcasted = int56(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
    }

    /**
     * @dev Returns the downcasted int48 from int256, reverting on
     * overflow (when the input is less than smallest int48 or
     * greater than largest int48).
     *
     * Counterpart to Solidity's `int48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toInt48(int256 value) internal pure returns (int48 downcasted) {
        downcasted = int48(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
    }

    /**
     * @dev Returns the downcasted int40 from int256, reverting on
     * overflow (when the input is less than smallest int40 or
     * greater than largest int40).
     *
     * Counterpart to Solidity's `int40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toInt40(int256 value) internal pure returns (int40 downcasted) {
        downcasted = int40(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32 downcasted) {
        downcasted = int32(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
    }

    /**
     * @dev Returns the downcasted int24 from int256, reverting on
     * overflow (when the input is less than smallest int24 or
     * greater than largest int24).
     *
     * Counterpart to Solidity's `int24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toInt24(int256 value) internal pure returns (int24 downcasted) {
        downcasted = int24(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16 downcasted) {
        downcasted = int16(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8 downcasted) {
        downcasted = int8(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     *
     * _Available since v3.0._
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

File 28 of 33 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

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

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

File 29 of 33 : ShortStrings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol)

pragma solidity ^0.8.8;

import "./StorageSlot.sol";

// | string  | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   |
// | length  | 0x                                                              BB |
type ShortString is bytes32;

/**
 * @dev This library provides functions to convert short memory strings
 * into a `ShortString` type that can be used as an immutable variable.
 *
 * Strings of arbitrary length can be optimized using this library if
 * they are short enough (up to 31 bytes) by packing them with their
 * length (1 byte) in a single EVM word (32 bytes). Additionally, a
 * fallback mechanism can be used for every other case.
 *
 * Usage example:
 *
 * ```solidity
 * contract Named {
 *     using ShortStrings for *;
 *
 *     ShortString private immutable _name;
 *     string private _nameFallback;
 *
 *     constructor(string memory contractName) {
 *         _name = contractName.toShortStringWithFallback(_nameFallback);
 *     }
 *
 *     function name() external view returns (string memory) {
 *         return _name.toStringWithFallback(_nameFallback);
 *     }
 * }
 * ```
 */
library ShortStrings {
    // Used as an identifier for strings longer than 31 bytes.
    bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;

    error StringTooLong(string str);
    error InvalidShortString();

    /**
     * @dev Encode a string of at most 31 chars into a `ShortString`.
     *
     * This will trigger a `StringTooLong` error is the input string is too long.
     */
    function toShortString(string memory str) internal pure returns (ShortString) {
        bytes memory bstr = bytes(str);
        if (bstr.length > 31) {
            revert StringTooLong(str);
        }
        return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));
    }

    /**
     * @dev Decode a `ShortString` back to a "normal" string.
     */
    function toString(ShortString sstr) internal pure returns (string memory) {
        uint256 len = byteLength(sstr);
        // using `new string(len)` would work locally but is not memory safe.
        string memory str = new string(32);
        /// @solidity memory-safe-assembly
        assembly {
            mstore(str, len)
            mstore(add(str, 0x20), sstr)
        }
        return str;
    }

    /**
     * @dev Return the length of a `ShortString`.
     */
    function byteLength(ShortString sstr) internal pure returns (uint256) {
        uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
        if (result > 31) {
            revert InvalidShortString();
        }
        return result;
    }

    /**
     * @dev Encode a string into a `ShortString`, or write it to storage if it is too long.
     */
    function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {
        if (bytes(value).length < 32) {
            return toShortString(value);
        } else {
            StorageSlot.getStringSlot(store).value = value;
            return ShortString.wrap(_FALLBACK_SENTINEL);
        }
    }

    /**
     * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     */
    function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return toString(value);
        } else {
            return store;
        }
    }

    /**
     * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     *
     * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
     * actual characters as the UTF-8 encoding of a single character can span over multiple bytes.
     */
    function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return byteLength(value);
        } else {
            return bytes(store).length;
        }
    }
}

File 30 of 33 : StorageSlot.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
 * _Available since v4.9 for `string`, `bytes`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}

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

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SignedMath.sol";

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

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

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

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

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

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

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 32 of 33 : IWETH.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.6;

interface IWETH {
    function deposit() external payable;

    function withdraw(uint256 wad) external;

    function transfer(address to, uint256 value) external returns (bool);
}

File 33 of 33 : Base64.sol
// SPDX-License-Identifier: MIT

/// @title Base64
/// @author Brecht Devos - <[email protected]>
/// @notice Provides a function for encoding some bytes in base64
pragma solidity ^0.8.18;
library Base64 {
    string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

    function encode(bytes memory data) internal pure returns (string memory) {
        if (data.length == 0) return '';
        
        // load the table into memory
        string memory table = TABLE;

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((data.length + 2) / 3);

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)
            
            // prepare the lookup table
            let tablePtr := add(table, 1)
            
            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))
            
            // result ptr, jump over length
            let resultPtr := add(result, 32)
            
            // run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {}
            {
               dataPtr := add(dataPtr, 3)
               
               // read 3 bytes
               let input := mload(dataPtr)
               
               // write 4 characters
               mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))
               resultPtr := add(resultPtr, 1)
               mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))
               resultPtr := add(resultPtr, 1)
               mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F)))))
               resultPtr := add(resultPtr, 1)
               mstore(resultPtr, shl(248, mload(add(tablePtr, and(        input,  0x3F)))))
               resultPtr := add(resultPtr, 1)
            }
            
            // padding with '='
            switch mod(mload(data), 3)
            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
        }
        
        return result;
    }
}

Settings
{
  "viaIR": true,
  "optimizer": {
    "enabled": true,
    "runs": 100
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"day","type":"uint256"}],"name":"Bid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum TheGoat.ItemType","name":"_itemType","type":"uint8"},{"internalType":"string[]","name":"_names","type":"string[]"},{"internalType":"string[]","name":"_svgs","type":"string[]"},{"internalType":"string[]","name":"_jsons","type":"string[]"}],"name":"addItems","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"artComplete","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_day","type":"uint256"}],"name":"calculateRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ownedNfts","type":"uint256[]"}],"name":"claimMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"day","outputs":[{"internalType":"address","name":"winner","type":"address"},{"internalType":"uint256","name":"highestBid","type":"uint256"},{"internalType":"bool","name":"minted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","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":"getDayId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGoatsSinceDeployment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getWinningDays","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"imageData","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"lockArt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"magicColors","outputs":[{"internalType":"uint8[3][9]","name":"","type":"uint8[3][9]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"goatId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"goatId","type":"uint256"}],"name":"mintUnminted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

604061016081523463000002db57630000004b630000001e63000003b1565b630000002a63000003d8565b630000003663000003f9565b9063000000436300000421565b926300000512565b601380546001600160a01b03191673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2179055630000008260ff1960235416602355565b6300000091636521b0d3601255565b63000001ed63000000a2630000036f565b63000000ae630000035c565b63000000ba6300000390565b606681529060209163000000d083820160489052565b602181870152815263000000e46300000390565b60878152606781840152602e818701528282015282526300000106630000035c565b63000001126300000390565b60628152606281840152606281870152815263000001306300000390565b60a0815260a08184015260a08187015282820152818301526300000154630000035c565b63000001606300000390565b607781526027818401526017818701528152630000017e6300000390565b60a28152604681840152601c81870152828201528483015263000001a2630000035c565b9063000001af6300000390565b60998152608581830152604381870152825263000001cd6300000390565b60bf81529060ab8282015260698287015282015260608201526300000476565b600a546300000206906001600160a01b03166300000c6c565b63000002126300000e68565b630000021e6300001006565b630000022a63000011ae565b63000002366300001347565b630000024263000014e0565b630000024e6300001679565b630000025a6300001812565b63000002666300001987565b63000002726300001b28565b630000027e6300001cc1565b630000028a6300001e5a565b51615a7490816300003c33823960805181612fff015260a051816130ba015260c05181612fc9015260e0518161304e015261010051816130740152610120518161117a015261014051816111a60152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b03821117630000031357604052565b63000002e0565b602081019081106001600160401b03821117630000031357604052565b601f909101601f19168101906001600160401b03821190821017630000031357604052565b60405190630000036d8263000002f6565b565b60405190608082016001600160401b03811183821017630000031357604052565b60405190606082016001600160401b03811183821017630000031357604052565b6040519063000003c28263000002f6565b6007825266151a1951dbd85d60ca1b6020830152565b6040519063000003e98263000002f6565b60018252603160f81b6020830152565b60405190630000040a8263000002f6565b6008825267151a194811d3d05560c21b6020830152565b6040519063000004328263000002f6565b600482526311d3d05560e21b6020830152565b634e487b7160e01b600052601160045260246000fd5b8181106300000468575050565b60008155600101630000045b565b601b906000905b60048210630000048c57505050565b8051836000915b6002831063000004b5575050506002602060019201930191019091630000047d565b919492829491945191600090815b6003908184101563000004f45760019160209160ff86818a5116931b92831b921b19161795019201919363000004c3565b88555094969495919460019081019492019250506020016300000493565b82519193909290916001600160401b038111630000031357600091630000054882630000054185546300000683565b63000006c3565b602090601f831160011463000005f05763000005869493929183918363000005e3575b50508160011b916000199060031b1c191617905563000007d7565b63000005933363000008d4565b63000005a081630000091d565b6101205263000005b1826300000a3f565b610140526020815191012060e05260208151910120610100524660a05263000005da6300000bff565b6080523060c052565b015190503880630000056b565b600080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639190601f198416855b8181106300000669575091600193918563000005869897969410630000064e575b505050811b01905563000007d7565b015160001960f88460031b161c19169055388080630000063f565b92936020600181928786015181550195019301630000061e565b90600182811c9216801563000006b7575b602083101463000006a157565b634e487b7160e01b600052602260045260246000fd5b91607f16916300000694565b90601f821163000006d2575050565b630000036d91600080526020600020906020601f840160051c830193106300000705575b601f0160051c0190630000045b565b909150819063000006f6565b90601f82116300000720575050565b630000036d9160016000526020600020906020601f840160051c83019310630000070557601f0160051c0190630000045b565b90601f82116300000762575050565b630000036d91600b6000526020600020906020601f840160051c83019310630000070557601f0160051c0190630000045b565b90601f821163000007a4575050565b630000036d91600c6000526020600020906020601f840160051c83019310630000070557601f0160051c0190630000045b565b80519091906001600160401b038111630000031357600190630000080a81630000080384546300000683565b6300000711565b602080601f8311600114630000084b575081929394600092630000083e575b5050600019600383901b1c191690821b179055565b0151905038806300000829565b6001600052601f198316959091907fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6926000905b88821063000008bb575050838596971063000008a0575b505050811b019055565b015160001960f88460031b161c191690553880806300000896565b808785968294968601518155019501930190630000087f565b600a80546001600160a01b039283166001600160a01b0319821681179092559091167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b9081516020808210600014630000094157505090630000093e906300000ba2565b90565b6001600160401b038211630000031357630000096d826300000966600b546300000683565b6300000753565b80601f831160011463000009b0575081929360009263000009a3575b50508160011b916000199060031b1c191617600b5560ff90565b0151905038806300000989565b600b600052601f198316949091907f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9926000905b8782106300000a255750508360019596106300000a0a575b505050811b01600b5560ff90565b015160001960f88460031b161c1916905538808063000009fc565b8060018596829496860151815501950193019063000009e4565b90815160208082106000146300000a6057505090630000093e906300000ba2565b6001600160401b0382116300000313576300000a8c826300000a85600c546300000683565b6300000795565b80601f83116001146300000acf57508192936000926300000ac2575b50508160011b916000199060031b1c191617600c5560ff90565b0151905038806300000aa8565b600c600052601f198316949091907fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7926000905b8782106300000b445750508360019596106300000b29575b505050811b01600c5560ff90565b015160001960f88460031b161c191690553880806300000b1b565b806001859682949686015181550195019301906300000b03565b919082519283825260005b8481106300000b8c575050826000602080949584010152601f8019910116010190565b6020818301810151848301820152016300000b69565b601f8151116300000bd25760208151910151602082106300000bc2571790565b6000198260200360031b1b161790565b60405163305a27a960e01b8152602060048201529081906300000bfb9060248301906300000b5e565b0390fd5b60e051610100516040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a0815260c0810181811060018060401b0382111763000003135760405251902090565b60008080527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99e805460ff191660011790557fa31547ce6245cdb9ecea19cf8c7eb9f5974025bb4075011409251ae855b30aed5460166020527f0263c2b778d062355049effc2dece97bc6547ff8a88a3258daa512061c2153dd80549293929182019182106300000e6157556040516300000d0781630000031a565b8281526001600160a01b0382169182156300000e1d57600080526002602052600080516020630000976783398151915254630000036d946300000e169490916300000d64906001600160a01b031615630000204c565b630000204c565b6300000d7183630000277e565b6000805260026020526000805160206300009767833981519152546300000da3906001600160a01b031615630000204c565b6001600160a01b038316600081815260036020908152604082208054600101905590805260029052600080516020630000976783398151915280546001600160a01b03191690911790558160008051602063000097c78339815191528180a46300000e0f816300003597565b6300002375565b6300001ff3565b606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b6300000445565b600160008181527fb6c61a840592cc84133e4b25bd509abf4659307c57b160799b38490a5aa48f2e805460ff1916831790557f27739e4bb5e6f8b5e4b57a047dca8767cc9b982a011081e086cbb0dfa9de818d5460166020527f4c4dc693d7db52f85fe052106f4b4b920e78e8ef37dee82878a60ab8585faf498054929391830192604092919084106300000e6157630000036d946300000e1694600080516020630000980783398151915292556300000f756300000d5d8551956300000f3087630000031a565b8387528584526002602052808420546001600160a01b0391906300000f5990831615630000204c565b6300000f656300002814565b8685526002602052842054161590565b6000805160206300009827833981519152805484019055600160005260026020526300000fdf7fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e05b80546001600160a01b0319166000805160206300009807833981519152179055565b60008051602063000097c78339815191528180a46300000fff6300002e9a565b6300002483565b600260008181527fa1930aa930426c54c34daad2b9ada7c5d0ef0c96078a3c5bb79f6fa6602c4a7c805460ff191660011790557f07d4ff730d9753101d832555708a37d38c2c45fce8cacaefc99f06074e93fe0b5460166020527fcaff291fe014adc6b72a172705750b4cabe8f8667664d2924a166caab28856488054929391830192604092919084106300000e6157630000036d946300000e169460008051602063000097a7833981519152925563000011146300000d5d85519563000010cf87630000031a565b8387528584526020869052808420546001600160a01b03919063000010f890831615630000204c565b63000011046300002896565b8685526020879052842054161590565b7f1d662cabbdba2d21e6ca0b7eecf1378c1a60cc6bc0d6bd1d6fc75c514fb3fb2480546001019055600260008190526020527f679795a0195a1b76cdebb7c51d74e058aee92919b8c3389af86ef24535e8a28c80546001600160a01b03191660008051602063000097a783398151915217905560008051602063000097c78339815191528180a463000011a76300002ff3565b63000024e6565b600360009081527f63d87a887046e0430be80fdeb014107d7198c879cbf2cddf39a6df195c86cb3a805460ff191660011790557fb3a65e8276bd33b3e4f7d6081ebd9899187264822358758dca2e2bc37b2a9c275460166020527ff06d282f967055cb1eee17e04aa005b9682a620f4bbcfaee55ba78607a3d87ae80549092916040919081019081106300000e615760008051602063000098678339815191526300000e1693600392630000036d965563000012ad6300000d5d855195630000127887630000031a565b8387528584526002602052808420546001600160a01b03919063000012a190831615630000204c565b6300000f656300002918565b7f499842051fc28b6f1cf7e6b91d8537e7602c1bbc5f521c28365b3ad6cddd95eb80546001019055600360005260026020527f88601476d11616a71c5be67555bd1dff4b1cbf21533d2669b768b61518cfe1c380546001600160a01b031916600080516020630000986783398151915217905560008051602063000097c78339815191528180a463000013406300003093565b6300002528565b600460009081527f52102136546d97ed3f65ec1070a32935d3048ea12f310d29c378dc9d6555c0d8805460ff191660011790557f8191f4eb6b8bafbfe9a5389c8d07d7f5fd81137a7ee653fc4358269845ee1d2e5460166020527fec061709de2491458f4c981032059d7d19b0e55f45018bac6b3e660bdc959a5980549092916040919081019081106300000e615760008051602063000096c78339815191526300000e1693600492630000036d965563000014466300000d5d855195630000141187630000031a565b8387528584526002602052808420546001600160a01b039190630000143a90831615630000204c565b6300000f65630000299a565b7feb4a5702d24e42c1ef2534b2c9bf87f52d5fabb71fb3f4e20c8ccaf0159d059080546001019055600460005260026020527fee60d0579bcffd98e668647d59fec1ff86a7fb340ce572e844f234ae73a6918f80546001600160a01b03191660008051602063000096c783398151915217905560008051602063000097c78339815191528180a463000014d96300003133565b630000256a565b600560009081527f116126bec5aaa49b347e966c49378cf0c441de9121e306ea3d824584a9615aa4805460ff191660011790557fbab719002e4be320868650dc7456e9a1d245e4d5dd64765588e2f21529d871d35460166020527f5696377e725b42a372ecc45f0fbdab5e9555865aef54619ad9381892f667bbf080549092916040919081019081106300000e615760008051602063000097278339815191526300000e1693600592630000036d965563000015df6300000d5d85519563000015aa87630000031a565b8387528584526002602052808420546001600160a01b03919063000015d390831615630000204c565b6300000f656300002a1c565b7f26f5fc8d4efd71a84c53331930e9e501a0e7f23ee9a4384ccb5b5f31d300578080546001019055600560005260026020527fb98b78633099fa36ed8b8680c4f8092689e1e04080eb9cbb077ca38a14d7e38480546001600160a01b031916600080516020630000972783398151915217905560008051602063000097c78339815191528180a4630000167263000031d3565b63000025ac565b600660009081527fe1f6b6a5fb7e47dad87547d4b0671e7e995a1dae22fbe5b3b5d10e2a77ed7b01805460ff191660011790557f25847c9ccf691da811a9f934d6b3b92e6062ef92feb71bf4cb08cbb4fad8d6525460166020527fc6a239f207aea309a1b4879cb5411b8facfc2bc1e4cc4717ff2598676c399b5f80549092916040919081019081106300000e615760008051602063000096e78339815191526300000e1693600692630000036d965563000017786300000d5d855195630000174387630000031a565b8387528584526002602052808420546001600160a01b039190630000176c90831615630000204c565b6300000f656300002a9e565b7f25aa483189eea11bdafa3b7873fe10d74e8c067ae4cf7bf5fd9d2577dd7d695b80546001019055600660005260026020527f59dd4b18488d12f51eda69757a0ed42a2010c14b564330cc74a06895e60c077b80546001600160a01b03191660008051602063000096e783398151915217905560008051602063000097c78339815191528180a4630000180b6300003273565b63000025ee565b600760009081527f904977a779b22381a36c6463d4166ef55ee8cb3392c83093cb1750f1a00c9d96805460ff191660011790557f5d0f48e37dc1225cdee8d6f2a0315d796f55423522fe638d7d95421802dfc0065460166020527f5c9294642c77fdf0ce4b0f45159c977165b1ec2ef3bb94ee3e2a496634c781e880549092916040919081019081106300000e615760008051602063000098078339815191526300000e1693600792630000036d965563000019116300000d5d85519563000018dc87630000031a565b8387528584526002602052808420546001600160a01b039190630000190590831615630000204c565b6300000f656300002b20565b6000805160206300009827833981519152805460010190556007600052600260205263000019607facd8ef244210bb6898e73c48bf820ed8ecc857a3bab8d79c10e4fa92b1e9ca656300000fbd565b60008051602063000097c78339815191528180a463000019806300002e9a565b6300002630565b600860009081527f125fdacc24f94fb724c0c32a4eab75d67204551eb2448dadf875d535a7449728805460ff191660011790557f2d0e46a571fdfbe57c7c718891a8a12999c102dfffa2b3314ea165dedd1684f55460166020527f5d722ae86c7aff0f95f426cf86f75793e8cd1a526603df14563c190f75fd2ef380549092916040919081019081106300000e6157735d2a610dfcff2b38e82df7f2c3c100cf6332527d6300000e1693600892630000036d96556300001a8a6300000d5d8551956300001a5587630000031a565b8387528584526002602052808420546001600160a01b0391906300001a7e90831615630000204c565b6300000f656300002ba0565b7fe9fe1ed8c835c5d67182e134314949756a777744f22cc0cc5fe1896a5d0b806d80546001019055600860005260026020527f3a5ea591190eeb3f8fcdced843c78df04ec0dfd42f5510375207515664fa0a7580546001600160a01b031916735d2a610dfcff2b38e82df7f2c3c100cf6332527d17905560008051602063000097c78339815191528180a46300001b216300003313565b6300002672565b600960009081527ff517404d914a19d455440d961937db67771e4bfb0b4293ff6fd7c75855208c1b805460ff191660011790557f497613c0658032a90a449a944031c57b1d03996c3a6148fe12146c45cf3214005460166020527f650982f08e47212452de30f662e413cf6044e641dedc09b52c1617e804a2611e80549092916040919081019081106300000e615760008051602063000097478339815191526300000e1693600992630000036d96556300001c276300000d5d8551956300001bf287630000031a565b8387528584526002602052808420546001600160a01b0391906300001c1b90831615630000204c565b6300000f656300002c20565b7f1fb0415d9ec93fef702bd1fe1fdf3720df8996f62006643c7db89c54121883fb80546001019055600960005260026020527ff85cc6ffc513dc6cf7d199ef87b7a63cf9defe62251c1c247cd12f1eec7bff2980546001600160a01b031916600080516020630000974783398151915217905560008051602063000097c78339815191528180a46300001cba63000033b7565b63000026b8565b600a60009081527f65f9512343925c57130fd77667cb42fc83560c400ede0c87f3de7c6c27cf09a8805460ff191660011790557f0cfcac9f3767130657d3b01a9146da544eeb39eb9670066ace5e84da7fc4319f5460166020527fd5b9797c47f98351da0d9dc8805f06430ade47345ddb9b2bd6f346a04809cc4180549092916040919081019081106300000e615760008051602063000097e78339815191526300000e1693600a92630000036d96556300001dc06300000d5d8551956300001d8b87630000031a565b8387528584526002602052808420546001600160a01b0391906300001db490831615630000204c565b6300000f656300002ca2565b7fac1ed389b01f09e7e3ee906fe3f0dba383dbdfa3b395cd23595cca45a37c5de680546001019055600a60005260026020527fd3604db978f6137b0d18816b77b2ce810487a3af08a922e0b184963be5f3adfc80546001600160a01b03191660008051602063000097e783398151915217905560008051602063000097c78339815191528180a46300001e536300003457565b63000026fa565b600b60009081527fdabe84bb17a8774762b6726edd7eb728da1732e1ab123804fc9345b7300e0a30805460ff191660011790557fcaeae41dfed97dfd8c41876ff591faa3e36cda388621c550caa3321a2a624e5f5460166020527fcfa8b17cfe829ccfb82a1b8bc946a78d914318562253e01c04a5bbac5c20f86b80549092916040919081019081106300000e615760008051602063000097078339815191526300000e1693600b92630000036d96556300001f596300000d5d8551956300001f2487630000031a565b8387528584526002602052808420546001600160a01b0391906300001f4d90831615630000204c565b6300000f656300002d24565b7fd025d06390c15c87ffed86920506c1d3118185ffc9f8ff498bd16fa5bd55001180546001019055600b60005260026020527fab9952baf6478d8cfb7253ce86a6c53a7b7549582c76210b1581ae682b7e556f80546001600160a01b031916600080516020630000970783398151915217905560008051602063000097c78339815191528180a46300001fec63000034f7565b630000273c565b156300001ffc57565b60405162461bcd60e51b8152602060048201526032602482015260008051602063000096a783398151915260448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608490fd5b15630000205557565b60405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606490fd5b9081602091031263000002db57516001600160e01b03198116810363000002db5790565b6001600160a01b0390911681526000602082018190526040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260016040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260026040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260036040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260046040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260056040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260066040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260076040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260086040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b0390911681526000602082015260096040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b03909116815260006020820152600a6040820152608060608201819052630000093e929101906300000b5e565b6001600160a01b03909116815260006020820152600b6040820152608060608201819052630000093e929101906300000b5e565b3d156300002370573d906001600160401b038211630000031357604051916300002364601f8201601f1916602001846300000337565b82523d6000602084013e565b606090565b803b15630000247c57602060405180928160008163000023a6630a85bd0160e11b98898352336004840163000020be565b03926001600160a01b03165af160009181630000243e575b5063000024305763000023d1630000232e565b80519081630000242b5760405162461bcd60e51b8152602060048201526032602482015260008051602063000096a783398151915260448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608490fd5b602001fd5b6001600160e01b0319161490565b630000246a91925060203d81116300002473575b630000246081836300000337565b810190630000209a565b903863000023be565b503d6300002452565b5050600190565b6000805160206300009807833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b98898352336004840163000020f2565b03925af160009181630000243e575063000024305763000023d1630000232e565b60008051602063000097a7833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b9889835233600484016300002126565b6000805160206300009867833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b988983523360048401630000215a565b60008051602063000096c7833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b988983523360048401630000218e565b6000805160206300009727833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b98898352336004840163000021c2565b60008051602063000096e7833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b98898352336004840163000021f6565b6000805160206300009807833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b988983523360048401630000222a565b735d2a610dfcff2b38e82df7f2c3c100cf6332527d803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b988983523360048401630000225e565b6000805160206300009747833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b9889835233600484016300002292565b60008051602063000097e7833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b98898352336004840163000022c6565b6000805160206300009707833981519152803b15630000247c57602060405180928160008163000024c5630a85bd0160e11b98898352336004840163000022fa565b6008549060009081805260209260098452806040842055680100000000000000008110156300000313576001810180600855811015630000280d5760088352838320018290556001600160a01b0316908163000027e457505050630000036d6300002dcd565b604091815260038352600782822054936006815283832085845281528284812055828052522055565b6300002da6565b6008546000906001825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600160409260088352848320015560008051602063000098078339815191528152600383526007828220549360068152838320858452815260018484205560018352522055565b6008546000906002825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600260409260088352848320015560008051602063000097a78339815191528152600383526007828220549360068152838320858452815260028484205560028352522055565b6008546000906003825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600360409260088352848320015560008051602063000098678339815191528152600383526007828220549360068152838320858452815260038484205560038352522055565b6008546000906004825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600460409260088352848320015560008051602063000096c78339815191528152600383526007828220549360068152838320858452815260048484205560048352522055565b6008546000906005825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600560409260088352848320015560008051602063000097278339815191528152600383526007828220549360068152838320858452815260058484205560058352522055565b6008546000906006825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600660409260088352848320015560008051602063000096e78339815191528152600383526007828220549360068152838320858452815260068484205560068352522055565b6008546000906007825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d5760076040926008835284832001556000805160206300009807833981519152815260038352600782822054936006815283832085845281528184842055818352522055565b600880546000828152602091600983528060408320556801000000000000000081101563000003135760018101808555811015630000280d57604092846007928185528285200155735d2a610dfcff2b38e82df7f2c3c100cf6332527d835260038152838320549460068252848420868552825280858520558352522055565b6008546000906009825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600960409260088352848320015560008051602063000097478339815191528152600383526007828220549360068152838320858452815260098484205560098352522055565b600854600090600a825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600a60409260088352848320015560008051602063000097e783398151915281526003835260078282205493600681528383208584528152600a84842055600a8352522055565b600854600090600b825260209160098352816040822055680100000000000000008210156300000313576001820180600855821015630000280d57600b604092600883528483200155600080516020630000970783398151915281526003835260078282205493600681528383208584528152600b84842055600b8352522055565b634e487b7160e01b600052603260045260246000fd5b6000198101919082116300000e6157565b6008805460001991908281018181116300000e61576000918280526009602052806040842054921015630000280d5783835284816020852001015490821015630000280d576300002e339084845280836020862001556000526009602052604060002090565b55600080526009602052807fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b5581549283156300002e86578084019380851015630000280d578383526020832001015555565b634e487b7160e01b82526031600452602482fd5b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b576300002ee2906300002ed86300002ed163000037e1565b6300003bfd565b904316630000398b565b5050600d60205260008051602063000097878339815191525460008051602063000098078339815191526000527f91528cfbcf02e8bdd2032119620887b742bf0d5264d867c6aec3273764c871b854630000036d916001600160a01b039182169116630000362d565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b6064820152608490fd5b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b57630000302a906300002ed86300002ed163000037e1565b5050600d60205260008051602063000097878339815191525460008051602063000097a78339815191526000527f3619c3727cc3e13dc0e59294f837cd91274ee1f0900a7e0f75e92f8c2c80941254630000036d916001600160a01b039182169116630000362d565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b5763000030ca906300002ed86300002ed163000037e1565b5050600d60205260008051602063000097878339815191525460008051602063000098678339815191526000527f6f7420a3bf5f659f66da61470606aa926dcaad448fe289394e68e1678fbfc84b54630000036d916001600160a01b039182169116630000362d565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b57630000316a906300002ed86300002ed163000037e1565b5050600d60205260008051602063000097878339815191525460008051602063000096c78339815191526000527ff79095a123280101f7d9ce38423ccf4623c03e56c1dcfd1cc7e9e8d545866cf454630000036d916001600160a01b039182169116630000362d565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b57630000320a906300002ed86300002ed163000037e1565b5050600d60205260008051602063000097878339815191525460008051602063000097278339815191526000527ff12336d992abbaef28dd80bdc4f4924d91b49a25551a9c9a4894d77853b15e1154630000036d916001600160a01b039182169116630000362d565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b5763000032aa906300002ed86300002ed163000037e1565b5050600d60205260008051602063000097878339815191525460008051602063000096e78339815191526000527f0373994cc7cad5706a8012bd6bc8c7cb29af41c0c8cbea3ed96eeb10fa267f2954630000036d916001600160a01b039182169116630000362d565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b57630000334a906300002ed86300002ed163000037e1565b5050600d602052600080516020630000978783398151915254735d2a610dfcff2b38e82df7f2c3c100cf6332527d6000527f55fccfb8cec076b32e2f3a623080194f5717f4d0e68f66b11475afb0d5f05c7d54630000036d916001600160a01b039182169116630000362d565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b5763000033ee906300002ed86300002ed163000037e1565b5050600d60205260008051602063000097878339815191525460008051602063000097478339815191526000527f4d30e08133ced5769d04bad2c27b29b870beed94414cfa7cc0e5987b7d33643d54630000036d916001600160a01b039182169116630000362d565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b57630000348e906300002ed86300002ed163000037e1565b5050600d60205260008051602063000097878339815191525460008051602063000097e78339815191526000527fac4d192149deea6ba3663fef566d93609edfe16ac755103a78c04990bf76115154630000036d916001600160a01b039182169116630000362d565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b57630000352e906300002ed86300002ed163000037e1565b5050600d60205260008051602063000097878339815191525460008051602063000097078339815191526000527fba3b2f6cbae13ab0376d617f3db4531b6ddcb2076fb4973e7257c7e185bfbd8154630000036d916001600160a01b039182169116630000362d565b65ffffffffffff908143116300002f9f5763ffffffff80924316116300002f4b5763000035d4630000036d926300002ed86300002ed163000037e1565b50506001600160a01b039081169081156300003618575b600d602052600080516020630000978783398151915254600092835260409092205481169116630000362d565b6300003624630000376e565b505063000035eb565b6001600160a01b0380831692919081169081841415806300003764575b6300003657575b50505050565b8163000036cc575b5050816300003672575b80806300003651565b6001600160a01b03166000908152600e6020526040902060008051602063000098878339815191529063000036a89063000037a9565b604080516001600160e01b039384168152919092166020820152a238806300003669565b6001600160a01b03166000908152600e6020526040902065ffffffffffff908143116300002f9f5763ffffffff80924316116300002f4b57600080516020630000988783398151915291816300003735630000372e6300003740946300003822565b6300003c17565b914316906300003ae3565b604080516001600160e01b039384168152919092166020820152a23880630000365f565b506001630000364a565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b5763000037a5906300002ed8630000372e63000037e1565b9091565b65ffffffffffff8043116300002f9f5763ffffffff80914316116300002f4b578163000037356300002ed163000037a5946300003822565b600f546000908063000037f5575050600090565b6000199181838101116300000e6157600f9052016000805160206300009847833981519152015460201c90565b805460009181630000383657505050600090565b6000199282848101116300000e615760209181522001015460201c90565b600f5490680100000000000000008210156300000313576001820180600f55821015630000280d57600f600052805160209182015190911b63ffffffff191663ffffffff9190911617600080516020630000984783398151915290910155565b9081546801000000000000000081101563000003135760018101808455811015630000280d57600092835260209283902082519284015190931b63ffffffff191663ffffffff9290921691909117910155565b604080519192919081016001600160401b03811182821017630000031357604052602081935463ffffffff81168352811c910152565b15630000394657565b60405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b65797300000000006044820152606490fd5b600f5491929180156300003aaf576300003a6991818563000039db63000039d463000039ba6020966300002dbc565b600f60005260008051602063000098478339815191520190565b6300003907565b9263000039ec845163ffffffff1690565b6300003a0763ffffffff91828416928391161115630000393d565b6300003a256300003a1c865163ffffffff1690565b63ffffffff1690565b036300003a6d57506300003a4463000039ba6300003a5b936300002dbc565b9063ffffffff82549181199060201b169116179055565b01516001600160e01b031690565b9190565b90506300003aa891506300003a936300003a87630000035c565b63ffffffff9092168252565b6001600160e01b038716818501526300003854565b6300003a5b565b506300003add906300003ac76300003a87630000035c565b6001600160e01b03841660208201526300003854565b60009190565b909291928382548015156000146300003bce579260209291846300003b2563000039d46300003b186300003a69986300002dbc565b8560005260206000200190565b936300003b36855163ffffffff1690565b6300003b5163ffffffff91828416928391161115630000393d565b6300003b666300003a1c875163ffffffff1690565b036300003b9357506300003a5b926300003b866300003a44926300002dbc565b9060005260206000200190565b9150506300003aa8916300003bb96300003bad630000035c565b63ffffffff9093168352565b6001600160e01b0388168286015263000038b4565b50506300003add916300003be76300003bad630000035c565b6001600160e01b038516602083015263000038b4565b6001600160e01b039081166001019081116300000e615790565b6001600160e01b03908116600019019081116300000e61579056fe6080604052600436101561001257600080fd5b60003560e01c806301ffc9a714610317578063040f15df14610312578063061ba2f11461030d57806306fdde0314610308578063081812fc14610303578063095ea7b3146102fe57806318160ddd146102f95780631998aeef146102f45780631f88c9d0146102ef57806323b872dd146102ea5780632f745c59146102e55780633644e515146102e0578063379607f5146102db57806338495761146102d65780633a46b1a8146102d15780633fc8cef3146102cc57806342842e0e146102c75780634bf5d7e9146102c25780634f6ccce7146102bd57806351c93569146102b8578063587cde1e146102b35780635c19a95c146102ae5780636352211e146102a957806370a08231146102a4578063715018a61461029f5780637ecebe001461029a57806384b0196e146102955780638da5cb5b146102905780638e539e8c1461028b5780638ff12b6d146102865780639051cce91461028157806391ddadf41461027c57806395d89b411461027757806396545927146102725780639ab24eb01461026d578063a0712d6814610268578063a22cb46514610263578063b88d4fde1461025e578063bfc12c0514610259578063c3cda52014610254578063c6c034431461024f578063c87b56dd1461024a578063d1d58b2514610245578063d3ea435014610240578063e985e9c51461023b578063f2fde38b14610236578063f8605801146102315763fe8e66ed1461022c57600080fd5b611d05565b611cd0565b611c0d565b611bb0565b611b94565b611b76565b6118bf565b61189c565b611772565b611754565b6116f5565b61160d565b611554565b61150b565b611498565b611413565b6113e7565b611377565b611327565b61124c565b611223565b611161565b611127565b6110c9565b6110a6565b611088565b611066565b61102b565b610fb5565b610f0a565b610e5d565b610e35565b610e0c565b610d0a565b610c92565b610a60565b610a45565b610992565b610969565b610831565b610689565b61066b565b610595565b610539565b61047c565b610445565b6103c6565b610333565b6001600160e01b031981160361032e57565b600080fd5b3461032e57602036600319011261032e5760206004356103528161031c565b63ffffffff60e01b1663780e9d6360e01b8114908115610378575b506040519015158152f35b6380ac58cd60e01b8114915081156103aa575b8115610399575b503861036d565b6301ffc9a760e01b14905038610392565b635b5e139f60e01b8114915061038b565b600091031261032e57565b3461032e57600036600319011261032e5760206103e1613ddc565b604051908152f35b60005b8381106103fc5750506000910152565b81810151838201526020016103ec565b90602091610425815180928185528580860191016103e9565b601f01601f1916010190565b90602061044292818152019061040c565b90565b3461032e57602036600319011261032e57610478610464600435614661565b60405191829160208352602083019061040c565b0390f35b3461032e576000806003193601126105365760405181805461049d81612288565b8084529060019081811690811561050e57506001146104d3575b610478846104c781880382610b4d565b60405191829182610431565b93508180526020938483205b8284106104fb5750505081610478936104c792820101936104b7565b80548585018701529285019281016104df565b61047896506104c79450602092508593915060ff191682840152151560051b820101936104b7565b80fd5b3461032e57602036600319011261032e576020610557600435612334565b6040516001600160a01b039091168152f35b600435906001600160a01b038216820361032e57565b602435906001600160a01b038216820361032e57565b3461032e57604036600319011261032e576105ae610569565b6024356105ba81612265565b916001600160a01b03808416908216811461061c576105ec936105e79133149081156105ee575b506122c2565b61265e565b005b6001600160a01b0316600090815260056020908152604080832033845290915290205460ff169050386105e1565b60405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608490fd5b3461032e57600036600319011261032e576020600854604051908152f35b600036600319011261032e576106a0341515613e28565b6106a8613dfc565b6106d26106cb60016106c4846000526014602052604060002090565b015461290c565b3411613e94565b6106f66106e9826000526014602052604060002090565b546001600160a01b031690565b6001600160a01b039061070d908216331415613ed7565b6107336107276106e9846000526014602052604060002090565b6001600160a01b031690565b6001610749846000526014602052604060002090565b015492346001610763836000526014602052604060002090565b015561079c3361077d836000526014602052604060002090565b80546001600160a01b0319166001600160a01b03909216919091179055565b6107a5816143a7565b60408051348152602081019290925233917f19421268847f42dd61705778018ddfc43bcdce8517e7a630acb12f122c7094819190a21690816107e357005b6105ec91615765565b90815180825260208080930193019160005b82811061080c575050505090565b8351855293810193928101926001016107fe565b9060206104429281815201906107ec565b3461032e57602036600319011261032e5761084a610569565b610852613dfc565b9061085c8261311e565b916000916001600160a01b0390811690835b8381106108bd5785856108808161311e565b9160005b82811061089957604051806104788682610820565b806108a76108b89284613833565b516108b28287613833565b5261381a565b610884565b82826108d66106e9846000526014602052604060002090565b16148061090c575b6108f1575b6108ec9061381a565b61086e565b9361090481866108b26108ec948a613833565b9490506108e3565b5061092e6002610926836000526014602052604060002090565b015460ff1690565b156108de565b606090600319011261032e576001600160a01b0390600435828116810361032e5791602435908116810361032e579060443590565b3461032e576105ec61097a36610934565b9161098d6109888433612465565b612360565b612537565b3461032e57604036600319011261032e576109ab610569565b602435906109b8816121a7565b8210156109ec576001600160a01b031660009081526006602090815260408083209383529281529082902054915191825290f35b60405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608490fd5b3461032e57600036600319011261032e5760206103e1612fc6565b3461032e57602036600319011261032e576105ec60043561429b565b634e487b7160e01b600052604160045260246000fd5b6001600160401b038111610aa557604052565b610a7c565b604081019081106001600160401b03821117610aa557604052565b606081019081106001600160401b03821117610aa557604052565b602081019081106001600160401b03821117610aa557604052565b60c081019081106001600160401b03821117610aa557604052565b608081019081106001600160401b03821117610aa557604052565b61012081019081106001600160401b03821117610aa557604052565b90601f801991011681019081106001600160401b03821117610aa557604052565b60405190610b7b82610aaa565b565b60405190610b7b82610ac5565b60405190610b7b82610b31565b6001600160401b038111610aa55760051b60200190565b6001600160401b038111610aa557601f01601f191660200190565b929192610bd582610bae565b91610be36040519384610b4d565b82948184528183011161032e578281602093846000960137010152565b81601f8201121561032e57803590610c1782610b97565b92604092610c2784519586610b4d565b808552602093848087019260051b8501019383851161032e57858101925b858410610c56575050505050505090565b83356001600160401b03811161032e57820185603f8201121561032e578791610c8787838786809601359101610bc9565b815201930192610c45565b3461032e57608036600319011261032e57600435600481101561032e576001600160401b039060243582811161032e57610cd0903690600401610c00565b60443583811161032e57610ce8903690600401610c00565b9060643593841161032e57610d046105ec943690600401610c00565b926135e6565b3461032e57604036600319011261032e57610d23610569565b60243590610d4265ffffffffffff610d3a4361351a565b168310611d8b565b6001600160a01b03166000908152600e6020526040812091610d6390613581565b91805482938160058111610db4575b5090602094610d819284612d90565b80610d9b5750505b6040516001600160e01b039091168152f35b91610da78492936128fd565b928152200154811c610d89565b94610dbe8661335f565b8603958611610e0757602095610d819385875263ffffffff80838a8a2001541690851610600014610df55750915b91925094610d72565b929150610e0190612920565b90610dec565b612191565b3461032e57600036600319011261032e576013546040516001600160a01b039091168152602090f35b3461032e576105ec610e4636610934565b9060405192610e5484610ae0565b600084526123c2565b3461032e57600036600319011261032e574365ffffffffffff610e7f4361351a565b1603610eca57610478604051610e9481610aaa565b601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015260405191829182610431565b60405162461bcd60e51b8152602060048201526018602482015277566f7465733a2062726f6b656e20636c6f636b206d6f646560401b6044820152606490fd5b3461032e57602036600319011261032e57600435600854811015610f5b5760086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30154604051908152602090f35b60405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608490fd5b3461032e57602036600319011261032e57600435806000526014602052610fe760ff6002604060002001541615613f23565b600a8101808211610e075761100490610ffe613dfc565b11613f6f565b60148106611015576105ec90613fbc565b600a546105ec91906001600160a01b0316614120565b3461032e57602036600319011261032e5760206001600160a01b038061104f610569565b16600052600d825260406000205416604051908152f35b3461032e57602036600319011261032e576105ec611082610569565b33611e11565b3461032e57602036600319011261032e576020610557600435612265565b3461032e57602036600319011261032e5760206103e16110c4610569565b6121a7565b3461032e57600080600319360112610536576110e3611d20565b600a80546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b3461032e57602036600319011261032e576001600160a01b03611148610569565b1660005260106020526020604060002054604051908152f35b3461032e57600036600319011261032e576111f461119e7f0000000000000000000000000000000000000000000000000000000000000000613150565b6104786111ca7f0000000000000000000000000000000000000000000000000000000000000000613244565b6112026111d5613106565b91604051958695600f60f81b875260e0602088015260e087019061040c565b90858203604087015261040c565b90466060850152306080850152600060a085015283820360c08501526107ec565b3461032e57600036600319011261032e57600a546040516001600160a01b039091168152602090f35b3461032e57602036600319011261032e5761128360043561127e65ffffffffffff6112764361351a565b168210611d8b565b613581565b600f549060008291600584116112ce575b61129e9350612d27565b6000816112b357505060405160008152602090f35b60206112bf81936128fd565b91600f8152200154811c610d89565b91926112d98161335f565b8103908111610e0757600f82526000805160206159ff83398151915281015461129e949063ffffffff9081169085161015611315575091611294565b92915061132190612920565b90611294565b3461032e57602036600319011261032e5760043560005260146020526060604060002060018060a01b038154169060ff600260018301549201541690604051928352602083015215156040820152f35b3461032e57602036600319011261032e576004356001600160401b0380821161032e573660238301121561032e57816004013590811161032e57600560243683831b850182011161032e5760005b8381106113ce57005b806113e183600193861b8801013561429b565b016113c5565b3461032e57600036600319011261032e5760206114034361351a565b65ffffffffffff60405191168152f35b3461032e576000806003193601126105365760405181600180549061143782612288565b8085529181811690811561050e575060011461145d57610478846104c781880382610b4d565b80945082526020938483205b8284106114855750505081610478936104c792820101936104b7565b8054858501870152928501928101611469565b3461032e5760208060031936011261032e576114b560043561519f565b604051918260009283915b600983106114ce5761036086f35b838251829087915b600383106114f2575050506060600192019201920191906114c0565b815160ff168152879360019093019291820191016114d6565b3461032e57602036600319011261032e576001600160a01b0361152c610569565b16600052600e602052602060018060e01b0361154b60406000206129bd565b16604051908152f35b3461032e57602036600319011261032e576004356000818152601460205260409020546001600160a01b031633036115c457806115ac6115a660026109266105ec956000526014602052604060002090565b15613f23565b6115be6115b7613dfc565b8210613f6f565b33614120565b60405162461bcd60e51b81526020600482015260176024820152762cb7ba9030b932903737ba103a3432903bb4b73732b91760491b6044820152606490fd5b8015150361032e57565b3461032e57604036600319011261032e57611626610569565b60243561163281611603565b6001600160a01b038216913383146116b457816116716116829233600052600560205260406000209060018060a01b0316600052602052604060002090565b9060ff801983541691151516179055565b604051901515815233907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190602090a3005b60405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606490fd5b3461032e57608036600319011261032e5761170e610569565b61171661057f565b606435916001600160401b03831161032e573660238401121561032e5761174a6105ec933690602481600401359101610bc9565b91604435916123c2565b3461032e57600036600319011261032e576020601254604051908152f35b3461032e5760c036600319011261032e5761178b610569565b6064359060243560443560ff8416840361032e5780421161185c5761182e611857916105ec9560405190611816826118086020820195898b8860609194939260808201957fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf835260018060a01b0316602083015260408201520152565b03601f198101845283610b4d565b61182960a43593608435935190206130e0565b612df2565b6001600160a01b0381166000908152601060205260409020805460018101909155909214611dce565b611e11565b60405162461bcd60e51b8152602060048201526018602482015277159bdd195cce881cda59db985d1d5c9948195e1c1a5c995960421b6044820152606490fd5b3461032e57600036600319011261032e57602060ff602354166040519015158152f35b3461032e57602036600319011261032e576004356118dc816126c2565b6118e590614c21565b6118ee81614b47565b6118f790614b82565b805160ff1661190590613847565b5090602081015160ff1661191890613866565b5092604082015160ff1661192b90613885565b50916060015160ff1661193d906138a4565b5061194782615270565b6119509061569a565b9061195a83614661565b611963906158eb565b9261196d90614c92565b604051707b202261747472696275746573223a205b60781b6020820152968796919591603188016119a0916002016145df565b6119a990614c85565b6119b5916002016145df565b6119be90614c85565b6119ca916002016145df565b6119d390614c85565b6119df916002016145df565b6119e890614c85565b7f7b2274726169745f74797065223a2022436f6c6f72222c202276616c7565223a815261101160f11b6020820152602201611a22916145c8565b61227d60f01b815260020161174b60f21b81526002017f226465736372697074696f6e223a20224372656174656420627920746865676f81527f61742e777466222c2265787465726e616c5f75726c223a202268747470733a2f60208201527f2f746865676f61742e777466222c22696d616765223a2022646174613a696d6160408201527119d94bdcdd99cade1b5b0ed8985cd94d8d0b60721b6060820152607201611ace916145c8565b74222c226e616d65223a202254686520476f6174202360581b8152601501611af5916145c8565b61227d60f01b81526002010390601f19918281018252611b159082610b4d565b611b1e906158eb565b6040517f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000602082015291908290603d8201611b58916145c8565b039081018252611b689082610b4d565b604051610478819282610431565b3461032e57602036600319011261032e5760206103e160043561432d565b3461032e57602036600319011261032e576105ec6004356143a7565b3461032e57604036600319011261032e57602060ff611c01611bd0610569565b611bd861057f565b6001600160a01b0391821660009081526005865260408082209290931681526020919091522090565b54166040519015158152f35b3461032e57602036600319011261032e57611c26610569565b611c2e611d20565b6001600160a01b03908116908115611c7c57600a80546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b3461032e57600036600319011261032e57611ce9611d20565b6001602354611cfb60ff8216156137d4565b60ff191617602355005b3461032e57600036600319011261032e5760206103e1613dfc565b600a546001600160a01b03163303611d3457565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60405190611d8582610ae0565b60008252565b15611d9257565b60405162461bcd60e51b81526020600482015260146024820152730566f7465733a20667574757265206c6f6f6b75760641b6044820152606490fd5b15611dd557565b60405162461bcd60e51b8152602060048201526014602482015273566f7465733a20696e76616c6964206e6f6e636560601b6044820152606490fd5b6001600160a01b038181166000818152600d6020526040812080548685166001600160a01b0319821681179092559095931693611e77929091869186917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9080a46121a7565b918381141580611f98575b611e8d575b50505050565b80611efe575b5082611ea0575b80611e87565b6001600160a01b03166000908152600e60205260409020600080516020615a1f83398151915291611edb91611ed590916134b1565b906120e4565b604080516001600160e01b039384168152919092166020820152a2388080611e9a565b6001600160a01b0381166000908152600e60205260409020611f1f846134b1565b611f3865ffffffffffff611f324361351a565b16613581565b6001600160e01b03918280611f4c866129bd565b169116900392828411610e0757600080516020615a1f83398151915293611f8f92611f7692612c41565b6040805192851683529316602082015291829190820190565b0390a238611e93565b50821515611e82565b6001600160a01b03808316929190811690818414158061209e575b611fc65750505050565b8161202d575b505081611fdb575b8080611e87565b6001600160a01b03166000908152600e60205260409020600080516020615a1f8339815191529061200b906120a6565b604080516001600160e01b039384168152919092166020820152a23880611fd4565b6001600160a01b03166000908152600e6020526040902061205765ffffffffffff611f324361351a565b6001600160e01b03906000198261206d856129bd565b160192828411610e0757600080516020615a1f8339815191529361209492611f7692612c41565b0390a23880611fcc565b506001611fbc565b6120b965ffffffffffff611f324361351a565b6001600160e01b03906001826120ce856129bd565b1601918211610e07576120e092612c41565b9091565b906120f865ffffffffffff611f324361351a565b6001600160e01b0391828061210c866129bd565b16911601918211610e07576120e092612c41565b61213365ffffffffffff611f324361351a565b6001600160e01b03600181612146612982565b1601908111610e07576120e091612b23565b61216b65ffffffffffff611f324361351a565b6001600160e01b036000198161217f612982565b1601908111612191576120e091612b23565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b031680156121c757600052600360205260406000205490565b60405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608490fd5b1561222557565b60405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606490fd5b6000908152600260205260409020546001600160a01b031661044281151561221e565b90600182811c921680156122b8575b60208310146122a257565b634e487b7160e01b600052602260045260246000fd5b91607f1691612297565b156122c957565b60405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608490fd5b612345612340826126c2565b61221e565b6000908152600460205260409020546001600160a01b031690565b1561236757565b60405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526c1c881bdc88185c1c1c9bdd9959609a1b6064820152608490fd5b91610b7b93916123e9936123d96109888433612465565b6123e4838383612537565b6128ab565b612441565b60809060208152603260208201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60608201520190565b1561244857565b60405162461bcd60e51b815280612461600482016123ee565b0390fd5b6001600160a01b038061247784612265565b1692818316928484149485156124ad575b50508315612497575b50505090565b6124a391929350612334565b1614388080612491565b60009081526005602090815260408083206001600160a01b03949094168352929052205460ff1693503880612488565b156124e457565b60405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608490fd5b61255b9261254481612265565b6001600160a01b03838116959091821686146124dd565b8316801561260d57610b7b94612572838686614dd0565b6125888161258261072786612265565b146124dd565b6125af61259f846000526004602052604060002090565b80546001600160a01b0319169055565b6001600160a01b038481166000908152600360209081526040808320805460001901905592881682528282208054600101905585825260029052206125f590869061077d565b6000805160206159df833981519152600080a4615051565b60405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b600082815260046020526040902080546001600160a01b0319166001600160a01b0383161790556001600160a01b038061269784612265565b169116907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a4565b6000908152600260205260409020546001600160a01b0316151590565b9081602091031261032e57516104428161031c565b610442939260809260018060a01b03168252600060208301526040820152816060820152019061040c565b6001600160a01b0391821681529116602082015260408101919091526080606082018190526104429291019061040c565b6040513d6000823e3d90fd5b3d15612787573d9061276d82610bae565b9161277b6040519384610b4d565b82523d6000602084013e565b606090565b9073cc44a5feb6ee172daaa31c1fee3fc1ce1654057f803b1561284f576127d1602091600093604051948580948193630a85bd0160e11b998a845233600485016126f4565b03925af16000918161281f575b50612811576127eb61275c565b8051908161280c5760405162461bcd60e51b815280612461600482016123ee565b602001fd5b6001600160e01b0319161490565b61284191925060203d8111612848575b6128398183610b4d565b8101906126df565b90386127de565b503d61282f565b505050600190565b909190803b1561284f57612889602091600093604051948580948193630a85bd0160e11b998a845233600485016126f4565b03926001600160a01b03165af16000918161281f5750612811576127eb61275c565b92909190823b156128de57612889926020926000604051809681958294630a85bd0160e11b9a8b8552336004860161271f565b50505050600190565b634e487b7160e01b600052603260045260246000fd5b600019810191908211610e0757565b9066038d7ea4c680008201809211610e0757565b9060018201809211610e0757565b9060028201809211610e0757565b9060208201809211610e0757565b9060d28201809211610e0757565b9060808201809211610e0757565b9060408201809211610e0757565b9060148201809211610e0757565b600f5460009080612994575050600090565b600019918183810111610e0757600f9052016000805160206159ff833981519152015460201c90565b8054600091816129cf57505050600090565b600019928284810111610e075760209181522001015460201c90565b634e487b7160e01b600052600060045260246000fd5b600f5490600160401b821015610aa5576001820180600f55821015612a5657600f600052805160209182015190911b63ffffffff191663ffffffff91909116176000805160206159ff83398151915290910155565b6128e7565b908154600160401b811015610aa55760018101808455811015612a5657600092835260209283902082519284015190931b63ffffffff191663ffffffff9290921691909117910155565b90604051604081018181106001600160401b03821117610aa557604052602081935463ffffffff81168352811c910152565b15612ade57565b60405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b65797300000000006044820152606490fd5b600f549192918015612c1757612bdd918185612b63612b5e612b466020966128fd565b600f6000526000805160206159ff8339815191520190565b612aa5565b92612b72845163ffffffff1690565b612b8963ffffffff91828416928391161115612ad7565b612ba3612b9a865163ffffffff1690565b63ffffffff1690565b03612be15750612bb8612b46612bcf936128fd565b9063ffffffff82549181199060201b169116179055565b01516001600160e01b031690565b9190565b9050612c129150612bff612bf3610b6e565b63ffffffff9092168252565b6001600160e01b03871681850152612a01565b612bcf565b50612c3b90612c27612bf3610b6e565b6001600160e01b0384166020820152612a01565b60009190565b90929192838254801515600014612d0257926020929184612c77612b5e612c6a612bdd986128fd565b8560005260206000200190565b93612c86855163ffffffff1690565b612c9d63ffffffff91828416928391161115612ad7565b612cae612b9a875163ffffffff1690565b03612cd15750612bcf92612cc4612bb8926128fd565b9060005260206000200190565b915050612c1291612cef612ce3610b6e565b63ffffffff9093168352565b6001600160e01b03881682860152612a5b565b5050612c3b91612d13612ce3610b6e565b6001600160e01b0385166020830152612a5b565b905b828110612d3557505090565b9091808216906001818418811c8301809311610e0757600f6000526000805160206159ff83398151915283015463ffffffff9081169086161015612d7d575050915b90612d29565b909392508101809111610e075790612d77565b91905b838210612da05750505090565b909192808316906001818518811c8301809311610e075760008681526020902083015463ffffffff9081169085161015612ddf575050925b9190612d93565b909493508101809111610e075791612dd8565b916104429391612e0193612f49565b919091612e2e565b634e487b7160e01b600052602160045260246000fd5b60051115612e2957565b612e09565b612e3781612e1f565b80612e3f5750565b612e4881612e1f565b60018103612e905760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b6044820152606490fd5b612e9981612e1f565b60028103612ee65760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b80612ef2600392612e1f565b14612ef957565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b9291906fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311612fba5791608094939160ff602094604051948552168484015260408301526060820152600093849182805260015afa15612fb55781516001600160a01b03811615612faf579190565b50600190565b612750565b50505050600090600390565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614806130b7575b15613021577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a081526130b181610afb565b51902090565b507f00000000000000000000000000000000000000000000000000000000000000004614612ff8565b6042906130eb612fc6565b906040519161190160f01b8352600283015260228201522090565b60405161311281610ae0565b60008152906000368137565b9061312882610b97565b6131356040519182610b4d565b8281528092613146601f1991610b97565b0190602036910137565b60ff811461318a5760ff811690601f82116131785761316d6132f9565b918252602082015290565b604051632cd44ac360e21b8152600490fd5b50604051600b5481600061319d83612288565b80835260019380851690811561322357506001146131c3575b5061044292500382610b4d565b600b60009081527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db994602093509091905b81831061320b5750506104429350820101386131b6565b855487840185015294850194869450918301916131f4565b905061044294506020925060ff191682840152151560051b820101386131b6565b60ff81146132615760ff811690601f82116131785761316d6132f9565b50604051600c5481600061327483612288565b8083526001938085169081156132235750600114613299575061044292500382610b4d565b600c60009081527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c794602093509091905b8183106132e15750506104429350820101386131b6565b855487840185015294850194869450918301916132ca565b6040519061330682610aaa565b60208083523683820137565b9061331c82610bae565b6133296040519182610b4d565b8281528092613146601f1991610bae565b634e487b7160e01b600052601260045260246000fd5b811561335a570490565b61333a565b8015613499578061343261342b61342161341761340d6134036133f96133ef60016104429a6000908b60801c8061348d575b508060401c80613480575b508060201c80613473575b508060101c80613466575b508060081c80613459575b508060041c8061344c575b508060021c8061343f575b50821c613438575b811c1b6133e8818b613350565b0160011c90565b6133e8818a613350565b6133e88189613350565b6133e88188613350565b6133e88187613350565b6133e88186613350565b6133e88185613350565b8092613350565b9061349f565b81016133db565b60029150910190386133d3565b60049150910190386133c8565b60089150910190386133bd565b60109150910190386133b2565b60209150910190386133a7565b604091509101903861339c565b91505060809038613391565b50600090565b90808210156134ac575090565b905090565b6001600160e01b03908181116134c5571690565b60405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608490fd5b65ffffffffffff9081811161352d571690565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b6064820152608490fd5b63ffffffff90818111613592571690565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608490fd5b939291936135f2611d20565b6136088251865181149081613782575b5061378d565b61362361361e61361a60235460ff1690565b1590565b6137d4565b60005b825181101561377a576136859061363c83613829565b8261368a5761368061364e8286613833565b51613659838a613833565b516136648489613833565b519061366e610b7d565b92835260208301526040820152613ced565b61381a565b613626565b61369383613829565b600183036136da576136806136a88286613833565b516136b3838a613833565b516136be8489613833565b51906136c8610b7d565b92835260208301526040820152613bfe565b6136e383613829565b6002830361372a576136806136f88286613833565b51613703838a613833565b5161370e8489613833565b5190613718610b7d565b92835260208301526040820152613b0f565b61373383613829565b60038303613680576136806137488286613833565b51613753838a613833565b5161375e8489613833565b5190613768610b7d565b928352602083015260408201526139e5565b505050509050565b905084511438613602565b1561379457565b60405162461bcd60e51b8152602060048201526018602482015277082e4e4c2f240d8cadccee8d0e640daeae6e840dac2e8c6d60431b6044820152606490fd5b156137db57565b60405162461bcd60e51b815260206004820152601760248201527641727420697320616c726561647920636f6d706c65746560481b6044820152606490fd5b6000198114610e075760010190565b60041115612e2957565b8051821015612a565760209160051b010190565b601754811015612a565760176000526003602060002091020190600090565b601854811015612a565760186000526003602060002091020190600090565b601954811015612a565760196000526003602060002091020190600090565b601a54811015612a5657601a6000526003602060002091020190600090565b90601f81116138d157505050565b600091825260208220906020601f850160051c8301941061390d575b601f0160051c01915b82811061390257505050565b8181556001016138f6565b90925082906138ed565b91909182516001600160401b038111610aa55761393e816139388454612288565b846138c3565b602080601f831160011461397a57508192939460009261396f575b50508160011b916000199060031b1c1916179055565b015190503880613959565b90601f1983169561399085600052602060002090565b926000905b8882106139cd575050836001959697106139b4575b505050811b019055565b015160001960f88460031b161c191690553880806139aa565b80600185968294968601518155019501930190613995565b6019549190600160401b831015610aa557613a07600193848101601955613885565b919091613b0a5780519384516001600160401b038111610aa557613a3581613a2f8654612288565b866138c3565b6020958690601f8311600114613a925792610b7b96978360029694613a7e94604097600092613a87575b5050600019600383901b1c191690831b1787555b830151908601613917565b01519101613917565b015190503880613a5f565b90601f19831691613aa887600052602060002090565b9260005b818110613af557509484613a7e948294610b7b9b9c9460029a9860409a10613adc575b505050811b018755613a73565b015160001960f88460031b161c19169055388080613acf565b82840151855593860193928a01928a01613aac565b6129eb565b601a549190600160401b831015610aa557613b31600193848101601a556138a4565b919091613b0a5780519384516001600160401b038111610aa557613b5981613a2f8654612288565b6020958690601f8311600114613ba05792610b7b96978360029694613a7e94604097600092613a87575050600019600383901b1c191690831b178755830151908601613917565b90601f19831691613bb687600052602060002090565b9260005b818110613be957509484613a7e948294610b7b9b9c9460029a9860409a10613adc57505050811b018755613a73565b82840151855593860193928a01928a01613bba565b6018549190600160401b831015610aa557613c20600193848101601855613866565b919091613b0a5780519384516001600160401b038111610aa557613c4881613a2f8654612288565b6020958690601f8311600114613c8f5792610b7b96978360029694613a7e94604097600092613a87575050600019600383901b1c191690831b178755830151908601613917565b90601f19831691613ca587600052602060002090565b9260005b818110613cd857509484613a7e948294610b7b9b9c9460029a9860409a10613adc57505050811b018755613a73565b82840151855593860193928a01928a01613ca9565b6017549190600160401b831015610aa557613d0f600193848101601755613847565b919091613b0a5780519384516001600160401b038111610aa557613d3781613a2f8654612288565b6020958690601f8311600114613d7e5792610b7b96978360029694613a7e94604097600092613a87575050600019600383901b1c191690831b178755830151908601613917565b90601f19831691613d9487600052602060002090565b9260005b818110613dc757509484613a7e948294610b7b9b9c9460029a9860409a10613adc57505050811b018755613a73565b82840151855593860193928a01928a01613d98565b6012544203428111610e075762015180900460018101809111610e075790565b613e04613ddc565b613e0c613ddc565b6000198101908111610e0757600990048101809111610e075790565b15613e2f57565b60405162461bcd60e51b815260206004820152603760248201527f596f75206d7573742073656e6420736f6d6520657468657220746f207061727460448201527634b1b4b830ba329034b7103a34329030bab1ba34b7b71760491b6064820152608490fd5b15613e9b57565b60405162461bcd60e51b81526020600482015260146024820152732cb7bab9103134b21034b9903a37b7903637bb9760611b6044820152606490fd5b15613ede57565b60405162461bcd60e51b815260206004820152601b60248201527f596f752061726520616c7265616479207468652077696e6e65722e00000000006044820152606490fd5b15613f2a57565b60405162461bcd60e51b815260206004820152601c60248201527f596f7520616c7265616479206d696e74656420796f7572204e46542e000000006044820152606490fd5b15613f7657565b60405162461bcd60e51b81526020600482015260146024820152732230bc903737ba103932b0b1b432b2103cb2ba1760611b6044820152606490fd5b811561335a570690565b600090808252601460205260026040832001600160ff198254161790556015602052604082205491601660205260408120918254938401809411610e0757610b7b936123e99355806040519261401184610ae0565b808452614026614020836126c2565b1561424f565b61402f82614f4d565b7f130d3b8ec5ca77745df8f9eefabec10d458057080e300991474408db5f897e855460008181527fdc8790dd48d9d7c4bd3f295ca5c205857bfaa48fc9197ec228cdb0e96e90034560209081526040808320869055858352600790915290205561409b614020836126c2565b73cc44a5feb6ee172daaa31c1fee3fc1ce1654057f90818152600360205260408120600181540190556141016140db846000526002602052604060002090565b80546001600160a01b03191673cc44a5feb6ee172daaa31c1fee3fc1ce1654057f179055565b6000805160206159df8339815191528180a461411b6150b3565b61278c565b600091808352601460205260026040842001600160ff19825416179055601560205260408320546016602052604084208054918201809211610e0757556040519061416a82610ae0565b8382526001600160a01b03831692831561420b57816123e994610b7b9661419b61419661361a856126c2565b61424f565b6141a58385614eee565b6141b461419661361a856126c2565b6001600160a01b0384166000908152600360205260409020600181540190556141eb8461077d856000526002602052604060002090565b6000805160206159df8339815191528180a461420681615134565b612857565b606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b1561425657565b60405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606490fd5b6142a4816126c2565b1561032e576001600160a01b036142ba82612265565b16330361032e576142c9613dfc565b81101561032e576142d98161432d565b9081159081156142e857505050565b6142fc906000526016602052604060002090565b805490838201809211610e0757600093849384938493558290614324575b3390f115612fb557565b506108fc61431a565b614335613dfc565b6000199290838101908111610e07575b6040600082815260156020522054158061439e575b1561436c578015610e07578301614345565b9092506000526015602052614391604060002054916000526016602052604060002090565b548103908111610e075790565b5080151561435a565b6143af613dfc565b811161032e57801561032e576000198101818111610e07576000526015602052604060002054158061444f575b614439575b6143fd6143ed826128fd565b6000526015602052604060002090565b5490806001614416826000526014602052604060002090565b0154048201809211610e0757614436906000526015602052604060002090565b55565b61444a614445826128fd565b6143a7565b6143e1565b50600181116143dc565b1561446057565b60405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420696e64657820666f72206172742e686561647300000000006044820152606490fd5b156144ac57565b60405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420696e64657820666f72206172742e686f726e7300000000006044820152606490fd5b156144f857565b60405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420696e64657820666f72206172742e626f64696573000000006044820152606490fd5b1561454457565b60405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420696e64657820666f72206172742e657965730000000000006044820152606490fd5b6004811015612a565760011b601b0190600090565b9060ff60405192548181168452818160081c16602085015260101c166040830152610b7b82610ac5565b906145db602092828151948592016103e9565b0190565b6000929181546145ee81612288565b92600191808316908115614646575060011461460a5750505050565b90919293945060005260209081600020906000915b8583106146355750505050019038808080611e87565b80548584015291830191810161461f565b60ff1916845250505081151590910201915038808080611e87565b614669613dfc565b81111561467590613f6f565b61467e81614b47565b61468790614b82565b9060ff91828151166017541161469c90614459565b602081019183835116601854116146b2906144a5565b604082019284845116601954116146c8906144f1565b606083019185835116601a54116146de9061453d565b6146e79061519f565b9283516146f39061569a565b9460208501516147029061569a565b9660408601516147119061569a565b9560608101516147209061569a565b90608081015161472f9061569a565b60a082015161473d9061569a565b60c083015161474b9061569a565b9160e084015161475a9061569a565b9361010001516147699061569a565b948689511661477790614589565b506147819061459e565b61478a9061569a565b96808080808d511661479b90614589565b506001016147a89061459e565b6147b19061569a565b9b51166147bd90613885565b509b51166147ca90613847565b509b51166147d790613866565b509b51166147e4906138a4565b509b6040519e8f9e8f60200161488290606f907f3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323081527f30302f737667272076696577426f783d2730202d302e3520323820323827207360208201527f686170652d72656e646572696e673d2763726973704564676573273e3c73747960408201526e36329f10173198bdb9ba3937b5b29d60891b60608201520190565b61488b916145c8565b6d1dbe901731993db9ba3937b5b29d60911b8152600e016148ab916145c8565b6d1dbe90173199bdb9ba3937b5b29d60911b8152600e016148cb916145c8565b6d1dbe9017319abdb9ba3937b5b29d60911b8152600e016148eb916145c8565b6d1dbe9017319b3db9ba3937b5b29d60911b8152600e0161490b916145c8565b6d1dbe901732193db9ba3937b5b29d60911b8152600e0161492b916145c8565b6d1dbe90173219bdb9ba3937b5b29d60911b8152600e0161494b916145c8565b6d1dbe9017321a3db9ba3937b5b29d60911b8152600e0161496b916145c8565b6d1dbe9017321b3db9ba3937b5b29d60911b8152600e0161498b916145c8565b6d1dbe90173998bdb9ba3937b5b29d60911b8152600e016149ab916145c8565b6d1dbe901739993db9ba3937b5b29d60911b8152600e016149cb916145c8565b7f3b7d203c2f7374796c653e3c7061746820636c6173733d2263312220643d224d81527f3020306832384d3020316832384d3020326832384d3020336832384d3020346860208201527f32384d3020356832384d3020366832384d3020376832384d3020386832384d3060408201527f20396832384d302031306832384d302031316832384d302031326832384d302060608201527f31336832384d302031346832384d302031356832384d302031366832384d302060808201527f31376832384d302031386832384d302031396832384d302032306832384d302060a08201527f32316832384d302032326832384d302032336832384d302032346832384d302060c082015277191ab4191c269810191b34191c269810191bb4191c11179f60411b60e082015260f801614b02916001016145df565b614b0e916001016145df565b614b1a916001016145df565b614b26916001016145df565b651e17b9bb339f60d11b815260060103601f19810182526104429082610b4d565b6040516020810191825266151a1951dbd85d60ca1b6040820152602781526130b181610ac5565b60405190614b7b82610ac5565b6060368337565b6080604051614b9081610b16565b36903760405190614ba082610b16565b608036833760175490811561335a5760ff82820616835204601854801561335a5780820660ff16602084015261044291614c1791614bfe91614c0e91614bea91613350565b613350565b60195490614be5614c04614bfe8484613fb2565b60ff1690565b60ff166040890152565b601a5490613fb2565b60ff166060830152565b15614c2857565b60405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608490fd5b600b60fa1b815260010190565b6000908072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b80821015614dc2575b506d04ee2d6d415b85acef810000000080831015614db3575b50662386f26fc1000080831015614da4575b506305f5e10080831015614d95575b5061271080831015614d86575b506064821015614d76575b600a80921015614d6c575b600190816021614d24828701613312565b95860101905b614d36575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a835304918215614d6757919082614d2a565b614d2f565b9160010191614d13565b9190606460029104910191614d08565b60049193920491019138614cfd565b60089193920491019138614cf0565b60109193920491019138614ce1565b60209193920491019138614ccf565b604093508104915038614cb6565b9091906001600160a01b038082169182614e135750614dee83614f4d565b831680614e01575050610b7b9150614fa5565b03614e0a575050565b610b7b91614f15565b8185168303614e23575b50614dee565b614e2c816121a7565b6000198101908111610e0757614e8460009286845260076020526040842054838103614e95575b5083614e69886000526007602052604060002090565b556001600160a01b0316600090815260066020526040902090565b908252602052604081205538614e1d565b868552600660205260408520848652602052614ee76040862054614ecb8460018060a01b03166000526006602052604060002090565b8388526020528060408820556000526007602052604060002090565b5538614e53565b90614ef881614f4d565b6001600160a01b038216614f1057610b7b9150614fa5565b610b7b915b604090614f21816121a7565b9260009160018060a01b0316825260066020528282208483526020528083832055815260076020522055565b60085481600052600960205280604060002055600160401b811015610aa5576001810180600855811015612a565760086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b60088054600019929083810190808211610e07576000928084526009602052816040852054931015612a565784845285826020862001015491831015612a5657839261500961501a9387865280836020882001556000526009602052604060002090565b556000526009602052604060002090565b55815492831561503d578084019380851015612a56578383526020832001015555565b634e487b7160e01b82526031600452602482fd5b610b7b916001600160a01b039182169190819083156150a4575b16918215615095575b600052600d6020528060406000205416916000526040600020541690611fa1565b61509d612158565b5050615074565b6150ac612120565b505061506b565b6150bb612120565b5050600d6020527f81955a0a11e65eac625c29e8882660bae4e165a75d72780094acae8ece9a29ee5473cc44a5feb6ee172daaa31c1fee3fc1ce1654057f6000527fcdb666f48cce5d344caea1f88d15637636615b6e9563a95f2881914947b8cef554610b7b916001600160a01b039182169116611fa1565b610b7b90615140612120565b50506001600160a01b03908116908115615190575b600d6020527f81955a0a11e65eac625c29e8882660bae4e165a75d72780094acae8ece9a29ee54600092835260409092205481169116611fa1565b615198612158565b5050615155565b60409081516151ad81610b31565b60005b61012081106152535750506151c761524a91615270565b6152166151d38261531c565b916151dc610b8a565b946151e6826153fc565b86526151f18261547f565b60208701526151ff826154f7565b9086015261520c8161556f565b6060860152615622565b60808401526152248161547f565b60a0840152615232816154f7565b60c08401526152408161556f565b60e0840152615622565b61010082015290565b602090845161526181610ac5565b606036823781840152016151b0565b606060405161527e81610ac5565b36903760405190606082018281106001600160401b03821117610aa55760405260ff6152a9826152ea565b1682526105398101808211610e07576152c360ff916152ea565b16602083015262cc07c98101809111610e07576152e160ff916152ea565b16604082015290565b60ff90604051602081019182526020815261530481610aaa565b5190201690565b60ff1660ff039060ff8211610e0757565b606060405161532a81610ac5565b36903760406152e181519261533e84610ac5565b606036853760ff928184615355818095511661530b565b168652826153688160208401511661530b565b16602087015201511661530b565b600281901b91906001600160fe1b03811603610e0757565b90602b820291808304602b1490151715610e0757565b90607082029180830460701490151715610e0757565b90608882029180830460881490151715610e0757565b908160061b9180830460401490151715610e0757565b90602c820291808304602c1490151715610e0757565b606060405161540a81610ac5565b369037615415614b6e565b9060ff80825116602b810290808204602b1490151715610e075781615460816040610442968261544981615474980461294a565b16895282615466816154608160208601511661538e565b0461294a565b1660208a015201511661538e565b1660ff166040830152565b606060405161548d81610ac5565b369037615498614b6e565b9060ff80825116607081029080820460701490151715610e0757816154e381604061044296826154cc816154749804612958565b168952826154e9816154e3816020860151166153a4565b04612958565b1660208a01520151166153a4565b606060405161550581610ac5565b369037615510614b6e565b9060ff80825116608881029080820460881490151715610e07578161555b8160406104429682615544816154749804612966565b168952826155618161555b816020860151166153ba565b04612966565b1660208a01520151166153ba565b606060405161557d81610ac5565b369037615588614b6e565b908051613fc060ff82169160061b169080820460401490151715610e0757614bfe6156006155f96155f460ff6040610442976155d56155ce614bfe856156189b04612966565b60ff168b52565b61560f615605614bfe6156006155f96155f48860208801511660ff1690565b6153d0565b60ff900490565b612966565b60ff1660208c0152565b01511660ff1690565b60ff166040830152565b606060405161563081610ac5565b36903761563b614b6e565b9060ff80825116602c810290808204602c1490151715610e075781615686816040610442968261566f816154749804612974565b1689528261568c81615686816020860151166153e6565b04612974565b1660208a01520151166153e6565b6104426156aa60ff835116614c92565b61574260266156ce60ff60406156c58260208a015116614c92565b97015116614c92565b604051958694630e4cec4560e31b60208701526156f581518092602060248a0191016103e9565b850190600b60fa1b918260248201526157188251809360206025850191016103e9565b0190602582015261573282518093602086850191016103e9565b0101600190602960f81b81520190565b03601f198101835282610b4d565b9081602091031261032e575161044281611603565b61577261361a8383615867565b61577a575050565b60135461579190610727906001600160a01b031681565b803b1561032e5760008391600460405180968193630d0e30db60e41b83525af1918215612fb5576158139360209361584e575b506013546157dc90610727906001600160a01b031681565b60405163a9059cbb60e01b81526001600160a01b039092166004830152602482019290925292839190829060009082906044820190565b03925af18015612fb5576158245750565b6158449060203d8111615847575b61583c8183610b4d565b810190615750565b50565b503d615832565b8061585b61586192610a92565b806103bb565b386157c4565b600080809381938260405161587b81610ae0565b52617530f161588861275c565b5090565b6040519061589982610ac5565b604082527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040837f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201520152565b8051156159d5576158fa61588c565b61591661591161590a845161292e565b6003900490565b615376565b916159286159238461293c565b613312565b92835280815182019060208501935b8282106159795750505060039051068060011461596857600214615959575090565b603d60f81b6000199091015290565b50613d3d60f01b6001199091015290565b90919360049060038094019384516001603f81818460121c16880101519260f893841b8652828282600c1c1689010151841b8387015282828260061c1689010151841b60028701521686010151901b9082015201939190615937565b50610442611d7856feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802dec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724a2646970667358221220c0e4395dd973041f975fbd791676deffcbea78d8dd2e583d8a826965b527f82c64736f6c634300081200334552433732313a207472616e7366657220746f206e6f6e204552433732315265000000000000000000000000d3678054aed0c09616684563f145318accff56a2000000000000000000000000c2b35534e47cdf3d787e01630129631d8270abfb0000000000000000000000002b6d02f088fd0b2fc521f6d034f4c93164125851000000000000000000000000a73827d96540e1d8cacd48017a2eb08b0e073e27000000000000000000000000957db774e28701a6e04c9d9ec43de1bcfaeeb176ac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b81955a0a11e65eac625c29e8882660bae4e165a75d72780094acae8ece9a29ee000000000000000000000000895fac7783c70d48e464a639ee3cb453dc8997e0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef00000000000000000000000050f461f471e7dce973e27f0e319ebe868135d7640000000000000000000000000e802eef59d855375e4826123a4145b829bc3f83dfa8dbdf6d3211bdac983d8cfb904c8192c5e5d2e815ae8862bc60f11fd9399f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802000000000000000000000000f728ce79c82bb99335e0a781cac0254b6a9aeb37dec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724

Deployed Bytecode

0x6080604052600436101561001257600080fd5b60003560e01c806301ffc9a714610317578063040f15df14610312578063061ba2f11461030d57806306fdde0314610308578063081812fc14610303578063095ea7b3146102fe57806318160ddd146102f95780631998aeef146102f45780631f88c9d0146102ef57806323b872dd146102ea5780632f745c59146102e55780633644e515146102e0578063379607f5146102db57806338495761146102d65780633a46b1a8146102d15780633fc8cef3146102cc57806342842e0e146102c75780634bf5d7e9146102c25780634f6ccce7146102bd57806351c93569146102b8578063587cde1e146102b35780635c19a95c146102ae5780636352211e146102a957806370a08231146102a4578063715018a61461029f5780637ecebe001461029a57806384b0196e146102955780638da5cb5b146102905780638e539e8c1461028b5780638ff12b6d146102865780639051cce91461028157806391ddadf41461027c57806395d89b411461027757806396545927146102725780639ab24eb01461026d578063a0712d6814610268578063a22cb46514610263578063b88d4fde1461025e578063bfc12c0514610259578063c3cda52014610254578063c6c034431461024f578063c87b56dd1461024a578063d1d58b2514610245578063d3ea435014610240578063e985e9c51461023b578063f2fde38b14610236578063f8605801146102315763fe8e66ed1461022c57600080fd5b611d05565b611cd0565b611c0d565b611bb0565b611b94565b611b76565b6118bf565b61189c565b611772565b611754565b6116f5565b61160d565b611554565b61150b565b611498565b611413565b6113e7565b611377565b611327565b61124c565b611223565b611161565b611127565b6110c9565b6110a6565b611088565b611066565b61102b565b610fb5565b610f0a565b610e5d565b610e35565b610e0c565b610d0a565b610c92565b610a60565b610a45565b610992565b610969565b610831565b610689565b61066b565b610595565b610539565b61047c565b610445565b6103c6565b610333565b6001600160e01b031981160361032e57565b600080fd5b3461032e57602036600319011261032e5760206004356103528161031c565b63ffffffff60e01b1663780e9d6360e01b8114908115610378575b506040519015158152f35b6380ac58cd60e01b8114915081156103aa575b8115610399575b503861036d565b6301ffc9a760e01b14905038610392565b635b5e139f60e01b8114915061038b565b600091031261032e57565b3461032e57600036600319011261032e5760206103e1613ddc565b604051908152f35b60005b8381106103fc5750506000910152565b81810151838201526020016103ec565b90602091610425815180928185528580860191016103e9565b601f01601f1916010190565b90602061044292818152019061040c565b90565b3461032e57602036600319011261032e57610478610464600435614661565b60405191829160208352602083019061040c565b0390f35b3461032e576000806003193601126105365760405181805461049d81612288565b8084529060019081811690811561050e57506001146104d3575b610478846104c781880382610b4d565b60405191829182610431565b93508180526020938483205b8284106104fb5750505081610478936104c792820101936104b7565b80548585018701529285019281016104df565b61047896506104c79450602092508593915060ff191682840152151560051b820101936104b7565b80fd5b3461032e57602036600319011261032e576020610557600435612334565b6040516001600160a01b039091168152f35b600435906001600160a01b038216820361032e57565b602435906001600160a01b038216820361032e57565b3461032e57604036600319011261032e576105ae610569565b6024356105ba81612265565b916001600160a01b03808416908216811461061c576105ec936105e79133149081156105ee575b506122c2565b61265e565b005b6001600160a01b0316600090815260056020908152604080832033845290915290205460ff169050386105e1565b60405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608490fd5b3461032e57600036600319011261032e576020600854604051908152f35b600036600319011261032e576106a0341515613e28565b6106a8613dfc565b6106d26106cb60016106c4846000526014602052604060002090565b015461290c565b3411613e94565b6106f66106e9826000526014602052604060002090565b546001600160a01b031690565b6001600160a01b039061070d908216331415613ed7565b6107336107276106e9846000526014602052604060002090565b6001600160a01b031690565b6001610749846000526014602052604060002090565b015492346001610763836000526014602052604060002090565b015561079c3361077d836000526014602052604060002090565b80546001600160a01b0319166001600160a01b03909216919091179055565b6107a5816143a7565b60408051348152602081019290925233917f19421268847f42dd61705778018ddfc43bcdce8517e7a630acb12f122c7094819190a21690816107e357005b6105ec91615765565b90815180825260208080930193019160005b82811061080c575050505090565b8351855293810193928101926001016107fe565b9060206104429281815201906107ec565b3461032e57602036600319011261032e5761084a610569565b610852613dfc565b9061085c8261311e565b916000916001600160a01b0390811690835b8381106108bd5785856108808161311e565b9160005b82811061089957604051806104788682610820565b806108a76108b89284613833565b516108b28287613833565b5261381a565b610884565b82826108d66106e9846000526014602052604060002090565b16148061090c575b6108f1575b6108ec9061381a565b61086e565b9361090481866108b26108ec948a613833565b9490506108e3565b5061092e6002610926836000526014602052604060002090565b015460ff1690565b156108de565b606090600319011261032e576001600160a01b0390600435828116810361032e5791602435908116810361032e579060443590565b3461032e576105ec61097a36610934565b9161098d6109888433612465565b612360565b612537565b3461032e57604036600319011261032e576109ab610569565b602435906109b8816121a7565b8210156109ec576001600160a01b031660009081526006602090815260408083209383529281529082902054915191825290f35b60405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608490fd5b3461032e57600036600319011261032e5760206103e1612fc6565b3461032e57602036600319011261032e576105ec60043561429b565b634e487b7160e01b600052604160045260246000fd5b6001600160401b038111610aa557604052565b610a7c565b604081019081106001600160401b03821117610aa557604052565b606081019081106001600160401b03821117610aa557604052565b602081019081106001600160401b03821117610aa557604052565b60c081019081106001600160401b03821117610aa557604052565b608081019081106001600160401b03821117610aa557604052565b61012081019081106001600160401b03821117610aa557604052565b90601f801991011681019081106001600160401b03821117610aa557604052565b60405190610b7b82610aaa565b565b60405190610b7b82610ac5565b60405190610b7b82610b31565b6001600160401b038111610aa55760051b60200190565b6001600160401b038111610aa557601f01601f191660200190565b929192610bd582610bae565b91610be36040519384610b4d565b82948184528183011161032e578281602093846000960137010152565b81601f8201121561032e57803590610c1782610b97565b92604092610c2784519586610b4d565b808552602093848087019260051b8501019383851161032e57858101925b858410610c56575050505050505090565b83356001600160401b03811161032e57820185603f8201121561032e578791610c8787838786809601359101610bc9565b815201930192610c45565b3461032e57608036600319011261032e57600435600481101561032e576001600160401b039060243582811161032e57610cd0903690600401610c00565b60443583811161032e57610ce8903690600401610c00565b9060643593841161032e57610d046105ec943690600401610c00565b926135e6565b3461032e57604036600319011261032e57610d23610569565b60243590610d4265ffffffffffff610d3a4361351a565b168310611d8b565b6001600160a01b03166000908152600e6020526040812091610d6390613581565b91805482938160058111610db4575b5090602094610d819284612d90565b80610d9b5750505b6040516001600160e01b039091168152f35b91610da78492936128fd565b928152200154811c610d89565b94610dbe8661335f565b8603958611610e0757602095610d819385875263ffffffff80838a8a2001541690851610600014610df55750915b91925094610d72565b929150610e0190612920565b90610dec565b612191565b3461032e57600036600319011261032e576013546040516001600160a01b039091168152602090f35b3461032e576105ec610e4636610934565b9060405192610e5484610ae0565b600084526123c2565b3461032e57600036600319011261032e574365ffffffffffff610e7f4361351a565b1603610eca57610478604051610e9481610aaa565b601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015260405191829182610431565b60405162461bcd60e51b8152602060048201526018602482015277566f7465733a2062726f6b656e20636c6f636b206d6f646560401b6044820152606490fd5b3461032e57602036600319011261032e57600435600854811015610f5b5760086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30154604051908152602090f35b60405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608490fd5b3461032e57602036600319011261032e57600435806000526014602052610fe760ff6002604060002001541615613f23565b600a8101808211610e075761100490610ffe613dfc565b11613f6f565b60148106611015576105ec90613fbc565b600a546105ec91906001600160a01b0316614120565b3461032e57602036600319011261032e5760206001600160a01b038061104f610569565b16600052600d825260406000205416604051908152f35b3461032e57602036600319011261032e576105ec611082610569565b33611e11565b3461032e57602036600319011261032e576020610557600435612265565b3461032e57602036600319011261032e5760206103e16110c4610569565b6121a7565b3461032e57600080600319360112610536576110e3611d20565b600a80546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b3461032e57602036600319011261032e576001600160a01b03611148610569565b1660005260106020526020604060002054604051908152f35b3461032e57600036600319011261032e576111f461119e7f546865476f617400000000000000000000000000000000000000000000000007613150565b6104786111ca7f3100000000000000000000000000000000000000000000000000000000000001613244565b6112026111d5613106565b91604051958695600f60f81b875260e0602088015260e087019061040c565b90858203604087015261040c565b90466060850152306080850152600060a085015283820360c08501526107ec565b3461032e57600036600319011261032e57600a546040516001600160a01b039091168152602090f35b3461032e57602036600319011261032e5761128360043561127e65ffffffffffff6112764361351a565b168210611d8b565b613581565b600f549060008291600584116112ce575b61129e9350612d27565b6000816112b357505060405160008152602090f35b60206112bf81936128fd565b91600f8152200154811c610d89565b91926112d98161335f565b8103908111610e0757600f82526000805160206159ff83398151915281015461129e949063ffffffff9081169085161015611315575091611294565b92915061132190612920565b90611294565b3461032e57602036600319011261032e5760043560005260146020526060604060002060018060a01b038154169060ff600260018301549201541690604051928352602083015215156040820152f35b3461032e57602036600319011261032e576004356001600160401b0380821161032e573660238301121561032e57816004013590811161032e57600560243683831b850182011161032e5760005b8381106113ce57005b806113e183600193861b8801013561429b565b016113c5565b3461032e57600036600319011261032e5760206114034361351a565b65ffffffffffff60405191168152f35b3461032e576000806003193601126105365760405181600180549061143782612288565b8085529181811690811561050e575060011461145d57610478846104c781880382610b4d565b80945082526020938483205b8284106114855750505081610478936104c792820101936104b7565b8054858501870152928501928101611469565b3461032e5760208060031936011261032e576114b560043561519f565b604051918260009283915b600983106114ce5761036086f35b838251829087915b600383106114f2575050506060600192019201920191906114c0565b815160ff168152879360019093019291820191016114d6565b3461032e57602036600319011261032e576001600160a01b0361152c610569565b16600052600e602052602060018060e01b0361154b60406000206129bd565b16604051908152f35b3461032e57602036600319011261032e576004356000818152601460205260409020546001600160a01b031633036115c457806115ac6115a660026109266105ec956000526014602052604060002090565b15613f23565b6115be6115b7613dfc565b8210613f6f565b33614120565b60405162461bcd60e51b81526020600482015260176024820152762cb7ba9030b932903737ba103a3432903bb4b73732b91760491b6044820152606490fd5b8015150361032e57565b3461032e57604036600319011261032e57611626610569565b60243561163281611603565b6001600160a01b038216913383146116b457816116716116829233600052600560205260406000209060018060a01b0316600052602052604060002090565b9060ff801983541691151516179055565b604051901515815233907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190602090a3005b60405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606490fd5b3461032e57608036600319011261032e5761170e610569565b61171661057f565b606435916001600160401b03831161032e573660238401121561032e5761174a6105ec933690602481600401359101610bc9565b91604435916123c2565b3461032e57600036600319011261032e576020601254604051908152f35b3461032e5760c036600319011261032e5761178b610569565b6064359060243560443560ff8416840361032e5780421161185c5761182e611857916105ec9560405190611816826118086020820195898b8860609194939260808201957fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf835260018060a01b0316602083015260408201520152565b03601f198101845283610b4d565b61182960a43593608435935190206130e0565b612df2565b6001600160a01b0381166000908152601060205260409020805460018101909155909214611dce565b611e11565b60405162461bcd60e51b8152602060048201526018602482015277159bdd195cce881cda59db985d1d5c9948195e1c1a5c995960421b6044820152606490fd5b3461032e57600036600319011261032e57602060ff602354166040519015158152f35b3461032e57602036600319011261032e576004356118dc816126c2565b6118e590614c21565b6118ee81614b47565b6118f790614b82565b805160ff1661190590613847565b5090602081015160ff1661191890613866565b5092604082015160ff1661192b90613885565b50916060015160ff1661193d906138a4565b5061194782615270565b6119509061569a565b9061195a83614661565b611963906158eb565b9261196d90614c92565b604051707b202261747472696275746573223a205b60781b6020820152968796919591603188016119a0916002016145df565b6119a990614c85565b6119b5916002016145df565b6119be90614c85565b6119ca916002016145df565b6119d390614c85565b6119df916002016145df565b6119e890614c85565b7f7b2274726169745f74797065223a2022436f6c6f72222c202276616c7565223a815261101160f11b6020820152602201611a22916145c8565b61227d60f01b815260020161174b60f21b81526002017f226465736372697074696f6e223a20224372656174656420627920746865676f81527f61742e777466222c2265787465726e616c5f75726c223a202268747470733a2f60208201527f2f746865676f61742e777466222c22696d616765223a2022646174613a696d6160408201527119d94bdcdd99cade1b5b0ed8985cd94d8d0b60721b6060820152607201611ace916145c8565b74222c226e616d65223a202254686520476f6174202360581b8152601501611af5916145c8565b61227d60f01b81526002010390601f19918281018252611b159082610b4d565b611b1e906158eb565b6040517f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000602082015291908290603d8201611b58916145c8565b039081018252611b689082610b4d565b604051610478819282610431565b3461032e57602036600319011261032e5760206103e160043561432d565b3461032e57602036600319011261032e576105ec6004356143a7565b3461032e57604036600319011261032e57602060ff611c01611bd0610569565b611bd861057f565b6001600160a01b0391821660009081526005865260408082209290931681526020919091522090565b54166040519015158152f35b3461032e57602036600319011261032e57611c26610569565b611c2e611d20565b6001600160a01b03908116908115611c7c57600a80546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b3461032e57600036600319011261032e57611ce9611d20565b6001602354611cfb60ff8216156137d4565b60ff191617602355005b3461032e57600036600319011261032e5760206103e1613dfc565b600a546001600160a01b03163303611d3457565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60405190611d8582610ae0565b60008252565b15611d9257565b60405162461bcd60e51b81526020600482015260146024820152730566f7465733a20667574757265206c6f6f6b75760641b6044820152606490fd5b15611dd557565b60405162461bcd60e51b8152602060048201526014602482015273566f7465733a20696e76616c6964206e6f6e636560601b6044820152606490fd5b6001600160a01b038181166000818152600d6020526040812080548685166001600160a01b0319821681179092559095931693611e77929091869186917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9080a46121a7565b918381141580611f98575b611e8d575b50505050565b80611efe575b5082611ea0575b80611e87565b6001600160a01b03166000908152600e60205260409020600080516020615a1f83398151915291611edb91611ed590916134b1565b906120e4565b604080516001600160e01b039384168152919092166020820152a2388080611e9a565b6001600160a01b0381166000908152600e60205260409020611f1f846134b1565b611f3865ffffffffffff611f324361351a565b16613581565b6001600160e01b03918280611f4c866129bd565b169116900392828411610e0757600080516020615a1f83398151915293611f8f92611f7692612c41565b6040805192851683529316602082015291829190820190565b0390a238611e93565b50821515611e82565b6001600160a01b03808316929190811690818414158061209e575b611fc65750505050565b8161202d575b505081611fdb575b8080611e87565b6001600160a01b03166000908152600e60205260409020600080516020615a1f8339815191529061200b906120a6565b604080516001600160e01b039384168152919092166020820152a23880611fd4565b6001600160a01b03166000908152600e6020526040902061205765ffffffffffff611f324361351a565b6001600160e01b03906000198261206d856129bd565b160192828411610e0757600080516020615a1f8339815191529361209492611f7692612c41565b0390a23880611fcc565b506001611fbc565b6120b965ffffffffffff611f324361351a565b6001600160e01b03906001826120ce856129bd565b1601918211610e07576120e092612c41565b9091565b906120f865ffffffffffff611f324361351a565b6001600160e01b0391828061210c866129bd565b16911601918211610e07576120e092612c41565b61213365ffffffffffff611f324361351a565b6001600160e01b03600181612146612982565b1601908111610e07576120e091612b23565b61216b65ffffffffffff611f324361351a565b6001600160e01b036000198161217f612982565b1601908111612191576120e091612b23565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b031680156121c757600052600360205260406000205490565b60405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608490fd5b1561222557565b60405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606490fd5b6000908152600260205260409020546001600160a01b031661044281151561221e565b90600182811c921680156122b8575b60208310146122a257565b634e487b7160e01b600052602260045260246000fd5b91607f1691612297565b156122c957565b60405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608490fd5b612345612340826126c2565b61221e565b6000908152600460205260409020546001600160a01b031690565b1561236757565b60405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526c1c881bdc88185c1c1c9bdd9959609a1b6064820152608490fd5b91610b7b93916123e9936123d96109888433612465565b6123e4838383612537565b6128ab565b612441565b60809060208152603260208201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60608201520190565b1561244857565b60405162461bcd60e51b815280612461600482016123ee565b0390fd5b6001600160a01b038061247784612265565b1692818316928484149485156124ad575b50508315612497575b50505090565b6124a391929350612334565b1614388080612491565b60009081526005602090815260408083206001600160a01b03949094168352929052205460ff1693503880612488565b156124e457565b60405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608490fd5b61255b9261254481612265565b6001600160a01b03838116959091821686146124dd565b8316801561260d57610b7b94612572838686614dd0565b6125888161258261072786612265565b146124dd565b6125af61259f846000526004602052604060002090565b80546001600160a01b0319169055565b6001600160a01b038481166000908152600360209081526040808320805460001901905592881682528282208054600101905585825260029052206125f590869061077d565b6000805160206159df833981519152600080a4615051565b60405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b600082815260046020526040902080546001600160a01b0319166001600160a01b0383161790556001600160a01b038061269784612265565b169116907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a4565b6000908152600260205260409020546001600160a01b0316151590565b9081602091031261032e57516104428161031c565b610442939260809260018060a01b03168252600060208301526040820152816060820152019061040c565b6001600160a01b0391821681529116602082015260408101919091526080606082018190526104429291019061040c565b6040513d6000823e3d90fd5b3d15612787573d9061276d82610bae565b9161277b6040519384610b4d565b82523d6000602084013e565b606090565b9073cc44a5feb6ee172daaa31c1fee3fc1ce1654057f803b1561284f576127d1602091600093604051948580948193630a85bd0160e11b998a845233600485016126f4565b03925af16000918161281f575b50612811576127eb61275c565b8051908161280c5760405162461bcd60e51b815280612461600482016123ee565b602001fd5b6001600160e01b0319161490565b61284191925060203d8111612848575b6128398183610b4d565b8101906126df565b90386127de565b503d61282f565b505050600190565b909190803b1561284f57612889602091600093604051948580948193630a85bd0160e11b998a845233600485016126f4565b03926001600160a01b03165af16000918161281f5750612811576127eb61275c565b92909190823b156128de57612889926020926000604051809681958294630a85bd0160e11b9a8b8552336004860161271f565b50505050600190565b634e487b7160e01b600052603260045260246000fd5b600019810191908211610e0757565b9066038d7ea4c680008201809211610e0757565b9060018201809211610e0757565b9060028201809211610e0757565b9060208201809211610e0757565b9060d28201809211610e0757565b9060808201809211610e0757565b9060408201809211610e0757565b9060148201809211610e0757565b600f5460009080612994575050600090565b600019918183810111610e0757600f9052016000805160206159ff833981519152015460201c90565b8054600091816129cf57505050600090565b600019928284810111610e075760209181522001015460201c90565b634e487b7160e01b600052600060045260246000fd5b600f5490600160401b821015610aa5576001820180600f55821015612a5657600f600052805160209182015190911b63ffffffff191663ffffffff91909116176000805160206159ff83398151915290910155565b6128e7565b908154600160401b811015610aa55760018101808455811015612a5657600092835260209283902082519284015190931b63ffffffff191663ffffffff9290921691909117910155565b90604051604081018181106001600160401b03821117610aa557604052602081935463ffffffff81168352811c910152565b15612ade57565b60405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b65797300000000006044820152606490fd5b600f549192918015612c1757612bdd918185612b63612b5e612b466020966128fd565b600f6000526000805160206159ff8339815191520190565b612aa5565b92612b72845163ffffffff1690565b612b8963ffffffff91828416928391161115612ad7565b612ba3612b9a865163ffffffff1690565b63ffffffff1690565b03612be15750612bb8612b46612bcf936128fd565b9063ffffffff82549181199060201b169116179055565b01516001600160e01b031690565b9190565b9050612c129150612bff612bf3610b6e565b63ffffffff9092168252565b6001600160e01b03871681850152612a01565b612bcf565b50612c3b90612c27612bf3610b6e565b6001600160e01b0384166020820152612a01565b60009190565b90929192838254801515600014612d0257926020929184612c77612b5e612c6a612bdd986128fd565b8560005260206000200190565b93612c86855163ffffffff1690565b612c9d63ffffffff91828416928391161115612ad7565b612cae612b9a875163ffffffff1690565b03612cd15750612bcf92612cc4612bb8926128fd565b9060005260206000200190565b915050612c1291612cef612ce3610b6e565b63ffffffff9093168352565b6001600160e01b03881682860152612a5b565b5050612c3b91612d13612ce3610b6e565b6001600160e01b0385166020830152612a5b565b905b828110612d3557505090565b9091808216906001818418811c8301809311610e0757600f6000526000805160206159ff83398151915283015463ffffffff9081169086161015612d7d575050915b90612d29565b909392508101809111610e075790612d77565b91905b838210612da05750505090565b909192808316906001818518811c8301809311610e075760008681526020902083015463ffffffff9081169085161015612ddf575050925b9190612d93565b909493508101809111610e075791612dd8565b916104429391612e0193612f49565b919091612e2e565b634e487b7160e01b600052602160045260246000fd5b60051115612e2957565b612e09565b612e3781612e1f565b80612e3f5750565b612e4881612e1f565b60018103612e905760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b6044820152606490fd5b612e9981612e1f565b60028103612ee65760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b80612ef2600392612e1f565b14612ef957565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b9291906fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311612fba5791608094939160ff602094604051948552168484015260408301526060820152600093849182805260015afa15612fb55781516001600160a01b03811615612faf579190565b50600190565b612750565b50505050600090600390565b307f000000000000000000000000b28214e8071f80697a71932785efc214d81ff07e6001600160a01b031614806130b7575b15613021577ffec428edcf60607eed4e8c33754cb212cd2d8ea31469f7cc6b240d9ebf8d619590565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f336d8d56a22928814c2b44d791f67cb12f3d3b6496219bbdd50d42b63948364e60408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a081526130b181610afb565b51902090565b507f00000000000000000000000000000000000000000000000000000000000000014614612ff8565b6042906130eb612fc6565b906040519161190160f01b8352600283015260228201522090565b60405161311281610ae0565b60008152906000368137565b9061312882610b97565b6131356040519182610b4d565b8281528092613146601f1991610b97565b0190602036910137565b60ff811461318a5760ff811690601f82116131785761316d6132f9565b918252602082015290565b604051632cd44ac360e21b8152600490fd5b50604051600b5481600061319d83612288565b80835260019380851690811561322357506001146131c3575b5061044292500382610b4d565b600b60009081527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db994602093509091905b81831061320b5750506104429350820101386131b6565b855487840185015294850194869450918301916131f4565b905061044294506020925060ff191682840152151560051b820101386131b6565b60ff81146132615760ff811690601f82116131785761316d6132f9565b50604051600c5481600061327483612288565b8083526001938085169081156132235750600114613299575061044292500382610b4d565b600c60009081527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c794602093509091905b8183106132e15750506104429350820101386131b6565b855487840185015294850194869450918301916132ca565b6040519061330682610aaa565b60208083523683820137565b9061331c82610bae565b6133296040519182610b4d565b8281528092613146601f1991610bae565b634e487b7160e01b600052601260045260246000fd5b811561335a570490565b61333a565b8015613499578061343261342b61342161341761340d6134036133f96133ef60016104429a6000908b60801c8061348d575b508060401c80613480575b508060201c80613473575b508060101c80613466575b508060081c80613459575b508060041c8061344c575b508060021c8061343f575b50821c613438575b811c1b6133e8818b613350565b0160011c90565b6133e8818a613350565b6133e88189613350565b6133e88188613350565b6133e88187613350565b6133e88186613350565b6133e88185613350565b8092613350565b9061349f565b81016133db565b60029150910190386133d3565b60049150910190386133c8565b60089150910190386133bd565b60109150910190386133b2565b60209150910190386133a7565b604091509101903861339c565b91505060809038613391565b50600090565b90808210156134ac575090565b905090565b6001600160e01b03908181116134c5571690565b60405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608490fd5b65ffffffffffff9081811161352d571690565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b6064820152608490fd5b63ffffffff90818111613592571690565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608490fd5b939291936135f2611d20565b6136088251865181149081613782575b5061378d565b61362361361e61361a60235460ff1690565b1590565b6137d4565b60005b825181101561377a576136859061363c83613829565b8261368a5761368061364e8286613833565b51613659838a613833565b516136648489613833565b519061366e610b7d565b92835260208301526040820152613ced565b61381a565b613626565b61369383613829565b600183036136da576136806136a88286613833565b516136b3838a613833565b516136be8489613833565b51906136c8610b7d565b92835260208301526040820152613bfe565b6136e383613829565b6002830361372a576136806136f88286613833565b51613703838a613833565b5161370e8489613833565b5190613718610b7d565b92835260208301526040820152613b0f565b61373383613829565b60038303613680576136806137488286613833565b51613753838a613833565b5161375e8489613833565b5190613768610b7d565b928352602083015260408201526139e5565b505050509050565b905084511438613602565b1561379457565b60405162461bcd60e51b8152602060048201526018602482015277082e4e4c2f240d8cadccee8d0e640daeae6e840dac2e8c6d60431b6044820152606490fd5b156137db57565b60405162461bcd60e51b815260206004820152601760248201527641727420697320616c726561647920636f6d706c65746560481b6044820152606490fd5b6000198114610e075760010190565b60041115612e2957565b8051821015612a565760209160051b010190565b601754811015612a565760176000526003602060002091020190600090565b601854811015612a565760186000526003602060002091020190600090565b601954811015612a565760196000526003602060002091020190600090565b601a54811015612a5657601a6000526003602060002091020190600090565b90601f81116138d157505050565b600091825260208220906020601f850160051c8301941061390d575b601f0160051c01915b82811061390257505050565b8181556001016138f6565b90925082906138ed565b91909182516001600160401b038111610aa55761393e816139388454612288565b846138c3565b602080601f831160011461397a57508192939460009261396f575b50508160011b916000199060031b1c1916179055565b015190503880613959565b90601f1983169561399085600052602060002090565b926000905b8882106139cd575050836001959697106139b4575b505050811b019055565b015160001960f88460031b161c191690553880806139aa565b80600185968294968601518155019501930190613995565b6019549190600160401b831015610aa557613a07600193848101601955613885565b919091613b0a5780519384516001600160401b038111610aa557613a3581613a2f8654612288565b866138c3565b6020958690601f8311600114613a925792610b7b96978360029694613a7e94604097600092613a87575b5050600019600383901b1c191690831b1787555b830151908601613917565b01519101613917565b015190503880613a5f565b90601f19831691613aa887600052602060002090565b9260005b818110613af557509484613a7e948294610b7b9b9c9460029a9860409a10613adc575b505050811b018755613a73565b015160001960f88460031b161c19169055388080613acf565b82840151855593860193928a01928a01613aac565b6129eb565b601a549190600160401b831015610aa557613b31600193848101601a556138a4565b919091613b0a5780519384516001600160401b038111610aa557613b5981613a2f8654612288565b6020958690601f8311600114613ba05792610b7b96978360029694613a7e94604097600092613a87575050600019600383901b1c191690831b178755830151908601613917565b90601f19831691613bb687600052602060002090565b9260005b818110613be957509484613a7e948294610b7b9b9c9460029a9860409a10613adc57505050811b018755613a73565b82840151855593860193928a01928a01613bba565b6018549190600160401b831015610aa557613c20600193848101601855613866565b919091613b0a5780519384516001600160401b038111610aa557613c4881613a2f8654612288565b6020958690601f8311600114613c8f5792610b7b96978360029694613a7e94604097600092613a87575050600019600383901b1c191690831b178755830151908601613917565b90601f19831691613ca587600052602060002090565b9260005b818110613cd857509484613a7e948294610b7b9b9c9460029a9860409a10613adc57505050811b018755613a73565b82840151855593860193928a01928a01613ca9565b6017549190600160401b831015610aa557613d0f600193848101601755613847565b919091613b0a5780519384516001600160401b038111610aa557613d3781613a2f8654612288565b6020958690601f8311600114613d7e5792610b7b96978360029694613a7e94604097600092613a87575050600019600383901b1c191690831b178755830151908601613917565b90601f19831691613d9487600052602060002090565b9260005b818110613dc757509484613a7e948294610b7b9b9c9460029a9860409a10613adc57505050811b018755613a73565b82840151855593860193928a01928a01613d98565b6012544203428111610e075762015180900460018101809111610e075790565b613e04613ddc565b613e0c613ddc565b6000198101908111610e0757600990048101809111610e075790565b15613e2f57565b60405162461bcd60e51b815260206004820152603760248201527f596f75206d7573742073656e6420736f6d6520657468657220746f207061727460448201527634b1b4b830ba329034b7103a34329030bab1ba34b7b71760491b6064820152608490fd5b15613e9b57565b60405162461bcd60e51b81526020600482015260146024820152732cb7bab9103134b21034b9903a37b7903637bb9760611b6044820152606490fd5b15613ede57565b60405162461bcd60e51b815260206004820152601b60248201527f596f752061726520616c7265616479207468652077696e6e65722e00000000006044820152606490fd5b15613f2a57565b60405162461bcd60e51b815260206004820152601c60248201527f596f7520616c7265616479206d696e74656420796f7572204e46542e000000006044820152606490fd5b15613f7657565b60405162461bcd60e51b81526020600482015260146024820152732230bc903737ba103932b0b1b432b2103cb2ba1760611b6044820152606490fd5b811561335a570690565b600090808252601460205260026040832001600160ff198254161790556015602052604082205491601660205260408120918254938401809411610e0757610b7b936123e99355806040519261401184610ae0565b808452614026614020836126c2565b1561424f565b61402f82614f4d565b7f130d3b8ec5ca77745df8f9eefabec10d458057080e300991474408db5f897e855460008181527fdc8790dd48d9d7c4bd3f295ca5c205857bfaa48fc9197ec228cdb0e96e90034560209081526040808320869055858352600790915290205561409b614020836126c2565b73cc44a5feb6ee172daaa31c1fee3fc1ce1654057f90818152600360205260408120600181540190556141016140db846000526002602052604060002090565b80546001600160a01b03191673cc44a5feb6ee172daaa31c1fee3fc1ce1654057f179055565b6000805160206159df8339815191528180a461411b6150b3565b61278c565b600091808352601460205260026040842001600160ff19825416179055601560205260408320546016602052604084208054918201809211610e0757556040519061416a82610ae0565b8382526001600160a01b03831692831561420b57816123e994610b7b9661419b61419661361a856126c2565b61424f565b6141a58385614eee565b6141b461419661361a856126c2565b6001600160a01b0384166000908152600360205260409020600181540190556141eb8461077d856000526002602052604060002090565b6000805160206159df8339815191528180a461420681615134565b612857565b606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b1561425657565b60405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606490fd5b6142a4816126c2565b1561032e576001600160a01b036142ba82612265565b16330361032e576142c9613dfc565b81101561032e576142d98161432d565b9081159081156142e857505050565b6142fc906000526016602052604060002090565b805490838201809211610e0757600093849384938493558290614324575b3390f115612fb557565b506108fc61431a565b614335613dfc565b6000199290838101908111610e07575b6040600082815260156020522054158061439e575b1561436c578015610e07578301614345565b9092506000526015602052614391604060002054916000526016602052604060002090565b548103908111610e075790565b5080151561435a565b6143af613dfc565b811161032e57801561032e576000198101818111610e07576000526015602052604060002054158061444f575b614439575b6143fd6143ed826128fd565b6000526015602052604060002090565b5490806001614416826000526014602052604060002090565b0154048201809211610e0757614436906000526015602052604060002090565b55565b61444a614445826128fd565b6143a7565b6143e1565b50600181116143dc565b1561446057565b60405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420696e64657820666f72206172742e686561647300000000006044820152606490fd5b156144ac57565b60405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420696e64657820666f72206172742e686f726e7300000000006044820152606490fd5b156144f857565b60405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420696e64657820666f72206172742e626f64696573000000006044820152606490fd5b1561454457565b60405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420696e64657820666f72206172742e657965730000000000006044820152606490fd5b6004811015612a565760011b601b0190600090565b9060ff60405192548181168452818160081c16602085015260101c166040830152610b7b82610ac5565b906145db602092828151948592016103e9565b0190565b6000929181546145ee81612288565b92600191808316908115614646575060011461460a5750505050565b90919293945060005260209081600020906000915b8583106146355750505050019038808080611e87565b80548584015291830191810161461f565b60ff1916845250505081151590910201915038808080611e87565b614669613dfc565b81111561467590613f6f565b61467e81614b47565b61468790614b82565b9060ff91828151166017541161469c90614459565b602081019183835116601854116146b2906144a5565b604082019284845116601954116146c8906144f1565b606083019185835116601a54116146de9061453d565b6146e79061519f565b9283516146f39061569a565b9460208501516147029061569a565b9660408601516147119061569a565b9560608101516147209061569a565b90608081015161472f9061569a565b60a082015161473d9061569a565b60c083015161474b9061569a565b9160e084015161475a9061569a565b9361010001516147699061569a565b948689511661477790614589565b506147819061459e565b61478a9061569a565b96808080808d511661479b90614589565b506001016147a89061459e565b6147b19061569a565b9b51166147bd90613885565b509b51166147ca90613847565b509b51166147d790613866565b509b51166147e4906138a4565b509b6040519e8f9e8f60200161488290606f907f3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323081527f30302f737667272076696577426f783d2730202d302e3520323820323827207360208201527f686170652d72656e646572696e673d2763726973704564676573273e3c73747960408201526e36329f10173198bdb9ba3937b5b29d60891b60608201520190565b61488b916145c8565b6d1dbe901731993db9ba3937b5b29d60911b8152600e016148ab916145c8565b6d1dbe90173199bdb9ba3937b5b29d60911b8152600e016148cb916145c8565b6d1dbe9017319abdb9ba3937b5b29d60911b8152600e016148eb916145c8565b6d1dbe9017319b3db9ba3937b5b29d60911b8152600e0161490b916145c8565b6d1dbe901732193db9ba3937b5b29d60911b8152600e0161492b916145c8565b6d1dbe90173219bdb9ba3937b5b29d60911b8152600e0161494b916145c8565b6d1dbe9017321a3db9ba3937b5b29d60911b8152600e0161496b916145c8565b6d1dbe9017321b3db9ba3937b5b29d60911b8152600e0161498b916145c8565b6d1dbe90173998bdb9ba3937b5b29d60911b8152600e016149ab916145c8565b6d1dbe901739993db9ba3937b5b29d60911b8152600e016149cb916145c8565b7f3b7d203c2f7374796c653e3c7061746820636c6173733d2263312220643d224d81527f3020306832384d3020316832384d3020326832384d3020336832384d3020346860208201527f32384d3020356832384d3020366832384d3020376832384d3020386832384d3060408201527f20396832384d302031306832384d302031316832384d302031326832384d302060608201527f31336832384d302031346832384d302031356832384d302031366832384d302060808201527f31376832384d302031386832384d302031396832384d302032306832384d302060a08201527f32316832384d302032326832384d302032336832384d302032346832384d302060c082015277191ab4191c269810191b34191c269810191bb4191c11179f60411b60e082015260f801614b02916001016145df565b614b0e916001016145df565b614b1a916001016145df565b614b26916001016145df565b651e17b9bb339f60d11b815260060103601f19810182526104429082610b4d565b6040516020810191825266151a1951dbd85d60ca1b6040820152602781526130b181610ac5565b60405190614b7b82610ac5565b6060368337565b6080604051614b9081610b16565b36903760405190614ba082610b16565b608036833760175490811561335a5760ff82820616835204601854801561335a5780820660ff16602084015261044291614c1791614bfe91614c0e91614bea91613350565b613350565b60195490614be5614c04614bfe8484613fb2565b60ff1690565b60ff166040890152565b601a5490613fb2565b60ff166060830152565b15614c2857565b60405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608490fd5b600b60fa1b815260010190565b6000908072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b80821015614dc2575b506d04ee2d6d415b85acef810000000080831015614db3575b50662386f26fc1000080831015614da4575b506305f5e10080831015614d95575b5061271080831015614d86575b506064821015614d76575b600a80921015614d6c575b600190816021614d24828701613312565b95860101905b614d36575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a835304918215614d6757919082614d2a565b614d2f565b9160010191614d13565b9190606460029104910191614d08565b60049193920491019138614cfd565b60089193920491019138614cf0565b60109193920491019138614ce1565b60209193920491019138614ccf565b604093508104915038614cb6565b9091906001600160a01b038082169182614e135750614dee83614f4d565b831680614e01575050610b7b9150614fa5565b03614e0a575050565b610b7b91614f15565b8185168303614e23575b50614dee565b614e2c816121a7565b6000198101908111610e0757614e8460009286845260076020526040842054838103614e95575b5083614e69886000526007602052604060002090565b556001600160a01b0316600090815260066020526040902090565b908252602052604081205538614e1d565b868552600660205260408520848652602052614ee76040862054614ecb8460018060a01b03166000526006602052604060002090565b8388526020528060408820556000526007602052604060002090565b5538614e53565b90614ef881614f4d565b6001600160a01b038216614f1057610b7b9150614fa5565b610b7b915b604090614f21816121a7565b9260009160018060a01b0316825260066020528282208483526020528083832055815260076020522055565b60085481600052600960205280604060002055600160401b811015610aa5576001810180600855811015612a565760086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b60088054600019929083810190808211610e07576000928084526009602052816040852054931015612a565784845285826020862001015491831015612a5657839261500961501a9387865280836020882001556000526009602052604060002090565b556000526009602052604060002090565b55815492831561503d578084019380851015612a56578383526020832001015555565b634e487b7160e01b82526031600452602482fd5b610b7b916001600160a01b039182169190819083156150a4575b16918215615095575b600052600d6020528060406000205416916000526040600020541690611fa1565b61509d612158565b5050615074565b6150ac612120565b505061506b565b6150bb612120565b5050600d6020527f81955a0a11e65eac625c29e8882660bae4e165a75d72780094acae8ece9a29ee5473cc44a5feb6ee172daaa31c1fee3fc1ce1654057f6000527fcdb666f48cce5d344caea1f88d15637636615b6e9563a95f2881914947b8cef554610b7b916001600160a01b039182169116611fa1565b610b7b90615140612120565b50506001600160a01b03908116908115615190575b600d6020527f81955a0a11e65eac625c29e8882660bae4e165a75d72780094acae8ece9a29ee54600092835260409092205481169116611fa1565b615198612158565b5050615155565b60409081516151ad81610b31565b60005b61012081106152535750506151c761524a91615270565b6152166151d38261531c565b916151dc610b8a565b946151e6826153fc565b86526151f18261547f565b60208701526151ff826154f7565b9086015261520c8161556f565b6060860152615622565b60808401526152248161547f565b60a0840152615232816154f7565b60c08401526152408161556f565b60e0840152615622565b61010082015290565b602090845161526181610ac5565b606036823781840152016151b0565b606060405161527e81610ac5565b36903760405190606082018281106001600160401b03821117610aa55760405260ff6152a9826152ea565b1682526105398101808211610e07576152c360ff916152ea565b16602083015262cc07c98101809111610e07576152e160ff916152ea565b16604082015290565b60ff90604051602081019182526020815261530481610aaa565b5190201690565b60ff1660ff039060ff8211610e0757565b606060405161532a81610ac5565b36903760406152e181519261533e84610ac5565b606036853760ff928184615355818095511661530b565b168652826153688160208401511661530b565b16602087015201511661530b565b600281901b91906001600160fe1b03811603610e0757565b90602b820291808304602b1490151715610e0757565b90607082029180830460701490151715610e0757565b90608882029180830460881490151715610e0757565b908160061b9180830460401490151715610e0757565b90602c820291808304602c1490151715610e0757565b606060405161540a81610ac5565b369037615415614b6e565b9060ff80825116602b810290808204602b1490151715610e075781615460816040610442968261544981615474980461294a565b16895282615466816154608160208601511661538e565b0461294a565b1660208a015201511661538e565b1660ff166040830152565b606060405161548d81610ac5565b369037615498614b6e565b9060ff80825116607081029080820460701490151715610e0757816154e381604061044296826154cc816154749804612958565b168952826154e9816154e3816020860151166153a4565b04612958565b1660208a01520151166153a4565b606060405161550581610ac5565b369037615510614b6e565b9060ff80825116608881029080820460881490151715610e07578161555b8160406104429682615544816154749804612966565b168952826155618161555b816020860151166153ba565b04612966565b1660208a01520151166153ba565b606060405161557d81610ac5565b369037615588614b6e565b908051613fc060ff82169160061b169080820460401490151715610e0757614bfe6156006155f96155f460ff6040610442976155d56155ce614bfe856156189b04612966565b60ff168b52565b61560f615605614bfe6156006155f96155f48860208801511660ff1690565b6153d0565b60ff900490565b612966565b60ff1660208c0152565b01511660ff1690565b60ff166040830152565b606060405161563081610ac5565b36903761563b614b6e565b9060ff80825116602c810290808204602c1490151715610e075781615686816040610442968261566f816154749804612974565b1689528261568c81615686816020860151166153e6565b04612974565b1660208a01520151166153e6565b6104426156aa60ff835116614c92565b61574260266156ce60ff60406156c58260208a015116614c92565b97015116614c92565b604051958694630e4cec4560e31b60208701526156f581518092602060248a0191016103e9565b850190600b60fa1b918260248201526157188251809360206025850191016103e9565b0190602582015261573282518093602086850191016103e9565b0101600190602960f81b81520190565b03601f198101835282610b4d565b9081602091031261032e575161044281611603565b61577261361a8383615867565b61577a575050565b60135461579190610727906001600160a01b031681565b803b1561032e5760008391600460405180968193630d0e30db60e41b83525af1918215612fb5576158139360209361584e575b506013546157dc90610727906001600160a01b031681565b60405163a9059cbb60e01b81526001600160a01b039092166004830152602482019290925292839190829060009082906044820190565b03925af18015612fb5576158245750565b6158449060203d8111615847575b61583c8183610b4d565b810190615750565b50565b503d615832565b8061585b61586192610a92565b806103bb565b386157c4565b600080809381938260405161587b81610ae0565b52617530f161588861275c565b5090565b6040519061589982610ac5565b604082527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040837f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201520152565b8051156159d5576158fa61588c565b61591661591161590a845161292e565b6003900490565b615376565b916159286159238461293c565b613312565b92835280815182019060208501935b8282106159795750505060039051068060011461596857600214615959575090565b603d60f81b6000199091015290565b50613d3d60f01b6001199091015290565b90919360049060038094019384516001603f81818460121c16880101519260f893841b8652828282600c1c1689010151841b8387015282828260061c1689010151841b60028701521686010151901b9082015201939190615937565b50610442611d7856feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802dec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724a2646970667358221220c0e4395dd973041f975fbd791676deffcbea78d8dd2e583d8a826965b527f82c64736f6c63430008120033

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.