ETH Price: $2,765.01 (-6.51%)
 

Overview

Max Total Supply

0 FMON-V1-1668196800

Holders

2

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
Null: 0x000...000
Balance
0 FMON-V1-1668196800
0x0000000000000000000000000000000000000000
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:
RaffleOperator

Compiler Version
v0.8.14+commit.80d49f37

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 7 of 9: RaffleOperator.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8;

import "./Finalizable.sol";
import "./RaffleManager.sol";
import "./RaffleCashier.sol";
import "./ERC721URIStorage.sol";
import "./RaffleWinnerNumberGenerator.sol";

interface IERC20 {
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

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

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

library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x095ea7b3, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::safeApprove: approve failed"
        );
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0xa9059cbb, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::safeTransfer: transfer failed"
        );
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x23b872dd, from, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::transferFrom: transferFrom failed"
        );
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(
            success,
            "TransferHelper::safeTransferETH: ETH transfer failed"
        );
    }
}

contract RaffleOperator is Finalizable, ERC721URIStorage {
    uint256 public dateOfDraw;
    bool public prizeClaimed;
    uint256 public drawLaunchedAt;
    address public immutable USDC;
    address public raffleMegaVault;
    uint256 public raffleTotalPrize;
    address public raffleWinnerPlayer; // The address of the owner of the NFT token that claim the prize
    uint16 public minNumberOfPlayers;
    uint16 public maxNumberOfPlayers;
    uint256[] public currentSpotsBought;
    address payable[] public ticketBuyers; // The player that buy the ticket to enter, can be different to the winner because can sell the ticket to other person
    address public xPresidentsVaultAddress;
    uint256 public raffleWinnerPositionNumber;
    uint16 public percentageOfPrizeToOperator;
    uint256 public priceOfTheRaffleTicketInUSDC;
    uint256 public raffleCostsDeliveredToOperator;
    mapping(address => bool) public isTicketBuyer;
    uint256 public rafflePotPrizeDeliveredToWinner;

    RaffleCashier raffleCashierInstance;
    RaffleManager raffleManagerInstance;
    RaffleWinnerNumberGenerator raffleWinnerNumberGeneratorInstance;

    constructor(
        address _USDC,
        uint256 _dateOfDraw,
        address _raffleMegaVault,
        string memory _raffleName,
        uint16 _minNumberOfPlayers,
        uint16 _maxNumberOfPlayers,
        string memory _raffleSymbol,
        uint16 _percentageOfPrizeToOperator,
        uint256 _priceOfTheRaffleTicketInUSDC,
        address _raffleWinnerNumberGeneratorAddress,
        address _raffleCashier
    ) ERC721(_raffleName, _raffleSymbol) {
        USDC = _USDC;
        owner = msg.sender;
        dateOfDraw = _dateOfDraw;
        raffleMegaVault = _raffleMegaVault;
        minNumberOfPlayers = _minNumberOfPlayers;
        maxNumberOfPlayers = _maxNumberOfPlayers;
        raffleManagerInstance = RaffleManager(msg.sender);
        raffleCashierInstance = RaffleCashier(_raffleCashier);
        percentageOfPrizeToOperator = _percentageOfPrizeToOperator;
        priceOfTheRaffleTicketInUSDC = _priceOfTheRaffleTicketInUSDC;
        raffleWinnerNumberGeneratorInstance = RaffleWinnerNumberGenerator(
            _raffleWinnerNumberGeneratorAddress
        );
    }

    function getRaffleTicketPlayerBySpotTicketId(uint256 _raffleSpotToSearch)
        external
        view
        returns (address _rafflePlayerBySpotTicketId)
    {
        return ownerOf(_raffleSpotToSearch);
    }

    function getRaffleTicketBuyers()
        external
        view
        returns (address payable[] memory _raffleBuyers)
    {
        return ticketBuyers;
    }

    function getRaffleTicketOwners()
        external
        view
        returns (
            address[] memory _ticketOwners,
            uint256[] memory _currentRafflePlayerNumbers
        )
    {
        _currentRafflePlayerNumbers = raffleWinnerNumberGeneratorInstance
            .getPlayerNumbers(address(this));
        _ticketOwners = new address[](_currentRafflePlayerNumbers.length);

        for (uint256 i = 0; i < _currentRafflePlayerNumbers.length; ++i) {
            _ticketOwners[i] = ownerOf(_currentRafflePlayerNumbers[i]);
        }
    }

    function getCurrentSpotsBought()
        external
        view
        returns (uint256[] memory _currentSpotsBought)
    {
        return currentSpotsBought;
    }

    function getIfAddressPlay(address _addressToCheck)
        external
        view
        returns (bool _addressPlay)
    {
        return (_balances[_addressToCheck] > 0);
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public override onlyIfRunning {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public override onlyIfRunning {
        safeTransferFrom(from, to, tokenId, "");
    }

    function setDateOfTheLaunch() public returns (bool success) {
        require(
            msg.sender == address(raffleWinnerNumberGeneratorInstance),
            "Unauthorized"
        );
        drawLaunchedAt = block.timestamp;
        return true;
    }

    function buyTicketsToPlay(
        uint256 _amountToBuyTickets,
        uint256[] memory _raffleTicketIds,
        string[] memory _raffleTicketTokenURIs,
        address _tokenToUseToBuyTickets
    ) public payable onlyIfRunning returns (bool success) {
        require(
            dateOfDraw - 600 >= block.timestamp,
            "The buying of the tickets for the raffle is closed."
        ); // 10 minutes
        require(
            ticketBuyers.length < maxNumberOfPlayers,
            "The maximum number of players was reached."
        );
        require(
            _raffleTicketIds.length == _raffleTicketTokenURIs.length,
            "tokenIds and tokenURIs length mismatch"
        );

        if (_tokenToUseToBuyTickets == USDC) {
            require(
                _amountToBuyTickets ==
                    (_raffleTicketIds.length * priceOfTheRaffleTicketInUSDC),
                "The amount to buy ticket is not correct."
            );

            uint256 balanceOfUSDCOfSender = IERC20(USDC).balanceOf(msg.sender);
            require(
                balanceOfUSDCOfSender >=
                    (_raffleTicketIds.length * priceOfTheRaffleTicketInUSDC),
                "You dont have USDC balance to buy tickets."
            );

            raffleCashierInstance.transferAmountToBuyTickets(
                USDC,
                msg.sender,
                address(this),
                _amountToBuyTickets
            );
        } else {
            // All amounts are without decimals
            uint256 decimalsOfToken = IERC20(_tokenToUseToBuyTickets)
                .decimals();
            uint256 balanceOfTokenOfSender = IERC20(_tokenToUseToBuyTickets)
                .balanceOf(msg.sender);

            uint256 currentPriceOfTokenByETHInUSDC = raffleCashierInstance
                .getCurrentPriceOfTokenByETHInUSDC(
                    _tokenToUseToBuyTickets,
                    USDC
                );
            uint256 amountOfTokensRequiredToBuy = ((priceOfTheRaffleTicketInUSDC *
                    (1 * 10**decimalsOfToken)) /
                    currentPriceOfTokenByETHInUSDC) * _raffleTicketIds.length;

            require(
                _amountToBuyTickets >= amountOfTokensRequiredToBuy,
                "The amount to buy ticket is not correct."
            );
            require(
                balanceOfTokenOfSender >= amountOfTokensRequiredToBuy,
                "You dont have token balance to buy tickets."
            );

            raffleCashierInstance.transferAmountOfUSDFromLiquidityToBuyTickets(
                USDC,
                msg.sender,
                address(this),
                _tokenToUseToBuyTickets,
                _amountToBuyTickets,
                _raffleTicketIds.length * priceOfTheRaffleTicketInUSDC
            );
        }

        for (uint256 i = 0; i < _raffleTicketIds.length; ++i) {
            require(
                _raffleTicketIds[i] != 0,
                "All the ticket ids has to be different from 0."
            );
            require(
                _raffleTicketIds[i] <= maxNumberOfPlayers,
                "Tickets cannot be greater than the number of players."
            );

            giveRaffleTicket(
                msg.sender,
                _raffleTicketIds[i],
                _raffleTicketTokenURIs[i]
            );
            raffleWinnerNumberGeneratorInstance.setNewRafflePlayingSpot(
                address(this),
                _raffleTicketIds[i]
            );

            ticketBuyers.push(payable(msg.sender));
            isTicketBuyer[msg.sender] = true;
            currentSpotsBought.push(_raffleTicketIds[i]);
        }

        return true;
    }

    function giveRaffleTicket(
        address buyer,
        uint256 newRaffleTicketId,
        string memory tokenURI
    ) internal returns (uint256) {
        require(!_exists(newRaffleTicketId), "Raffle ticket id already sold.");

        _mint(buyer, newRaffleTicketId);
        _setTokenURI(newRaffleTicketId, tokenURI);

        return newRaffleTicketId;
    }

    function returnMoneyToOwners()
        public
        onlyOwner
        onlyIfRunning
        returns (bool _raffleIsFinished)
    {
        for (uint256 i = 0; i < currentSpotsBought.length; ++i) {
            address spotOwner = ownerOf(currentSpotsBought[i]);
            TransferHelper.safeTransfer(
                USDC,
                spotOwner,
                priceOfTheRaffleTicketInUSDC
            );
        }

        running = false;
        return true;
    }

    function setRaffleWinner(uint256 _raffleWinnerNumber)
        public
        onlyOwner
        onlyIfRunning
        returns (bool _raffleIsFinished)
    {
        raffleWinnerPlayer = ownerOf(_raffleWinnerNumber);
        raffleTotalPrize = IERC20(USDC).balanceOf(address(this));

        sendRaffleCostsToOperator();
        claimRafflePrizePot(raffleWinnerPlayer);

        raffleWinnerPositionNumber = _raffleWinnerNumber;
        running = false;
        return true;
    }

    function sendRaffleCostsToOperator() internal returns (bool _success) {
        raffleCostsDeliveredToOperator = ((raffleTotalPrize *
            percentageOfPrizeToOperator) / 100);
        uint256 raffleCostsDeliveredToMegaVault = (raffleCostsDeliveredToOperator *
                85) / 100;
        uint256 raffleCostsDeliveredToProject = (raffleCostsDeliveredToOperator *
                15) / 100;

        TransferHelper.safeTransfer(
            USDC,
            address(raffleManagerInstance.megaVaultAddress()),
            raffleCostsDeliveredToMegaVault
        );
        TransferHelper.safeTransfer(
            USDC,
            address(raffleManagerInstance.treasuryAddress()),
            raffleCostsDeliveredToProject / 2
        );
        TransferHelper.safeTransfer(
            USDC,
            address(raffleManagerInstance.xPresidentsVaultAddress()),
            raffleCostsDeliveredToProject / 2
        );
        return true;
    }

    function claimRafflePrizePot(address _raffleWinnerPlayer)
        internal
        returns (bool _success)
    {
        require(!prizeClaimed, "The prize was already claimed.");

        uint16 percentageOfThePotToTheWinner = 100 -
            percentageOfPrizeToOperator;
        rafflePotPrizeDeliveredToWinner = ((raffleTotalPrize *
            percentageOfThePotToTheWinner) / 100);

        TransferHelper.safeTransfer(
            USDC,
            address(raffleCashierInstance),
            rafflePotPrizeDeliveredToWinner
        );
        raffleCashierInstance.transferPrizeToWinner(
            address(this),
            USDC,
            _raffleWinnerPlayer,
            rafflePotPrizeDeliveredToWinner
        );

        prizeClaimed = true;
        return true;
    }
}

File 1 of 9: ERC721.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC165 {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

interface IERC721 is IERC165 {
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );
    event Approval(
        address indexed owner,
        address indexed approved,
        uint256 indexed tokenId
    );
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );

    function balanceOf(address owner) external view returns (uint256 balance);

    function ownerOf(uint256 tokenId) external view returns (address owner);

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    function approve(address to, uint256 tokenId) external;

    function setApprovalForAll(address operator, bool _approved) external;

    function getApproved(uint256 tokenId)
        external
        view
        returns (address operator);

    function isApprovedForAll(address owner, address operator)
        external
        view
        returns (bool);
}

interface IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

interface IERC721Metadata is IERC721 {
    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

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

library Address {
    function isContract(address account) internal view returns (bool) {
        return account.code.length > 0;
    }

    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"
        );
    }

    function functionCall(address target, bytes memory data)
        internal
        returns (bytes memory)
    {
        return functionCall(target, data, "Address: low-level call failed");
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    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"
            );
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(
            address(this).balance >= value,
            "Address: insufficient balance for call"
        );
        require(isContract(target), "Address: call to non-contract");

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

    function functionStaticCall(address target, bytes memory data)
        internal
        view
        returns (bytes memory)
    {
        return
            functionStaticCall(
                target,
                data,
                "Address: low-level static call failed"
            );
    }

    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

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

    function functionDelegateCall(address target, bytes memory data)
        internal
        returns (bytes memory)
    {
        return
            functionDelegateCall(
                target,
                data,
                "Address: low-level delegate call failed"
            );
    }

    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

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

    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            if (returndata.length > 0) {
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

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

    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    function toHexString(uint256 value, uint256 length)
        internal
        pure
        returns (string memory)
    {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override
        returns (bool)
    {
        return interfaceId == type(IERC165).interfaceId;
    }
}

contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    string private _name;
    string private _symbol;
    mapping(uint256 => address) private _owners;
    mapping(address => uint256) internal _balances;
    mapping(uint256 => address) private _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

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

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

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

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

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

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

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

    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

    function getApproved(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        require(
            _exists(tokenId),
            "ERC721: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    function isApprovedForAll(address owner, address operator)
        public
        view
        virtual
        override
        returns (bool)
    {
        return _operatorApprovals[owner][operator];
    }

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

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

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

    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"
        );
    }

    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    function _isApprovedOrOwner(address spender, uint256 tokenId)
        internal
        view
        virtual
        returns (bool)
    {
        require(
            _exists(tokenId),
            "ERC721: operator query for nonexistent token"
        );
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner ||
            isApprovedForAll(owner, spender) ||
            getApproved(tokenId) == spender);
    }

    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    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"
        );
    }

    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

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

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

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

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

    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        _approve(address(0), tokenId);

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

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

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

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

        _approve(address(0), tokenId);

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

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

    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try
                IERC721Receiver(to).onERC721Received(
                    _msgSender(),
                    from,
                    tokenId,
                    _data
                )
            returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert(
                        "ERC721: transfer to non ERC721Receiver implementer"
                    );
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}

    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

File 2 of 9: ERC721URIStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./ERC721.sol";

abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    mapping(uint256 => string) private _tokenURIs;

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721URIStorage: URI query for nonexistent token"
        );

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        if (bytes(base).length == 0) {
            return _tokenURI;
        }

        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    function _setTokenURI(uint256 tokenId, string memory _tokenURI)
        internal
        virtual
    {
        require(
            _exists(tokenId),
            "ERC721URIStorage: URI set of nonexistent token"
        );
        _tokenURIs[tokenId] = _tokenURI;
    }

    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

File 3 of 9: Finalizable.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8;

import "./Owned.sol";

contract Finalizable is Owned {
    bool public running;

    event LogRunSwitch(address sender, bool switchSetting);

    modifier onlyIfRunning() {
        require(running, "Is not running.");
        _;
    }

    modifier onlyIfNotRunning() {
        require(!running, "Is still running.");
        _;
    }

    constructor() {
        running = true;
    }

    function runSwitch(bool onOff)
        external
        onlyOwner
        onlyIfRunning
        returns (bool success)
    {
        running = onOff;
        emit LogRunSwitch(msg.sender, onOff);
        return true;
    }
}

File 4 of 9: Owned.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8;

contract Owned {
    address public owner;

    event LogActualOwner(address sender, address oldOwner, address newOwner);

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    constructor() {
        owner = msg.sender;
    }

    function changeOwner(address newOwner)
        internal
        onlyOwner
        returns (bool success)
    {
        require(
            newOwner != address(0x0),
            "You are not the owner of the contract."
        );
        owner = newOwner;
        emit LogActualOwner(msg.sender, owner, newOwner);
        return true;
    }
}

File 5 of 9: RaffleCashier.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8;

import "./RaffleManager.sol";
import "./RaffleOperator.sol";

interface IPair {
    function token0() external view returns (address);

    function token1() external view returns (address);

    function balanceOf(address owner) external view returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );
}

interface IRouter {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);
}

interface IFactory {
    function getPair(address tokenA, address tokenB)
        external
        view
        returns (address pair);

    function createPair(address tokenA, address tokenB)
        external
        returns (address pair);
}

interface AggregatorV3Interface {
    function decimals() external view returns (uint8);

    function description() external view returns (string memory);

    function version() external view returns (uint256);

    function getRoundData(uint80 _roundId)
        external
        view
        returns (
            uint80 roundId,
            int256 answer,
            uint256 startedAt,
            uint256 updatedAt,
            uint80 answeredInRound
        );

    function latestRoundData()
        external
        view
        returns (
            uint80 roundId,
            int256 answer,
            uint256 startedAt,
            uint256 updatedAt,
            uint80 answeredInRound
        );
}

contract RaffleCashier is Owned {
    IRouter public router;
    address public immutable WETH;
    address public immutable FMON;
    address public treasuryAddress;
    AggregatorV3Interface internal priceFeed;

    RaffleManager raffleManagerInstance;

    error Unauthorized();

    constructor(
        address _routerAddress,
        address _WETH,
        address _FMON
    ) {
        IRouter _router = IRouter(_routerAddress);
        router = _router;
        WETH = _WETH;
        FMON = _FMON;
        raffleManagerInstance = RaffleManager(msg.sender);
        priceFeed = AggregatorV3Interface(
            0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
        );
    }

    function getCurrentPriceOfTokenByETHInUSDC(address _tokenA, address _USDC)
        public
        view
        returns (uint256 _currentPriceOfTokenWithoutDecimalsInUSD)
    {
        // tokenA always the token which we want to know the price
        address _pair = IFactory(router.factory()).getPair(_tokenA, WETH);
        uint256 decimalsUSDC = IERC20(_USDC).decimals();
        uint256 decimalsToken0 = IERC20(IPair(_pair).token0()).decimals();
        uint256 decimalsToken1 = IERC20(IPair(_pair).token1()).decimals();
        (uint256 reserve0, uint256 reserve1, ) = IPair(_pair).getReserves();

        uint256 currentToken0PriceWithoutDecimals = (1 *
            10**decimalsToken0 *
            reserve1) / reserve0; // --> For 1 FMON is this ETH
        uint256 currentToken1PriceWithoutDecimals = (1 *
            10**decimalsToken1 *
            reserve0) / reserve1; // --> For 1 ETH is this FMON

        uint256 currentETHPrice = uint256(getETHLatestPrice());
        uint8 ETHPriceDecimals = getETHPriceDecimals();
        uint256 currentPriceETHInUSD = currentETHPrice / 10**ETHPriceDecimals;
        uint256 currentPriceETHInUSDWithoutDecimals = 1 *
            10**decimalsUSDC *
            currentPriceETHInUSD;

        // If token0 is ETH, token1 is FMON
        if (_tokenA == IPair(_pair).token0()) {
            _currentPriceOfTokenWithoutDecimalsInUSD =
                ((1 * 10**decimalsToken0) *
                    currentPriceETHInUSDWithoutDecimals) /
                currentToken1PriceWithoutDecimals;
        } else if (_tokenA == IPair(_pair).token1()) {
            _currentPriceOfTokenWithoutDecimalsInUSD =
                ((1 * 10**decimalsToken1) *
                    currentPriceETHInUSDWithoutDecimals) /
                currentToken0PriceWithoutDecimals;
        }
    }

    function addUSDCLiquidity(
        address _USDC,
        address _liquidityProvider,
        uint256 _liquidityToAdd
    ) external onlyOwner returns (bool _success) {
        TransferHelper.safeTransferFrom(
            _USDC,
            _liquidityProvider,
            address(this),
            _liquidityToAdd
        );
        return true;
    }

    function removeUSDCLiquidity(
        address _USDC,
        uint256 _liquidityToRemove,
        address _liquidityReceiver
    ) external onlyOwner returns (bool _removeLiquiditySuccess) {
        TransferHelper.safeTransfer(
            _USDC,
            _liquidityReceiver,
            _liquidityToRemove
        );
        return true;
    }

    function changeRouterToMakeSwap(address _newRouterAddress)
        external
        onlyOwner
        returns (bool _success)
    {
        IRouter _router = IRouter(_newRouterAddress);
        router = _router;
        return true;
    }

    function transferAmountToBuyTickets(
        address _USDC,
        address _ticketsBuyer,
        address _raffleOperator,
        uint256 _amountToBuyTickets
    ) external returns (bool _transferSuccess) {
        if (msg.sender != _raffleOperator) revert Unauthorized();

        TransferHelper.safeTransferFrom(
            _USDC,
            _ticketsBuyer,
            _raffleOperator,
            _amountToBuyTickets
        );
        return true;
    }

    function transferAmountOfUSDFromLiquidityToBuyTickets(
        address _USDC,
        address _ticketsBuyer,
        address _raffleOperator,
        address _tokenToUseToBuyTickets,
        uint256 _amountToBuyTickets,
        uint256 _amountOfUSDCToBuyTickets
    ) external returns (bool _transferSuccess) {
        if (msg.sender != _raffleOperator) revert Unauthorized();

        TransferHelper.safeTransferFrom(
            _tokenToUseToBuyTickets,
            _ticketsBuyer,
            address(this),
            _amountToBuyTickets
        );
        TransferHelper.safeTransfer(
            _USDC,
            _raffleOperator,
            _amountOfUSDCToBuyTickets
        );
        return true;
    }

    function swapTokenToUSDC(
        address _USDC,
        address _ticketsBuyer,
        address _raffleOperator,
        address _tokenToUseToBuyTickets,
        uint256 _amountToBuyTickets,
        uint256 _amountOfUSDCToReceive
    ) external returns (bool _swapSuccess) {
        if (msg.sender != _raffleOperator) revert Unauthorized();

        address[] memory path = new address[](2);
        path[0] = address(_tokenToUseToBuyTickets);
        path[1] = address(_USDC);

        TransferHelper.safeTransferFrom(
            _tokenToUseToBuyTickets,
            _ticketsBuyer,
            address(this),
            _amountToBuyTickets
        );

        router.swapTokensForExactTokens(
            _amountOfUSDCToReceive,
            _amountToBuyTickets,
            path,
            address(this),
            block.timestamp + 600
        );

        TransferHelper.safeTransfer(
            _USDC,
            _raffleOperator,
            _amountOfUSDCToReceive
        );
        return true;
    }

    function transferPrizeToWinner(
        address _raffleOperator,
        address _USDC,
        address _raffleWinnerPlayer,
        uint256 _prizeToDeliverToWinner
    ) external returns (bool _transferSuccess) {
        if (msg.sender != _raffleOperator) revert Unauthorized();

        uint256 currentPriceOfFMONByETHInUSDC = getCurrentPriceOfTokenByETHInUSDC(
                FMON,
                _USDC
            );
        uint256 decimalsFMON = IERC20(FMON).decimals();
        uint256 currentFMONBalanceOfCashier = IERC20(FMON).balanceOf(
            address(this)
        );

        uint256 prizeToDeliverToWinnerInFMON = ((_prizeToDeliverToWinner *
            (1 * 10**decimalsFMON)) / currentPriceOfFMONByETHInUSDC);
        TransferHelper.safeTransfer(
            FMON,
            _raffleWinnerPlayer,
            prizeToDeliverToWinnerInFMON
        );

        if (currentFMONBalanceOfCashier < prizeToDeliverToWinnerInFMON) {
            uint256 extraAmountToSend = prizeToDeliverToWinnerInFMON -
                currentFMONBalanceOfCashier;
            TransferHelper.safeTransferFrom(
                FMON,
                address(raffleManagerInstance.treasuryAddress()),
                _raffleWinnerPlayer,
                extraAmountToSend
            );
        }

        return true;
    }

    function approveRouterToSwapToken(address _tokenToApprove)
        external
        onlyOwner
        returns (bool _approvalSuccess)
    {
        uint256 tokenTotalSupply = IERC20(_tokenToApprove).totalSupply();
        IERC20(_tokenToApprove).approve(address(router), tokenTotalSupply);
        return true;
    }

    function getETHLatestPrice() public view returns (int256) {
        (, int256 price, , , ) = priceFeed.latestRoundData();
        return price;
    }

    function getETHPriceDecimals() public view returns (uint8) {
        uint8 decimals = priceFeed.decimals();
        return decimals;
    }
}

File 6 of 9: RaffleManager.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8;

import "./Owned.sol";
import "./RaffleCashier.sol";
import "./RaffleOperator.sol";
import "./RaffleWinnerNumberGenerator.sol";

contract RaffleManager is Owned {
    address[] private adminUsers;
    address public raffleCashier;
    address public treasuryAddress;
    address public megaVaultAddress;
    address[] public rafflesAddresses;
    uint256 public currentRaffleId = 0;
    address public xPresidentsVaultAddress;
    uint16 private constant MAX_ADMINS = 10;
    address public raffleWinnerNumberGenerator;
    mapping(address => bool) public isAdminUser;
    uint256 private constant RAFFLE_IN_PROGRESS = 3200000;

    error TooManyAdminUsers();
    error OwnerCantBeRemoved();
    error AdminUsersCantBeEmpty();
    error AdminUserAlreadyAdded();
    error UserToRemoveIsNotAdmin();

    event AdminUserAdded(address indexed adminUserAddress);
    event AdminUserRemoved(address indexed adminUserAddress);
    event RaffleFinished(address indexed raffleOperatorContract);
    event RaffleRestarted(address indexed raffleOperatorContract);
    event RaffleCashierCreated(
        address indexed raffleCashierContract,
        bytes32 indexed raffleCashierSalt
    );
    event RaffleCreated(
        address indexed raffleOperatorContract,
        bytes32 indexed raffleSalt,
        uint256 currentRafflesLength
    );
    event RaffleWinnerNumberGeneratorCreated(
        address indexed raffleWinnerNumberGeneratorContract,
        bytes32 indexed raffleWinnerNumberGeneratorSalt
    );

    modifier onlyIfAdminUser() {
        require(isAdminUser[msg.sender] == true, "You are not authorized");
        _;
    }

    constructor(
        uint64 _subscriptionId,
        address _routerAddress,
        address _treasuryAddress,
        address _megaVaultAddress,
        address _xPresidentsVaultAddress,
        address _WETH,
        address _FMON
    ) {
        owner = msg.sender;
        adminUsers.push(msg.sender);
        isAdminUser[msg.sender] = true;
        treasuryAddress = _treasuryAddress;
        megaVaultAddress = _megaVaultAddress;
        xPresidentsVaultAddress = _xPresidentsVaultAddress;

        raffleCashier = createRaffleCashier(_routerAddress, _WETH, _FMON);
        raffleWinnerNumberGenerator = createRaffleWinnerNumberGenerator(
            address(this),
            _subscriptionId
        );
    }

    function getCurrentAdminUsers()
        external
        view
        onlyIfAdminUser
        returns (address[] memory _currentAdminUsers)
    {
        return adminUsers;
    }

    function getIfUserIsAdmin(address userToCheck)
        external
        view
        returns (bool _userIsAdmin)
    {
        return isAdminUser[userToCheck];
    }

    function allRafflesLength()
        external
        view
        returns (uint256 _rafflesAddressesQuantity)
    {
        return rafflesAddresses.length;
    }

    function updateMegaVaultWallet(address newWallet) external onlyOwner {
        require(megaVaultAddress != newWallet, "Wallet already set");
        megaVaultAddress = newWallet;
    }

    function updateXPresidentsVaultWallet(address newWallet)
        external
        onlyOwner
    {
        require(xPresidentsVaultAddress != newWallet, "Wallet already set");
        xPresidentsVaultAddress = newWallet;
    }

    function updateTreasuryWallet(address newWallet) external onlyOwner {
        require(treasuryAddress != newWallet, "Wallet already set");
        treasuryAddress = newWallet;
    }

    function approveRouterToSwapToken(address _tokenToApprove)
        external
        onlyIfAdminUser
        returns (bool _approvalSuccess)
    {
        RaffleCashier(raffleCashier).approveRouterToSwapToken(_tokenToApprove);
        return true;
    }

    function addUSDCLiquidity(address _USDC, uint256 _liquidityToAdd)
        external
        onlyOwner
        returns (bool _removeLiquiditySuccess)
    {
        require(_USDC != address(0), "FmoneyRaffleV1: ZERO_USDC_ADDRESS");
        require(
            _liquidityToAdd > 0,
            "Please set the quantity of liquidity that you want to add"
        );
        RaffleCashier(raffleCashier).addUSDCLiquidity(
            _USDC,
            msg.sender,
            _liquidityToAdd
        );
        return true;
    }

    function removeUSDCLiquidity(address _USDC, uint256 _liquidityToRemove)
        external
        onlyOwner
        returns (bool _removeLiquiditySuccess)
    {
        RaffleCashier(raffleCashier).removeUSDCLiquidity(
            _USDC,
            _liquidityToRemove,
            msg.sender
        );
        return true;
    }

    function changeRouterToBuyTickets(address _newRouterAddress)
        external
        onlyOwner
        returns (bool _success)
    {
        RaffleCashier(raffleCashier).changeRouterToMakeSwap(_newRouterAddress);
        return true;
    }

    function addAdminUser(address adminUserToAdd) external onlyOwner {
        // Already maxed, cannot add any more admin users.
        if (adminUsers.length == MAX_ADMINS) revert TooManyAdminUsers();
        if (isAdminUser[adminUserToAdd] == true) revert AdminUserAlreadyAdded();

        adminUsers.push(adminUserToAdd);
        isAdminUser[adminUserToAdd] = true;

        emit AdminUserAdded(adminUserToAdd);
    }

    function removeAdminUser(address adminUserToRemove)
        external
        onlyIfAdminUser
    {
        if (adminUsers.length == 1) revert AdminUsersCantBeEmpty();
        if (adminUserToRemove == owner) revert OwnerCantBeRemoved();
        if (!isAdminUser[adminUserToRemove]) revert UserToRemoveIsNotAdmin();

        uint256 lastAdminUserIndex = adminUsers.length - 1;
        for (uint256 i = 0; i < adminUsers.length; i++) {
            if (adminUsers[i] == adminUserToRemove) {
                address last = adminUsers[lastAdminUserIndex];
                adminUsers[i] = last;
                adminUsers.pop();
                break;
            }
        }

        isAdminUser[adminUserToRemove] = false;
        emit AdminUserRemoved(adminUserToRemove);
    }

    function createRaffleCashier(
        address _routerAddress,
        address _WETH,
        address _FMON
    ) internal returns (address _raffleCashier) {
        bytes32 salt = keccak256(abi.encodePacked(_routerAddress));

        RaffleCashier _raffleCashierContract = new RaffleCashier{salt: salt}(
            _routerAddress,
            _WETH,
            _FMON
        );

        emit RaffleCashierCreated(address(_raffleCashierContract), salt);
        return address(_raffleCashierContract);
    }

    function createRaffleWinnerNumberGenerator(
        address _raffleManagerAddress,
        uint64 _subscriptionId
    ) internal returns (address _raffleWinnerNumberGenerator) {
        bytes32 salt = keccak256(
            abi.encodePacked(_raffleManagerAddress, _subscriptionId)
        );

        RaffleWinnerNumberGenerator _raffleWinnerNumberGeneratorContract = new RaffleWinnerNumberGenerator{
                salt: salt
            }(_raffleManagerAddress, _subscriptionId);

        emit RaffleWinnerNumberGeneratorCreated(
            address(_raffleWinnerNumberGeneratorContract),
            salt
        );
        return address(_raffleWinnerNumberGeneratorContract);
    }

    function createRaffle(
        address _USDC,
        uint256 _dateOfDraw,
        string memory _raffleName,
        uint16 _minNumberOfPlayers,
        uint16 _maxNumberOfPlayers,
        string memory _raffleSymbol,
        uint16 _percentageOfPrizeToOperator,
        uint256 _priceOfTheRaffleTicketInUSDC
    ) external onlyIfAdminUser returns (address _raffleOperatorAddress) {
        require(_USDC != address(0), "FmoneyRaffleV1: ZERO_USDC_ADDRESS");

        bytes32 salt = keccak256(
            abi.encodePacked(
                _USDC,
                _dateOfDraw,
                _raffleName,
                _minNumberOfPlayers,
                _maxNumberOfPlayers,
                _raffleSymbol,
                _percentageOfPrizeToOperator,
                _priceOfTheRaffleTicketInUSDC,
                raffleWinnerNumberGenerator,
                raffleCashier
            )
        );

        RaffleOperator _raffleOperatorContract = new RaffleOperator{salt: salt}(
            _USDC,
            _dateOfDraw,
            owner,
            _raffleName,
            _minNumberOfPlayers,
            _maxNumberOfPlayers,
            _raffleSymbol,
            _percentageOfPrizeToOperator,
            _priceOfTheRaffleTicketInUSDC,
            raffleWinnerNumberGenerator,
            raffleCashier
        );

        rafflesAddresses.push(address(_raffleOperatorContract));
        currentRaffleId++;

        emit RaffleCreated(
            address(_raffleOperatorContract),
            salt,
            rafflesAddresses.length
        );
        return address(_raffleOperatorContract);
    }

    function drawRaffle(address _raffleOperatorContract)
        external
        onlyIfAdminUser
        returns (bool _raffleIsInProgress)
    {
        uint256 _dateOfDraw = RaffleOperator(_raffleOperatorContract)
            .dateOfDraw();
        uint32 _maxNumberOfPlayers = RaffleOperator(_raffleOperatorContract)
            .maxNumberOfPlayers();
        uint32 _minNumberOfPlayers = RaffleOperator(_raffleOperatorContract)
            .minNumberOfPlayers();
        address payable[] memory _ticketBuyers = RaffleOperator(
            _raffleOperatorContract
        ).getRaffleTicketBuyers();

        if (_ticketBuyers.length < _maxNumberOfPlayers) {
            require(block.timestamp >= _dateOfDraw, "The draw is not yet.");
        }

        if (_ticketBuyers.length == 0) {
            RaffleOperator(_raffleOperatorContract).runSwitch(false); // We close the raffle because there is no players
            return true;
        }

        if (_ticketBuyers.length < _minNumberOfPlayers) {
            RaffleOperator(_raffleOperatorContract).returnMoneyToOwners(); // We close the raffle because there is less players
            return true;
        }

        RaffleWinnerNumberGenerator(raffleWinnerNumberGenerator).launchRaffle(
            _raffleOperatorContract
        );
        return true;
    }

    function getRaffleWinner(address _raffleOperatorContract)
        external
        onlyOwner
        returns (uint256 _raffleWinnerNumber)
    {
        _raffleWinnerNumber = RaffleWinnerNumberGenerator(
            raffleWinnerNumberGenerator
        ).getRaffleWinnerNumber(_raffleOperatorContract);
        require(
            _raffleWinnerNumber != RAFFLE_IN_PROGRESS,
            "Raffle in progress."
        );
        RaffleOperator(_raffleOperatorContract).setRaffleWinner(
            _raffleWinnerNumber
        );
    }
}

File 8 of 9: RaffleWinnerNumberGenerator.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8;

import "./RaffleOperator.sol";
import "./VRFConsumerBaseV2.sol";

interface VRFCoordinatorV2Interface {
    /**
     * @notice Get configuration relevant for making requests
     * @return minimumRequestConfirmations global min for request confirmations
     * @return maxGasLimit global max for request gas limit
     * @return s_provingKeyHashes list of registered key hashes
     */
    function getRequestConfig()
        external
        view
        returns (
            uint16,
            uint32,
            bytes32[] memory
        );

    /**
     * @notice Request a set of random words.
     * @param keyHash - Corresponds to a particular oracle job which uses
     * that key for generating the VRF proof. Different keyHash's have different gas price
     * ceilings, so you can select a specific one to bound your maximum per request cost.
     * @param subId  - The ID of the VRF subscription. Must be funded
     * with the minimum subscription balance required for the selected keyHash.
     * @param minimumRequestConfirmations - How many blocks you'd like the
     * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS
     * for why you may want to request more. The acceptable range is
     * [minimumRequestBlockConfirmations, 200].
     * @param callbackGasLimit - How much gas you'd like to receive in your
     * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords
     * may be slightly less than this amount because of gas used calling the function
     * (argument decoding etc.), so you may need to request slightly more than you expect
     * to have inside fulfillRandomWords. The acceptable range is
     * [0, maxGasLimit]
     * @param numWords - The number of uint256 random values you'd like to receive
     * in your fulfillRandomWords callback. Note these numbers are expanded in a
     * secure way by the VRFCoordinator from a single random value supplied by the oracle.
     * @return requestId - A unique identifier of the request. Can be used to match
     * a request to a response in fulfillRandomWords.
     */
    function requestRandomWords(
        bytes32 keyHash,
        uint64 subId,
        uint16 minimumRequestConfirmations,
        uint32 callbackGasLimit,
        uint32 numWords
    ) external returns (uint256 requestId);

    /**
     * @notice Create a VRF subscription.
     * @return subId - A unique subscription id.
     * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
     * @dev Note to fund the subscription, use transferAndCall. For example
     * @dev  LINKTOKEN.transferAndCall(
     * @dev    address(COORDINATOR),
     * @dev    amount,
     * @dev    abi.encode(subId));
     */
    function createSubscription() external returns (uint64 subId);

    /**
     * @notice Get a VRF subscription.
     * @param subId - ID of the subscription
     * @return balance - LINK balance of the subscription in juels.
     * @return reqCount - number of requests for this subscription, determines fee tier.
     * @return owner - owner of the subscription.
     * @return consumers - list of consumer address which are able to use this subscription.
     */
    function getSubscription(uint64 subId)
        external
        view
        returns (
            uint96 balance,
            uint64 reqCount,
            address owner,
            address[] memory consumers
        );

    /**
     * @notice Request subscription owner transfer.
     * @param subId - ID of the subscription
     * @param newOwner - proposed new owner of the subscription
     */
    function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner)
        external;

    /**
     * @notice Request subscription owner transfer.
     * @param subId - ID of the subscription
     * @dev will revert if original owner of subId has
     * not requested that msg.sender become the new owner.
     */
    function acceptSubscriptionOwnerTransfer(uint64 subId) external;

    /**
     * @notice Add a consumer to a VRF subscription.
     * @param subId - ID of the subscription
     * @param consumer - New consumer which can use the subscription
     */
    function addConsumer(uint64 subId, address consumer) external;

    /**
     * @notice Remove a consumer from a VRF subscription.
     * @param subId - ID of the subscription
     * @param consumer - Consumer to remove from the subscription
     */
    function removeConsumer(uint64 subId, address consumer) external;

    /**
     * @notice Cancel a subscription
     * @param subId - ID of the subscription
     * @param to - Where to send the remaining LINK to
     */
    function cancelSubscription(uint64 subId, address to) external;

    /*
     * @notice Check to see if there exists a request commitment consumers
     * for all consumers and keyhashes for a given sub.
     * @param subId - ID of the subscription
     * @return true if there exists at least one unfulfilled request for the subscription, false
     * otherwise.
     */
    function pendingRequestExists(uint64 subId) external view returns (bool);
}

contract RaffleWinnerNumberGenerator is VRFConsumerBaseV2 {
    mapping(uint256 => address) private rafflesHistory;
    mapping(address => uint256) public rafflesResults;
    mapping(address => uint256[]) private rafflesPlayerNumbers;
    uint256 public constant RAFFLE_IN_PROGRESS = 3200000;
    uint64 s_subscriptionId;

    VRFCoordinatorV2Interface COORDINATOR;
    error Unauthorized();

    address s_owner;
    uint32 numWords = 1;
    uint16 requestConfirmations = 3;
    uint32 callbackGasLimit = 40000;
    uint32 limitOfRequestedNumber;
    address vrfCoordinator = 0x271682DEB8C4E0901D1a1550aD2e64D568E69909;
    bytes32 s_keyHash =
        0xff8dedfbfa60af186cf3c830acbc32c05aae823045ae5ea7da1e45fbfaba4f92;

    event RaffleLaunched(
        uint256 indexed requestId,
        address indexed raffleOperatorAddress
    );
    event RaffleLanded(
        uint256 indexed requestId,
        address indexed raffleOperatorAddress,
        uint256 indexed result
    );

    modifier onlyOwner() {
        require(msg.sender == s_owner, "You are not the owner");
        _;
    }

    modifier onlyIfRaffleRunning(address _raffleOperator) {
        bool isRaffleRunning = RaffleOperator(_raffleOperator).running();
        require(isRaffleRunning == true, "Raffle was finished");
        _;
    }

    constructor(address raffleManager, uint64 subscriptionId)
        VRFConsumerBaseV2(vrfCoordinator)
    {
        COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
        s_owner = raffleManager;
        s_subscriptionId = subscriptionId;
    }

    function getPlayerNumbers(address _raffleOperator)
        external
        view
        returns (uint256[] memory _currentRafflePlayerNumbers)
    {
        return rafflesPlayerNumbers[_raffleOperator];
    }

    function getRaffleWinnerNumber(address _raffleOperator)
        public
        view
        onlyOwner
        returns (uint256 _raffleWinnerNumber)
    {
        require(rafflesResults[_raffleOperator] != 0, "Raffle not subscribed");

        if (rafflesResults[_raffleOperator] == RAFFLE_IN_PROGRESS) {
            return RAFFLE_IN_PROGRESS;
        }

        return rafflesResults[_raffleOperator];
    }

    function setNewRafflePlayingSpot(
        address _raffleOperator,
        uint256 _playerNumber
    ) public returns (bool _success) {
        if (msg.sender != _raffleOperator) revert Unauthorized();

        rafflesPlayerNumbers[_raffleOperator].push(_playerNumber);
        return true;
    }

    function restartRaffle(address _raffleOperator)
        public
        onlyOwner
        returns (bool _raffleRestarted)
    {
        require(
            rafflesResults[_raffleOperator] != RAFFLE_IN_PROGRESS,
            "Raffle in progress"
        );
        rafflesResults[_raffleOperator] = 0;
        return true;
    }

    function launchRaffle(address _raffleOperator)
        public
        onlyOwner
        onlyIfRaffleRunning(_raffleOperator)
        returns (uint256 requestId)
    {
        require(rafflesResults[_raffleOperator] == 0, "Already drawn");
        // Will revert if subscription is not set and funded.

        RaffleOperator(_raffleOperator).setDateOfTheLaunch();
        requestId = COORDINATOR.requestRandomWords(
            s_keyHash,
            s_subscriptionId,
            requestConfirmations,
            callbackGasLimit,
            numWords
        );

        limitOfRequestedNumber = uint32(
            rafflesPlayerNumbers[_raffleOperator].length
        );
        rafflesHistory[requestId] = _raffleOperator;
        rafflesResults[_raffleOperator] = RAFFLE_IN_PROGRESS;

        emit RaffleLaunched(requestId, _raffleOperator);
    }

    function fulfillRandomWords(
        uint256 requestId,
        uint256[] memory randomNumbers
    ) internal override {
        uint256 positionOfWinnerNumber = (randomNumbers[0] %
            limitOfRequestedNumber) + 1;
        uint256 winnerNumber = rafflesPlayerNumbers[rafflesHistory[requestId]][
            positionOfWinnerNumber - 1
        ]; // Because zero counts
        rafflesResults[rafflesHistory[requestId]] = winnerNumber;
    }
}

File 9 of 9: VRFConsumerBaseV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness. It ensures 2 things:
 * @dev 1. The fulfillment came from the VRFCoordinator
 * @dev 2. The consumer contract implements fulfillRandomWords.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constructor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash). Create subscription, fund it
 * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface
 * @dev subscription management functions).
 * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations,
 * @dev callbackGasLimit, numWords),
 * @dev see (VRFCoordinatorInterface for a description of the arguments).
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomWords method.
 *
 * @dev The randomness argument to fulfillRandomWords is a set of random words
 * @dev generated from your requestId and the blockHash of the request.
 *
 * @dev If your contract could have concurrent requests open, you can use the
 * @dev requestId returned from requestRandomWords to track which response is associated
 * @dev with which randomness request.
 * @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ.
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request. It is for this reason that
 * @dev that you can signal to an oracle you'd like them to wait longer before
 * @dev responding to the request (however this is not enforced in the contract
 * @dev and so remains effective only in the case of unmodified oracle software).
 */
abstract contract VRFConsumerBaseV2 {
    error OnlyCoordinatorCanFulfill(address have, address want);
    address private immutable vrfCoordinator;

    /**
     * @param _vrfCoordinator address of VRFCoordinator contract
     */
    constructor(address _vrfCoordinator) {
        vrfCoordinator = _vrfCoordinator;
    }

    /**
     * @notice fulfillRandomness handles the VRF response. Your contract must
     * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
     * @notice principles to keep in mind when implementing your fulfillRandomness
     * @notice method.
     *
     * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this
     * @dev signature, and will call it once it has verified the proof
     * @dev associated with the randomness. (It is triggered via a call to
     * @dev rawFulfillRandomness, below.)
     *
     * @param requestId The Id initially returned by requestRandomness
     * @param randomWords the VRF output expanded to the requested number of words
     */
    function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords)
        internal
        virtual;

    // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
    // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
    // the origin of the call
    function rawFulfillRandomWords(
        uint256 requestId,
        uint256[] memory randomWords
    ) external {
        if (msg.sender != vrfCoordinator) {
            revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator);
        }
        fulfillRandomWords(requestId, randomWords);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_USDC","type":"address"},{"internalType":"uint256","name":"_dateOfDraw","type":"uint256"},{"internalType":"address","name":"_raffleMegaVault","type":"address"},{"internalType":"string","name":"_raffleName","type":"string"},{"internalType":"uint16","name":"_minNumberOfPlayers","type":"uint16"},{"internalType":"uint16","name":"_maxNumberOfPlayers","type":"uint16"},{"internalType":"string","name":"_raffleSymbol","type":"string"},{"internalType":"uint16","name":"_percentageOfPrizeToOperator","type":"uint16"},{"internalType":"uint256","name":"_priceOfTheRaffleTicketInUSDC","type":"uint256"},{"internalType":"address","name":"_raffleWinnerNumberGeneratorAddress","type":"address"},{"internalType":"address","name":"_raffleCashier","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"LogActualOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bool","name":"switchSetting","type":"bool"}],"name":"LogRunSwitch","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":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountToBuyTickets","type":"uint256"},{"internalType":"uint256[]","name":"_raffleTicketIds","type":"uint256[]"},{"internalType":"string[]","name":"_raffleTicketTokenURIs","type":"string[]"},{"internalType":"address","name":"_tokenToUseToBuyTickets","type":"address"}],"name":"buyTicketsToPlay","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"currentSpotsBought","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dateOfDraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"drawLaunchedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentSpotsBought","outputs":[{"internalType":"uint256[]","name":"_currentSpotsBought","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addressToCheck","type":"address"}],"name":"getIfAddressPlay","outputs":[{"internalType":"bool","name":"_addressPlay","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRaffleTicketBuyers","outputs":[{"internalType":"address payable[]","name":"_raffleBuyers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRaffleTicketOwners","outputs":[{"internalType":"address[]","name":"_ticketOwners","type":"address[]"},{"internalType":"uint256[]","name":"_currentRafflePlayerNumbers","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleSpotToSearch","type":"uint256"}],"name":"getRaffleTicketPlayerBySpotTicketId","outputs":[{"internalType":"address","name":"_rafflePlayerBySpotTicketId","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTicketBuyer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxNumberOfPlayers","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minNumberOfPlayers","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentageOfPrizeToOperator","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceOfTheRaffleTicketInUSDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prizeClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"raffleCostsDeliveredToOperator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"raffleMegaVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rafflePotPrizeDeliveredToWinner","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"raffleTotalPrize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"raffleWinnerPlayer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"raffleWinnerPositionNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"returnMoneyToOwners","outputs":[{"internalType":"bool","name":"_raffleIsFinished","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"onOff","type":"bool"}],"name":"runSwitch","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"running","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setDateOfTheLaunch","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleWinnerNumber","type":"uint256"}],"name":"setRaffleWinner","outputs":[{"internalType":"bool","name":"_raffleIsFinished","type":"bool"}],"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":"","type":"uint256"}],"name":"ticketBuyers","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xPresidentsVaultAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60a06040523480156200001157600080fd5b5060405162003a3c38038062003a3c8339810160408190526200003491620002e1565b6000805460ff60a01b1933166001600160a81b031990911617600160a01b1790558751889086906200006e9060019060208501906200013e565b508051620000849060029060208401906200013e565b5050506001600160a01b039a8b1660805260008054336001600160a01b0319918216811790925560089b909b55600b80548c169a8d169a909a17909955600d805463ffffffff60a01b1916600160a01b61ffff998a160261ffff60b01b191617600160b01b9789169790970296909617909555601880548a16909817909755601780548916948a16949094179093556012805461ffff19169190941617909255601355505060198054909216921691909117905562000426565b8280546200014c90620003ea565b90600052602060002090601f016020900481019282620001705760008555620001bb565b82601f106200018b57805160ff1916838001178555620001bb565b82800160010185558215620001bb579182015b82811115620001bb5782518255916020019190600101906200019e565b50620001c9929150620001cd565b5090565b5b80821115620001c95760008155600101620001ce565b80516001600160a01b0381168114620001fc57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200022957600080fd5b81516001600160401b038082111562000246576200024662000201565b604051601f8301601f19908116603f0116810190828211818310171562000271576200027162000201565b816040528381526020925086838588010111156200028e57600080fd5b600091505b83821015620002b2578582018301518183018401529082019062000293565b83821115620002c45760008385830101525b9695505050505050565b805161ffff81168114620001fc57600080fd5b60008060008060008060008060008060006101608c8e0312156200030457600080fd5b6200030f8c620001e4565b9a5060208c015199506200032660408d01620001e4565b60608d01519099506001600160401b038111156200034357600080fd5b620003518e828f0162000217565b9850506200036260808d01620002ce565b96506200037260a08d01620002ce565b60c08d01519096506001600160401b038111156200038f57600080fd5b6200039d8e828f0162000217565b955050620003ae60e08d01620002ce565b93506101008c01519250620003c76101208d01620001e4565b9150620003d86101408d01620001e4565b90509295989b509295989b9093969950565b600181811c90821680620003ff57607f821691505b6020821081036200042057634e487b7160e01b600052602260045260246000fd5b50919050565b6080516135a6620004966000396000818161058301528181610d6901528181610fe70152818161120501528181611281015281816113810152818161150a01528181611670015281816120fc0152818161219d015281816122480152818161235c01526123ae01526135a66000f3fe60806040526004361061025c5760003560e01c806389a3027111610144578063b7e8575c116100b6578063e47fd4c51161007a578063e47fd4c514610745578063e985e9c514610765578063ece4d76814610785578063f3d5ae881461079a578063f99f5f80146107b0578063fdc4b149146107c657600080fd5b8063b7e8575c146106ae578063b88d4fde146106c4578063c87b56dd146106e4578063ce010ba314610704578063d85bd5261461072457600080fd5b806395d89b411161010857806395d89b411461060857806398473a661461061d5780639e2d7df81461063d578063a22cb4651461065d578063b57c15741461067d578063b6444c821461069357600080fd5b806389a30271146105715780638da5cb5b146105a55780639042bbf3146105c557806393962966146105df57806395c3ef57146105f257600080fd5b80633e7e31d1116101dd5780636352211e116101a15780636352211e1461049d5780636730e7e8146104bd57806370a08231146104df578063728fdffa146104ff5780637607e692146105215780637b5ab0db1461054157600080fd5b80633e7e31d1146103d957806342842e0e1461040e57806342c9443d1461042e57806355273ea3146104665780635f90071c1461047b57600080fd5b806323b872dd1161022457806323b872dd146103365780632561837a1461035657806326ae9c2b146103765780632dd97058146103995780633a23ef81146103b957600080fd5b806301ffc9a71461026157806303f514181461029657806306fdde03146102ba578063081812fc146102dc578063095ea7b314610314575b600080fd5b34801561026d57600080fd5b5061028161027c366004612b07565b6107dc565b60405190151581526020015b60405180910390f35b3480156102a257600080fd5b506102ac600c5481565b60405190815260200161028d565b3480156102c657600080fd5b506102cf61082e565b60405161028d9190612b7c565b3480156102e857600080fd5b506102fc6102f7366004612b8f565b6108c0565b6040516001600160a01b03909116815260200161028d565b34801561032057600080fd5b5061033461032f366004612bc8565b61094d565b005b34801561034257600080fd5b50610334610351366004612bf4565b610a62565b34801561036257600080fd5b506102ac610371366004612b8f565b610abc565b34801561038257600080fd5b5061038b610add565b60405161028d929190612c70565b3480156103a557600080fd5b506102816103b4366004612cde565b610c07565b3480156103c557600080fd5b50600d546102fc906001600160a01b031681565b3480156103e557600080fd5b50600d546103fb90600160a01b900461ffff1681565b60405161ffff909116815260200161028d565b34801561041a57600080fd5b50610334610429366004612bf4565b610ca8565b34801561043a57600080fd5b50610281610449366004612cfb565b6001600160a01b0316600090815260046020526040902054151590565b34801561047257600080fd5b50610281610cec565b34801561048757600080fd5b50610490610db6565b60405161028d9190612d18565b3480156104a957600080fd5b506102fc6104b8366004612b8f565b610e17565b3480156104c957600080fd5b506104d2610e8e565b60405161028d9190612d65565b3480156104eb57600080fd5b506102ac6104fa366004612cfb565b610ee5565b34801561050b57600080fd5b50600d546103fb90600160b01b900461ffff1681565b34801561052d57600080fd5b5061028161053c366004612b8f565b610f6c565b34801561054d57600080fd5b5061028161055c366004612cfb565b60156020526000908152604090205460ff1681565b34801561057d57600080fd5b506102fc7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105b157600080fd5b506000546102fc906001600160a01b031681565b3480156105d157600080fd5b506009546102819060ff1681565b6102816105ed366004612ee0565b61108c565b3480156105fe57600080fd5b506102ac60165481565b34801561061457600080fd5b506102cf6119f4565b34801561062957600080fd5b506102fc610638366004612b8f565b611a03565b34801561064957600080fd5b50600b546102fc906001600160a01b031681565b34801561066957600080fd5b50610334610678366004612fb5565b611a0e565b34801561068957600080fd5b506102ac60115481565b34801561069f57600080fd5b506012546103fb9061ffff1681565b3480156106ba57600080fd5b506102ac600a5481565b3480156106d057600080fd5b506103346106df366004612fee565b611a1d565b3480156106f057600080fd5b506102cf6106ff366004612b8f565b611a55565b34801561071057600080fd5b506102fc61071f366004612b8f565b611bc3565b34801561073057600080fd5b5060005461028190600160a01b900460ff1681565b34801561075157600080fd5b506010546102fc906001600160a01b031681565b34801561077157600080fd5b5061028161078036600461306e565b611bed565b34801561079157600080fd5b50610281611c1b565b3480156107a657600080fd5b506102ac60085481565b3480156107bc57600080fd5b506102ac60135481565b3480156107d257600080fd5b506102ac60145481565b60006001600160e01b031982166380ac58cd60e01b148061080d57506001600160e01b03198216635b5e139f60e01b145b8061082857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606001805461083d9061309c565b80601f01602080910402602001604051908101604052809291908181526020018280546108699061309c565b80156108b65780601f1061088b576101008083540402835291602001916108b6565b820191906000526020600020905b81548152906001019060200180831161089957829003601f168201915b5050505050905090565b60006108cb82611c71565b6109315760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061095882610e17565b9050806001600160a01b0316836001600160a01b0316036109c55760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610928565b336001600160a01b03821614806109e157506109e18133611bed565b610a535760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610928565b610a5d8383611c8e565b505050565b600054600160a01b900460ff16610a8b5760405162461bcd60e51b8152600401610928906130d6565b610a953382611cfc565b610ab15760405162461bcd60e51b8152600401610928906130ff565b610a5d838383611dc5565b600e8181548110610acc57600080fd5b600091825260209091200154905081565b601954604051636e771d9560e11b815230600482015260609182916001600160a01b039091169063dcee3b2a90602401600060405180830381865afa158015610b2a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b529190810190613150565b9050805167ffffffffffffffff811115610b6e57610b6e612d78565b604051908082528060200260200182016040528015610b97578160200160208202803683370190505b50915060005b8151811015610c0257610bc8828281518110610bbb57610bbb6131e1565b6020026020010151610e17565b838281518110610bda57610bda6131e1565b6001600160a01b0390921660209283029190910190910152610bfb8161320d565b9050610b9d565b509091565b600080546001600160a01b03163314610c1f57600080fd5b600054600160a01b900460ff16610c485760405162461bcd60e51b8152600401610928906130d6565b6000805460ff60a01b1916600160a01b841515908102919091179091556040805133815260208101929092527fe149139e745b87d23672d6d1bd3f9160008dc717a946188ef8c5155e4ee6b845910160405180910390a15060015b919050565b600054600160a01b900460ff16610cd15760405162461bcd60e51b8152600401610928906130d6565b610a5d83838360405180602001604052806000815250611a1d565b600080546001600160a01b03163314610d0457600080fd5b600054600160a01b900460ff16610d2d5760405162461bcd60e51b8152600401610928906130d6565b60005b600e54811015610da2576000610d62600e8381548110610d5257610d526131e1565b9060005260206000200154610e17565b9050610d917f000000000000000000000000000000000000000000000000000000000000000082601354611f61565b50610d9b8161320d565b9050610d30565b50506000805460ff60a01b19169055600190565b6060600f8054806020026020016040519081016040528092919081815260200182805480156108b657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610df0575050505050905090565b6000818152600360205260408120546001600160a01b0316806108285760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610928565b6060600e8054806020026020016040519081016040528092919081815260200182805480156108b657602002820191906000526020600020905b815481526020019060010190808311610ec8575050505050905090565b60006001600160a01b038216610f505760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610928565b506001600160a01b031660009081526004602052604090205490565b600080546001600160a01b03163314610f8457600080fd5b600054600160a01b900460ff16610fad5760405162461bcd60e51b8152600401610928906130d6565b610fb682610e17565b600d80546001600160a01b0319166001600160a01b039283161790556040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015611030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110549190613226565b600c5561105f612092565b50600d54611075906001600160a01b03166122c3565b50506011556000805460ff60a01b19169055600190565b60008054600160a01b900460ff166110b65760405162461bcd60e51b8152600401610928906130d6565b426102586008546110c7919061323f565b10156111315760405162461bcd60e51b815260206004820152603360248201527f54686520627579696e67206f6620746865207469636b65747320666f7220746860448201527232903930b33336329034b99031b637b9b2b21760691b6064820152608401610928565b600d54600f54600160b01b90910461ffff16116111a35760405162461bcd60e51b815260206004820152602a60248201527f546865206d6178696d756d206e756d626572206f6620706c617965727320776160448201526939903932b0b1b432b21760b11b6064820152608401610928565b82518451146112035760405162461bcd60e51b815260206004820152602660248201527f746f6b656e49647320616e6420746f6b656e55524973206c656e677468206d696044820152650e6dac2e8c6d60d31b6064820152608401610928565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03160361141157601354845161124b9190613256565b85146112695760405162461bcd60e51b815260040161092890613275565b6040516370a0823160e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156112d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f49190613226565b905060135485516113059190613256565b8110156113675760405162461bcd60e51b815260206004820152602a60248201527f596f7520646f6e74206861766520555344432062616c616e636520746f2062756044820152693c903a34b1b5b2ba399760b11b6064820152608401610928565b601754604051636678ac0160e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152336024830152306044830152606482018990529091169063ccf15802906084016020604051808303816000875af11580156113e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140a91906132bd565b5050611739565b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611451573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147591906132da565b6040516370a0823160e01b815233600482015260ff9190911691506000906001600160a01b038516906370a0823190602401602060405180830381865afa1580156114c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e89190613226565b601754604051633d42e25d60e21b81526001600160a01b0387811660048301527f0000000000000000000000000000000000000000000000000000000000000000811660248301529293506000929091169063f50b897490604401602060405180830381865afa158015611560573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115849190613226565b9050600087518285600a61159891906133e1565b6115a3906001613256565b6013546115b09190613256565b6115ba9190613403565b6115c49190613256565b9050808910156115e65760405162461bcd60e51b815260040161092890613275565b8083101561164a5760405162461bcd60e51b815260206004820152602b60248201527f596f7520646f6e74206861766520746f6b656e2062616c616e636520746f206260448201526a3abc903a34b1b5b2ba399760a91b6064820152608401610928565b601760009054906101000a90046001600160a01b03166001600160a01b031663550a4a397f000000000000000000000000000000000000000000000000000000000000000033308a8e6013548f516116a29190613256565b6040516001600160e01b031960e089901b1681526001600160a01b0396871660048201529486166024860152928516604485015293166064830152608482019290925260a481019190915260c4016020604051808303816000875af115801561170f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173391906132bd565b50505050505b60005b84518110156119e657848181518110611757576117576131e1565b60200260200101516000036117c55760405162461bcd60e51b815260206004820152602e60248201527f416c6c20746865207469636b6574206964732068617320746f2062652064696660448201526d3332b932b73a10333937b690181760911b6064820152608401610928565b600d60169054906101000a900461ffff1661ffff168582815181106117ec576117ec6131e1565b602002602001015111156118605760405162461bcd60e51b815260206004820152603560248201527f5469636b6574732063616e6e6f742062652067726561746572207468616e2074604482015274343290373ab6b132b91037b310383630bcb2b9399760591b6064820152608401610928565b61189d33868381518110611876576118766131e1565b6020026020010151868481518110611890576118906131e1565b602002602001015161244b565b5060195485516001600160a01b0390911690631d09da469030908890859081106118c9576118c96131e1565b60200260200101516040518363ffffffff1660e01b81526004016119029291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015611921573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194591906132bd565b50600f805460018181019092557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180546001600160a01b031916339081179091556000908152601560205260409020805460ff191690911790558451600e908690839081106119b7576119b76131e1565b602090810291909101810151825460018101845560009384529190922001556119df8161320d565b905061173c565b50600190505b949350505050565b60606002805461083d9061309c565b600061082882610e17565b611a193383836124bf565b5050565b611a273383611cfc565b611a435760405162461bcd60e51b8152600401610928906130ff565b611a4f8484848461258d565b50505050565b6060611a6082611c71565b611ac65760405162461bcd60e51b815260206004820152603160248201527f45524337323155524953746f726167653a2055524920717565727920666f72206044820152703737b732bc34b9ba32b73a103a37b5b2b760791b6064820152608401610928565b60008281526007602052604081208054611adf9061309c565b80601f0160208091040260200160405190810160405280929190818152602001828054611b0b9061309c565b8015611b585780601f10611b2d57610100808354040283529160200191611b58565b820191906000526020600020905b815481529060010190602001808311611b3b57829003601f168201915b505050505090506000611b7660408051602081019091526000815290565b90508051600003611b88575092915050565b815115611bba578082604051602001611ba2929190613417565b60405160208183030381529060405292505050919050565b6119ec846125c0565b600f8181548110611bd357600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b6019546000906001600160a01b03163314611c675760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b6044820152606401610928565b5042600a55600190565b6000908152600360205260409020546001600160a01b0316151590565b600081815260056020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611cc382610e17565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d0782611c71565b611d685760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610928565b6000611d7383610e17565b9050806001600160a01b0316846001600160a01b03161480611d9a5750611d9a8185611bed565b806119ec5750836001600160a01b0316611db3846108c0565b6001600160a01b031614949350505050565b826001600160a01b0316611dd882610e17565b6001600160a01b031614611e3c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610928565b6001600160a01b038216611e9e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610928565b611ea9600082611c8e565b6001600160a01b0383166000908152600460205260408120805460019290611ed290849061323f565b90915550506001600160a01b0382166000908152600460205260408120805460019290611f00908490613446565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611fbd919061345e565b6000604051808303816000865af19150503d8060008114611ffa576040519150601f19603f3d011682016040523d82523d6000602084013e611fff565b606091505b509150915081801561202957508051158061202957508080602001905181019061202991906132bd565b61208b5760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b6064820152608401610928565b5050505050565b601254600c546000916064916120ac9161ffff1690613256565b6120b69190613403565b60148190556000906064906120cc906055613256565b6120d69190613403565b905060006064601454600f6120eb9190613256565b6120f59190613403565b90506121987f0000000000000000000000000000000000000000000000000000000000000000601860009054906101000a90046001600160a01b03166001600160a01b031663462f2e746040518163ffffffff1660e01b8152600401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612192919061347a565b84611f61565b6122437f0000000000000000000000000000000000000000000000000000000000000000601860009054906101000a90046001600160a01b03166001600160a01b031663c5f956af6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561220f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612233919061347a565b61223e600285613403565b611f61565b6122ba7f0000000000000000000000000000000000000000000000000000000000000000601860009054906101000a90046001600160a01b03166001600160a01b031663e47fd4c56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561220f573d6000803e3d6000fd5b60019250505090565b60095460009060ff16156123195760405162461bcd60e51b815260206004820152601e60248201527f546865207072697a652077617320616c726561647920636c61696d65642e00006044820152606401610928565b60125460009061232e9061ffff166064613497565b905060648161ffff16600c546123449190613256565b61234e9190613403565b601681905560175461238b917f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b031690611f61565b60175460165460405163c42fbc0b60e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301528681166044830152606482019290925291169063c42fbc0b906084016020604051808303816000875af115801561240f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243391906132bd565b50506009805460ff1916600190811790915592915050565b600061245683611c71565b156124a35760405162461bcd60e51b815260206004820152601e60248201527f526166666c65207469636b657420696420616c726561647920736f6c642e00006044820152606401610928565b6124ad8484612698565b6124b783836127cb565b509092915050565b816001600160a01b0316836001600160a01b0316036125205760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610928565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612598848484611dc5565b6125a484848484612856565b611a4f5760405162461bcd60e51b8152600401610928906134ba565b60606125cb82611c71565b61262f5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610928565b600061264660408051602081019091526000815290565b905060008151116126665760405180602001604052806000815250612691565b8061267084612954565b604051602001612681929190613417565b6040516020818303038152906040525b9392505050565b6001600160a01b0382166126ee5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610928565b6126f781611c71565b156127445760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610928565b6001600160a01b038216600090815260046020526040812080546001929061276d908490613446565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6127d482611c71565b6128375760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610928565b60008281526007602090815260409091208251610a5d92840190612a55565b60006001600160a01b0384163b1561294c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061289a90339089908890889060040161350c565b6020604051808303816000875af19250505080156128d5575060408051601f3d908101601f191682019092526128d29181019061353f565b60015b612932573d808015612903576040519150601f19603f3d011682016040523d82523d6000602084013e612908565b606091505b50805160000361292a5760405162461bcd60e51b8152600401610928906134ba565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506119ec565b5060016119ec565b60608160000361297b5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156129a5578061298f8161320d565b915061299e9050600a83613403565b915061297f565b60008167ffffffffffffffff8111156129c0576129c0612d78565b6040519080825280601f01601f1916602001820160405280156129ea576020820181803683370190505b5090505b84156119ec576129ff60018361323f565b9150612a0c600a8661355c565b612a17906030613446565b60f81b818381518110612a2c57612a2c6131e1565b60200101906001600160f81b031916908160001a905350612a4e600a86613403565b94506129ee565b828054612a619061309c565b90600052602060002090601f016020900481019282612a835760008555612ac9565b82601f10612a9c57805160ff1916838001178555612ac9565b82800160010185558215612ac9579182015b82811115612ac9578251825591602001919060010190612aae565b50612ad5929150612ad9565b5090565b5b80821115612ad55760008155600101612ada565b6001600160e01b031981168114612b0457600080fd5b50565b600060208284031215612b1957600080fd5b813561269181612aee565b60005b83811015612b3f578181015183820152602001612b27565b83811115611a4f5750506000910152565b60008151808452612b68816020860160208601612b24565b601f01601f19169290920160200192915050565b6020815260006126916020830184612b50565b600060208284031215612ba157600080fd5b5035919050565b6001600160a01b0381168114612b0457600080fd5b8035610ca381612ba8565b60008060408385031215612bdb57600080fd5b8235612be681612ba8565b946020939093013593505050565b600080600060608486031215612c0957600080fd5b8335612c1481612ba8565b92506020840135612c2481612ba8565b929592945050506040919091013590565b600081518084526020808501945080840160005b83811015612c6557815187529582019590820190600101612c49565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b82811015612cb25781516001600160a01b031684529284019290840190600101612c8d565b50505083810382850152612cc68186612c35565b9695505050505050565b8015158114612b0457600080fd5b600060208284031215612cf057600080fd5b813561269181612cd0565b600060208284031215612d0d57600080fd5b813561269181612ba8565b6020808252825182820181905260009190848201906040850190845b81811015612d595783516001600160a01b031683529284019291840191600101612d34565b50909695505050505050565b6020815260006126916020830184612c35565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612db757612db7612d78565b604052919050565b600067ffffffffffffffff821115612dd957612dd9612d78565b5060051b60200190565b600067ffffffffffffffff831115612dfd57612dfd612d78565b612e10601f8401601f1916602001612d8e565b9050828152838383011115612e2457600080fd5b828260208301376000602084830101529392505050565b600082601f830112612e4c57600080fd5b81356020612e61612e5c83612dbf565b612d8e565b82815260059290921b84018101918181019086841115612e8057600080fd5b8286015b84811015612ed557803567ffffffffffffffff811115612ea45760008081fd5b8701603f81018913612eb65760008081fd5b612ec7898683013560408401612de3565b845250918301918301612e84565b509695505050505050565b60008060008060808587031215612ef657600080fd5b8435935060208086013567ffffffffffffffff80821115612f1657600080fd5b818801915088601f830112612f2a57600080fd5b8135612f38612e5c82612dbf565b81815260059190911b8301840190848101908b831115612f5757600080fd5b938501935b82851015612f7557843582529385019390850190612f5c565b975050506040880135925080831115612f8d57600080fd5b5050612f9b87828801612e3b565b925050612faa60608601612bbd565b905092959194509250565b60008060408385031215612fc857600080fd5b8235612fd381612ba8565b91506020830135612fe381612cd0565b809150509250929050565b6000806000806080858703121561300457600080fd5b843561300f81612ba8565b9350602085013561301f81612ba8565b925060408501359150606085013567ffffffffffffffff81111561304257600080fd5b8501601f8101871361305357600080fd5b61306287823560208401612de3565b91505092959194509250565b6000806040838503121561308157600080fd5b823561308c81612ba8565b91506020830135612fe381612ba8565b600181811c908216806130b057607f821691505b6020821081036130d057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600f908201526e24b9903737ba10393ab73734b7339760891b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000602080838503121561316357600080fd5b825167ffffffffffffffff81111561317a57600080fd5b8301601f8101851361318b57600080fd5b8051613199612e5c82612dbf565b81815260059190911b820183019083810190878311156131b857600080fd5b928401925b828410156131d6578351825292840192908401906131bd565b979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161321f5761321f6131f7565b5060010190565b60006020828403121561323857600080fd5b5051919050565b600082821015613251576132516131f7565b500390565b6000816000190483118215151615613270576132706131f7565b500290565b60208082526028908201527f54686520616d6f756e7420746f20627579207469636b6574206973206e6f742060408201526731b7b93932b1ba1760c11b606082015260800190565b6000602082840312156132cf57600080fd5b815161269181612cd0565b6000602082840312156132ec57600080fd5b815160ff8116811461269157600080fd5b600181815b8085111561333857816000190482111561331e5761331e6131f7565b8085161561332b57918102915b93841c9390800290613302565b509250929050565b60008261334f57506001610828565b8161335c57506000610828565b8160018114613372576002811461337c57613398565b6001915050610828565b60ff84111561338d5761338d6131f7565b50506001821b610828565b5060208310610133831016604e8410600b84101617156133bb575081810a610828565b6133c583836132fd565b80600019048211156133d9576133d96131f7565b029392505050565b60006126918383613340565b634e487b7160e01b600052601260045260246000fd5b600082613412576134126133ed565b500490565b60008351613429818460208801612b24565b83519083019061343d818360208801612b24565b01949350505050565b60008219821115613459576134596131f7565b500190565b60008251613470818460208701612b24565b9190910192915050565b60006020828403121561348c57600080fd5b815161269181612ba8565b600061ffff838116908316818110156134b2576134b26131f7565b039392505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612cc690830184612b50565b60006020828403121561355157600080fd5b815161269181612aee565b60008261356b5761356b6133ed565b50069056fea26469706673582212202dc58dda23aa48723de586106ab821c373660f0848be0a0aa260d485ddeabed864736f6c634300080e0033000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000636ea9c00000000000000000000000001571beabd5e4eec540bc827e7827fe443c7d91ff00000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000001e84800000000000000000000000009f0b3aa5d8cbac649494f36700f5d17660a168fd000000000000000000000000e10ce8b28e91bcdc7c642c4a5af8b7c117f02bfc000000000000000000000000000000000000000000000000000000000000000b524146464c4520544553540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012464d4f4e2d56312d313636383139363830300000000000000000000000000000

Deployed Bytecode

0x60806040526004361061025c5760003560e01c806389a3027111610144578063b7e8575c116100b6578063e47fd4c51161007a578063e47fd4c514610745578063e985e9c514610765578063ece4d76814610785578063f3d5ae881461079a578063f99f5f80146107b0578063fdc4b149146107c657600080fd5b8063b7e8575c146106ae578063b88d4fde146106c4578063c87b56dd146106e4578063ce010ba314610704578063d85bd5261461072457600080fd5b806395d89b411161010857806395d89b411461060857806398473a661461061d5780639e2d7df81461063d578063a22cb4651461065d578063b57c15741461067d578063b6444c821461069357600080fd5b806389a30271146105715780638da5cb5b146105a55780639042bbf3146105c557806393962966146105df57806395c3ef57146105f257600080fd5b80633e7e31d1116101dd5780636352211e116101a15780636352211e1461049d5780636730e7e8146104bd57806370a08231146104df578063728fdffa146104ff5780637607e692146105215780637b5ab0db1461054157600080fd5b80633e7e31d1146103d957806342842e0e1461040e57806342c9443d1461042e57806355273ea3146104665780635f90071c1461047b57600080fd5b806323b872dd1161022457806323b872dd146103365780632561837a1461035657806326ae9c2b146103765780632dd97058146103995780633a23ef81146103b957600080fd5b806301ffc9a71461026157806303f514181461029657806306fdde03146102ba578063081812fc146102dc578063095ea7b314610314575b600080fd5b34801561026d57600080fd5b5061028161027c366004612b07565b6107dc565b60405190151581526020015b60405180910390f35b3480156102a257600080fd5b506102ac600c5481565b60405190815260200161028d565b3480156102c657600080fd5b506102cf61082e565b60405161028d9190612b7c565b3480156102e857600080fd5b506102fc6102f7366004612b8f565b6108c0565b6040516001600160a01b03909116815260200161028d565b34801561032057600080fd5b5061033461032f366004612bc8565b61094d565b005b34801561034257600080fd5b50610334610351366004612bf4565b610a62565b34801561036257600080fd5b506102ac610371366004612b8f565b610abc565b34801561038257600080fd5b5061038b610add565b60405161028d929190612c70565b3480156103a557600080fd5b506102816103b4366004612cde565b610c07565b3480156103c557600080fd5b50600d546102fc906001600160a01b031681565b3480156103e557600080fd5b50600d546103fb90600160a01b900461ffff1681565b60405161ffff909116815260200161028d565b34801561041a57600080fd5b50610334610429366004612bf4565b610ca8565b34801561043a57600080fd5b50610281610449366004612cfb565b6001600160a01b0316600090815260046020526040902054151590565b34801561047257600080fd5b50610281610cec565b34801561048757600080fd5b50610490610db6565b60405161028d9190612d18565b3480156104a957600080fd5b506102fc6104b8366004612b8f565b610e17565b3480156104c957600080fd5b506104d2610e8e565b60405161028d9190612d65565b3480156104eb57600080fd5b506102ac6104fa366004612cfb565b610ee5565b34801561050b57600080fd5b50600d546103fb90600160b01b900461ffff1681565b34801561052d57600080fd5b5061028161053c366004612b8f565b610f6c565b34801561054d57600080fd5b5061028161055c366004612cfb565b60156020526000908152604090205460ff1681565b34801561057d57600080fd5b506102fc7f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec781565b3480156105b157600080fd5b506000546102fc906001600160a01b031681565b3480156105d157600080fd5b506009546102819060ff1681565b6102816105ed366004612ee0565b61108c565b3480156105fe57600080fd5b506102ac60165481565b34801561061457600080fd5b506102cf6119f4565b34801561062957600080fd5b506102fc610638366004612b8f565b611a03565b34801561064957600080fd5b50600b546102fc906001600160a01b031681565b34801561066957600080fd5b50610334610678366004612fb5565b611a0e565b34801561068957600080fd5b506102ac60115481565b34801561069f57600080fd5b506012546103fb9061ffff1681565b3480156106ba57600080fd5b506102ac600a5481565b3480156106d057600080fd5b506103346106df366004612fee565b611a1d565b3480156106f057600080fd5b506102cf6106ff366004612b8f565b611a55565b34801561071057600080fd5b506102fc61071f366004612b8f565b611bc3565b34801561073057600080fd5b5060005461028190600160a01b900460ff1681565b34801561075157600080fd5b506010546102fc906001600160a01b031681565b34801561077157600080fd5b5061028161078036600461306e565b611bed565b34801561079157600080fd5b50610281611c1b565b3480156107a657600080fd5b506102ac60085481565b3480156107bc57600080fd5b506102ac60135481565b3480156107d257600080fd5b506102ac60145481565b60006001600160e01b031982166380ac58cd60e01b148061080d57506001600160e01b03198216635b5e139f60e01b145b8061082857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606001805461083d9061309c565b80601f01602080910402602001604051908101604052809291908181526020018280546108699061309c565b80156108b65780601f1061088b576101008083540402835291602001916108b6565b820191906000526020600020905b81548152906001019060200180831161089957829003601f168201915b5050505050905090565b60006108cb82611c71565b6109315760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061095882610e17565b9050806001600160a01b0316836001600160a01b0316036109c55760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610928565b336001600160a01b03821614806109e157506109e18133611bed565b610a535760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610928565b610a5d8383611c8e565b505050565b600054600160a01b900460ff16610a8b5760405162461bcd60e51b8152600401610928906130d6565b610a953382611cfc565b610ab15760405162461bcd60e51b8152600401610928906130ff565b610a5d838383611dc5565b600e8181548110610acc57600080fd5b600091825260209091200154905081565b601954604051636e771d9560e11b815230600482015260609182916001600160a01b039091169063dcee3b2a90602401600060405180830381865afa158015610b2a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b529190810190613150565b9050805167ffffffffffffffff811115610b6e57610b6e612d78565b604051908082528060200260200182016040528015610b97578160200160208202803683370190505b50915060005b8151811015610c0257610bc8828281518110610bbb57610bbb6131e1565b6020026020010151610e17565b838281518110610bda57610bda6131e1565b6001600160a01b0390921660209283029190910190910152610bfb8161320d565b9050610b9d565b509091565b600080546001600160a01b03163314610c1f57600080fd5b600054600160a01b900460ff16610c485760405162461bcd60e51b8152600401610928906130d6565b6000805460ff60a01b1916600160a01b841515908102919091179091556040805133815260208101929092527fe149139e745b87d23672d6d1bd3f9160008dc717a946188ef8c5155e4ee6b845910160405180910390a15060015b919050565b600054600160a01b900460ff16610cd15760405162461bcd60e51b8152600401610928906130d6565b610a5d83838360405180602001604052806000815250611a1d565b600080546001600160a01b03163314610d0457600080fd5b600054600160a01b900460ff16610d2d5760405162461bcd60e51b8152600401610928906130d6565b60005b600e54811015610da2576000610d62600e8381548110610d5257610d526131e1565b9060005260206000200154610e17565b9050610d917f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec782601354611f61565b50610d9b8161320d565b9050610d30565b50506000805460ff60a01b19169055600190565b6060600f8054806020026020016040519081016040528092919081815260200182805480156108b657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610df0575050505050905090565b6000818152600360205260408120546001600160a01b0316806108285760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610928565b6060600e8054806020026020016040519081016040528092919081815260200182805480156108b657602002820191906000526020600020905b815481526020019060010190808311610ec8575050505050905090565b60006001600160a01b038216610f505760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610928565b506001600160a01b031660009081526004602052604090205490565b600080546001600160a01b03163314610f8457600080fd5b600054600160a01b900460ff16610fad5760405162461bcd60e51b8152600401610928906130d6565b610fb682610e17565b600d80546001600160a01b0319166001600160a01b039283161790556040516370a0823160e01b81523060048201527f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7909116906370a0823190602401602060405180830381865afa158015611030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110549190613226565b600c5561105f612092565b50600d54611075906001600160a01b03166122c3565b50506011556000805460ff60a01b19169055600190565b60008054600160a01b900460ff166110b65760405162461bcd60e51b8152600401610928906130d6565b426102586008546110c7919061323f565b10156111315760405162461bcd60e51b815260206004820152603360248201527f54686520627579696e67206f6620746865207469636b65747320666f7220746860448201527232903930b33336329034b99031b637b9b2b21760691b6064820152608401610928565b600d54600f54600160b01b90910461ffff16116111a35760405162461bcd60e51b815260206004820152602a60248201527f546865206d6178696d756d206e756d626572206f6620706c617965727320776160448201526939903932b0b1b432b21760b11b6064820152608401610928565b82518451146112035760405162461bcd60e51b815260206004820152602660248201527f746f6b656e49647320616e6420746f6b656e55524973206c656e677468206d696044820152650e6dac2e8c6d60d31b6064820152608401610928565b7f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec76001600160a01b0316826001600160a01b03160361141157601354845161124b9190613256565b85146112695760405162461bcd60e51b815260040161092890613275565b6040516370a0823160e01b81523360048201526000907f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec76001600160a01b0316906370a0823190602401602060405180830381865afa1580156112d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f49190613226565b905060135485516113059190613256565b8110156113675760405162461bcd60e51b815260206004820152602a60248201527f596f7520646f6e74206861766520555344432062616c616e636520746f2062756044820152693c903a34b1b5b2ba399760b11b6064820152608401610928565b601754604051636678ac0160e11b81526001600160a01b037f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec781166004830152336024830152306044830152606482018990529091169063ccf15802906084016020604051808303816000875af11580156113e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140a91906132bd565b5050611739565b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611451573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147591906132da565b6040516370a0823160e01b815233600482015260ff9190911691506000906001600160a01b038516906370a0823190602401602060405180830381865afa1580156114c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e89190613226565b601754604051633d42e25d60e21b81526001600160a01b0387811660048301527f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7811660248301529293506000929091169063f50b897490604401602060405180830381865afa158015611560573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115849190613226565b9050600087518285600a61159891906133e1565b6115a3906001613256565b6013546115b09190613256565b6115ba9190613403565b6115c49190613256565b9050808910156115e65760405162461bcd60e51b815260040161092890613275565b8083101561164a5760405162461bcd60e51b815260206004820152602b60248201527f596f7520646f6e74206861766520746f6b656e2062616c616e636520746f206260448201526a3abc903a34b1b5b2ba399760a91b6064820152608401610928565b601760009054906101000a90046001600160a01b03166001600160a01b031663550a4a397f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec733308a8e6013548f516116a29190613256565b6040516001600160e01b031960e089901b1681526001600160a01b0396871660048201529486166024860152928516604485015293166064830152608482019290925260a481019190915260c4016020604051808303816000875af115801561170f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173391906132bd565b50505050505b60005b84518110156119e657848181518110611757576117576131e1565b60200260200101516000036117c55760405162461bcd60e51b815260206004820152602e60248201527f416c6c20746865207469636b6574206964732068617320746f2062652064696660448201526d3332b932b73a10333937b690181760911b6064820152608401610928565b600d60169054906101000a900461ffff1661ffff168582815181106117ec576117ec6131e1565b602002602001015111156118605760405162461bcd60e51b815260206004820152603560248201527f5469636b6574732063616e6e6f742062652067726561746572207468616e2074604482015274343290373ab6b132b91037b310383630bcb2b9399760591b6064820152608401610928565b61189d33868381518110611876576118766131e1565b6020026020010151868481518110611890576118906131e1565b602002602001015161244b565b5060195485516001600160a01b0390911690631d09da469030908890859081106118c9576118c96131e1565b60200260200101516040518363ffffffff1660e01b81526004016119029291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015611921573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194591906132bd565b50600f805460018181019092557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180546001600160a01b031916339081179091556000908152601560205260409020805460ff191690911790558451600e908690839081106119b7576119b76131e1565b602090810291909101810151825460018101845560009384529190922001556119df8161320d565b905061173c565b50600190505b949350505050565b60606002805461083d9061309c565b600061082882610e17565b611a193383836124bf565b5050565b611a273383611cfc565b611a435760405162461bcd60e51b8152600401610928906130ff565b611a4f8484848461258d565b50505050565b6060611a6082611c71565b611ac65760405162461bcd60e51b815260206004820152603160248201527f45524337323155524953746f726167653a2055524920717565727920666f72206044820152703737b732bc34b9ba32b73a103a37b5b2b760791b6064820152608401610928565b60008281526007602052604081208054611adf9061309c565b80601f0160208091040260200160405190810160405280929190818152602001828054611b0b9061309c565b8015611b585780601f10611b2d57610100808354040283529160200191611b58565b820191906000526020600020905b815481529060010190602001808311611b3b57829003601f168201915b505050505090506000611b7660408051602081019091526000815290565b90508051600003611b88575092915050565b815115611bba578082604051602001611ba2929190613417565b60405160208183030381529060405292505050919050565b6119ec846125c0565b600f8181548110611bd357600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b6019546000906001600160a01b03163314611c675760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b6044820152606401610928565b5042600a55600190565b6000908152600360205260409020546001600160a01b0316151590565b600081815260056020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611cc382610e17565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d0782611c71565b611d685760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610928565b6000611d7383610e17565b9050806001600160a01b0316846001600160a01b03161480611d9a5750611d9a8185611bed565b806119ec5750836001600160a01b0316611db3846108c0565b6001600160a01b031614949350505050565b826001600160a01b0316611dd882610e17565b6001600160a01b031614611e3c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610928565b6001600160a01b038216611e9e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610928565b611ea9600082611c8e565b6001600160a01b0383166000908152600460205260408120805460019290611ed290849061323f565b90915550506001600160a01b0382166000908152600460205260408120805460019290611f00908490613446565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611fbd919061345e565b6000604051808303816000865af19150503d8060008114611ffa576040519150601f19603f3d011682016040523d82523d6000602084013e611fff565b606091505b509150915081801561202957508051158061202957508080602001905181019061202991906132bd565b61208b5760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b6064820152608401610928565b5050505050565b601254600c546000916064916120ac9161ffff1690613256565b6120b69190613403565b60148190556000906064906120cc906055613256565b6120d69190613403565b905060006064601454600f6120eb9190613256565b6120f59190613403565b90506121987f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7601860009054906101000a90046001600160a01b03166001600160a01b031663462f2e746040518163ffffffff1660e01b8152600401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612192919061347a565b84611f61565b6122437f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7601860009054906101000a90046001600160a01b03166001600160a01b031663c5f956af6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561220f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612233919061347a565b61223e600285613403565b611f61565b6122ba7f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7601860009054906101000a90046001600160a01b03166001600160a01b031663e47fd4c56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561220f573d6000803e3d6000fd5b60019250505090565b60095460009060ff16156123195760405162461bcd60e51b815260206004820152601e60248201527f546865207072697a652077617320616c726561647920636c61696d65642e00006044820152606401610928565b60125460009061232e9061ffff166064613497565b905060648161ffff16600c546123449190613256565b61234e9190613403565b601681905560175461238b917f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7916001600160a01b031690611f61565b60175460165460405163c42fbc0b60e01b81523060048201526001600160a01b037f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7811660248301528681166044830152606482019290925291169063c42fbc0b906084016020604051808303816000875af115801561240f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243391906132bd565b50506009805460ff1916600190811790915592915050565b600061245683611c71565b156124a35760405162461bcd60e51b815260206004820152601e60248201527f526166666c65207469636b657420696420616c726561647920736f6c642e00006044820152606401610928565b6124ad8484612698565b6124b783836127cb565b509092915050565b816001600160a01b0316836001600160a01b0316036125205760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610928565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612598848484611dc5565b6125a484848484612856565b611a4f5760405162461bcd60e51b8152600401610928906134ba565b60606125cb82611c71565b61262f5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610928565b600061264660408051602081019091526000815290565b905060008151116126665760405180602001604052806000815250612691565b8061267084612954565b604051602001612681929190613417565b6040516020818303038152906040525b9392505050565b6001600160a01b0382166126ee5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610928565b6126f781611c71565b156127445760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610928565b6001600160a01b038216600090815260046020526040812080546001929061276d908490613446565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6127d482611c71565b6128375760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610928565b60008281526007602090815260409091208251610a5d92840190612a55565b60006001600160a01b0384163b1561294c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061289a90339089908890889060040161350c565b6020604051808303816000875af19250505080156128d5575060408051601f3d908101601f191682019092526128d29181019061353f565b60015b612932573d808015612903576040519150601f19603f3d011682016040523d82523d6000602084013e612908565b606091505b50805160000361292a5760405162461bcd60e51b8152600401610928906134ba565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506119ec565b5060016119ec565b60608160000361297b5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156129a5578061298f8161320d565b915061299e9050600a83613403565b915061297f565b60008167ffffffffffffffff8111156129c0576129c0612d78565b6040519080825280601f01601f1916602001820160405280156129ea576020820181803683370190505b5090505b84156119ec576129ff60018361323f565b9150612a0c600a8661355c565b612a17906030613446565b60f81b818381518110612a2c57612a2c6131e1565b60200101906001600160f81b031916908160001a905350612a4e600a86613403565b94506129ee565b828054612a619061309c565b90600052602060002090601f016020900481019282612a835760008555612ac9565b82601f10612a9c57805160ff1916838001178555612ac9565b82800160010185558215612ac9579182015b82811115612ac9578251825591602001919060010190612aae565b50612ad5929150612ad9565b5090565b5b80821115612ad55760008155600101612ada565b6001600160e01b031981168114612b0457600080fd5b50565b600060208284031215612b1957600080fd5b813561269181612aee565b60005b83811015612b3f578181015183820152602001612b27565b83811115611a4f5750506000910152565b60008151808452612b68816020860160208601612b24565b601f01601f19169290920160200192915050565b6020815260006126916020830184612b50565b600060208284031215612ba157600080fd5b5035919050565b6001600160a01b0381168114612b0457600080fd5b8035610ca381612ba8565b60008060408385031215612bdb57600080fd5b8235612be681612ba8565b946020939093013593505050565b600080600060608486031215612c0957600080fd5b8335612c1481612ba8565b92506020840135612c2481612ba8565b929592945050506040919091013590565b600081518084526020808501945080840160005b83811015612c6557815187529582019590820190600101612c49565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b82811015612cb25781516001600160a01b031684529284019290840190600101612c8d565b50505083810382850152612cc68186612c35565b9695505050505050565b8015158114612b0457600080fd5b600060208284031215612cf057600080fd5b813561269181612cd0565b600060208284031215612d0d57600080fd5b813561269181612ba8565b6020808252825182820181905260009190848201906040850190845b81811015612d595783516001600160a01b031683529284019291840191600101612d34565b50909695505050505050565b6020815260006126916020830184612c35565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612db757612db7612d78565b604052919050565b600067ffffffffffffffff821115612dd957612dd9612d78565b5060051b60200190565b600067ffffffffffffffff831115612dfd57612dfd612d78565b612e10601f8401601f1916602001612d8e565b9050828152838383011115612e2457600080fd5b828260208301376000602084830101529392505050565b600082601f830112612e4c57600080fd5b81356020612e61612e5c83612dbf565b612d8e565b82815260059290921b84018101918181019086841115612e8057600080fd5b8286015b84811015612ed557803567ffffffffffffffff811115612ea45760008081fd5b8701603f81018913612eb65760008081fd5b612ec7898683013560408401612de3565b845250918301918301612e84565b509695505050505050565b60008060008060808587031215612ef657600080fd5b8435935060208086013567ffffffffffffffff80821115612f1657600080fd5b818801915088601f830112612f2a57600080fd5b8135612f38612e5c82612dbf565b81815260059190911b8301840190848101908b831115612f5757600080fd5b938501935b82851015612f7557843582529385019390850190612f5c565b975050506040880135925080831115612f8d57600080fd5b5050612f9b87828801612e3b565b925050612faa60608601612bbd565b905092959194509250565b60008060408385031215612fc857600080fd5b8235612fd381612ba8565b91506020830135612fe381612cd0565b809150509250929050565b6000806000806080858703121561300457600080fd5b843561300f81612ba8565b9350602085013561301f81612ba8565b925060408501359150606085013567ffffffffffffffff81111561304257600080fd5b8501601f8101871361305357600080fd5b61306287823560208401612de3565b91505092959194509250565b6000806040838503121561308157600080fd5b823561308c81612ba8565b91506020830135612fe381612ba8565b600181811c908216806130b057607f821691505b6020821081036130d057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600f908201526e24b9903737ba10393ab73734b7339760891b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000602080838503121561316357600080fd5b825167ffffffffffffffff81111561317a57600080fd5b8301601f8101851361318b57600080fd5b8051613199612e5c82612dbf565b81815260059190911b820183019083810190878311156131b857600080fd5b928401925b828410156131d6578351825292840192908401906131bd565b979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161321f5761321f6131f7565b5060010190565b60006020828403121561323857600080fd5b5051919050565b600082821015613251576132516131f7565b500390565b6000816000190483118215151615613270576132706131f7565b500290565b60208082526028908201527f54686520616d6f756e7420746f20627579207469636b6574206973206e6f742060408201526731b7b93932b1ba1760c11b606082015260800190565b6000602082840312156132cf57600080fd5b815161269181612cd0565b6000602082840312156132ec57600080fd5b815160ff8116811461269157600080fd5b600181815b8085111561333857816000190482111561331e5761331e6131f7565b8085161561332b57918102915b93841c9390800290613302565b509250929050565b60008261334f57506001610828565b8161335c57506000610828565b8160018114613372576002811461337c57613398565b6001915050610828565b60ff84111561338d5761338d6131f7565b50506001821b610828565b5060208310610133831016604e8410600b84101617156133bb575081810a610828565b6133c583836132fd565b80600019048211156133d9576133d96131f7565b029392505050565b60006126918383613340565b634e487b7160e01b600052601260045260246000fd5b600082613412576134126133ed565b500490565b60008351613429818460208801612b24565b83519083019061343d818360208801612b24565b01949350505050565b60008219821115613459576134596131f7565b500190565b60008251613470818460208701612b24565b9190910192915050565b60006020828403121561348c57600080fd5b815161269181612ba8565b600061ffff838116908316818110156134b2576134b26131f7565b039392505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612cc690830184612b50565b60006020828403121561355157600080fd5b815161269181612aee565b60008261356b5761356b6133ed565b50069056fea26469706673582212202dc58dda23aa48723de586106ab821c373660f0848be0a0aa260d485ddeabed864736f6c634300080e0033

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

000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000636ea9c00000000000000000000000001571beabd5e4eec540bc827e7827fe443c7d91ff00000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000001e84800000000000000000000000009f0b3aa5d8cbac649494f36700f5d17660a168fd000000000000000000000000e10ce8b28e91bcdc7c642c4a5af8b7c117f02bfc000000000000000000000000000000000000000000000000000000000000000b524146464c4520544553540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012464d4f4e2d56312d313636383139363830300000000000000000000000000000

-----Decoded View---------------
Arg [0] : _USDC (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [1] : _dateOfDraw (uint256): 1668196800
Arg [2] : _raffleMegaVault (address): 0x1571beABD5E4eeC540BC827E7827FE443C7d91fF
Arg [3] : _raffleName (string): RAFFLE TEST
Arg [4] : _minNumberOfPlayers (uint16): 2
Arg [5] : _maxNumberOfPlayers (uint16): 10
Arg [6] : _raffleSymbol (string): FMON-V1-1668196800
Arg [7] : _percentageOfPrizeToOperator (uint16): 20
Arg [8] : _priceOfTheRaffleTicketInUSDC (uint256): 2000000
Arg [9] : _raffleWinnerNumberGeneratorAddress (address): 0x9f0B3aA5D8CBaC649494f36700f5D17660A168FD
Arg [10] : _raffleCashier (address): 0xe10CE8B28E91BcdC7C642C4A5aF8b7c117F02bfC

-----Encoded View---------------
15 Constructor Arguments found :
Arg [0] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [1] : 00000000000000000000000000000000000000000000000000000000636ea9c0
Arg [2] : 0000000000000000000000001571beabd5e4eec540bc827e7827fe443c7d91ff
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [6] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [8] : 00000000000000000000000000000000000000000000000000000000001e8480
Arg [9] : 0000000000000000000000009f0b3aa5d8cbac649494f36700f5d17660a168fd
Arg [10] : 000000000000000000000000e10ce8b28e91bcdc7c642c4a5af8b7c117f02bfc
Arg [11] : 000000000000000000000000000000000000000000000000000000000000000b
Arg [12] : 524146464c452054455354000000000000000000000000000000000000000000
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [14] : 464d4f4e2d56312d313636383139363830300000000000000000000000000000


Deployed Bytecode Sourcemap

2957:11508:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8476:355:0;;;;;;;;;;-1:-1:-1;8476:355:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:9;;558:22;540:41;;528:2;513:18;8476:355:0;;;;;;;;3193:31:6;;;;;;;;;;;;;;;;;;;738:25:9;;;726:2;711:18;3193:31:6;592:177:9;9476:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;10693:308::-;;;;;;;;;;-1:-1:-1;10693:308:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1874:32:9;;;1856:51;;1844:2;1829:18;10693:308:0;1710:203:9;10274:411:0;;;;;;;;;;-1:-1:-1;10274:411:0;;;;;:::i;:::-;;:::i;:::-;;6599:382:6;;;;;;;;;;-1:-1:-1;6599:382:6;;;;;:::i;:::-;;:::i;3415:35::-;;;;;;;;;;-1:-1:-1;3415:35:6;;;;;:::i;:::-;;:::i;5651:571::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;471:231:2:-;;;;;;;;;;-1:-1:-1;471:231:2;;;;;:::i;:::-;;:::i;3231:33:6:-;;;;;;;;;;-1:-1:-1;3231:33:6;;;;-1:-1:-1;;;;;3231:33:6;;;3337:32;;;;;;;;;;-1:-1:-1;3337:32:6;;;;-1:-1:-1;;;3337:32:6;;;;;;;;;4794:6:9;4782:19;;;4764:38;;4752:2;4737:18;3337:32:6;4620:188:9;6989:191:6;;;;;;;;;;-1:-1:-1;6989:191:6;;;;;:::i;:::-;;:::i;6408:183::-;;;;;;;;;;-1:-1:-1;6408:183:6;;;;;:::i;:::-;-1:-1:-1;;;;;6552:26:6;6509:17;6552:26;;;:9;:26;;;;;;:30;;;6408:183;11660:492;;;;;;;;;;;;;:::i;5477:166::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;9142:326:0:-;;;;;;;;;;-1:-1:-1;9142:326:0;;;;;:::i;:::-;;:::i;6230:170:6:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;8839:295:0:-;;;;;;;;;;-1:-1:-1;8839:295:0;;;;;:::i;:::-;;:::i;3376:32:6:-;;;;;;;;;;-1:-1:-1;3376:32:6;;;;-1:-1:-1;;;3376:32:6;;;;;;12160:493;;;;;;;;;;-1:-1:-1;12160:493:6;;;;;:::i;:::-;;:::i;3863:45::-;;;;;;;;;;-1:-1:-1;3863:45:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;3120:29;;;;;;;;;;;;;;;81:20:3;;;;;;;;;;-1:-1:-1;81:20:3;;;;-1:-1:-1;;;;;81:20:3;;;3053:24:6;;;;;;;;;;-1:-1:-1;3053:24:6;;;;;;;;7460:3809;;;;;;:::i;:::-;;:::i;3915:46::-;;;;;;;;;;;;;;;;9584:104:0;;;;;;;;;;;;;:::i;5249:220:6:-;;;;;;;;;;-1:-1:-1;5249:220:6;;;;;:::i;:::-;;:::i;3156:30::-;;;;;;;;;;-1:-1:-1;3156:30:6;;;;-1:-1:-1;;;;;3156:30:6;;;11009:187:0;;;;;;;;;;-1:-1:-1;11009:187:0;;;;;:::i;:::-;;:::i;3665:41:6:-;;;;;;;;;;;;;;;;3713;;;;;;;;;;-1:-1:-1;3713:41:6;;;;;;;;3084:29;;;;;;;;;;;;;;;;12003:365:0;;;;;;;;;;-1:-1:-1;12003:365:0;;;;;:::i;:::-;;:::i;226:619:1:-;;;;;;;;;;-1:-1:-1;226:619:1;;;;;:::i;:::-;;:::i;3457:37:6:-;;;;;;;;;;-1:-1:-1;3457:37:6;;;;;:::i;:::-;;:::i;121:19:2:-;;;;;;;;;;-1:-1:-1;121:19:2;;;;-1:-1:-1;;;121:19:2;;;;;;3620:38:6;;;;;;;;;;-1:-1:-1;3620:38:6;;;;-1:-1:-1;;;;;3620:38:6;;;11204:214:0;;;;;;;;;;-1:-1:-1;11204:214:0;;;;;:::i;:::-;;:::i;7188:264:6:-;;;;;;;;;;;;;:::i;3021:25::-;;;;;;;;;;;;;;;;3761:43;;;;;;;;;;;;;;;;3811:45;;;;;;;;;;;;;;;;8476:355:0;8623:4;-1:-1:-1;;;;;;8665:40:0;;-1:-1:-1;;;8665:40:0;;:105;;-1:-1:-1;;;;;;;8722:48:0;;-1:-1:-1;;;8722:48:0;8665:105;:158;;;-1:-1:-1;;;;;;;;;;7866:40:0;;;8787:36;8645:178;8476:355;-1:-1:-1;;8476:355:0:o;9476:100::-;9530:13;9563:5;9556:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9476:100;:::o;10693:308::-;10814:7;10861:16;10869:7;10861;:16::i;:::-;10839:110;;;;-1:-1:-1;;;10839:110:0;;11802:2:9;10839:110:0;;;11784:21:9;11841:2;11821:18;;;11814:30;11880:34;11860:18;;;11853:62;-1:-1:-1;;;11931:18:9;;;11924:42;11983:19;;10839:110:0;;;;;;;;;-1:-1:-1;10969:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;10969:24:0;;10693:308::o;10274:411::-;10355:13;10371:23;10386:7;10371:14;:23::i;:::-;10355:39;;10419:5;-1:-1:-1;;;;;10413:11:0;:2;-1:-1:-1;;;;;10413:11:0;;10405:57;;;;-1:-1:-1;;;10405:57:0;;12215:2:9;10405:57:0;;;12197:21:9;12254:2;12234:18;;;12227:30;12293:34;12273:18;;;12266:62;-1:-1:-1;;;12344:18:9;;;12337:31;12385:19;;10405:57:0;12013:397:9;10405:57:0;5998:10;-1:-1:-1;;;;;10497:21:0;;;;:62;;-1:-1:-1;10522:37:0;10539:5;5998:10;11204:214;:::i;10522:37::-;10475:168;;;;-1:-1:-1;;;10475:168:0;;12617:2:9;10475:168:0;;;12599:21:9;12656:2;12636:18;;;12629:30;12695:34;12675:18;;;12668:62;12766:26;12746:18;;;12739:54;12810:19;;10475:168:0;12415:420:9;10475:168:0;10656:21;10665:2;10669:7;10656:8;:21::i;:::-;10344:341;10274:411;;:::o;6599:382:6:-;256:7:2;;-1:-1:-1;;;256:7:2;;;;248:35;;;;-1:-1:-1;;;248:35:2;;;;;;;:::i;:::-;6814:41:6::1;5998:10:0::0;6847:7:6::1;6814:18;:41::i;:::-;6792:140;;;;-1:-1:-1::0;;;6792:140:6::1;;;;;;;:::i;:::-;6945:28;6955:4;6961:2;6965:7;6945:9;:28::i;3415:35::-:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3415:35:6;:::o;5651:571::-;5895:35;;:81;;-1:-1:-1;;;5895:81:6;;5970:4;5895:81;;;1856:51:9;5748:30:6;;;;-1:-1:-1;;;;;5895:35:6;;;;:66;;1829:18:9;;5895:81:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5895:81:6;;;;;;;;;;;;:::i;:::-;5865:111;;6017:27;:34;6003:49;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6003:49:6;;5987:65;;6070:9;6065:150;6089:27;:34;6085:1;:38;6065:150;;;6164:39;6172:27;6200:1;6172:30;;;;;;;;:::i;:::-;;;;;;;6164:7;:39::i;:::-;6145:13;6159:1;6145:16;;;;;;;;:::i;:::-;-1:-1:-1;;;;;6145:58:6;;;:16;;;;;;;;;;;:58;6125:3;;;:::i;:::-;;;6065:150;;;;5651:571;;:::o;471:231:2:-;580:12;245:5:3;;-1:-1:-1;;;;;245:5:3;231:10;:19;223:28;;;;;;256:7:2::1;::::0;-1:-1:-1;;;256:7:2;::::1;;;248:35;;;;-1:-1:-1::0;;;248:35:2::1;;;;;;;:::i;:::-;610:7:::2;:15:::0;;-1:-1:-1;;;;610:15:2::2;-1:-1:-1::0;;;610:15:2;::::2;;::::0;;::::2;::::0;;;::::2;::::0;;;641:31:::2;::::0;;654:10:::2;15060:51:9::0;;15142:2;15127:18;;15120:50;;;;641:31:2::2;::::0;15033:18:9;641:31:2::2;;;;;;;-1:-1:-1::0;690:4:2::2;294:1;471:231:::0;;;:::o;6989:191:6:-;256:7:2;;-1:-1:-1;;;256:7:2;;;;248:35;;;;-1:-1:-1;;;248:35:2;;;;;;;:::i;:::-;7133:39:6::1;7150:4;7156:2;7160:7;7133:39;;;;;;;;;;;::::0;:16:::1;:39::i;11660:492::-:0;11767:22;245:5:3;;-1:-1:-1;;;;;245:5:3;231:10;:19;223:28;;;;;;256:7:2::1;::::0;-1:-1:-1;;;256:7:2;::::1;;;248:35;;;;-1:-1:-1::0;;;248:35:2::1;;;;;;;:::i;:::-;11812:9:6::2;11807:288;11831:18;:25:::0;11827:29;::::2;11807:288;;;11878:17;11898:30;11906:18;11925:1;11906:21;;;;;;;;:::i;:::-;;;;;;;;;11898:7;:30::i;:::-;11878:50;;11943:140;11989:4;12012:9;12040:28;;11943:27;:140::i;:::-;-1:-1:-1::0;11858:3:6::2;::::0;::::2;:::i;:::-;;;11807:288;;;-1:-1:-1::0;;12117:5:6::2;12107:15:::0;;-1:-1:-1;;;;12107:15:6::2;::::0;;;11660:492;:::o;5477:166::-;5560:38;5623:12;5616:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5616:19:6;;;;;;;;;;;;;;;;;;;;;;5477:166;:::o;9142:326:0:-;9259:7;9300:16;;;:7;:16;;;;;;-1:-1:-1;;;;;9300:16:0;;9327:110;;;;-1:-1:-1;;;9327:110:0;;15383:2:9;9327:110:0;;;15365:21:9;15422:2;15402:18;;;15395:30;15461:34;15441:18;;;15434:62;-1:-1:-1;;;15512:18:9;;;15505:39;15561:19;;9327:110:0;15181:405:9;6230:170:6;6313:36;6374:18;6367:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6230:170;:::o;8839:295:0:-;8956:7;-1:-1:-1;;;;;9003:19:0;;8981:111;;;;-1:-1:-1;;;8981:111:0;;15793:2:9;8981:111:0;;;15775:21:9;15832:2;15812:18;;;15805:30;15871:34;15851:18;;;15844:62;-1:-1:-1;;;15922:18:9;;;15915:40;15972:19;;8981:111:0;15591:406:9;8981:111:0;-1:-1:-1;;;;;;9110:16:0;;;;;:9;:16;;;;;;;8839:295::o;12160:493:6:-;12290:22;245:5:3;;-1:-1:-1;;;;;245:5:3;231:10;:19;223:28;;;;;;256:7:2::1;::::0;-1:-1:-1;;;256:7:2;::::1;;;248:35;;;;-1:-1:-1::0;;;248:35:2::1;;;;;;;:::i;:::-;12351:28:6::2;12359:19;12351:7;:28::i;:::-;12330:18;:49:::0;;-1:-1:-1;;;;;;12330:49:6::2;-1:-1:-1::0;;;;;12330:49:6;;::::2;;::::0;;12409:37:::2;::::0;-1:-1:-1;;;12409:37:6;;12440:4:::2;12409:37;::::0;::::2;1856:51:9::0;12416:4:6::2;12409:22:::0;;::::2;::::0;::::2;::::0;1829:18:9;;12409:37:6::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12390:16;:56:::0;12459:27:::2;:25;:27::i;:::-;-1:-1:-1::0;12517:18:6::2;::::0;12497:39:::2;::::0;-1:-1:-1;;;;;12517:18:6::2;12497:19;:39::i;:::-;-1:-1:-1::0;;12549:26:6::2;:48:::0;12618:5:::2;12608:15:::0;;-1:-1:-1;;;;12608:15:6::2;::::0;;-1:-1:-1;;12160:493:6:o;7460:3809::-;7704:12;256:7:2;;-1:-1:-1;;;256:7:2;;;;248:35;;;;-1:-1:-1;;;248:35:2;;;;;;;:::i;:::-;7771:15:6::1;7764:3;7751:10;;:16;;;;:::i;:::-;:35;;7729:136;;;::::0;-1:-1:-1;;;7729:136:6;;16523:2:9;7729:136:6::1;::::0;::::1;16505:21:9::0;16562:2;16542:18;;;16535:30;16601:34;16581:18;;;16574:62;-1:-1:-1;;;16652:18:9;;;16645:49;16711:19;;7729:136:6::1;16321:415:9::0;7729:136:6::1;7934:18;::::0;7912:12:::1;:19:::0;-1:-1:-1;;;7934:18:6;;::::1;;;-1:-1:-1::0;7890:132:6::1;;;::::0;-1:-1:-1;;;7890:132:6;;16943:2:9;7890:132:6::1;::::0;::::1;16925:21:9::0;16982:2;16962:18;;;16955:30;17021:34;17001:18;;;16994:62;-1:-1:-1;;;17072:18:9;;;17065:40;17122:19;;7890:132:6::1;16741:406:9::0;7890:132:6::1;8082:22;:29;8055:16;:23;:56;8033:144;;;::::0;-1:-1:-1;;;8033:144:6;;17354:2:9;8033:144:6::1;::::0;::::1;17336:21:9::0;17393:2;17373:18;;;17366:30;17432:34;17412:18;;;17405:62;-1:-1:-1;;;17483:18:9;;;17476:36;17529:19;;8033:144:6::1;17152:402:9::0;8033:144:6::1;8221:4;-1:-1:-1::0;;;;;8194:31:6::1;:23;-1:-1:-1::0;;;;;8194:31:6::1;::::0;8190:2173:::1;;8339:28;;8313:16;:23;:54;;;;:::i;:::-;8268:19;:100;8242:202;;;;-1:-1:-1::0;;;8242:202:6::1;;;;;;;:::i;:::-;8493:34;::::0;-1:-1:-1;;;8493:34:6;;8516:10:::1;8493:34;::::0;::::1;1856:51:9::0;8461:29:6::1;::::0;8500:4:::1;-1:-1:-1::0;;;;;8493:22:6::1;::::0;::::1;::::0;1829:18:9;;8493:34:6::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8461:66;;8641:28;;8615:16;:23;:54;;;;:::i;:::-;8568:21;:102;;8542:206;;;::::0;-1:-1:-1;;;8542:206:6;;18343:2:9;8542:206:6::1;::::0;::::1;18325:21:9::0;18382:2;18362:18;;;18355:30;18421:34;18401:18;;;18394:62;-1:-1:-1;;;18472:18:9;;;18465:40;18522:19;;8542:206:6::1;18141:406:9::0;8542:206:6::1;8765:21;::::0;:185:::1;::::0;-1:-1:-1;;;8765:185:6;;-1:-1:-1;;;;;8832:4:6::1;18839:15:9::0;;8765:185:6::1;::::0;::::1;18821:34:9::0;8855:10:6::1;18871:18:9::0;;;18864:43;8892:4:6::1;18923:18:9::0;;;18916:43;18975:18;;;18968:34;;;8765:21:6;;::::1;::::0;:48:::1;::::0;18755:19:9;;8765:185:6::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;8227:735;8190:2173;;;9032:23;9065;-1:-1:-1::0;;;;;9058:58:6::1;;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9166:71;::::0;-1:-1:-1;;;9166:71:6;;9226:10:::1;9166:71;::::0;::::1;1856:51:9::0;9032:86:6::1;::::0;;;::::1;::::0;-1:-1:-1;9133:30:6::1;::::0;-1:-1:-1;;;;;9166:59:6;::::1;::::0;::::1;::::0;1829:18:9;;9166:71:6::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9295:21;::::0;:165:::1;::::0;-1:-1:-1;;;9295:165:6;;-1:-1:-1;;;;;19771:15:9;;;9295:165:6::1;::::0;::::1;19753:34:9::0;9437:4:6::1;19823:15:9::0;;19803:18;;;19796:43;9133:104:6;;-1:-1:-1;9254:38:6::1;::::0;9295:21;;::::1;::::0;:73:::1;::::0;19688:18:9;;9295:165:6::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9254:206;;9475:35;9651:16;:23;9617:30;9576:15;9572:2;:19;;;;:::i;:::-;9568:23;::::0;:1:::1;:23;:::i;:::-;9515:28;;:77;;;;:::i;:::-;9514:133;;;;:::i;:::-;9513:161;;;;:::i;:::-;9475:199;;9740:27;9717:19;:50;;9691:152;;;;-1:-1:-1::0;;;9691:152:6::1;;;;;;;:::i;:::-;9910:27;9884:22;:53;;9858:158;;;::::0;-1:-1:-1;;;9858:158:6;;21683:2:9;9858:158:6::1;::::0;::::1;21665:21:9::0;21722:2;21702:18;;;21695:30;21761:34;21741:18;;;21734:62;-1:-1:-1;;;21812:18:9;;;21805:41;21863:19;;9858:158:6::1;21481:407:9::0;9858:158:6::1;10033:21;;;;;;;;;-1:-1:-1::0;;;;;10033:21:6::1;-1:-1:-1::0;;;;;10033:66:6::1;;10118:4;10141:10;10178:4;10202:23;10244:19;10308:28;;10282:16;:23;:54;;;;:::i;:::-;10033:318;::::0;-1:-1:-1;;;;;;10033:318:6::1;::::0;;;;;;-1:-1:-1;;;;;22236:15:9;;;10033:318:6::1;::::0;::::1;22218:34:9::0;22288:15;;;22268:18;;;22261:43;22340:15;;;22320:18;;;22313:43;22392:15;;22372:18;;;22365:43;22424:19;;;22417:35;;;;22468:19;;;22461:35;;;;22152:19;;10033:318:6::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;8968:1395;;;;8190:2173;10380:9;10375:863;10399:16;:23;10395:1;:27;10375:863;;;10470:16;10487:1;10470:19;;;;;;;;:::i;:::-;;;;;;;10493:1;10470:24:::0;10444:132:::1;;;::::0;-1:-1:-1;;;10444:132:6;;22709:2:9;10444:132:6::1;::::0;::::1;22691:21:9::0;22748:2;22728:18;;;22721:30;22787:34;22767:18;;;22760:62;-1:-1:-1;;;22838:18:9;;;22831:44;22892:19;;10444:132:6::1;22507:410:9::0;10444:132:6::1;10640:18;;;;;;;;;;;10617:41;;:16;10634:1;10617:19;;;;;;;;:::i;:::-;;;;;;;:41;;10591:156;;;::::0;-1:-1:-1;;;10591:156:6;;23124:2:9;10591:156:6::1;::::0;::::1;23106:21:9::0;23163:2;23143:18;;;23136:30;23202:34;23182:18;;;23175:62;-1:-1:-1;;;23253:18:9;;;23246:51;23314:19;;10591:156:6::1;22922:417:9::0;10591:156:6::1;10764:142;10799:10;10828:16;10845:1;10828:19;;;;;;;;:::i;:::-;;;;;;;10866:22;10889:1;10866:25;;;;;;;;:::i;:::-;;;;;;;10764:16;:142::i;:::-;-1:-1:-1::0;10921:35:6::1;::::0;11031:19;;-1:-1:-1;;;;;10921:35:6;;::::1;::::0;:59:::1;::::0;11007:4:::1;::::0;11031:16;;11048:1;;11031:19;::::1;;;;;:::i;:::-;;;;;;;10921:144;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;23536:32:9;;;;23518:51;;23600:2;23585:18;;23578:34;23506:2;23491:18;;23344:274;10921:144:6::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;11082:12:6::1;:38:::0;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;-1:-1:-1;;;;;;11082:38:6::1;11108:10;11082:38:::0;;::::1;::::0;;;-1:-1:-1;11135:25:6;;;:13:::1;11082:38;11135:25:::0;;;;:32;;-1:-1:-1;;11135:32:6::1;::::0;;::::1;::::0;;11206:19;;11182:18:::1;::::0;11206:16;;11223:1;;11206:19;::::1;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;11182:44;;::::1;::::0;::::1;::::0;;-1:-1:-1;11182:44:6;;;;;;;::::1;::::0;10424:3:::1;::::0;::::1;:::i;:::-;;;10375:863;;;;11257:4;11250:11;;294:1:2;7460:3809:6::0;;;;;;:::o;9584:104:0:-;9640:13;9673:7;9666:14;;;;;:::i;5249:220:6:-;5373:35;5433:28;5441:19;5433:7;:28::i;11009:187:0:-;11136:52;5998:10;11169:8;11179;11136:18;:52::i;:::-;11009:187;;:::o;12003:365::-;12192:41;5998:10;12225:7;12192:18;:41::i;:::-;12170:140;;;;-1:-1:-1;;;12170:140:0;;;;;;;:::i;:::-;12321:39;12335:4;12341:2;12345:7;12354:5;12321:13;:39::i;:::-;12003:365;;;;:::o;226:619:1:-;344:13;397:16;405:7;397;:16::i;:::-;375:115;;;;-1:-1:-1;;;375:115:1;;23825:2:9;375:115:1;;;23807:21:9;23864:2;23844:18;;;23837:30;23903:34;23883:18;;;23876:62;-1:-1:-1;;;23954:18:9;;;23947:47;24011:19;;375:115:1;23623:413:9;375:115:1;503:23;529:19;;;:10;:19;;;;;503:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;559:18;580:10;10249:9:0;;;;;;;;;-1:-1:-1;10249:9:0;;;10172:94;580:10:1;559:31;;613:4;607:18;629:1;607:23;603:72;;-1:-1:-1;654:9:1;226:619;-1:-1:-1;;226:619:1:o;603:72::-;691:23;;:27;687:108;;766:4;772:9;749:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;735:48;;;;226:619;;;:::o;687:108::-;814:23;829:7;814:14;:23::i;3457:37:6:-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3457:37:6;;-1:-1:-1;3457:37:6;:::o;11204:214:0:-;-1:-1:-1;;;;;11375:25:0;;;11346:4;11375:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;11204:214::o;7188:264:6:-;7303:35;;7234:12;;-1:-1:-1;;;;;7303:35:6;7281:10;:58;7259:120;;;;-1:-1:-1;;;7259:120:6;;24718:2:9;7259:120:6;;;24700:21:9;24757:2;24737:18;;;24730:30;-1:-1:-1;;;24776:18:9;;;24769:42;24828:18;;7259:120:6;24516:336:9;7259:120:6;-1:-1:-1;7407:15:6;7390:14;:32;7440:4;;7188:264::o;12736:127:0:-;12801:4;12825:16;;;:7;:16;;;;;;-1:-1:-1;;;;;12825:16:0;:30;;;12736:127::o;15243:174::-;15318:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;15318:29:0;-1:-1:-1;;;;;15318:29:0;;;;;;;;:24;;15372:23;15318:24;15372:14;:23::i;:::-;-1:-1:-1;;;;;15363:46:0;;;;;;;;;;;15243:174;;:::o;12871:452::-;13000:4;13044:16;13052:7;13044;:16::i;:::-;13022:110;;;;-1:-1:-1;;;13022:110:0;;25059:2:9;13022:110:0;;;25041:21:9;25098:2;25078:18;;;25071:30;25137:34;25117:18;;;25110:62;-1:-1:-1;;;25188:18:9;;;25181:42;25240:19;;13022:110:0;24857:408:9;13022:110:0;13143:13;13159:23;13174:7;13159:14;:23::i;:::-;13143:39;;13212:5;-1:-1:-1;;;;;13201:16:0;:7;-1:-1:-1;;;;;13201:16:0;;:65;;;;13234:32;13251:5;13258:7;13234:16;:32::i;:::-;13201:113;;;;13307:7;-1:-1:-1;;;;;13283:31:0;:20;13295:7;13283:11;:20::i;:::-;-1:-1:-1;;;;;13283:31:0;;13193:122;12871:452;-1:-1:-1;;;;12871:452:0:o;14625:610::-;14798:4;-1:-1:-1;;;;;14771:31:0;:23;14786:7;14771:14;:23::i;:::-;-1:-1:-1;;;;;14771:31:0;;14749:118;;;;-1:-1:-1;;;14749:118:0;;25472:2:9;14749:118:0;;;25454:21:9;25511:2;25491:18;;;25484:30;25550:34;25530:18;;;25523:62;-1:-1:-1;;;25601:18:9;;;25594:35;25646:19;;14749:118:0;25270:401:9;14749:118:0;-1:-1:-1;;;;;14886:16:0;;14878:65;;;;-1:-1:-1;;;14878:65:0;;25878:2:9;14878:65:0;;;25860:21:9;25917:2;25897:18;;;25890:30;25956:34;25936:18;;;25929:62;-1:-1:-1;;;26007:18:9;;;26000:34;26051:19;;14878:65:0;25676:400:9;14878:65:0;15008:29;15025:1;15029:7;15008:8;:29::i;:::-;-1:-1:-1;;;;;15050:15:0;;;;;;:9;:15;;;;;:20;;15069:1;;15050:15;:20;;15069:1;;15050:20;:::i;:::-;;;;-1:-1:-1;;;;;;;15081:13:0;;;;;;:9;:13;;;;;:18;;15098:1;;15081:13;:18;;15098:1;;15081:18;:::i;:::-;;;;-1:-1:-1;;15110:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;15110:21:0;-1:-1:-1;;;;;15110:21:0;;;;;;;;;15149:27;;15110:16;;15149:27;;;;;;;10344:341;10274:411;;:::o;1685:473:6:-;1931:45;;;-1:-1:-1;;;;;23536:32:9;;;1931:45:6;;;23518:51:9;23585:18;;;;23578:34;;;1931:45:6;;;;;;;;;;23491:18:9;;;;1931:45:6;;;;;;;-1:-1:-1;;;;;1931:45:6;-1:-1:-1;;;1931:45:6;;;1906:81;;-1:-1:-1;;;;1906:10:6;;;;:81;;1931:45;1906:81;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1870:117;;;;2020:7;:57;;;;-1:-1:-1;2032:11:6;;:16;;:44;;;2063:4;2052:24;;;;;;;;;;;;:::i;:::-;1998:152;;;;-1:-1:-1;;;1998:152:6;;26695:2:9;1998:152:6;;;26677:21:9;26734:2;26714:18;;;26707:30;26773:34;26753:18;;;26746:62;-1:-1:-1;;;26824:18:9;;;26817:43;26877:19;;1998:152:6;26493:409:9;1998:152:6;1792:366;;1685:473;;;:::o;12661:983::-;12809:27;;12777:16;;12716:13;;12840:3;;12777:59;;12809:27;;;12777:59;:::i;:::-;12776:67;;;;:::i;:::-;12742:30;:102;;;12855:39;;12954:3;;12898:52;;12948:2;12898:52;:::i;:::-;12897:60;;;;:::i;:::-;12855:102;;12968:37;13065:3;13009:30;;13059:2;13009:52;;;;:::i;:::-;13008:60;;;;:::i;:::-;12968:100;;13081:167;13123:4;13150:21;;;;;;;;;-1:-1:-1;;;;;13150:21:6;-1:-1:-1;;;;;13150:38:6;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13206:31;13081:27;:167::i;:::-;13259:168;13301:4;13328:21;;;;;;;;;-1:-1:-1;;;;;13328:21:6;-1:-1:-1;;;;;13328:37:6;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13383:33;13415:1;13383:29;:33;:::i;:::-;13259:27;:168::i;:::-;13438:176;13480:4;13507:21;;;;;;;;;-1:-1:-1;;;;;13507:21:6;-1:-1:-1;;;;;13507:45:6;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13438:176;13632:4;13625:11;;;;12661:983;:::o;13652:810::-;13786:12;;13746:13;;13786:12;;13785:13;13777:56;;;;-1:-1:-1;;;13777:56:6;;27365:2:9;13777:56:6;;;27347:21:9;27404:2;27384:18;;;27377:30;27443:32;27423:18;;;27416:60;27493:18;;13777:56:6;27163:354:9;13777:56:6;13904:27;;13846:36;;13885:46;;13904:27;;13885:3;:46;:::i;:::-;13846:85;;14043:3;14010:29;13978:61;;:16;;:61;;;;:::i;:::-;13977:69;;;;:::i;:::-;13942:31;:105;;;14129:21;;14060:148;;14102:4;;-1:-1:-1;;;;;14129:21:6;;14060:27;:148::i;:::-;14219:21;;14358:31;;14219:181;;-1:-1:-1;;;14219:181:6;;14285:4;14219:181;;;18821:34:9;-1:-1:-1;;;;;14305:4:6;18891:15:9;;18871:18;;;18864:43;18943:15;;;18923:18;;;18916:43;18975:18;;;18968:34;;;;14219:21:6;;;:43;;18755:19:9;;14219:181:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;14413:12:6;:19;;-1:-1:-1;;14413:19:6;14428:4;14413:19;;;;;;14428:4;13652:810;-1:-1:-1;;13652:810:6:o;11277:375::-;11421:7;11450:26;11458:17;11450:7;:26::i;:::-;11449:27;11441:70;;;;-1:-1:-1;;;11441:70:6;;27946:2:9;11441:70:6;;;27928:21:9;27985:2;27965:18;;;27958:30;28024:32;28004:18;;;27997:60;28074:18;;11441:70:6;27744:354:9;11441:70:6;11524:31;11530:5;11537:17;11524:5;:31::i;:::-;11566:41;11579:17;11598:8;11566:12;:41::i;:::-;-1:-1:-1;11627:17:6;;11277:375;-1:-1:-1;;11277:375:6:o;15425:315:0:-;15580:8;-1:-1:-1;;;;;15571:17:0;:5;-1:-1:-1;;;;;15571:17:0;;15563:55;;;;-1:-1:-1;;;15563:55:0;;28305:2:9;15563:55:0;;;28287:21:9;28344:2;28324:18;;;28317:30;28383:27;28363:18;;;28356:55;28428:18;;15563:55:0;28103:349:9;15563:55:0;-1:-1:-1;;;;;15629:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;15629:46:0;;;;;;;;;;15691:41;;540::9;;;15691::0;;513:18:9;15691:41:0;;;;;;;15425:315;;;:::o;12376:352::-;12533:28;12543:4;12549:2;12553:7;12533:9;:28::i;:::-;12594:48;12617:4;12623:2;12627:7;12636:5;12594:22;:48::i;:::-;12572:148;;;;-1:-1:-1;;;12572:148:0;;;;;;;:::i;9696:468::-;9814:13;9867:16;9875:7;9867;:16::i;:::-;9845:113;;;;-1:-1:-1;;;9845:113:0;;29078:2:9;9845:113:0;;;29060:21:9;29117:2;29097:18;;;29090:30;29156:34;29136:18;;;29129:62;-1:-1:-1;;;29207:18:9;;;29200:45;29262:19;;9845:113:0;28876:411:9;9845:113:0;9971:21;9995:10;10249:9;;;;;;;;;-1:-1:-1;10249:9:0;;;10172:94;9995:10;9971:34;;10060:1;10042:7;10036:21;:25;:120;;;;;;;;;;;;;;;;;10105:7;10114:18;:7;:16;:18::i;:::-;10088:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10036:120;10016:140;9696:468;-1:-1:-1;;;9696:468:0:o;13778:439::-;-1:-1:-1;;;;;13858:16:0;;13850:61;;;;-1:-1:-1;;;13850:61:0;;29494:2:9;13850:61:0;;;29476:21:9;;;29513:18;;;29506:30;29572:34;29552:18;;;29545:62;29624:18;;13850:61:0;29292:356:9;13850:61:0;13931:16;13939:7;13931;:16::i;:::-;13930:17;13922:58;;;;-1:-1:-1;;;13922:58:0;;29855:2:9;13922:58:0;;;29837:21:9;29894:2;29874:18;;;29867:30;29933;29913:18;;;29906:58;29981:18;;13922:58:0;29653:352:9;13922:58:0;-1:-1:-1;;;;;14051:13:0;;;;;;:9;:13;;;;;:18;;14068:1;;14051:13;:18;;14068:1;;14051:18;:::i;:::-;;;;-1:-1:-1;;14080:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;14080:21:0;-1:-1:-1;;;;;14080:21:0;;;;;;;;14119:33;;14080:16;;;14119:33;;14080:16;;14119:33;11009:187;;:::o;853:277:1:-;990:16;998:7;990;:16::i;:::-;968:112;;;;-1:-1:-1;;;968:112:1;;30212:2:9;968:112:1;;;30194:21:9;30251:2;30231:18;;;30224:30;30290:34;30270:18;;;30263:62;-1:-1:-1;;;30341:18:9;;;30334:44;30395:19;;968:112:1;30010:410:9;968:112:1;1091:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;15748:980:0:-;15903:4;-1:-1:-1;;;;;15924:13:0;;2069:19;:23;15920:801;;15977:175;;-1:-1:-1;;;15977:175:0;;-1:-1:-1;;;;;15977:36:0;;;;;:175;;5998:10;;16071:4;;16098:7;;16128:5;;15977:175;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15977:175:0;;;;;;;;-1:-1:-1;;15977:175:0;;;;;;;;;;;;:::i;:::-;;;15956:710;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16335:6;:13;16352:1;16335:18;16331:320;;16378:108;;-1:-1:-1;;;16378:108:0;;;;;;;:::i;16331:320::-;16601:6;16595:13;16586:6;16582:2;16578:15;16571:38;15956:710;-1:-1:-1;;;;;;16216:51:0;-1:-1:-1;;;16216:51:0;;-1:-1:-1;16209:58:0;;15920:801;-1:-1:-1;16705:4:0;16698:11;;6222:532;6278:13;6308:5;6317:1;6308:10;6304:53;;-1:-1:-1;;6335:10:0;;;;;;;;;;;;-1:-1:-1;;;6335:10:0;;;;;6222:532::o;6304:53::-;6382:5;6367:12;6423:78;6430:9;;6423:78;;6456:8;;;;:::i;:::-;;-1:-1:-1;6479:10:0;;-1:-1:-1;6487:2:0;6479:10;;:::i;:::-;;;6423:78;;;6511:19;6543:6;6533:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6533:17:0;;6511:39;;6561:154;6568:10;;6561:154;;6595:11;6605:1;6595:11;;:::i;:::-;;-1:-1:-1;6664:10:0;6672:2;6664:5;:10;:::i;:::-;6651:24;;:2;:24;:::i;:::-;6638:39;;6621:6;6628;6621:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;6621:56:0;;;;;;;;-1:-1:-1;6692:11:0;6701:2;6692:11;;:::i;:::-;;;6561:154;;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:9;-1:-1:-1;;;;;;88:32:9;;78:43;;68:71;;135:1;132;125:12;68:71;14:131;:::o;150:245::-;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;774:258::-;846:1;856:113;870:6;867:1;864:13;856:113;;;946:11;;;940:18;927:11;;;920:39;892:2;885:10;856:113;;;987:6;984:1;981:13;978:48;;;-1:-1:-1;;1022:1:9;1004:16;;997:27;774:258::o;1037:::-;1079:3;1117:5;1111:12;1144:6;1139:3;1132:19;1160:63;1216:6;1209:4;1204:3;1200:14;1193:4;1186:5;1182:16;1160:63;:::i;:::-;1277:2;1256:15;-1:-1:-1;;1252:29:9;1243:39;;;;1284:4;1239:50;;1037:258;-1:-1:-1;;1037:258:9:o;1300:220::-;1449:2;1438:9;1431:21;1412:4;1469:45;1510:2;1499:9;1495:18;1487:6;1469:45;:::i;1525:180::-;1584:6;1637:2;1625:9;1616:7;1612:23;1608:32;1605:52;;;1653:1;1650;1643:12;1605:52;-1:-1:-1;1676:23:9;;1525:180;-1:-1:-1;1525:180:9:o;1918:131::-;-1:-1:-1;;;;;1993:31:9;;1983:42;;1973:70;;2039:1;2036;2029:12;2054:134;2122:20;;2151:31;2122:20;2151:31;:::i;2193:315::-;2261:6;2269;2322:2;2310:9;2301:7;2297:23;2293:32;2290:52;;;2338:1;2335;2328:12;2290:52;2377:9;2364:23;2396:31;2421:5;2396:31;:::i;:::-;2446:5;2498:2;2483:18;;;;2470:32;;-1:-1:-1;;;2193:315:9:o;2513:456::-;2590:6;2598;2606;2659:2;2647:9;2638:7;2634:23;2630:32;2627:52;;;2675:1;2672;2665:12;2627:52;2714:9;2701:23;2733:31;2758:5;2733:31;:::i;:::-;2783:5;-1:-1:-1;2840:2:9;2825:18;;2812:32;2853:33;2812:32;2853:33;:::i;:::-;2513:456;;2905:7;;-1:-1:-1;;;2959:2:9;2944:18;;;;2931:32;;2513:456::o;2974:435::-;3027:3;3065:5;3059:12;3092:6;3087:3;3080:19;3118:4;3147:2;3142:3;3138:12;3131:19;;3184:2;3177:5;3173:14;3205:1;3215:169;3229:6;3226:1;3223:13;3215:169;;;3290:13;;3278:26;;3324:12;;;;3359:15;;;;3251:1;3244:9;3215:169;;;-1:-1:-1;3400:3:9;;2974:435;-1:-1:-1;;;;;2974:435:9:o;3414:832::-;3682:2;3694:21;;;3764:13;;3667:18;;;3786:22;;;3634:4;;3861;;3839:2;3824:18;;;3888:15;;;3634:4;3931:195;3945:6;3942:1;3939:13;3931:195;;;4010:13;;-1:-1:-1;;;;;4006:39:9;3994:52;;4066:12;;;;4101:15;;;;4042:1;3960:9;3931:195;;;3935:3;;;4171:9;4166:3;4162:19;4157:2;4146:9;4142:18;4135:47;4199:41;4236:3;4228:6;4199:41;:::i;:::-;4191:49;3414:832;-1:-1:-1;;;;;;3414:832:9:o;4251:118::-;4337:5;4330:13;4323:21;4316:5;4313:32;4303:60;;4359:1;4356;4349:12;4374:241;4430:6;4483:2;4471:9;4462:7;4458:23;4454:32;4451:52;;;4499:1;4496;4489:12;4451:52;4538:9;4525:23;4557:28;4579:5;4557:28;:::i;4813:247::-;4872:6;4925:2;4913:9;4904:7;4900:23;4896:32;4893:52;;;4941:1;4938;4931:12;4893:52;4980:9;4967:23;4999:31;5024:5;4999:31;:::i;5065:674::-;5252:2;5304:21;;;5374:13;;5277:18;;;5396:22;;;5223:4;;5252:2;5475:15;;;;5449:2;5434:18;;;5223:4;5518:195;5532:6;5529:1;5526:13;5518:195;;;5597:13;;-1:-1:-1;;;;;5593:39:9;5581:52;;5688:15;;;;5653:12;;;;5629:1;5547:9;5518:195;;;-1:-1:-1;5730:3:9;;5065:674;-1:-1:-1;;;;;;5065:674:9:o;5744:261::-;5923:2;5912:9;5905:21;5886:4;5943:56;5995:2;5984:9;5980:18;5972:6;5943:56;:::i;6010:127::-;6071:10;6066:3;6062:20;6059:1;6052:31;6102:4;6099:1;6092:15;6126:4;6123:1;6116:15;6142:275;6213:2;6207:9;6278:2;6259:13;;-1:-1:-1;;6255:27:9;6243:40;;6313:18;6298:34;;6334:22;;;6295:62;6292:88;;;6360:18;;:::i;:::-;6396:2;6389:22;6142:275;;-1:-1:-1;6142:275:9:o;6422:183::-;6482:4;6515:18;6507:6;6504:30;6501:56;;;6537:18;;:::i;:::-;-1:-1:-1;6582:1:9;6578:14;6594:4;6574:25;;6422:183::o;6610:407::-;6675:5;6709:18;6701:6;6698:30;6695:56;;;6731:18;;:::i;:::-;6769:57;6814:2;6793:15;;-1:-1:-1;;6789:29:9;6820:4;6785:40;6769:57;:::i;:::-;6760:66;;6849:6;6842:5;6835:21;6889:3;6880:6;6875:3;6871:16;6868:25;6865:45;;;6906:1;6903;6896:12;6865:45;6955:6;6950:3;6943:4;6936:5;6932:16;6919:43;7009:1;7002:4;6993:6;6986:5;6982:18;6978:29;6971:40;6610:407;;;;;:::o;7022:1089::-;7075:5;7128:3;7121:4;7113:6;7109:17;7105:27;7095:55;;7146:1;7143;7136:12;7095:55;7182:6;7169:20;7208:4;7232:60;7248:43;7288:2;7248:43;:::i;:::-;7232:60;:::i;:::-;7326:15;;;7412:1;7408:10;;;;7396:23;;7392:32;;;7357:12;;;;7436:15;;;7433:35;;;7464:1;7461;7454:12;7433:35;7500:2;7492:6;7488:15;7512:570;7528:6;7523:3;7520:15;7512:570;;;7614:3;7601:17;7650:18;7637:11;7634:35;7631:125;;;7710:1;7739:2;7735;7728:14;7631:125;7779:24;;7838:2;7830:11;;7826:21;-1:-1:-1;7816:119:9;;7889:1;7918:2;7914;7907:14;7816:119;7960:79;8035:3;8029:2;8025;8021:11;8008:25;8003:2;7999;7995:11;7960:79;:::i;:::-;7948:92;;-1:-1:-1;8060:12:9;;;;7545;;7512:570;;;-1:-1:-1;8100:5:9;7022:1089;-1:-1:-1;;;;;;7022:1089:9:o;8116:1290::-;8262:6;8270;8278;8286;8339:3;8327:9;8318:7;8314:23;8310:33;8307:53;;;8356:1;8353;8346:12;8307:53;8392:9;8379:23;8369:33;;8421:2;8474;8463:9;8459:18;8446:32;8497:18;8538:2;8530:6;8527:14;8524:34;;;8554:1;8551;8544:12;8524:34;8592:6;8581:9;8577:22;8567:32;;8637:7;8630:4;8626:2;8622:13;8618:27;8608:55;;8659:1;8656;8649:12;8608:55;8695:2;8682:16;8718:60;8734:43;8774:2;8734:43;:::i;8718:60::-;8812:15;;;8894:1;8890:10;;;;8882:19;;8878:28;;;8843:12;;;;8918:19;;;8915:39;;;8950:1;8947;8940:12;8915:39;8974:11;;;;8994:142;9010:6;9005:3;9002:15;8994:142;;;9076:17;;9064:30;;9027:12;;;;9114;;;;8994:142;;;9155:5;-1:-1:-1;;;9213:2:9;9198:18;;9185:32;;-1:-1:-1;9229:16:9;;;9226:36;;;9258:1;9255;9248:12;9226:36;;;9281:62;9335:7;9324:8;9313:9;9309:24;9281:62;:::i;:::-;9271:72;;;9362:38;9396:2;9385:9;9381:18;9362:38;:::i;:::-;9352:48;;8116:1290;;;;;;;:::o;9411:382::-;9476:6;9484;9537:2;9525:9;9516:7;9512:23;9508:32;9505:52;;;9553:1;9550;9543:12;9505:52;9592:9;9579:23;9611:31;9636:5;9611:31;:::i;:::-;9661:5;-1:-1:-1;9718:2:9;9703:18;;9690:32;9731:30;9690:32;9731:30;:::i;:::-;9780:7;9770:17;;;9411:382;;;;;:::o;9798:795::-;9893:6;9901;9909;9917;9970:3;9958:9;9949:7;9945:23;9941:33;9938:53;;;9987:1;9984;9977:12;9938:53;10026:9;10013:23;10045:31;10070:5;10045:31;:::i;:::-;10095:5;-1:-1:-1;10152:2:9;10137:18;;10124:32;10165:33;10124:32;10165:33;:::i;:::-;10217:7;-1:-1:-1;10271:2:9;10256:18;;10243:32;;-1:-1:-1;10326:2:9;10311:18;;10298:32;10353:18;10342:30;;10339:50;;;10385:1;10382;10375:12;10339:50;10408:22;;10461:4;10453:13;;10449:27;-1:-1:-1;10439:55:9;;10490:1;10487;10480:12;10439:55;10513:74;10579:7;10574:2;10561:16;10556:2;10552;10548:11;10513:74;:::i;:::-;10503:84;;;9798:795;;;;;;;:::o;10822:388::-;10890:6;10898;10951:2;10939:9;10930:7;10926:23;10922:32;10919:52;;;10967:1;10964;10957:12;10919:52;11006:9;10993:23;11025:31;11050:5;11025:31;:::i;:::-;11075:5;-1:-1:-1;11132:2:9;11117:18;;11104:32;11145:33;11104:32;11145:33;:::i;11215:380::-;11294:1;11290:12;;;;11337;;;11358:61;;11412:4;11404:6;11400:17;11390:27;;11358:61;11465:2;11457:6;11454:14;11434:18;11431:38;11428:161;;11511:10;11506:3;11502:20;11499:1;11492:31;11546:4;11543:1;11536:15;11574:4;11571:1;11564:15;11428:161;;11215:380;;;:::o;12840:339::-;13042:2;13024:21;;;13081:2;13061:18;;;13054:30;-1:-1:-1;;;13115:2:9;13100:18;;13093:45;13170:2;13155:18;;12840:339::o;13184:413::-;13386:2;13368:21;;;13425:2;13405:18;;;13398:30;13464:34;13459:2;13444:18;;13437:62;-1:-1:-1;;;13530:2:9;13515:18;;13508:47;13587:3;13572:19;;13184:413::o;13602:881::-;13697:6;13728:2;13771;13759:9;13750:7;13746:23;13742:32;13739:52;;;13787:1;13784;13777:12;13739:52;13820:9;13814:16;13853:18;13845:6;13842:30;13839:50;;;13885:1;13882;13875:12;13839:50;13908:22;;13961:4;13953:13;;13949:27;-1:-1:-1;13939:55:9;;13990:1;13987;13980:12;13939:55;14019:2;14013:9;14042:60;14058:43;14098:2;14058:43;:::i;14042:60::-;14136:15;;;14218:1;14214:10;;;;14206:19;;14202:28;;;14167:12;;;;14242:19;;;14239:39;;;14274:1;14271;14264:12;14239:39;14298:11;;;;14318:135;14334:6;14329:3;14326:15;14318:135;;;14400:10;;14388:23;;14351:12;;;;14431;;;;14318:135;;;14472:5;13602:881;-1:-1:-1;;;;;;;13602:881:9:o;14488:127::-;14549:10;14544:3;14540:20;14537:1;14530:31;14580:4;14577:1;14570:15;14604:4;14601:1;14594:15;14620:127;14681:10;14676:3;14672:20;14669:1;14662:31;14712:4;14709:1;14702:15;14736:4;14733:1;14726:15;14752:135;14791:3;14812:17;;;14809:43;;14832:18;;:::i;:::-;-1:-1:-1;14879:1:9;14868:13;;14752:135::o;16002:184::-;16072:6;16125:2;16113:9;16104:7;16100:23;16096:32;16093:52;;;16141:1;16138;16131:12;16093:52;-1:-1:-1;16164:16:9;;16002:184;-1:-1:-1;16002:184:9:o;16191:125::-;16231:4;16259:1;16256;16253:8;16250:34;;;16264:18;;:::i;:::-;-1:-1:-1;16301:9:9;;16191:125::o;17559:168::-;17599:7;17665:1;17661;17657:6;17653:14;17650:1;17647:21;17642:1;17635:9;17628:17;17624:45;17621:71;;;17672:18;;:::i;:::-;-1:-1:-1;17712:9:9;;17559:168::o;17732:404::-;17934:2;17916:21;;;17973:2;17953:18;;;17946:30;18012:34;18007:2;17992:18;;17985:62;-1:-1:-1;;;18078:2:9;18063:18;;18056:38;18126:3;18111:19;;17732:404::o;19013:245::-;19080:6;19133:2;19121:9;19112:7;19108:23;19104:32;19101:52;;;19149:1;19146;19139:12;19101:52;19181:9;19175:16;19200:28;19222:5;19200:28;:::i;19263:273::-;19331:6;19384:2;19372:9;19363:7;19359:23;19355:32;19352:52;;;19400:1;19397;19390:12;19352:52;19432:9;19426:16;19482:4;19475:5;19471:16;19464:5;19461:27;19451:55;;19502:1;19499;19492:12;19850:422;19939:1;19982:5;19939:1;19996:270;20017:7;20007:8;20004:21;19996:270;;;20076:4;20072:1;20068:6;20064:17;20058:4;20055:27;20052:53;;;20085:18;;:::i;:::-;20135:7;20125:8;20121:22;20118:55;;;20155:16;;;;20118:55;20234:22;;;;20194:15;;;;19996:270;;;20000:3;19850:422;;;;;:::o;20277:806::-;20326:5;20356:8;20346:80;;-1:-1:-1;20397:1:9;20411:5;;20346:80;20445:4;20435:76;;-1:-1:-1;20482:1:9;20496:5;;20435:76;20527:4;20545:1;20540:59;;;;20613:1;20608:130;;;;20520:218;;20540:59;20570:1;20561:10;;20584:5;;;20608:130;20645:3;20635:8;20632:17;20629:43;;;20652:18;;:::i;:::-;-1:-1:-1;;20708:1:9;20694:16;;20723:5;;20520:218;;20822:2;20812:8;20809:16;20803:3;20797:4;20794:13;20790:36;20784:2;20774:8;20771:16;20766:2;20760:4;20757:12;20753:35;20750:77;20747:159;;;-1:-1:-1;20859:19:9;;;20891:5;;20747:159;20938:34;20963:8;20957:4;20938:34;:::i;:::-;21008:6;21004:1;21000:6;20996:19;20987:7;20984:32;20981:58;;;21019:18;;:::i;:::-;21057:20;;20277:806;-1:-1:-1;;;20277:806:9:o;21088:131::-;21148:5;21177:36;21204:8;21198:4;21177:36;:::i;21224:127::-;21285:10;21280:3;21276:20;21273:1;21266:31;21316:4;21313:1;21306:15;21340:4;21337:1;21330:15;21356:120;21396:1;21422;21412:35;;21427:18;;:::i;:::-;-1:-1:-1;21461:9:9;;21356:120::o;24041:470::-;24220:3;24258:6;24252:13;24274:53;24320:6;24315:3;24308:4;24300:6;24296:17;24274:53;:::i;:::-;24390:13;;24349:16;;;;24412:57;24390:13;24349:16;24446:4;24434:17;;24412:57;:::i;:::-;24485:20;;24041:470;-1:-1:-1;;;;24041:470:9:o;26081:128::-;26121:3;26152:1;26148:6;26145:1;26142:13;26139:39;;;26158:18;;:::i;:::-;-1:-1:-1;26194:9:9;;26081:128::o;26214:274::-;26343:3;26381:6;26375:13;26397:53;26443:6;26438:3;26431:4;26423:6;26419:17;26397:53;:::i;:::-;26466:16;;;;;26214:274;-1:-1:-1;;26214:274:9:o;26907:251::-;26977:6;27030:2;27018:9;27009:7;27005:23;27001:32;26998:52;;;27046:1;27043;27036:12;26998:52;27078:9;27072:16;27097:31;27122:5;27097:31;:::i;27522:217::-;27561:4;27590:6;27646:10;;;;27616;;27668:12;;;27665:38;;;27683:18;;:::i;:::-;27720:13;;27522:217;-1:-1:-1;;;27522:217:9:o;28457:414::-;28659:2;28641:21;;;28698:2;28678:18;;;28671:30;28737:34;28732:2;28717:18;;28710:62;-1:-1:-1;;;28803:2:9;28788:18;;28781:48;28861:3;28846:19;;28457:414::o;30425:489::-;-1:-1:-1;;;;;30694:15:9;;;30676:34;;30746:15;;30741:2;30726:18;;30719:43;30793:2;30778:18;;30771:34;;;30841:3;30836:2;30821:18;;30814:31;;;30619:4;;30862:46;;30888:19;;30880:6;30862:46;:::i;30919:249::-;30988:6;31041:2;31029:9;31020:7;31016:23;31012:32;31009:52;;;31057:1;31054;31047:12;31009:52;31089:9;31083:16;31108:30;31132:5;31108:30;:::i;31173:112::-;31205:1;31231;31221:35;;31236:18;;:::i;:::-;-1:-1:-1;31270:9:9;;31173:112::o

Swarm Source

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