ETH Price: $3,313.39 (-3.94%)

Contract

0x5d2BF3b4264EFADE95fC89348f1367fCa0552861
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...211097552024-11-03 21:18:4723 days ago1730668727IN
0x5d2BF3b4...Ca0552861
0 ETH0.000220834.78436042
Set Approval For...211061802024-11-03 9:20:4723 days ago1730625647IN
0x5d2BF3b4...Ca0552861
0 ETH0.000109844.52604072
Set Approval For...210428712024-10-25 13:16:3532 days ago1729862195IN
0x5d2BF3b4...Ca0552861
0 ETH0.000378418.18343606
Set Approval For...210018192024-10-19 19:50:4738 days ago1729367447IN
0x5d2BF3b4...Ca0552861
0 ETH0.000388648.42007442
Set Approval For...209776072024-10-16 10:44:4741 days ago1729075487IN
0x5d2BF3b4...Ca0552861
0 ETH0.000588512.75004593
Set Approval For...209762162024-10-16 6:04:4741 days ago1729058687IN
0x5d2BF3b4...Ca0552861
0 ETH0.000458249.92801247
Set Approval For...206714872024-09-03 17:16:5984 days ago1725383819IN
0x5d2BF3b4...Ca0552861
0 ETH0.000057592.36725841
Set Approval For...205903882024-08-23 9:24:2395 days ago1724405063IN
0x5d2BF3b4...Ca0552861
0 ETH0.000024331.00379723
Set Approval For...205902432024-08-23 8:55:1195 days ago1724403311IN
0x5d2BF3b4...Ca0552861
0 ETH0.000047911.03802937
Set Approval For...204255372024-07-31 9:07:47118 days ago1722416867IN
0x5d2BF3b4...Ca0552861
0 ETH0.000196387.45907232
Set Approval For...204255192024-07-31 9:04:11118 days ago1722416651IN
0x5d2BF3b4...Ca0552861
0 ETH0.000175537.21525344
Set Approval For...202076782024-06-30 23:05:47149 days ago1719788747IN
0x5d2BF3b4...Ca0552861
0 ETH0.000196654.26056346
Set Approval For...201886112024-06-28 7:12:11151 days ago1719558731IN
0x5d2BF3b4...Ca0552861
0 ETH0.00008813.62143428
Set Approval For...201886102024-06-28 7:11:59151 days ago1719558719IN
0x5d2BF3b4...Ca0552861
0 ETH0.000085053.49620998
Safe Transfer Fr...201883482024-06-28 6:19:23151 days ago1719555563IN
0x5d2BF3b4...Ca0552861
0 ETH0.000424743.11966577
Approve201839082024-06-27 15:25:47152 days ago1719501947IN
0x5d2BF3b4...Ca0552861
0 ETH0.0008299216.28072332
Approve201838762024-06-27 15:19:11152 days ago1719501551IN
0x5d2BF3b4...Ca0552861
0 ETH0.0007928115.55280125
Set Approval For...200502752024-06-08 23:04:23171 days ago1717887863IN
0x5d2BF3b4...Ca0552861
0 ETH0.000220654.78058536
Set Approval For...200399122024-06-07 12:20:11172 days ago1717762811IN
0x5d2BF3b4...Ca0552861
0 ETH0.0007077515.30575557
Choose Equipment199533612024-05-26 10:09:23184 days ago1716718163IN
0x5d2BF3b4...Ca0552861
0 ETH0.000199433.7716784
Safe Transfer Fr...199248332024-05-22 10:29:35188 days ago1716373775IN
0x5d2BF3b4...Ca0552861
0 ETH0.000558987.15693046
Set Approval For...198749442024-05-15 11:00:35195 days ago1715770835IN
0x5d2BF3b4...Ca0552861
0 ETH0.000234865.08846387
Set Approval For...198652652024-05-14 2:27:23196 days ago1715653643IN
0x5d2BF3b4...Ca0552861
0 ETH0.000095663.94586606
Set Approval For...198652652024-05-14 2:27:23196 days ago1715653643IN
0x5d2BF3b4...Ca0552861
0 ETH0.000095993.94586606
Set Approval For...198271142024-05-08 18:25:47202 days ago1715192747IN
0x5d2BF3b4...Ca0552861
0 ETH0.000133545.48898979
View all transactions

Latest 5 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
141418342022-02-04 20:52:531026 days ago1644007973
0x5d2BF3b4...Ca0552861
269.76 ETH
141221132022-02-01 19:46:131029 days ago1643744773
0x5d2BF3b4...Ca0552861
189.2 ETH
141216402022-02-01 18:09:511029 days ago1643738991
0x5d2BF3b4...Ca0552861
69.92 ETH
141152332022-01-31 18:20:341030 days ago1643653234
0x5d2BF3b4...Ca0552861
18.56 ETH
141151392022-01-31 18:00:161030 days ago1643652016
0x5d2BF3b4...Ca0552861
0.72 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Starkade

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 6 : Starkade.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2022 Ponderware Ltd

pragma solidity ^0.8.9;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";

interface IReverseResolver {
    function claim(address owner) external returns (bytes32);
}

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
}

interface IMoonCatSVGS {
    function uint2str (uint value) external pure returns (string memory);
}

interface IMetadata {
    function legionMetadata (uint256 tokenId) external view returns (string memory);
}

/*
 * @title STARKADE Legion
 * @author Ponderware Ltd
 * @dev ERC-721 contract for Starkade Legion NFT
 * @notice license: https://starkade.com/licences/nft/starkade-legion/
 */
contract Starkade is IERC721Enumerable, IERC721Metadata {

    string public IPFS_URI_Prefix = "https://starkade-legion.mypinata.cloud/ipfs/";
    string public IPFS_Pass_Folder = "";
    string public IPFS_Core_Folder = "";
    string public IPFS_Legion_Folder = "";

    address public MetadataContractAddress;

    address public contractOwner;
    address internal flightlistSigner;

    bool public paused = true;

    string public name = "STARKADE";
    string public symbol = unicode"💫";

    address[7015] private Owners;
    mapping (address => uint256[]) internal TokensByOwner;
    uint16[7015] internal OwnerTokenIndex;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private TokenApprovals;
    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private OperatorApprovals;

    uint256 internal constant maxSupply = 7015;
    uint256 public totalSupply = 0;

    enum State
    {
     Ready,
     SaleOpen,
     RevealPrepped,
     Revealed
    }

    State public contractState = State.Ready;

    uint256 public saleOpenBlock;

    bytes32 public revealHash;
    uint256 public revealBlock;
    bytes32 public revealSeed;

    uint256 public coreRaffleIncrement;
    uint256[8] internal Primes = [81918643972203779099,
                                  72729269248899238429,
                                  19314683338901247061,
                                  38707402401747623009,
                                  54451314435228525599,
                                  16972551169207064863,
                                  44527956848616763003,
                                  51240633499522341181];

    uint256 coreRaffleOffset;

    /**
     * @dev Begin the reveal process by submitting the ipfs asset CIDs and a commitment hash of a secret "seed" value
     */
    function setSeedHash (bytes32 hash, string calldata ipfsCore, string calldata ipfsLegion) public onlyOwner {
        require(contractState == State.SaleOpen ||
                contractState == State.RevealPrepped,
                "Invalid State");
        require(block.number > revealBlock + 200);
        contractState = State.RevealPrepped;
        revealHash = hash;
        revealBlock = block.number;
        IPFS_Core_Folder = ipfsCore;
        IPFS_Legion_Folder = ipfsLegion;
    }

    /**
     * @dev Reveal all legion NFTs and determine core indexes by combining the value of the seed with blockhashes
     */
    function reveal (uint256 seed) public onlyOwner {
        require(block.number > revealBlock + 4
                && block.number < revealBlock + 200,
                "Block Range");
        require(contractState == State.RevealPrepped, "Already Revealed");
        require(keccak256(abi.encodePacked(seed)) == revealHash, "Seed Mismatch");
        revealSeed = keccak256(abi.encodePacked(seed,
                                                blockhash(revealBlock + 1),
                                                blockhash(revealBlock + 2),
                                                blockhash(revealBlock + 3)));
        coreRaffleOffset = uint256(revealSeed) % (totalSupply - 5);
        coreRaffleIncrement = Primes[uint256(revealSeed) % 8];
        contractState = State.Revealed;
    }

    /**
     * @dev Return the coreIndex of a token (only valid if returned value is < 15)
     */
    function coreIndex (uint256 tokenId) internal view returns (uint256) {
        if (tokenId < 5) {
            return tokenId;
        } else {
            return ((coreRaffleIncrement * (tokenId - 5) + coreRaffleOffset) % (totalSupply - 5)) + 5;
        }
    }

    /**
     * @dev Return whether a given tokenId represents a core character and, if so, the associated coreIndex
     */
    function isCore (uint256 tokenId) public view returns (bool, uint256) {
        uint256 coreIdx = coreIndex(tokenId);
        if (coreIdx < 15) {
            return (true, coreIdx);
        } else {
            return (false, 0);
        }
    }

    /* Minting/Passes */

    uint256 constant FLIGHTLIST_ISSUANCE_DELAY = 830; // Approximately 3 hours time

    uint256 public price = 0.08 ether;

    uint256 giftCutoff = 8000;
    uint256 flightlistCutoff = 8000;

    /**
     * @dev Set mint price
     */
    function setPrice (uint256 priceWei) public onlyOwner {
        price = priceWei;
    }

    /**
     * @dev Begin token sale
     */
    function openSale () public onlyOwner {
        require(contractState == State.Ready, "Not Ready");
        contractState = State.SaleOpen;
        saleOpenBlock = block.number;
        giftCutoff = totalSupply;
    }

    /**
     * @dev Bookeeping for pass issuance
     */
    function issuePassHelper (address recipient, uint256 passId) private whenNotPaused {
        TokensByOwner[recipient].push(passId);
        OwnerTokenIndex[passId] = uint16(TokensByOwner[recipient].length);
        Owners[passId] = recipient;
        emit Transfer(address(0), recipient, passId);
    }

    /**
     * @dev Allow contract owner to give a single pass
     */
    function givePass (address recipient) public onlyOwner {
        require(contractState == State.SaleOpen
                || contractState == State.Ready,
                "Sale Closed");
        require(totalSupply < maxSupply, "Max Supply Exceeded");
        issuePassHelper(recipient, totalSupply);
        totalSupply++;
    }

    /**
     * @dev Allow contract owner to give multiple passes
     */
    function givePasses (address[] calldata recipients) public onlyOwner {
        require(contractState == State.SaleOpen
                || contractState == State.Ready,
                "Sale Closed");
        require((totalSupply + recipients.length) <= maxSupply, "Max Supply Exceeded");
        for (uint i = 0; i < recipients.length; i++) {
            issuePassHelper(recipients[i], totalSupply + i);
        }
        totalSupply += recipients.length;
    }

    /**
     * @dev Check if a flightpass represents the given recipient and is signed by the flightlistSigner address
     */
    function validFlightlistPass (address recipient, bytes memory pass) public view returns (bool) {
        bytes32 m = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(abi.encodePacked("flightlisted", recipient))));

        uint8 v;
        bytes32 r;
        bytes32 s;

        require(pass.length == 65, "Invalid Flightpass");

        assembly {
            r := mload(add(pass, 32))
            s := mload(add(pass, 64))
            v := byte(0, mload(add(pass, 96)))
        }

        return (ecrecover(m, v, r, s) == flightlistSigner);
    }

    /**
     * @dev Mint one or more tokens to the provided address
     */
    function mint (address recipient, uint256 quantity, bytes memory pass) public payable {
        if (quantity > 10) {
            quantity = 10;
        }

        require(contractState == State.SaleOpen, "Sale Closed");

        if (block.number < saleOpenBlock + (8 * FLIGHTLIST_ISSUANCE_DELAY)) {
            require(validFlightlistPass(recipient, pass), "Invalid Flightpass");
            require(balanceOf(recipient) == 0, "Preflight Claimed");
            quantity = 1;
        } else if (block.number < saleOpenBlock + (9 * FLIGHTLIST_ISSUANCE_DELAY)) {
            require(validFlightlistPass(recipient, pass), "Invalid Flightpass");
            require(balanceOf(recipient) + quantity <= 11, "Flightpass limit exceeded");
        } else if (flightlistCutoff == 8000) {
            flightlistCutoff = totalSupply;
        }

        require((totalSupply + quantity) <= maxSupply, "Max Supply Exceeded");

        uint256 cost = price * quantity;
        require(msg.value >= cost, "Insufficient Funds");

        for (uint i = 0; i < quantity; i++) {
            issuePassHelper(recipient, totalSupply + i);
        }

        totalSupply += quantity;

        if (msg.value > cost) {
            (bool success,) = payable(msg.sender).call{value: msg.value - cost}("");
            require(success, "Refund Transfer Failed");
        }

    }

    /**
     * @dev Withdraw collected ETH to the contractOwner address
     */
    function withdraw () public {
        payable(contractOwner).transfer(address(this).balance);
    }

    /**
     * @dev Determine which issuance window a pass was minted in: 0 => Gift; 1 => Flightlist; 2 => General Sale
     */
    function passType (uint256 tokenId) public view returns (uint8) {
        require(tokenExists(tokenId), "Nonexistent Token");
        if (tokenId < giftCutoff) return 0;
        if (tokenId < flightlistCutoff) return 1;
        return 2;
    }

    /* SVG Assembly */

    IMoonCatSVGS MoonCatSVGS = IMoonCatSVGS(0xB39C61fe6281324A23e079464f7E697F8Ba6968f);

    /**
     * @dev Assemble one png layer of the SVG composite
     */
    function svgLayer (uint16 componentId)
        internal
        view
        returns (bytes memory)
    {
        return abi.encodePacked("<image x=\"0\" y=\"0\" width=\"600\" height=\"600\" href=\"",
                                IPFS_URI_Prefix,
                                IPFS_Legion_Folder,
                                "/",
                                MoonCatSVGS.uint2str(componentId),
                                ".png\" />");
    }

    /**
     * @dev Assemble the full SVG image for a legion fighter
     */
    function assembleSVG (uint16[13] memory componentIds) internal view returns (string memory) {
        bytes memory svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 600 600\" width=\"600\" height=\"600\">";
        for (uint i = 0; i < 12; i++) {
            svg = abi.encodePacked(svg, svgLayer(componentIds[i]));
        }
        return string(abi.encodePacked(svg, "</svg>"));
    }

    /* Enumerable */

    function tokenByIndex(uint256 tokenId) public view returns (uint256) {
        require(tokenExists(tokenId), "Nonexistent Token");
        return tokenId;
    }

    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return TokensByOwner[owner][index];
    }

    /* Owner Functions */

    constructor(address flightlistSigningAddress, string memory ipfsPass) {
        contractOwner = msg.sender;
        flightlistSigner = flightlistSigningAddress;
        // https://docs.ens.domains/contract-api-reference/reverseregistrar#claim-address
        IReverseResolver(0x084b1c3C81545d370f3634392De611CaaBFf8148).claim(msg.sender);
        configureCities();
        IPFS_Pass_Folder = ipfsPass;
    }

    /**
     * @dev Reset the flightlist signing address used for passes
     */
    function setFlightlistSigningAddress (address flightlistSigningAddress) public onlyOwner {
        flightlistSigner = flightlistSigningAddress;
    }

    /**
     * @dev Set the contract address for on-chain metadata assembly
     */
    function setMetadataContract (address metadata) public onlyOwner {
        MetadataContractAddress = metadata;
    }

    /**
     * @dev Set the URI prefix for accessing ipfs resources through a gateway
     */
    function setIpfsURIPrefix (string calldata ipfsURIPrefix) public onlyOwner {
        IPFS_URI_Prefix = ipfsURIPrefix;
    }

    /**
     * @dev Change the owner of the contract
     */
    function transferOwnership(address newOwner) public onlyOwner {
        contractOwner = newOwner;
    }

    function pause () public onlyOwner {
        paused = true;
    }

    function unpause () public onlyOwner {
        paused = false;
    }

    /**
     * @dev Public method to fetch a core character or assemble the image of a legion character on-chain (or passes, if not yet revealed)
     */
    function tokenImage (uint256 tokenId) public view returns (string memory) {
        require(tokenExists(tokenId), "Nonexistent Token");
        if (contractState == State.Revealed) {
            uint256 coreIdx = coreIndex(tokenId);
            if(coreIdx < 15) {
                return string(abi.encodePacked("ipfs://", IPFS_Core_Folder, "/", MoonCatSVGS.uint2str(coreIdx), ".png"));
            } else {
                uint256 dna = getDNA(tokenId);
                (uint16[13] memory components,,,) = getTraitComponents(tokenId, dna);
                return assembleSVG(components);
            }
        } else {
            return string(abi.encodePacked("ipfs://", IPFS_Pass_Folder, "/", MoonCatSVGS.uint2str(passType(tokenId)), ".png"));
        }
    }

    /**
     * @notice tokenURIs are returned as IPFS URIs for core characters and on-chain generated BASE64 encoded JSON for legion characters (or IPFS URIs for passes, if not yet revealed)
     * @dev JSON data is generated by a call to an external metadata contract
     */
    function tokenURI(uint256 tokenId) public view returns (string memory) {
        require(tokenId < totalSupply, "ERC721Metadata: URI query for nonexistent token");
        if (contractState == State.Revealed) {
            uint256 coreIdx = coreIndex(tokenId);
            if (coreIdx < 15) {
                return string(abi.encodePacked("ipfs://", IPFS_Core_Folder, "/", MoonCatSVGS.uint2str(coreIdx), ".json"));
            } else {
                return IMetadata(MetadataContractAddress).legionMetadata(tokenId);
            }
        } else {
            return string(abi.encodePacked("ipfs://", IPFS_Pass_Folder, "/", MoonCatSVGS.uint2str(passType(tokenId)), ".json"));
        }
    }

    function tokenExists(uint256 tokenId) public view returns (bool) {
        return (tokenId < totalSupply);
    }

    function ownerOf(uint256 tokenId) public view returns (address) {
        require(tokenExists(tokenId), "ERC721: Nonexistent token");
        return Owners[tokenId];
    }

    function balanceOf(address owner) public view returns (uint256) {
        return TokensByOwner[owner].length;
    }

    function supportsInterface(bytes4 interfaceId) public pure returns (bool) {
        return
            interfaceId == type(IERC165).interfaceId ||
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            interfaceId == type(IERC721Enumerable).interfaceId;
    }

    function _approve(address to, uint256 tokenId) internal {
        TokenApprovals[tokenId] = to;
        emit Approval(ownerOf(tokenId), to, tokenId);
    }

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

        require(
                msg.sender == owner || isApprovedForAll(owner, msg.sender),
                "ERC721: approve caller is not owner nor approved for all"
                );
        _approve(to, tokenId);
    }

    function getApproved(uint256 tokenId) public view returns (address) {
        require(tokenId < totalSupply, "ERC721: approved query for nonexistent token");
        return TokenApprovals[tokenId];
    }

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

    function setApprovalForAll(
                               address operator,
                               bool approved
                               ) external virtual {
        require(msg.sender != operator, "ERC721: approve to caller");
        OperatorApprovals[msg.sender][operator] = approved;
        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
        size := extcodesize(account)
                }
        return size > 0;
    }

    function _checkOnERC721Received(
                                    address from,
                                    address to,
                                    uint256 tokenId,
                                    bytes memory _data
                                    ) private returns (bool) {
        if (isContract(to)) {
            try IERC721Receiver(to).onERC721Received(msg.sender, 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 _transfer(
                       address from,
                       address to,
                       uint256 tokenId
                       ) private whenNotPaused {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");
        require(block.number > saleOpenBlock + (9 * FLIGHTLIST_ISSUANCE_DELAY), "Flightlist Active");
        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        uint16 valueIndex = OwnerTokenIndex[tokenId];
        uint256 toDeleteIndex = valueIndex - 1;
        uint256 lastIndex = TokensByOwner[from].length - 1;
        if (lastIndex != toDeleteIndex) {
            uint256 lastTokenId = TokensByOwner[from][lastIndex];
            TokensByOwner[from][toDeleteIndex] = lastTokenId;
            OwnerTokenIndex[lastTokenId] = valueIndex;
        }
        TokensByOwner[from].pop();

        TokensByOwner[to].push(tokenId);
        OwnerTokenIndex[tokenId] = uint16(TokensByOwner[to].length);

        Owners[tokenId] = to;
        emit Transfer(from, to, tokenId);
    }

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

    function transferFrom(
                          address from,
                          address to,
                          uint256 tokenId
                          ) public {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

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

    function safeTransferFrom(
                              address from,
                              address to,
                              uint256 tokenId,
                              bytes memory _data
                              ) public {
        require(_isApprovedOrOwner(msg.sender, 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
                           ) private {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /* Modifiers */

    modifier onlyOwner() {
        require(msg.sender == contractOwner, "Not Owner");
        _;
    }

    modifier whenNotPaused() {
        require(paused == false, "Paused");
        _;
    }

    modifier whenRevealed() {
        require(contractState == State.Revealed, "Not Revealed");
        _;
    }


    /* Rescuers */
    /**
    * @dev Rescue ERC20 assets sent directly to this contract.
    */
    function withdrawForeignERC20(address tokenContract) public onlyOwner {
        IERC20 token = IERC20(tokenContract);
        token.transfer(contractOwner, token.balanceOf(address(this)));
        }

    /**
     * @dev Rescue ERC721 assets sent directly to this contract.
     */
    function withdrawForeignERC721(address tokenContract, uint256 tokenId) public onlyOwner {
        IERC721(tokenContract).safeTransferFrom(address(this), contractOwner, tokenId);
    }

    /* Tokens */

    string[3] public PassTypeNames =
        [
         "Signalnoise",
         "Flight List",
         "STARKADE"
         ];

    string[182] internal Tokens =
        [
         "",
         "None",
         "$Magna",
         "Aeon",
         "Agile",
         "Ai",
         "Arcade",
         "Arm",
         "Armband",
         "Arms",
         "Arrows",
         "Athletic",
         "Aviators",
         "Awesome",
         "Back",
         "Bangs",
         "Basher",
         "Beefy",
         "Biker",
         "Black",
         "Blaster",
         "Blonde",
         "Blue",
         "Bounty",
         "Braids",
         "Bronco",
         "Camo",
         "Cap",
         "Chaos",
         "Choker",
         "Classic",
         "Clenched",
         "Comms",
         "Crash",
         "CrossStrap",
         "Cyan",
         "Cyber",
         "CyberBangs",
         "CyberWolf",
         "Digital",
         "Doomsday",
         "Double",
         "Dreadlocks",
         "Earring",
         "Elv",
         "Evil",
         "Eye",
         "Eyes",
         "Fangs",
         "Field",
         "Finisher",
         "Fire",
         "Flaming",
         "Flash",
         "Focussed",
         "Force",
         "Fortress",
         "Frostware",
         "Future",
         "GM",
         "Gem",
         "Green",
         "Grimm",
         "Grin",
         "Growl",
         "Grump",
         "Half-sleeves",
         "Hat",
         "Headphones",
         "Helmet",
         "Hex",
         "Hood",
         "Ice",
         "JacK",
         "Jacket",
         "Jet",
         "Kentaro",
         "Laugh",
         "Lavaware",
         "Leather",
         "Legion",
         "Leopard",
         "Lightning",
         "Line",
         "Long",
         "Magic",
         "Magna",
         "Magnaton",
         "Mask",
         "Mauve",
         "Mech",
         "Meh",
         "Merc",
         "Mohawk",
         "Morningstar",
         "Multi",
         "Necro",
         "NeonFire",
         "NuTech",
         "OG",
         "Obrakian",
         "Ochre",
         "Ombre",
         "Orange",
         "Pads",
         "Panther",
         "Paradise",
         "Patch",
         "Pink",
         "Pods",
         "Ponderware",
         "Ponytail",
         "Pout",
         "Power",
         "Punk",
         "Purple",
         "Rad",
         "Rain",
         "Rainbow",
         "Rev",
         "Ripped",
         "Robo",
         "Rocker",
         "SN",
         "Samurai",
         "Savage",
         "Shade",
         "Shades",
         "SharpShooter",
         "Shave",
         "Short",
         "Showhawk",
         "Side",
         "Silver",
         "Skull",
         "Sleeves",
         "Smile",
         "Sneer",
         "Spear",
         "Spears",
         "Spectran",
         "Spiked",
         "Spikes",
         "Staff",
         "Staffs",
         "Starkadian",
         "Stay",
         "Stealth",
         "Strapped",
         "Strike",
         "Stripe",
         "Stripes",
         "Stubble",
         "SunFire",
         "Sweep",
         "Swoosh",
         "Sword",
         "Syndicate",
         "Tattoos",
         "Tawny",
         "Tezukan",
         "Tongue",
         "Toothy",
         "Tribe",
         "VR",
         "Vapour",
         "Vest",
         "Visor",
         "Visualiser",
         "Volta",
         "Volume",
         "Warrior",
         "Wave",
         "Whip",
         "White",
         "Wig",
         "Wild",
         "Windblown",
         "Wink",
         "Yell",
         "Zebra",
         "Shaved"
         ];

    /* Trait Names */

    uint8[996] internal TraitNames =
        [
         17 , 0  , 0  , 11 , 0  , 0  , 86 , 117, 0  , 51 , 0  , 0  , 82 , 0  , 0  ,
         28 , 0  , 103, 28 , 0  , 108, 28 , 0  , 22 , 28 , 0  , 115, 113, 0  , 103,
         113, 0  , 108, 113, 0  , 22 , 113, 0  , 115, 86 , 143, 0  , 173, 0  , 0  ,
         20 , 0  , 0  , 75 , 109, 0  , 94 , 0  , 0  , 41 , 139, 0  , 55 , 49 , 0  ,
         10 , 0  , 0  , 138, 0  , 0  , 156, 0  , 0  , 86 , 143, 0  , 173, 0  , 0  ,
         20 , 0  , 0  , 75 , 109, 0  , 94 , 0  , 0  , 41 , 139, 0  , 144, 0  , 0  ,
         10 , 0  , 0  , 138, 0  , 0  , 156, 0  , 0  , 89 , 0  , 0  , 35 , 0  , 0  ,
         44 , 0  , 0  , 101, 0  , 0  , 159, 0  , 0  , 89 , 0  , 0  , 35 , 0  , 0  ,
         44 , 0  , 0  , 101, 0  , 0  , 159, 0  , 0  , 13 , 0  , 0  , 39 , 106, 0  ,
         157, 0  , 0  , 123, 134, 0  , 180, 0  , 22 , 145, 0  , 0  , 2  , 0  , 0  ,
         59 , 0  , 0  , 180, 0  , 108, 80 , 0  , 0  , 146, 116, 0  , 26 , 0  , 0  ,
         169, 62 , 0  , 39 , 106, 0  , 98 , 0  , 0  , 123, 134, 0  , 81 , 0  , 0  ,
         145, 0  , 0  , 2  , 0  , 0  , 105, 0  , 0  , 180, 0  , 108, 80 , 0  , 0  ,
         151, 0  , 0  , 26 , 0  , 0  , 5  , 0  , 0  , 145, 0  , 0  , 38 , 0  , 0  ,
         128, 0  , 0  , 126, 0  , 0  , 57 , 0  , 0  , 99 , 0  , 0  , 34 , 0  , 0  ,
         160, 0  , 0  , 80 , 0  , 115, 80 , 0  , 174, 100, 0  , 22 , 100, 0  , 61 ,
         5  , 0  , 0  , 145, 0  , 0  , 60 , 0  , 0  , 128, 0  , 0  , 126, 0  , 0  ,
         57 , 0  , 0  , 23 , 0  , 0  , 34 , 0  , 0  , 147, 0  , 0  , 80 , 0  , 174,
         78 , 0  , 0  , 87 , 0  , 0  , 100, 0  , 61 , 53 , 0  , 0  , 3  , 0  , 108,
         3  , 0  , 174, 1  , 0  , 0  , 40 , 0  , 0  , 16 , 0  , 19 , 16 , 0  , 108,
         16 , 0  , 115, 152, 0  , 0  , 36 , 163, 108, 36 , 163, 115, 53 , 0  , 0  ,
         3  , 0  , 108, 3  , 0  , 174, 1  , 0  , 0  , 171, 47 , 0  , 150, 0  , 0  ,
         16 , 0  , 22 , 16 , 0  , 115, 16 , 0  , 174, 36 , 163, 108, 36 , 163, 115,
         48 , 0  , 0  , 161, 0  , 0  , 162, 136, 0  , 91 , 0  , 0  , 31 , 0  , 0  ,
         65 , 0  , 0  , 77 , 0  , 0  , 137, 0  , 0  , 63 , 0  , 0  , 179, 0  , 0  ,
         48 , 0  , 0  , 161, 0  , 0  , 162, 136, 0  , 112, 0  , 0  , 31 , 0  , 0  ,
         137, 0  , 19 , 64 , 0  , 0  , 137, 0  , 0  , 136, 0  , 0  , 179, 0  , 0  ,
         90 , 0  , 0  , 153, 0  , 0  , 72 , 0  , 0  , 97 , 0  , 0  , 96 , 0  , 0  ,
         45 , 0  , 0  , 85 , 0  , 0  , 178, 0  , 0  , 30 , 0  , 0  , 54 , 0  , 0  ,
         90 , 0  , 0  , 153, 0  , 0  , 72 , 0  , 0  , 97 , 0  , 0  , 96 , 0  , 0  ,
         45 , 0  , 0  , 85 , 0  , 0  , 178, 0  , 0  , 30 , 0  , 0  , 54 , 0  , 0  ,
         36 , 46 , 0  , 118, 167, 0  , 124, 88 , 108, 134, 88 , 108, 164, 167, 0  ,
         46 , 107, 0  , 124, 88 , 61 , 83 , 127, 0  , 134, 88 , 174, 168, 0  , 0  ,
         60 , 0  , 0  , 33 , 88 , 0  , 121, 167, 108, 127, 0  , 133, 127, 0  , 19 ,
         127, 0  , 108, 12 , 0  , 0  , 50 , 88 , 22 , 50 , 88 , 115, 43 , 0  , 0  ,
         36 , 46 , 0  , 118, 167, 0  , 124, 88 , 103, 134, 88 , 115, 164, 167, 0  ,
         46 , 107, 0  , 57 , 88 , 0  , 83 , 127, 0  , 134, 88 , 103, 168, 0  , 0  ,
         60 , 0  , 0  , 121, 167, 19 , 121, 167, 174, 127, 0  , 133, 127, 0  , 19 ,
         125, 127, 0  , 12 , 0  , 0  , 50 , 88 , 103, 50 , 88 , 61 , 43 , 0  , 0  ,
         93 , 0  , 108, 124, 84 , 22 , 155, 0  , 174, 42 , 0  , 115, 176, 0  , 19 ,
         176, 0  , 174, 124, 0  , 174, 93 , 0  , 19 , 172, 0  , 115, 93 , 0  , 174,
         124, 84 , 174, 172, 0  , 174, 155, 0  , 19 , 42 , 0  , 174, 177, 0  , 19 ,
         131, 0  , 19 , 177, 0  , 108, 141, 0  , 19 , 141, 0  , 21 , 130, 142, 19 ,
         130, 142, 21 , 124, 0  , 19 , 124, 84 , 19 , 155, 0  , 21 , 172, 0  , 19 ,
         102, 0  , 0  , 93 , 0  , 115, 24 , 0  , 115, 141, 14 , 22 , 132, 129, 174,
         37 , 0  , 22 , 37 , 0  , 115, 154, 0  , 108, 130, 0  , 115, 111, 0  , 108,
         141, 130, 35 , 141, 84 , 35 , 141, 84 , 174, 130, 0  , 174, 24 , 0  , 22 ,
         132, 129, 19 , 111, 0  , 19 , 170, 0  , 0  , 141, 14 , 19 , 141, 130, 174,
         141, 84 , 19 , 15 , 0  , 108, 15 , 0  , 174, 93 , 0  , 19 , 154, 0  , 19 ,
         76 , 74 , 108, 6  , 74 , 0  , 50 , 104, 115, 36 , 7  , 0  , 128, 9  , 0  ,
         5  , 9  , 0  , 126, 9  , 0  , 76 , 74 , 22 , 92 , 104, 115, 40 , 104, 108,
         40 , 104, 115, 36 , 158, 0  , 73 , 9  , 174, 18 , 166, 0  , 79 , 74 , 19 ,
         148, 104, 0  , 149, 104, 108, 149, 104, 22 , 50 , 104, 22 , 145, 9  , 0  ,
         73 , 9  , 115, 70 , 9  , 103, 120, 135, 0  , 76 , 74 , 95 , 6  , 74 , 0  ,
         114, 166, 0  , 36 , 7  , 0  , 128, 9  , 0  , 5  , 9  , 0  , 126, 9  , 0  ,
         92 , 104, 95 , 141, 104, 0  , 40 , 104, 19 , 36 , 158, 0  , 73 , 9  , 174,
         29 , 0  , 115, 56 , 104, 0  , 79 , 74 , 174, 66 , 0  , 0  , 149, 104, 108,
         4  , 104, 0  , 145, 9  , 0  , 73 , 9  , 115, 29 , 0  , 19 , 120, 135, 0  ,
         8  , 0  , 0  , 128, 69 , 0  , 38 , 69 , 0  , 52 , 134, 0  , 73 , 69 , 174,
         5  , 69 , 0  , 121, 69 , 0  , 110, 69 , 108, 73 , 69 , 19 , 126, 69 , 0  ,
         119, 69 , 19 , 110, 69 , 22 , 119, 69 , 115, 25 , 67 , 0  , 122, 175, 0  ,
         71 , 0  , 22 , 71 , 0  , 115, 80 , 27 , 0  , 68 , 0  , 0  , 32 , 0  , 0  ,
         58 , 167, 0  , 128, 69 , 0  , 57 , 69 , 0  , 52 , 134, 0  , 73 , 69 , 174,
         5  , 69 , 0  , 78 , 69 , 0  , 110, 69 , 108, 73 , 69 , 19 , 126, 69 , 0  ,
         119, 69 , 19 , 110, 69 , 22 , 119, 69 , 115, 165, 88 , 0  , 25 , 67 , 0  ,
         140, 69 , 0  , 71 , 0  , 22 , 71 , 0  , 174, 80 , 27 , 0  , 68 , 0  , 0  ,
         32 , 0  , 0  , 181, 0  , 0
         ];

    /*
     * @dev Assemble the name associated with a traitIndex by building TraitNames from their associated Tokens
     */
    function traitName (uint256 traitIndex) public view returns (string memory) {
        uint256 baseIndex = traitIndex * 3;
        uint8 index1 = TraitNames[baseIndex];
        uint8 index2 = TraitNames[baseIndex + 1];
        uint8 index3 = TraitNames[baseIndex + 2];
        bytes memory result = bytes(Tokens[index1]);
        if (index2 > 0) {
            result = abi.encodePacked(result, " ", Tokens[index2]);
        }
        if (index3 > 0) {
            result = abi.encodePacked(result, ": ", Tokens[index3]);
        }
        return string(result);
    }

    string[7] public RegionNames =
      ["Shoreridge",
       "Skyroar Mountains",
       "Ark Teknos",
       "The Wailands",
       "Aeon Morrow",
       "Neowave Desert",
       "Grinferno Plains"];

    struct City {
        uint8 region;
        string name;
        string characteristic;
        uint8[5] bonus;
    }
    mapping (uint256 => City) internal Cities;

    /*
     * @dev Initialize Cities
     */
    function configureCities() internal {
        //                Rg. CityName             Characteristic   Po En Sp De Ch
        Cities[0] =  City(0, "Fellbreeze",         "Idealistic",   [0, 15, 0, 0, 0]);
        Cities[1] =  City(1, "Driftwood Quay",     "Imposing",     [0, 0, 0, 15, 0]);
        Cities[2] =  City(2, "Westforge",          "Industrious",  [15, 0, 0, 0, 0]);
        Cities[3] =  City(3, "Stonebrigg",         "Regimented",   [5, 0, 0, 5, 5]);
        Cities[4] =  City(3, "Kingdom of Spectra", "Fantastical",  [0, 0, 0, 0, 15]);
        Cities[5] =  City(4, "Magnaton City",      "Proud",        [5, 10, 0, 0, 0]);
        Cities[6] =  City(4, "Los Astra",          "Boisterous",   [0, 10, 0, 5, 0]);
        Cities[7] =  City(5, "Tezuka",             "Adaptable",    [0, 10, 0, 5, 0]);
        Cities[8] =  City(6, "Castor Locke",       "Cosmopolitan", [5, 5, 5, 0, 0]);
        Cities[9] =  City(6, "Obrak",              "Resourceful",  [0, 5, 5, 0, 5]);
        Cities[10] = City(6, "Warren Lake",        "Grim",         [5, 0, 5, 5, 0]);
        Cities[11] = City(6, "Brawna",             "Optimistic",   [0, 10, 5, 0, 0]);
    }

    /*
     * @dev Get info about a particular city
     */
    function cityInfo (uint256 cityId) public view returns (string memory regionName, string memory cityName, string memory characteristic) {
        require(cityId < 12, "Invalid cityId");
        City memory city = Cities[cityId];
        regionName = RegionNames[city.region];
        cityName = city.name;
        characteristic = city.characteristic;
    }

    //                                   Pow Ene Spe Def Cha
    uint8[55] public EquipmentBonuses = [ 0,  0,  0,  0,  0,
                                          0,  0,  0,  0, 15,
                                          5,  5,  5,  0,  0,
                                         15,  0,  0,  0,  0,
                                          0,  0, 15,  0,  0,
                                          5,  0,  0, 10,  0,
                                         10,  0,  0,  5,  0,
                                          0,  0,  5, 10,  0,
                                          0,  5, 10,  0,  0,
                                          5,  0,  5,  5,  0,
                                         10,  0,  5,  0,  0];

    string[5] public BoostNames =
        ["Power",
         "Energy",
         "Speed",
         "Defence",
         "Chaos"];

    /*
     * @dev Determines the bonus associated with a trait based on its rarity
     */
    function determineTraitBonus (uint8 strand)
        internal
        pure
        returns (uint8)
    {
        if (strand < 4) {
            return 6; // UltraRare
        } else if (strand < 24) {
            return 5; // Rare
        } else if (strand < 96) {
            return 4; // Uncommon
        } else {
            return 3; // Common
        }
    }

    /*
     * @dev Computes the component and bonus associated with an indexed trait
     */
    function determineTraitValue (uint256 dna,
                                  bool altBodyType,
                                  uint8 traitIndex,
                                  uint16 traitOffset,
                                  uint8 numElite,
                                  uint8 numRare,
                                  uint8 numUncommon,
                                  uint8 numCommon)

        internal
        pure
        returns (uint16 componentIndex, uint8 traitBonus)
    {
        uint8 strand = uint8(dna >> (traitIndex * 8));

        traitBonus = determineTraitBonus(strand);

        componentIndex = traitOffset;

        if (traitBonus == 6) {
            // UltraRare
            componentIndex += strand % numElite;
        } else if (traitBonus == 5) {
            // Rare
            componentIndex += (strand % numRare) + numElite;
        } else if (traitBonus == 4) {
            // Uncommon
            componentIndex += (strand % numUncommon) + numElite + numRare;
        } else {
            // Common
            componentIndex += (strand % numCommon) + numElite + numRare + numUncommon;
        }

        if (altBodyType) {
            componentIndex += (numElite + numRare + numUncommon + numCommon);
        }
    }


    mapping (uint256 => uint8) public Equipped;

    enum EquipmentSelectionStates
    {
     Open,
     Closed,
     Frozen
    }


    EquipmentSelectionStates public equipmentSelectionState = EquipmentSelectionStates.Closed;

    /*
     * @dev Allow equipment selection
     */
    function openEquipmentSelection () public onlyOwner {
        require (equipmentSelectionState == EquipmentSelectionStates.Closed, "Not Closed");
        equipmentSelectionState = EquipmentSelectionStates.Open;
    }

    /*
     * @dev Temporarily halt equipment selection
     */
    function closeEquipmentSelection () public onlyOwner {
        require (equipmentSelectionState == EquipmentSelectionStates.Open, "Not Open");
        equipmentSelectionState = EquipmentSelectionStates.Closed;
    }

    /*
     * @dev Permanently halt equipment selection
     */
    function permanentlyFreezeEquimentSelection () public onlyOwner {
        equipmentSelectionState = EquipmentSelectionStates.Frozen;
    }

    /*
     * @dev One-time selection of equipment for a legion character as an index from 1 through 5 into their specific equipment options
     */
    function chooseEquipment (uint256 tokenId, uint8 choice) public whenRevealed {
        require(ownerOf(tokenId) == msg.sender, "Not owner");
        require(choice > 0 && choice <= 5, "Invalid Choice");
        require(Equipped[tokenId] == 0, "Already Equipped");
        require(equipmentSelectionState == EquipmentSelectionStates.Open, "Not Open");
        Equipped[tokenId] = choice;
    }

    /*
     * @dev Process a tokenId into its associated DNA sequence by combining with the revealSeed (not applicable to core characters)
     */
    function getDNA (uint256 tokenId) public view returns (uint256) {
        require (coreIndex(tokenId) >= 15, "Core Character");
        return uint256(keccak256(abi.encodePacked(revealSeed, tokenId)));
    }

    /*
     * @dev Determine the pseudorandom selection of equipment available to a specific legion character
     */
    function equipmentOptions (uint256 dna) internal pure returns (uint8[5] memory) {

        uint16 equipmentSeed = uint8(dna >> 16);
        uint8[5] memory options;
        for (uint8 i = 0; i < 10; i++) {
            uint8 index = uint8((13 * i + equipmentSeed) % 10);
            if(index < 5) {
                options[index] = i + 1;
            }
        }

        return options;
    }

    uint16 constant EQUIPMENT_OFFSET = 13;
    uint16 constant SKIN_TONE_OFFSET = 33;

    /*
     * @dev Convert token DNA into an array of trait components, total bonus, active equipment, and body type
     */
    function getTraitComponents (uint256 tokenId, uint256 dna)
        internal
        view
        returns (uint16[13] memory components, uint8 totalBonus, uint8 equipmentId, bool alt)
    {

        alt = (dna >> 252 & 1) == 1;
        bool head = (dna >> 253 & 1) == 1; // Hair or Head Gear
        bool wear = (dna >> 254 & 1) == 1; // Shirt or Armour

        uint8 tempBonus;

        (components[0], tempBonus) = determineTraitValue(dna, false, 0, 2, 1, 2, 4, 4); // Background
        totalBonus += tempBonus;

        uint8 equipmentOption = Equipped[tokenId];
        if (equipmentOption > 0) {
            uint8[5] memory options = equipmentOptions(dna);
            equipmentId = options[equipmentOption - 1];
            components[1] = equipmentId - 1 + EQUIPMENT_OFFSET;
            if (alt) {
                components[1] += 10;
            }
        } else {
            components[1] = 96;
        }


        components[2] = uint16((((dna >> 24) & 255) % 5) + SKIN_TONE_OFFSET);
        if (alt) {
            components[2] += 5; // Skin Tone
        }

        if (wear) {
            (components[3], tempBonus) = determineTraitValue(dna, alt, 3, 43, 1, 3, 3, 5); // Shirt
            components[4] = 96;
        } else {
            (components[4], tempBonus) = determineTraitValue(dna, alt, 4, 67, 1, 2, 4, 6); // Armour
            components[3] = 96;
        }
        totalBonus += tempBonus;

        (components[5], tempBonus) = determineTraitValue(dna, alt, 5, 93, 1, 3, 3, 4); // Face Paint
        totalBonus += tempBonus;
        (components[6], tempBonus) = determineTraitValue(dna, alt, 6, 115, 1, 1, 4, 4); // Mouth
        totalBonus += tempBonus;
        (components[7], tempBonus) = determineTraitValue(dna, alt, 7, 135, 1, 4, 3, 2); // Eyes
        totalBonus += tempBonus;
        (components[8], tempBonus) = determineTraitValue(dna, alt, 8, 155, 3, 4, 6, 7); // Face Gear
        totalBonus += tempBonus;

        if (head) {
            (components[9], tempBonus) = determineTraitValue(dna, alt, 9, 195, 4, 5, 6, 10); // Hair
            components[11] = 96;
        } else {
            (components[11], tempBonus) = determineTraitValue(dna, alt, 11, 291, 3, 4, 6, 7); // Head Gear
            components[9] = 331;
        }
        totalBonus += tempBonus;

        (components[10], tempBonus) = determineTraitValue(dna, alt, 10, 245, 2, 4, 7, 10); // Gear
        totalBonus += tempBonus;

        components[12] = uint16((dna >> 96)) % 12; // City

    }

    /*
     * @dev Compute the boosts for each of Power, Energy, Speed, Defence, & Chaos
     */
    function getBoosts (uint256 dna, uint16 cityId, uint8 traitBonus, uint8 equipmentId) internal view returns (uint8[5] memory boosts) {
        uint8[5] memory cityBonus = Cities[cityId].bonus;

        for (uint i = 0; i < 10; i++) {
            uint boostId = (dna >> (i * 2 + 14 * 8)) & 3;
            while (boosts[boostId] >= 20) {
                if(boostId == 3) {
                    boostId = 0;
                } else {
                    boostId++;
                }
            }
            boosts[boostId] += 5;
        }

        for (uint i = 0; i < 5; i++) {
            boosts[i] += 10 + traitBonus + cityBonus[i] + EquipmentBonuses[equipmentId * 5 + i];
        }

        return boosts;
    }

    /*
     * @dev Public method for fetching the 5 pseudorandom equipment options for a legion character
     */
    function getEquipmentOptions (uint256 tokenId) public view whenRevealed returns (uint8[5] memory) {
        return equipmentOptions(getDNA(tokenId));
    }

    string[16] public Attributes =
        ["Body Type",
         "Background",
         "Equipment",
         "Skin Tone",
         "Shirt",
         "Armour",
         "Face Paint",
         "Mouth",
         "Eyes",
         "Face Gear",
         "Hair",
         "Gear",
         "Head Gear",
         "Region",
         "City",
         "Characteristic"];

    /*
     * @dev Return human-readable traits and boosts, along with a generated SVG for the provided tokenId (not applicable to core characters)
     */
    function getTraits (uint256 tokenId) public view whenRevealed returns (string[16] memory attributes, uint8[5] memory boosts, string memory image) {
        //  ** Attributes **
        //  0 - Body Type
        //  1 - Background
        //  2 - Equipment
        //  3 - Skin Tone
        //  4 - Shirt
        //  5 - Armour
        //  6 - Face Paint
        //  7 - Mouth
        //  8 - Eyes
        //  9 - Face Gear
        // 10 - Hair
        // 11 - Gear
        // 12 - Head Gear
        // 13 - Region
        // 14 - City
        // 15 - Characteristic

        // ** Boosts **
        //  0 - Power
        //  1 - Energy
        //  2 - Speed
        //  3 - Defence
        //  4 - Chaos

        uint256 dna = getDNA(tokenId);
        (uint16[13] memory components, uint8 totalBonus, uint8 equipmentId, bool alt) = getTraitComponents(tokenId, dna);
        boosts = getBoosts(dna, components[12], totalBonus, equipmentId);

        if(alt) {
            attributes[0] = traitName(1);
        } else {
            attributes[0] = traitName(0);
        }

        for (uint i = 0; i < 12; i++) {
            attributes[i + 1] = traitName(components[i]);
        }

        City memory city = Cities[components[12]];

        attributes[13] = RegionNames[city.region];
        attributes[14] = city.name;
        attributes[15] = city.characteristic;

        image = assembleSVG(components);
    }

    /*
     * @dev Return attributes and boosts for metadata or other contract consumption
     */
    function getTraitIndexes (uint256 tokenId) public view whenRevealed returns (uint16[15] memory attributes, uint8[5] memory boosts) {
        uint256 dna = getDNA(tokenId);
        (uint16[13] memory components, uint8 totalBonus, uint8 equipmentId, bool alt) = getTraitComponents(tokenId, dna);
        boosts = getBoosts(dna, components[12], totalBonus, equipmentId);

        if(alt) {
            attributes[0] = 1;
        } else {
            attributes[0] = 0;
        }

        for (uint i = 0; i < 12; i++) {
            attributes[i + 1] = components[i];
        }

        City memory city = Cities[components[12]];

        attributes[13] = city.region;
        attributes[14] = components[12];
    }

}

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

pragma solidity ^0.8.0;

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

File 3 of 6 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

File 4 of 6 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 5 of 6 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

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

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"flightlistSigningAddress","type":"address"},{"internalType":"string","name":"ipfsPass","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Attributes","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"BoostNames","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"EquipmentBonuses","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Equipped","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IPFS_Core_Folder","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IPFS_Legion_Folder","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IPFS_Pass_Folder","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IPFS_URI_Prefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MetadataContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"PassTypeNames","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"RegionNames","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint8","name":"choice","type":"uint8"}],"name":"chooseEquipment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"cityId","type":"uint256"}],"name":"cityInfo","outputs":[{"internalType":"string","name":"regionName","type":"string"},{"internalType":"string","name":"cityName","type":"string"},{"internalType":"string","name":"characteristic","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closeEquipmentSelection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractState","outputs":[{"internalType":"enum Starkade.State","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coreRaffleIncrement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"equipmentSelectionState","outputs":[{"internalType":"enum Starkade.EquipmentSelectionStates","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDNA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEquipmentOptions","outputs":[{"internalType":"uint8[5]","name":"","type":"uint8[5]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTraitIndexes","outputs":[{"internalType":"uint16[15]","name":"attributes","type":"uint16[15]"},{"internalType":"uint8[5]","name":"boosts","type":"uint8[5]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTraits","outputs":[{"internalType":"string[16]","name":"attributes","type":"string[16]"},{"internalType":"uint8[5]","name":"boosts","type":"uint8[5]"},{"internalType":"string","name":"image","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"givePass","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"givePasses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isCore","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes","name":"pass","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openEquipmentSelection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"openSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"passType","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permanentlyFreezeEquimentSelection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revealHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revealSeed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":[],"name":"saleOpenBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"flightlistSigningAddress","type":"address"}],"name":"setFlightlistSigningAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsURIPrefix","type":"string"}],"name":"setIpfsURIPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"metadata","type":"address"}],"name":"setMetadataContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"priceWei","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"string","name":"ipfsCore","type":"string"},{"internalType":"string","name":"ipfsLegion","type":"string"}],"name":"setSeedHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenImage","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"traitIndex","type":"uint256"}],"name":"traitName","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":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes","name":"pass","type":"bytes"}],"name":"validFlightlistPass","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawForeignERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdrawForeignERC721","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e0604052602c6080818152906200ade360a039805162000029916000916020909101906200546a565b506040805160208101918290526000908190526200004a916001916200546a565b506040805160208101918290526000908190526200006b916002916200546a565b506040805160208101918290526000908190526200008c916003916200546a565b506006805460ff60a01b1916600160a01b17905560408051808201909152600880825267535441524b41444560c01b6020909201918252620000d1916007916200546a565b5060408051808201909152600480825263f09f92ab60e01b6020909201918252620000ff916008916200546a565b506000611d2a55611d2b805460ff191690556040805161010081018252680470d97cab4ce6941b81526803f152450bb2614a1d602082015268010c0b8a29c45d5455918101919091526802192c51675e44dc6160608201526802f3a9edfbc0e5641f608082015267eb8a9d5d2cba591f60a0820152680269f314d5a7b96e7b60c08201526802c71b4caeed02993d60e0820152620001a390611d31906008620054f9565b5067011c37937e080000611d3a55611f40611d3b819055611d3c55611d3d80546001600160a01b03191673b39c61fe6281324a23e079464f7e697f8ba6968f1790556040805160a081018252600b606082018181526a5369676e616c6e6f69736560a81b60808401528252825180840184529081526a119b1a59da1d08131a5cdd60aa1b60208281019190915280830191909152825180840184526008815267535441524b41444560c01b91810191909152918101919091526200026d90611d3e90600362005535565b50604080516116e08101825260006116c082019081528152815180830183526004808252634e6f6e6560e01b6020838101919091528084019290925283518085018552600680825265244d61676e6160d01b8285015284860191909152845180860186528281526320b2b7b760e11b818501526060850152845180860186526005808252644167696c6560d81b82860152608086019190915285518087018752600280825261416960f01b8287015260a0870191909152865180880188528381526541726361646560d01b8187015260c08701528651808801885260038082526241726d60e81b8288015260e088019190915287518089018952600780825266105c9b58985b9960ca1b828901526101008901919091528851808a018a528681526341726d7360e01b818901526101208901528851808a018a52858152654172726f777360d01b818901526101408901528851808a018a526008808252674174686c6574696360c01b828a01526101608a01919091528951808b018b528181526741766961746f727360c01b818a01526101808a01528951808b018b5282815266417765736f6d6560c81b818a01526101a08a01528951808b018b52878152634261636b60e01b818a01526101c08a01528951808b018b528581526442616e677360d81b818a01526101e08a01528951808b018b52868152652130b9b432b960d11b818a01526102008a01528951808b018b5285815264426565667960d81b818a01526102208a01528951808b018b52858152642134b5b2b960d91b818a01526102408a01528951808b018b5285815264426c61636b60d81b818a01526102608a01528951808b018b5282815266213630b9ba32b960c91b818a01526102808a01528951808b018b5286815265426c6f6e646560d01b818a01526102a08a01528951808b018b5287815263426c756560e01b818a01526102c08a01528951808b018b5286815265426f756e747960d01b818a01526102e08a01528951808b018b528681526542726169647360d01b818a01526103008a01528951808b018b528681526542726f6e636f60d01b818a01526103208a01528951808b018b528781526343616d6f60e01b818a01526103408a01528951808b018b528381526204361760ec1b818a01526103608a01528951808b018b52858152644368616f7360d81b818a01526103808a01528951808b018b528681526521b437b5b2b960d11b818a01526103a08a01528951808b018b5282815266436c617373696360c81b818a01526103c08a01528951808b018b528181526710db195b98da195960c21b818a01526103e08a01528951808b018b5285815264436f6d6d7360d81b818a01526104008a01528951808b018b5285815264086e4c2e6d60db1b818a01526104208a01528951808b018b52600a80825269043726f737353747261760b41b828b01526104408b01919091528a51808c018c528881526321bcb0b760e11b818b01526104608b01528a51808c018c528681526421bcb132b960d91b818b01526104808b01528a51808c018c5281815269437962657242616e677360b01b818b01526104a08b01528a51808c018c5260098082526821bcb132b92bb7b63360b91b828c01526104c08c01919091528b51808d018d5284815266111a59da5d185b60ca1b818c01526104e08c01528b51808d018d5283815267446f6f6d7364617960c01b818c01526105008c01528b51808d018d5288815265446f75626c6560d01b818c01526105208c01528b51808d018d528281526944726561646c6f636b7360b01b818c01526105408c01528b51808d018d528481526645617272696e6760c81b818c01526105608c01528b51808d018d528581526222b63b60e91b818c01526105808c01528b51808d018d5289815263115d9a5b60e21b818c01526105a08c01528b51808d018d528581526245796560e81b818c01526105c08c01528b51808d018d52898152634579657360e01b818c01526105e08c01528b51808d018d528781526446616e677360d81b818c01526106008c01528b51808d018d5287815264119a595b1960da1b818c01526106208c01528b51808d018d52838152672334b734b9b432b960c11b818c01526106408c01528b51808d018d52898152634669726560e01b818c01526106608c01528b51808d018d5284815266466c616d696e6760c81b818c01526106808c01528b51808d018d528781526408cd8c2e6d60db1b818c01526106a08c01528b51808d018d5283815267119bd8dd5cdcd95960c21b818c01526106c08c01528b51808d018d5287815264466f72636560d81b818c01526106e08c01528b51808d018d5283815267466f72747265737360c01b818c01526107008c01528b51808d018d528181526846726f73747761726560b81b818c01526107208c01528b51808d018d528881526546757475726560d01b818c01526107408c01528b51808d018d5286815261474d60f01b818c01526107608c01528b51808d018d528581526247656d60e81b818c01526107808c01528b51808d018d528781526423b932b2b760d91b818c01526107a08c01528b51808d018d52878152644772696d6d60d81b818c01526107c08c01528b51808d018d528981526323b934b760e11b818c01526107e08c01528b51808d018d528781526411dc9bdddb60da1b818c01526108008c01528b51808d018d528781526404772756d760dc1b818c01526108208c01528b51808d018d52600c8082526b48616c662d736c656576657360a01b828d01526108408d01919091528c51808e018e528681526212185d60ea1b818d01526108608d01528c51808e018e52838152694865616470686f6e657360b01b818d01526108808d01528c51808e018e528981526512195b1b595d60d21b818d01526108a08d01528c51808e018e5286815262090caf60eb1b818d01526108c08d01528c51808e018e528a815263121bdbd960e21b818d01526108e08d01528c51808e018e528681526249636560e81b818d01526109008d01528c51808e018e528a8152634a61634b60e01b818d01526109208d01528c51808e018e5289815265129858dad95d60d21b818d01526109408d01528c51808e018e528681526212995d60ea1b818d01526109608d01528c51808e018e52858152664b656e7461726f60c81b818d01526109808d01528c51808e018e5288815264098c2eaced60db1b818d01526109a08d01528c51808e018e52848152674c6176617761726560c01b818d01526109c08d01528c51808e018e52858152662632b0ba3432b960c91b818d01526109e08d01528c51808e018e52898152652632b3b4b7b760d11b818d0152610a008d01528c51808e018e528581526613195bdc185c9960ca1b818d0152610a208d01528c51808e018e52828152684c696768746e696e6760b81b818d0152610a408d01528c51808e018e528a8152634c696e6560e01b818d0152610a608d01528c51808e018e528a8152634c6f6e6760e01b818d0152610a808d01528c51808e018e52888152644d6167696360d81b818d0152610aa08d01528c51808e018e52888152644d61676e6160d81b818d0152610ac08d01528c51808e018e528481526726b0b3b730ba37b760c11b818d0152610ae08d01528c51808e018e528a8152634d61736b60e01b818d0152610b008d01528c51808e018e52888152644d6175766560d81b818d0152610b208d01528c51808e018e528a81526309acac6d60e31b818d0152610b408d01528c51808e018e528681526209acad60eb1b818d0152610b608d01528c51808e018e528a8152634d65726360e01b818d0152610b808d01528c51808e018e52898152654d6f6861776b60d01b818d0152610ba08d01528c51808e018e52600b81526a26b7b93734b733b9ba30b960a91b818d0152610bc08d01528c51808e018e52888152644d756c746960d81b818d0152610be08d01528c51808e018e52888152644e6563726f60d81b818d0152610c008d01528c51808e018e52848152674e656f6e4669726560c01b818d0152610c208d01528c51808e018e528981526509ceaa8cac6d60d31b818d0152610c408d01528c51808e018e52878152614f4760f01b818d0152610c608d01528c51808e018e528481526727b13930b5b4b0b760c11b818d0152610c808d01528c51808e018e52888152644f6368726560d81b818d0152610ca08d01528c51808e018e52888152644f6d62726560d81b818d0152610cc08d01528c51808e018e52898152654f72616e676560d01b818d0152610ce08d01528c51808e018e528a8152635061647360e01b818d0152610d008d01528c51808e018e52858152662830b73a3432b960c91b818d0152610d208d01528c51808e018e5284815267506172616469736560c01b818d0152610d408d01528c51808e018e52888152640a0c2e8c6d60db1b818d0152610d608d01528c51808e018e528a81526350696e6b60e01b818d0152610d808d01528c51808e018e528a815263506f647360e01b818d0152610da08d01528c51808e018e5283815269506f6e6465727761726560b01b818d0152610dc08d01528c51808e018e5284815267141bdb9e5d185a5b60c21b818d0152610de08d01528c51808e018e528a815263141bdd5d60e21b818d0152610e008d01528c51808e018e52888152642837bbb2b960d91b818d0152610e208d01528c51808e018e528a81526350756e6b60e01b818d0152610e408d01528c51808e018e5289815265507572706c6560d01b818d0152610e608d01528c51808e018e528681526214985960ea1b818d0152610e808d01528c51808e018e528a8152632930b4b760e11b818d0152610ea08d01528c51808e018e52858152665261696e626f7760c81b818d0152610ec08d01528c51808e018e52868152622932bb60e91b818d0152610ee08d01528c51808e018e5289815265149a5c1c195960d21b818d0152610f008d01528c51808e018e528a815263526f626f60e01b818d0152610f208d01528c51808e018e52898152652937b1b5b2b960d11b818d0152610f408d01528c51808e018e528781526129a760f11b818d0152610f608d01528c51808e018e528581526653616d7572616960c81b818d0152610f808d01528c51808e018e528981526553617661676560d01b818d0152610fa08d01528c51808e018e5288815264536861646560d81b818d0152610fc08d01528c51808e018e528981526553686164657360d01b818d0152610fe08d01528c51808e018e529081526b29b430b93829b437b7ba32b960a11b818c01526110008c01528b51808d018d5287815264536861766560d81b818c01526110208c01528b51808d018d528781526414da1bdc9d60da1b818c01526110408c01528b51808d018d528381526753686f776861776b60c01b818c01526110608c01528b51808d018d52898152635369646560e01b818c01526110808c01528b51808d018d528881526529b4b63b32b960d11b818c01526110a08c01528b51808d018d528781526414dadd5b1b60da1b818c01526110c08c01528b51808d018d5284815266536c656576657360c81b818c01526110e08c01528b51808d018d5287815264536d696c6560d81b818c01526111008c01528b51808d018d528781526429b732b2b960d91b818c01526111208c01528b51808d018d528781526429b832b0b960d91b818c01526111408c01528b51808d018d528881526553706561727360d01b818c01526111608c01528b51808d018d528381526729b832b1ba3930b760c11b818c01526111808c01528b51808d018d528881526514dc1a5ad95960d21b818c01526111a08c01528b51808d018d52888152655370696b657360d01b818c01526111c08c01528b51808d018d528781526429ba30b33360d91b818c01526111e08c01528b51808d018d528881526553746166667360d01b818c01526112008c01528b51808d018d528281526929ba30b935b0b234b0b760b11b818c01526112208c01528b51808d018d52898152635374617960e01b818c01526112408c01528b51808d018d52848152660a6e8cac2d8e8d60cb1b818c01526112608c01528b51808d018d529283526714dd1c985c1c195960c21b838b01526112808b01929092528a51808c018c5287815265537472696b6560d01b818b01526112a08b01528a51808c018c528781526553747269706560d01b818b01526112c08b01528a51808c018c52838152665374726970657360c81b818b01526112e08b01528a51808c018c528381526653747562626c6560c81b818b01526113008b01528a51808c018c528381526653756e4669726560c81b818b01526113208b01528a51808c018c5286815264053776565760dc1b818b01526113408b01528a51808c018c52878152650a6eededee6d60d31b818b01526113608b01528a51808c018c528681526414dddbdc9960da1b818b01526113808b01528a51808c018c528281526853796e64696361746560b81b818b01526113a08b01528a51808c018c5283815266546174746f6f7360c81b818b01526113c08b01528a51808c018c52868152645461776e7960d81b818b01526113e08b01528a51808c018c52838152662a32bd3ab5b0b760c91b818b01526114008b01528a51808c018c5287815265546f6e67756560d01b818b01526114208b01528a51808c018c5287815265546f6f74687960d01b818b01526114408b01528a51808c018c5286815264547269626560d81b818b01526114608b01528a51808c018c52948552612b2960f11b858a01526114808a01949094528951808b018b52868152652b30b837bab960d11b818a01526114a08a01528951808b018b528781526315995cdd60e21b818a01526114c08a01528951808b018b52858152642b34b9b7b960d91b818a01526114e08a01528951808b018b52938452692b34b9bab0b634b9b2b960b11b848901526115008901939093528851808a018a5284815264566f6c746160d81b818901526115208901528851808a018a5285815265566f6c756d6560d01b818901526115408901528851808a018a52908152662bb0b93934b7b960c91b8188015261156088015287518089018952858152635761766560e01b8188015261158088015287518089018952858152630576869760e41b818801526115a08801528751808901895283815264576869746560d81b818801526115c0880152875180890189529081526257696760e81b818701526115e0870152865180880188528481526315da5b1960e21b8187015261160087015286518088018852908152682bb4b732313637bbb760b91b81860152611620860152855180870187528381526357696e6b60e01b81860152611640860152855180870187529283526316595b1b60e21b8385015261166085019290925284518086018652918252645a6562726160d81b82840152611680840191909152835180850190945283526514da185d995960d21b908301526116a0810191909152620017d690611d419060b662005588565b5060405180617c800160405280601160ff168152602001600060ff168152602001600060ff168152602001600b60ff168152602001600060ff168152602001600060ff168152602001605660ff168152602001607560ff168152602001600060ff168152602001603360ff168152602001600060ff168152602001600060ff168152602001605260ff168152602001600060ff168152602001600060ff168152602001601c60ff168152602001600060ff168152602001606760ff168152602001601c60ff168152602001600060ff168152602001606c60ff168152602001601c60ff168152602001600060ff168152602001601660ff168152602001601c60ff168152602001600060ff168152602001607360ff168152602001607160ff168152602001600060ff168152602001606760ff168152602001607160ff168152602001600060ff168152602001606c60ff168152602001607160ff168152602001600060ff168152602001601660ff168152602001607160ff168152602001600060ff168152602001607360ff168152602001605660ff168152602001608f60ff168152602001600060ff16815260200160ad60ff168152602001600060ff168152602001600060ff168152602001601460ff168152602001600060ff168152602001600060ff168152602001604b60ff168152602001606d60ff168152602001600060ff168152602001605e60ff168152602001600060ff168152602001600060ff168152602001602960ff168152602001608b60ff168152602001600060ff168152602001603760ff168152602001603160ff168152602001600060ff168152602001600a60ff168152602001600060ff168152602001600060ff168152602001608a60ff168152602001600060ff168152602001600060ff168152602001609c60ff168152602001600060ff168152602001600060ff168152602001605660ff168152602001608f60ff168152602001600060ff16815260200160ad60ff168152602001600060ff168152602001600060ff168152602001601460ff168152602001600060ff168152602001600060ff168152602001604b60ff168152602001606d60ff168152602001600060ff168152602001605e60ff168152602001600060ff168152602001600060ff168152602001602960ff168152602001608b60ff168152602001600060ff168152602001609060ff168152602001600060ff168152602001600060ff168152602001600a60ff168152602001600060ff168152602001600060ff168152602001608a60ff168152602001600060ff168152602001600060ff168152602001609c60ff168152602001600060ff168152602001600060ff168152602001605960ff168152602001600060ff168152602001600060ff168152602001602360ff168152602001600060ff168152602001600060ff168152602001602c60ff168152602001600060ff168152602001600060ff168152602001606560ff168152602001600060ff168152602001600060ff168152602001609f60ff168152602001600060ff168152602001600060ff168152602001605960ff168152602001600060ff168152602001600060ff168152602001602360ff168152602001600060ff168152602001600060ff168152602001602c60ff168152602001600060ff168152602001600060ff168152602001606560ff168152602001600060ff168152602001600060ff168152602001609f60ff168152602001600060ff168152602001600060ff168152602001600d60ff168152602001600060ff168152602001600060ff168152602001602760ff168152602001606a60ff168152602001600060ff168152602001609d60ff168152602001600060ff168152602001600060ff168152602001607b60ff168152602001608660ff168152602001600060ff16815260200160b460ff168152602001600060ff168152602001601660ff168152602001609160ff168152602001600060ff168152602001600060ff168152602001600260ff168152602001600060ff168152602001600060ff168152602001603b60ff168152602001600060ff168152602001600060ff16815260200160b460ff168152602001600060ff168152602001606c60ff168152602001605060ff168152602001600060ff168152602001600060ff168152602001609260ff168152602001607460ff168152602001600060ff168152602001601a60ff168152602001600060ff168152602001600060ff16815260200160a960ff168152602001603e60ff168152602001600060ff168152602001602760ff168152602001606a60ff168152602001600060ff168152602001606260ff168152602001600060ff168152602001600060ff168152602001607b60ff168152602001608660ff168152602001600060ff168152602001605160ff168152602001600060ff168152602001600060ff168152602001609160ff168152602001600060ff168152602001600060ff168152602001600260ff168152602001600060ff168152602001600060ff168152602001606960ff168152602001600060ff168152602001600060ff16815260200160b460ff168152602001600060ff168152602001606c60ff168152602001605060ff168152602001600060ff168152602001600060ff168152602001609760ff168152602001600060ff168152602001600060ff168152602001601a60ff168152602001600060ff168152602001600060ff168152602001600560ff168152602001600060ff168152602001600060ff168152602001609160ff168152602001600060ff168152602001600060ff168152602001602660ff168152602001600060ff168152602001600060ff168152602001608060ff168152602001600060ff168152602001600060ff168152602001607e60ff168152602001600060ff168152602001600060ff168152602001603960ff168152602001600060ff168152602001600060ff168152602001606360ff168152602001600060ff168152602001600060ff168152602001602260ff168152602001600060ff168152602001600060ff16815260200160a060ff168152602001600060ff168152602001600060ff168152602001605060ff168152602001600060ff168152602001607360ff168152602001605060ff168152602001600060ff16815260200160ae60ff168152602001606460ff168152602001600060ff168152602001601660ff168152602001606460ff168152602001600060ff168152602001603d60ff168152602001600560ff168152602001600060ff168152602001600060ff168152602001609160ff168152602001600060ff168152602001600060ff168152602001603c60ff168152602001600060ff168152602001600060ff168152602001608060ff168152602001600060ff168152602001600060ff168152602001607e60ff168152602001600060ff168152602001600060ff168152602001603960ff168152602001600060ff168152602001600060ff168152602001601760ff168152602001600060ff168152602001600060ff168152602001602260ff168152602001600060ff168152602001600060ff168152602001609360ff168152602001600060ff168152602001600060ff168152602001605060ff168152602001600060ff16815260200160ae60ff168152602001604e60ff168152602001600060ff168152602001600060ff168152602001605760ff168152602001600060ff168152602001600060ff168152602001606460ff168152602001600060ff168152602001603d60ff168152602001603560ff168152602001600060ff168152602001600060ff168152602001600360ff168152602001600060ff168152602001606c60ff168152602001600360ff168152602001600060ff16815260200160ae60ff168152602001600160ff168152602001600060ff168152602001600060ff168152602001602860ff168152602001600060ff168152602001600060ff168152602001601060ff168152602001600060ff168152602001601360ff168152602001601060ff168152602001600060ff168152602001606c60ff168152602001601060ff168152602001600060ff168152602001607360ff168152602001609860ff168152602001600060ff168152602001600060ff168152602001602460ff16815260200160a360ff168152602001606c60ff168152602001602460ff16815260200160a360ff168152602001607360ff168152602001603560ff168152602001600060ff168152602001600060ff168152602001600360ff168152602001600060ff168152602001606c60ff168152602001600360ff168152602001600060ff16815260200160ae60ff168152602001600160ff168152602001600060ff168152602001600060ff16815260200160ab60ff168152602001602f60ff168152602001600060ff168152602001609660ff168152602001600060ff168152602001600060ff168152602001601060ff168152602001600060ff168152602001601660ff168152602001601060ff168152602001600060ff168152602001607360ff168152602001601060ff168152602001600060ff16815260200160ae60ff168152602001602460ff16815260200160a360ff168152602001606c60ff168152602001602460ff16815260200160a360ff168152602001607360ff168152602001603060ff168152602001600060ff168152602001600060ff16815260200160a160ff168152602001600060ff168152602001600060ff16815260200160a260ff168152602001608860ff168152602001600060ff168152602001605b60ff168152602001600060ff168152602001600060ff168152602001601f60ff168152602001600060ff168152602001600060ff168152602001604160ff168152602001600060ff168152602001600060ff168152602001604d60ff168152602001600060ff168152602001600060ff168152602001608960ff168152602001600060ff168152602001600060ff168152602001603f60ff168152602001600060ff168152602001600060ff16815260200160b360ff168152602001600060ff168152602001600060ff168152602001603060ff168152602001600060ff168152602001600060ff16815260200160a160ff168152602001600060ff168152602001600060ff16815260200160a260ff168152602001608860ff168152602001600060ff168152602001607060ff168152602001600060ff168152602001600060ff168152602001601f60ff168152602001600060ff168152602001600060ff168152602001608960ff168152602001600060ff168152602001601360ff168152602001604060ff168152602001600060ff168152602001600060ff168152602001608960ff168152602001600060ff168152602001600060ff168152602001608860ff168152602001600060ff168152602001600060ff16815260200160b360ff168152602001600060ff168152602001600060ff168152602001605a60ff168152602001600060ff168152602001600060ff168152602001609960ff168152602001600060ff168152602001600060ff168152602001604860ff168152602001600060ff168152602001600060ff168152602001606160ff168152602001600060ff168152602001600060ff168152602001606060ff168152602001600060ff168152602001600060ff168152602001602d60ff168152602001600060ff168152602001600060ff168152602001605560ff168152602001600060ff168152602001600060ff16815260200160b260ff168152602001600060ff168152602001600060ff168152602001601e60ff168152602001600060ff168152602001600060ff168152602001603660ff168152602001600060ff168152602001600060ff168152602001605a60ff168152602001600060ff168152602001600060ff168152602001609960ff168152602001600060ff168152602001600060ff168152602001604860ff168152602001600060ff168152602001600060ff168152602001606160ff168152602001600060ff168152602001600060ff168152602001606060ff168152602001600060ff168152602001600060ff168152602001602d60ff168152602001600060ff168152602001600060ff168152602001605560ff168152602001600060ff168152602001600060ff16815260200160b260ff168152602001600060ff168152602001600060ff168152602001601e60ff168152602001600060ff168152602001600060ff168152602001603660ff168152602001600060ff168152602001600060ff168152602001602460ff168152602001602e60ff168152602001600060ff168152602001607660ff16815260200160a760ff168152602001600060ff168152602001607c60ff168152602001605860ff168152602001606c60ff168152602001608660ff168152602001605860ff168152602001606c60ff16815260200160a460ff16815260200160a760ff168152602001600060ff168152602001602e60ff168152602001606b60ff168152602001600060ff168152602001607c60ff168152602001605860ff168152602001603d60ff168152602001605360ff168152602001607f60ff168152602001600060ff168152602001608660ff168152602001605860ff16815260200160ae60ff16815260200160a860ff168152602001600060ff168152602001600060ff168152602001603c60ff168152602001600060ff168152602001600060ff168152602001602160ff168152602001605860ff168152602001600060ff168152602001607960ff16815260200160a760ff168152602001606c60ff168152602001607f60ff168152602001600060ff168152602001608560ff168152602001607f60ff168152602001600060ff168152602001601360ff168152602001607f60ff168152602001600060ff168152602001606c60ff168152602001600c60ff168152602001600060ff168152602001600060ff168152602001603260ff168152602001605860ff168152602001601660ff168152602001603260ff168152602001605860ff168152602001607360ff168152602001602b60ff168152602001600060ff168152602001600060ff168152602001602460ff168152602001602e60ff168152602001600060ff168152602001607660ff16815260200160a760ff168152602001600060ff168152602001607c60ff168152602001605860ff168152602001606760ff168152602001608660ff168152602001605860ff168152602001607360ff16815260200160a460ff16815260200160a760ff168152602001600060ff168152602001602e60ff168152602001606b60ff168152602001600060ff168152602001603960ff168152602001605860ff168152602001600060ff168152602001605360ff168152602001607f60ff168152602001600060ff168152602001608660ff168152602001605860ff168152602001606760ff16815260200160a860ff168152602001600060ff168152602001600060ff168152602001603c60ff168152602001600060ff168152602001600060ff168152602001607960ff16815260200160a760ff168152602001601360ff168152602001607960ff16815260200160a760ff16815260200160ae60ff168152602001607f60ff168152602001600060ff168152602001608560ff168152602001607f60ff168152602001600060ff168152602001601360ff168152602001607d60ff168152602001607f60ff168152602001600060ff168152602001600c60ff168152602001600060ff168152602001600060ff168152602001603260ff168152602001605860ff168152602001606760ff168152602001603260ff168152602001605860ff168152602001603d60ff168152602001602b60ff168152602001600060ff168152602001600060ff168152602001605d60ff168152602001600060ff168152602001606c60ff168152602001607c60ff168152602001605460ff168152602001601660ff168152602001609b60ff168152602001600060ff16815260200160ae60ff168152602001602a60ff168152602001600060ff168152602001607360ff16815260200160b060ff168152602001600060ff168152602001601360ff16815260200160b060ff168152602001600060ff16815260200160ae60ff168152602001607c60ff168152602001600060ff16815260200160ae60ff168152602001605d60ff168152602001600060ff168152602001601360ff16815260200160ac60ff168152602001600060ff168152602001607360ff168152602001605d60ff168152602001600060ff16815260200160ae60ff168152602001607c60ff168152602001605460ff16815260200160ae60ff16815260200160ac60ff168152602001600060ff16815260200160ae60ff168152602001609b60ff168152602001600060ff168152602001601360ff168152602001602a60ff168152602001600060ff16815260200160ae60ff16815260200160b160ff168152602001600060ff168152602001601360ff168152602001608360ff168152602001600060ff168152602001601360ff16815260200160b160ff168152602001600060ff168152602001606c60ff168152602001608d60ff168152602001600060ff168152602001601360ff168152602001608d60ff168152602001600060ff168152602001601560ff168152602001608260ff168152602001608e60ff168152602001601360ff168152602001608260ff168152602001608e60ff168152602001601560ff168152602001607c60ff168152602001600060ff168152602001601360ff168152602001607c60ff168152602001605460ff168152602001601360ff168152602001609b60ff168152602001600060ff168152602001601560ff16815260200160ac60ff168152602001600060ff168152602001601360ff168152602001606660ff168152602001600060ff168152602001600060ff168152602001605d60ff168152602001600060ff168152602001607360ff168152602001601860ff168152602001600060ff168152602001607360ff168152602001608d60ff168152602001600e60ff168152602001601660ff168152602001608460ff168152602001608160ff16815260200160ae60ff168152602001602560ff168152602001600060ff168152602001601660ff168152602001602560ff168152602001600060ff168152602001607360ff168152602001609a60ff168152602001600060ff168152602001606c60ff168152602001608260ff168152602001600060ff168152602001607360ff168152602001606f60ff168152602001600060ff168152602001606c60ff168152602001608d60ff168152602001608260ff168152602001602360ff168152602001608d60ff168152602001605460ff168152602001602360ff168152602001608d60ff168152602001605460ff16815260200160ae60ff168152602001608260ff168152602001600060ff16815260200160ae60ff168152602001601860ff168152602001600060ff168152602001601660ff168152602001608460ff168152602001608160ff168152602001601360ff168152602001606f60ff168152602001600060ff168152602001601360ff16815260200160aa60ff168152602001600060ff168152602001600060ff168152602001608d60ff168152602001600e60ff168152602001601360ff168152602001608d60ff168152602001608260ff16815260200160ae60ff168152602001608d60ff168152602001605460ff168152602001601360ff168152602001600f60ff168152602001600060ff168152602001606c60ff168152602001600f60ff168152602001600060ff16815260200160ae60ff168152602001605d60ff168152602001600060ff168152602001601360ff168152602001609a60ff168152602001600060ff168152602001601360ff168152602001604c60ff168152602001604a60ff168152602001606c60ff168152602001600660ff168152602001604a60ff168152602001600060ff168152602001603260ff168152602001606860ff168152602001607360ff168152602001602460ff168152602001600760ff168152602001600060ff168152602001608060ff168152602001600960ff168152602001600060ff168152602001600560ff168152602001600960ff168152602001600060ff168152602001607e60ff168152602001600960ff168152602001600060ff168152602001604c60ff168152602001604a60ff168152602001601660ff168152602001605c60ff168152602001606860ff168152602001607360ff168152602001602860ff168152602001606860ff168152602001606c60ff168152602001602860ff168152602001606860ff168152602001607360ff168152602001602460ff168152602001609e60ff168152602001600060ff168152602001604960ff168152602001600960ff16815260200160ae60ff168152602001601260ff16815260200160a660ff168152602001600060ff168152602001604f60ff168152602001604a60ff168152602001601360ff168152602001609460ff168152602001606860ff168152602001600060ff168152602001609560ff168152602001606860ff168152602001606c60ff168152602001609560ff168152602001606860ff168152602001601660ff168152602001603260ff168152602001606860ff168152602001601660ff168152602001609160ff168152602001600960ff168152602001600060ff168152602001604960ff168152602001600960ff168152602001607360ff168152602001604660ff168152602001600960ff168152602001606760ff168152602001607860ff168152602001608760ff168152602001600060ff168152602001604c60ff168152602001604a60ff168152602001605f60ff168152602001600660ff168152602001604a60ff168152602001600060ff168152602001607260ff16815260200160a660ff168152602001600060ff168152602001602460ff168152602001600760ff168152602001600060ff168152602001608060ff168152602001600960ff168152602001600060ff168152602001600560ff168152602001600960ff168152602001600060ff168152602001607e60ff168152602001600960ff168152602001600060ff168152602001605c60ff168152602001606860ff168152602001605f60ff168152602001608d60ff168152602001606860ff168152602001600060ff168152602001602860ff168152602001606860ff168152602001601360ff168152602001602460ff168152602001609e60ff168152602001600060ff168152602001604960ff168152602001600960ff16815260200160ae60ff168152602001601d60ff168152602001600060ff168152602001607360ff168152602001603860ff168152602001606860ff168152602001600060ff168152602001604f60ff168152602001604a60ff16815260200160ae60ff168152602001604260ff168152602001600060ff168152602001600060ff168152602001609560ff168152602001606860ff168152602001606c60ff168152602001600460ff168152602001606860ff168152602001600060ff168152602001609160ff168152602001600960ff168152602001600060ff168152602001604960ff168152602001600960ff168152602001607360ff168152602001601d60ff168152602001600060ff168152602001601360ff168152602001607860ff168152602001608760ff168152602001600060ff168152602001600860ff168152602001600060ff168152602001600060ff168152602001608060ff168152602001604560ff168152602001600060ff168152602001602660ff168152602001604560ff168152602001600060ff168152602001603460ff168152602001608660ff168152602001600060ff168152602001604960ff168152602001604560ff16815260200160ae60ff168152602001600560ff168152602001604560ff168152602001600060ff168152602001607960ff168152602001604560ff168152602001600060ff168152602001606e60ff168152602001604560ff168152602001606c60ff168152602001604960ff168152602001604560ff168152602001601360ff168152602001607e60ff168152602001604560ff168152602001600060ff168152602001607760ff168152602001604560ff168152602001601360ff168152602001606e60ff168152602001604560ff168152602001601660ff168152602001607760ff168152602001604560ff168152602001607360ff168152602001601960ff168152602001604360ff168152602001600060ff168152602001607a60ff16815260200160af60ff168152602001600060ff168152602001604760ff168152602001600060ff168152602001601660ff168152602001604760ff168152602001600060ff168152602001607360ff168152602001605060ff168152602001601b60ff168152602001600060ff168152602001604460ff168152602001600060ff168152602001600060ff168152602001602060ff168152602001600060ff168152602001600060ff168152602001603a60ff16815260200160a760ff168152602001600060ff168152602001608060ff168152602001604560ff168152602001600060ff168152602001603960ff168152602001604560ff168152602001600060ff168152602001603460ff168152602001608660ff168152602001600060ff168152602001604960ff168152602001604560ff16815260200160ae60ff168152602001600560ff168152602001604560ff168152602001600060ff168152602001604e60ff168152602001604560ff168152602001600060ff168152602001606e60ff168152602001604560ff168152602001606c60ff168152602001604960ff168152602001604560ff168152602001601360ff168152602001607e60ff168152602001604560ff168152602001600060ff168152602001607760ff168152602001604560ff168152602001601360ff168152602001606e60ff168152602001604560ff168152602001601660ff168152602001607760ff168152602001604560ff168152602001607360ff16815260200160a560ff168152602001605860ff168152602001600060ff168152602001601960ff168152602001604360ff168152602001600060ff168152602001608c60ff168152602001604560ff168152602001600060ff168152602001604760ff168152602001600060ff168152602001601660ff168152602001604760ff168152602001600060ff16815260200160ae60ff168152602001605060ff168152602001601b60ff168152602001600060ff168152602001604460ff168152602001600060ff168152602001600060ff168152602001602060ff168152602001600060ff168152602001600060ff16815260200160b560ff168152602001600060ff168152602001600060ff16815250611df7906103e462003edd929190620055cd565b506040805161012081018252600a60e082018181526953686f7265726964676560b01b6101008401528252825180840184526011815270536b79726f6172204d6f756e7461696e7360781b60208281019190915280840191909152835180850185529182526941726b2054656b6e6f7360b01b828201528284019190915282518084018452600c81526b546865205761696c616e647360a01b81830152606083015282518084018452600b81526a41656f6e204d6f72726f7760a81b81830152608083015282518084018452600e81526d13995bddd85d994811195cd95c9d60921b8183015260a08301528251808401909352601083526f4772696e6665726e6f20506c61696e7360801b9083015260c08101919091526200400590611e1790600762005662565b50604080516106e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052600f610120820181905260056101408301819052610160830181905261018083018190526101a083018490526101c083018490526101e08301829052610200830184905261022083018490526102408301849052610260830184905261028083018490526102a083018490526102c08301919091526102e082018390526103008201839052610320820181905261034082018390526103608201839052600a61038083018190526103a083018490526103c083018190526103e08301849052610400830184905261042083018290526104408301849052610460830184905261048083018490526104a083018290526104c083018190526104e08301849052610500830184905261052083018290526105408301819052610560830184905261058083018490526105a083018290526105c083018490526105e083018290526106008301829052610620830184905261064083015261066082018390526106808201526106a081018290526106c0810191909152620041d390611e1f906037620056a7565b506040805160e081018252600560a08201818152642837bbb2b960d91b60c08401528252825180840184526006815265456e6572677960d01b60208281019190915280840191909152835180850185528281526414dc19595960da1b8183015283850152835180850185526007815266446566656e636560c81b8183015260608401528351808501909452818452644368616f7360d81b9084015260808201929092526200428691611e219190620056fd565b50611e27805460ff1916600117905560408051610240810182526009610200820181815268426f6479205479706560b81b610220840152825282518084018452600a80825269109858dad9dc9bdd5b9960b21b602080840191909152808501929092528451808601865283815268115c5d5a5c1b595b9d60ba1b81840152848601528451808601865283815268536b696e20546f6e6560b81b8184015260608501528451808601865260058082526414da1a5c9d60da1b8285015260808601919091528551808701875260068082526520b936b7bab960d11b8286015260a08701919091528651808801885292835269119858d94814185a5b9d60b21b8385015260c0860192909252855180870187529081526409adeeae8d60db1b8184015260e0850152845180860186526004808252634579657360e01b8285015261010086019190915285518087018752848152682330b1b29023b2b0b960b91b8185015261012086015285518087018752818152632430b4b960e11b81850152610140860152855180870187528181526323b2b0b960e11b8185015261016086015285518087018752938452682432b0b21023b2b0b960b91b8484015261018085019390935284518086018652908152652932b3b4b7b760d11b818301526101a084015283518085018552918252634369747960e01b828201526101c08301919091528251808401909352600e83526d436861726163746572697374696360901b908301526101e0810191909152620044c290611e2890601062005742565b50348015620044d057600080fd5b506040516200ae0f3803806200ae0f833981016040819052620044f3916200586d565b60058054336001600160a01b03199182168117909255600680549091166001600160a01b038516179055604051630f41a04d60e11b8152600481019190915273084b1c3c81545d370f3634392de611caabff814890631e83409a90602401602060405180830381600087803b1580156200456c57600080fd5b505af115801562004581573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620045a791906200596d565b50620045b2620045d0565b8051620045c79060019060208401906200546a565b505050620059c4565b6040805160808082018352600080835283518085018552600a8082526946656c6c627265657a6560b01b6020808401919091528086019283528651808801885291825269496465616c697374696360b01b8282015285870191909152855160a081018752838152600f818301529586018390526060808701849052938601839052928401949094528052611e1e815281517f7ee5b629881c3c2d5bc2a77f863e700ce29107715e36dda86584d4ab241a8b78805460ff191660ff90921691909117815592518051929392620046c9927f7ee5b629881c3c2d5bc2a77f863e700ce29107715e36dda86584d4ab241a8b799201906200546a565b5060408201518051620046e79160028401916020909101906200546a565b506060820151620046ff906003830190600562005787565b50506040805160808082018352600180835283518085018552600e81526d4472696674776f6f64205175617960901b602080830191909152808501918252855180870187526008815267496d706f73696e6760c01b8183015285870152855160a0810187526000808252818301819052968101879052600f606080830191909152948101879052938501939093529352611e1e815281517f4024c42b59ef1ee82b0af9257e97dd419404d615ee9e3f29f4f67acadbd30495805460ff191660ff9092169190911781559251805192945062004801927f4024c42b59ef1ee82b0af9257e97dd419404d615ee9e3f29f4f67acadbd304969291909101906200546a565b50604082015180516200481f9160028401916020909101906200546a565b50606082015162004837906003830190600562005787565b50506040805160808082018352600280835283518085018552600981526857657374666f72676560b81b60208083019190915280850191825285518087018752600b81526a496e6475737472696f757360a81b8183015285870152855160a081018752600f815260008183018190529681018790526060808201889052948101879052938501939093529352611e1e815281517f2616c2f5e6f6f2bfe69aef3348e359699dfdff2adee7e4a77427946068cecc6c805460ff191660ff9092169190911781559251805192945062004935927f2616c2f5e6f6f2bfe69aef3348e359699dfdff2adee7e4a77427946068cecc6d9291909101906200546a565b5060408201518051620049539160028401916020909101906200546a565b5060608201516200496b906003830190600562005787565b50506040805160808082018352600380835283518085018552600a8082526953746f6e65627269676760b01b6020808401919091528086019283528651808801885291825269149959da5b595b9d195960b21b8282015285870191909152855160a08101875260058082526000828401819052978201889052606080830182905295820152938501939093529352611e1e815281517fdae7c609cb86fb9d13709dbf3bbd98fbf3c9bfbeb42091f0a876870dbe27ccea805460ff191660ff9092169190911781559251805192945062004a6b927fdae7c609cb86fb9d13709dbf3bbd98fbf3c9bfbeb42091f0a876870dbe27cceb9291909101906200546a565b506040820151805162004a899160028401916020909101906200546a565b50606082015162004aa1906003830190600562005787565b50506040805160808082018352600382528251808401845260128152714b696e67646f6d206f66205370656374726160701b60208083019190915280840191825284518086018652600b81526a11985b9d185cdd1a58d85b60aa1b8183015284860152845160a08101865260008082528183018190529581018690526060808201879052600f94820194909452928401929092526004909352611e1e815281517fc92508ee1ec491843f236f063e58a8f5a8f90ce9c06d48027221daa864aa8ea9805460ff191660ff9092169190911781559251805192945062004bac927fc92508ee1ec491843f236f063e58a8f5a8f90ce9c06d48027221daa864aa8eaa9291909101906200546a565b506040820151805162004bca9160028401916020909101906200546a565b50606082015162004be2906003830190600562005787565b505060408051608080820183526004825282518084018452600d81526c4d61676e61746f6e204369747960981b60208083019190915280840191825284518086018652600580825264141c9bdd5960da1b8284015285870191909152855160a081018752818152600a81840152600096810187905260608082018890529481018790529385019390935291909352611e1e815281517ffbaa6904266f7d64e86ecc2d78d69d1daff6f556f3e3f59727585d81fa7ad083805460ff191660ff9092169190911781559251805192945062004ce2927ffbaa6904266f7d64e86ecc2d78d69d1daff6f556f3e3f59727585d81fa7ad0849291909101906200546a565b506040820151805162004d009160028401916020909101906200546a565b50606082015162004d18906003830190600562005787565b50506040805160808082018352600482528251808401845260098152684c6f7320417374726160b81b60208083019190915280840191825284518086018652600a80825269426f69737465726f757360b01b8284015285870191909152855160a0810187526000808252818401929092529586018190526005606080880191909152938601819052928401949094526006909152611e1e835281517f6dcb5983c95ad9f90f94739878bb57be91181c3fee24eaa20dfcb6d2f6ce7471805460ff191660ff90921691909117815590518051929450909262004e1f927f6dcb5983c95ad9f90f94739878bb57be91181c3fee24eaa20dfcb6d2f6ce747292909101906200546a565b506040820151805162004e3d9160028401916020909101906200546a565b50606082015162004e55906003830190600562005787565b50506040805160808082018352600580835283518085018552600681526554657a756b6160d01b602080830191909152808501918252855180870187526009815268416461707461626c6560b81b8183015285870152855160a0810187526000808252600a82840152968101879052606080820194909452938401869052918401929092526007909352611e1e835281517f5e2fcab25bf8366ff98eedb229a45fed42a648d7c1e7f607bbf6d216336d4c7f805460ff191660ff90921691909117815590518051929450909262004f52927f5e2fcab25bf8366ff98eedb229a45fed42a648d7c1e7f607bbf6d216336d4c8092909101906200546a565b506040820151805162004f709160028401916020909101906200546a565b50606082015162004f88906003830190600562005787565b505060408051608080820183526006825282518084018452600c8082526b436173746f72204c6f636b6560a01b602080840191909152808501928352855180870187529182526b21b7b9b6b7b837b634ba30b760a11b8282015284860191909152845160a08101865260058082528183018190529581019590955260006060808701829052938601819052928401949094526008909152611e1e835281517f657543772a14ce42569cd93d524d75ea14073e7ba7cd1135231593c07870a944805460ff191660ff90921691909117815590518051929450909262005092927f657543772a14ce42569cd93d524d75ea14073e7ba7cd1135231593c07870a94592909101906200546a565b5060408201518051620050b09160028401916020909101906200546a565b506060820151620050c8906003830190600562005787565b5050604080516080808201835260068252825180840184526005808252644f6272616b60d81b60208084019190915280850192835285518087018752600b81526a14995cdbdd5c98d9599d5b60aa1b8183015285870152855160a0810187526000808252818301849052968101839052606080820188905294810192909252928401526009909352611e1e815281517f40460841f2e1aaaa7891b7d693d6254ba60e668b6b0196357e9aebea418b0885805460ff191660ff90921691909117815592518051929450620051c2927f40460841f2e1aaaa7891b7d693d6254ba60e668b6b0196357e9aebea418b08869291909101906200546a565b5060408201518051620051e09160028401916020909101906200546a565b506060820151620051f8906003830190600562005787565b505060408051608080820183526006825282518084018452600b81526a57617272656e204c616b6560a81b6020808301919091528084019182528451808601865260048152634772696d60e01b8183015284860152845160a0810186526005808252600082840181905296820181905260608083019190915293810186905292840192909252600a909352611e1e815281517f989fa6094b8c990594a3db5422a258ae685f4be5851f77c93aaaef9c52ff215e805460ff191660ff90921691909117815592518051929450620052f5927f989fa6094b8c990594a3db5422a258ae685f4be5851f77c93aaaef9c52ff215f9291909101906200546a565b5060408201518051620053139160028401916020909101906200546a565b5060608201516200532b906003830190600562005787565b5050604080516080808201835260068083528351808501855290815265427261776e6160d01b60208083019190915280840191825284518086018652600a808252694f7074696d697374696360b01b8284015285870191909152855160a081018752600080825281840192909252600596810196909652606080870182905293860181905292840194909452600b909152611e1e835281517fd58ae58c0ef2b7b6b56f30c71842da04ea18f7d23b87a7ac8a7b462e21d0a988805460ff191660ff9092169190911781559051805192945090926200542f927fd58ae58c0ef2b7b6b56f30c71842da04ea18f7d23b87a7ac8a7b462e21d0a98992909101906200546a565b50604082015180516200544d9160028401916020909101906200546a565b50606082015162005465906003830190600562005787565b505050565b828054620054789062005987565b90600052602060002090601f0160209004810192826200549c5760008555620054e7565b82601f10620054b757805160ff1916838001178555620054e7565b82800160010185558215620054e7579182015b82811115620054e7578251825591602001919060010190620054ca565b50620054f5929150620057dd565b5090565b8260088101928215620054e7579160200282015b82811115620054e757825182906001600160481b03169055916020019190600101906200550d565b82600381019282156200557a579160200282015b828111156200557a5782518051620055699184916020909101906200546a565b509160200191906001019062005549565b50620054f5929150620057f4565b8260b681019282156200557a579160200282015b828111156200557a5782518051620055bc9184916020909101906200546a565b50916020019190600101906200559c565b602083019183908215620054e75791602002820160005b838211156200562457835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302620055e4565b8015620056535782816101000a81549060ff021916905560010160208160000104928301926001030262005624565b5050620054f5929150620057dd565b82600781019282156200557a579160200282015b828111156200557a5782518051620056969184916020909101906200546a565b509160200191906001019062005676565b600283019183908215620054e7579160200282016000838211156200562457835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302620055e4565b82600581019282156200557a579160200282015b828111156200557a5782518051620057319184916020909101906200546a565b509160200191906001019062005711565b82601081019282156200557a579160200282015b828111156200557a5782518051620057769184916020909101906200546a565b509160200191906001019062005756565b600183019183908215620054e7579160200282016000838211156200562457835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302620055e4565b5b80821115620054f55760008155600101620057de565b80821115620054f55760006200580b828262005815565b50600101620057f4565b508054620058239062005987565b6000825580601f1062005834575050565b601f016020900490600052602060002090810190620058549190620057dd565b50565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200588157600080fd5b82516001600160a01b03811681146200589957600080fd5b602084810151919350906001600160401b0380821115620058b957600080fd5b818601915086601f830112620058ce57600080fd5b815181811115620058e357620058e362005857565b604051601f8201601f19908116603f011681019083821181831017156200590e576200590e62005857565b8160405282815289868487010111156200592757600080fd5b600093505b828410156200594b57848401860151818501870152928501926200592c565b828411156200595d5760008684830101525b8096505050505050509250929050565b6000602082840312156200598057600080fd5b5051919050565b600181811c908216806200599c57607f821691505b60208210811415620059be57634e487b7160e01b600052602260045260246000fd5b50919050565b61540f80620059d46000396000f3fe6080604052600436106103ee5760003560e01c806366bb81c711610208578063c404811711610118578063e1dc0761116100ab578063e634cb091161007a578063e634cb0914610be3578063e64d2f6114610c03578063e985e9c514610c2b578063f2fde38b14610c4b578063fece9bc314610c6b57600080fd5b8063e1dc076114610b45578063e5187f4314610b74578063e541ed3414610b94578063e5bea43514610bb457600080fd5b8063cf348425116100e7578063cf34842514610ace578063d2560bbb14610aee578063d7dc9a7e14610b05578063e1a5bfa114610b2557600080fd5b8063c404811714610a4e578063c87b56dd14610a6e578063cac95fdb14610a8e578063ce606ee014610aae57600080fd5b80639c7afe8b1161019b578063b88d4fde1161016a578063b88d4fde1461099d578063b9da56a9146109bd578063be448206146109dd578063c27b335f14610a0e578063c2ca0ac514610a2e57600080fd5b80639c7afe8b1461092f578063a035b1fe1461094f578063a22cb46514610966578063b047570a1461098657600080fd5b806391b7f5ed116101d757806391b7f5ed146108d257806394d008ef146108f257806395d89b41146109055780639c5b470d1461091a57600080fd5b806366bb81c71461084757806370a082311461085e5780638456cb591461089557806385209ee0146108aa57600080fd5b80632f8e9f4211610303578063517c6876116102965780635c471995116102655780635c471995146107a45780635c975abb146107c457806360159abb146107e557806361e47b56146108125780636352211e1461082757600080fd5b8063517c68761461071d578063538cddb61461073d57806355e732da146107525780635bb209a51461078457600080fd5b806340bdce0d116102d257806340bdce0d1461069157806342842e0e146106c857806342ef1508146106e85780634f6ccce7146106fd57600080fd5b80632f8e9f421461063b57806332c2f7f8146106505780633ccfd60b146106675780633f4ba83a1461067c57600080fd5b8063167ff46f116103865780631d458bd1116103555780631d458bd11461059b57806320733880146105bb57806323b872dd146105db578063255a87fe146105fb5780632f745c591461061b57600080fd5b8063167ff46f146105215780631711862d1461053657806318160ddd146105565780631b7b87131461056d57600080fd5b8063081812fc116103c2578063081812fc14610492578063095ea7b3146104ca5780630ce06b68146104ec57806311f3a5941461050c57600080fd5b8062923f9e146103f357806301ffc9a71461042b57806304a7b8d21461044b57806306fdde0314610470575b600080fd5b3480156103ff57600080fd5b5061041661040e36600461459c565b611d2a541190565b60405190151581526020015b60405180910390f35b34801561043757600080fd5b506104166104463660046145cb565b610c80565b34801561045757600080fd5b50610462611d305481565b604051908152602001610422565b34801561047c57600080fd5b50610485610ced565b6040516104229190614640565b34801561049e57600080fd5b506104b26104ad36600461459c565b610d7b565b6040516001600160a01b039091168152602001610422565b3480156104d657600080fd5b506104ea6104e536600461466a565b610e06565b005b3480156104f857600080fd5b506104ea61050736600461466a565b610f1c565b34801561051857600080fd5b50610485610fb6565b34801561052d57600080fd5b506104ea610fc3565b34801561054257600080fd5b506004546104b2906001600160a01b031681565b34801561056257600080fd5b50610462611d2a5481565b34801561057957600080fd5b5061058d61058836600461459c565b61105d565b6040516104229291906146ba565b3480156105a757600080fd5b506104856105b636600461459c565b61132c565b3480156105c757600080fd5b506104ea6105d63660046146f8565b61151a565b3480156105e757600080fd5b506104ea6105f6366004614713565b6115e7565b34801561060757600080fd5b506104ea610616366004614798565b611618565b34801561062757600080fd5b5061046261063636600461466a565b61164e565b34801561064757600080fd5b50610485611708565b34801561065c57600080fd5b50610462611d2f5481565b34801561067357600080fd5b506104ea611715565b34801561068857600080fd5b506104ea611751565b34801561069d57600080fd5b506106b16106ac36600461459c565b61178a565b604080519215158352602083019190915201610422565b3480156106d457600080fd5b506104ea6106e3366004614713565b6117ba565b3480156106f457600080fd5b506104ea6117d5565b34801561070957600080fd5b5061046261071836600461459c565b61186b565b34801561072957600080fd5b5061041661073836600461489f565b611899565b34801561074957600080fd5b506104856119ef565b34801561075e57600080fd5b5061077261076d36600461459c565b6119fc565b60405160ff9091168152602001610422565b34801561079057600080fd5b5061046261079f36600461459c565b611a54565b3480156107b057600080fd5b506104ea6107bf3660046146f8565b611ad1565b3480156107d057600080fd5b5060065461041690600160a01b900460ff1681565b3480156107f157600080fd5b5061080561080036600461459c565b611c03565b60405161042291906148ed565b34801561081e57600080fd5b506104ea611c58565b34801561083357600080fd5b506104b261084236600461459c565b611c97565b34801561085357600080fd5b50610462611d2e5481565b34801561086a57600080fd5b506104626108793660046146f8565b6001600160a01b03166000908152611b70602052604090205490565b3480156108a157600080fd5b506104ea611d16565b3480156108b657600080fd5b50611d2b546108c59060ff1681565b6040516104229190614911565b3480156108de57600080fd5b506104ea6108ed36600461459c565b611d55565b6104ea61090036600461492b565b611d85565b34801561091157600080fd5b506104856120d2565b34801561092657600080fd5b506104856120df565b34801561093b57600080fd5b506104ea61094a366004614982565b6120ec565b34801561095b57600080fd5b50610462611d3a5481565b34801561097257600080fd5b506104ea610981366004614a0a565b6121dd565b34801561099257600080fd5b50610462611d2d5481565b3480156109a957600080fd5b506104ea6109b8366004614a41565b6122a3565b3480156109c957600080fd5b506104ea6109d8366004614aa9565b6122d5565b3480156109e957600080fd5b506107726109f836600461459c565b611e266020526000908152604090205460ff1681565b348015610a1a57600080fd5b506104ea610a293660046146f8565b612474565b348015610a3a57600080fd5b506104ea610a4936600461459c565b6124c0565b348015610a5a57600080fd5b50610485610a6936600461459c565b6126d7565b348015610a7a57600080fd5b50610485610a8936600461459c565b6126f7565b348015610a9a57600080fd5b50610485610aa936600461459c565b612982565b348015610aba57600080fd5b506005546104b2906001600160a01b031681565b348015610ada57600080fd5b50610485610ae936600461459c565b612993565b348015610afa57600080fd5b50610462611d2c5481565b348015610b1157600080fd5b506104ea610b20366004614ad4565b612b5a565b348015610b3157600080fd5b50610485610b4036600461459c565b612c84565b348015610b5157600080fd5b50610b65610b6036600461459c565b612c95565b60405161042293929190614b49565b348015610b8057600080fd5b506104ea610b8f3660046146f8565b613048565b348015610ba057600080fd5b50610485610baf36600461459c565b613094565b348015610bc057600080fd5b50610bd4610bcf36600461459c565b6130a5565b60405161042293929190614bb0565b348015610bef57600080fd5b50610772610bfe36600461459c565b61334d565b348015610c0f57600080fd5b50611e2754610c1e9060ff1681565b6040516104229190614be9565b348015610c3757600080fd5b50610416610c46366004614bfd565b613378565b348015610c5757600080fd5b506104ea610c663660046146f8565b6133a7565b348015610c7757600080fd5b506104ea6133f3565b60006001600160e01b031982166301ffc9a760e01b1480610cb157506001600160e01b031982166380ac58cd60e01b145b80610ccc57506001600160e01b03198216635b5e139f60e01b145b80610ce757506001600160e01b0319821663780e9d6360e01b145b92915050565b60078054610cfa90614c30565b80601f0160208091040260200160405190810160405280929190818152602001828054610d2690614c30565b8015610d735780601f10610d4857610100808354040283529160200191610d73565b820191906000526020600020905b815481529060010190602001808311610d5657829003601f168201915b505050505081565b6000611d2a548210610de95760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152611d2860205260409020546001600160a01b031690565b6000610e1182611c97565b9050806001600160a01b0316836001600160a01b03161415610e7f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610de0565b336001600160a01b0382161480610e9b5750610e9b8133613378565b610f0d5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610de0565b610f178383613483565b505050565b6005546001600160a01b03163314610f465760405162461bcd60e51b8152600401610de090614c6b565b600554604051632142170760e11b81523060048201526001600160a01b03918216602482015260448101839052908316906342842e0e90606401600060405180830381600087803b158015610f9a57600080fd5b505af1158015610fae573d6000803e3d6000fd5b505050505050565b60028054610cfa90614c30565b6005546001600160a01b03163314610fed5760405162461bcd60e51b8152600401610de090614c6b565b6000611d2b5460ff166003811115611007576110076148fb565b146110405760405162461bcd60e51b81526020600482015260096024820152684e6f7420526561647960b81b6044820152606401610de0565b611d2b805460ff1916600117905543611d2c55611d2a54611d3b55565b611065614483565b61106d6144a2565b6003611d2b5460ff166003811115611087576110876148fb565b146110a45760405162461bcd60e51b8152600401610de090614c8e565b60006110af84611a54565b90506000806000806110c188866134f2565b929650909450925090506110df8585600c5b6020020151858561383f565b955080156110f057600187526110f5565b600087525b60005b600c811015611154578481600d811061111357611113614cb4565b602002015188611124836001614ce0565b600f811061113457611134614cb4565b61ffff90921660209290920201528061114c81614cf8565b9150506110f8565b5061018084015161ffff166000908152611e1e60209081526040808320815160808101909252805460ff168252600181018054929391929184019161119890614c30565b80601f01602080910402602001604051908101604052809291908181526020018280546111c490614c30565b80156112115780601f106111e657610100808354040283529160200191611211565b820191906000526020600020905b8154815290600101906020018083116111f457829003601f168201915b5050505050815260200160028201805461122a90614c30565b80601f016020809104026020016040519081016040528092919081815260200182805461125690614c30565b80156112a35780601f10611278576101008083540402835291602001916112a3565b820191906000526020600020905b81548152906001019060200180831161128657829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116112cb57505050929093525050915160ff166101a08b01525050506101809093015161ffff166101c08701525093959294509192505050565b6060600061133b836003614d13565b90506000611df7826103e4811061135457611354614cb4565b602081049091015460ff601f9092166101000a90041690506000611df761137c846001614ce0565b6103e4811061138d5761138d614cb4565b602081049091015460ff601f9092166101000a90041690506000611df76113b5856002614ce0565b6103e481106113c6576113c6614cb4565b602091828204019190069054906101000a900460ff1690506000611d418460ff1660b681106113f7576113f7614cb4565b01805461140390614c30565b80601f016020809104026020016040519081016040528092919081815260200182805461142f90614c30565b801561147c5780601f106114515761010080835404028352916020019161147c565b820191906000526020600020905b81548152906001019060200180831161145f57829003601f168201915b5050505050905060008360ff1611156114cb5780611d418460ff1660b681106114a7576114a7614cb4565b016040516020016114b9929190614dcc565b60405160208183030381529060405290505b60ff8216156115105780611d418360ff1660b681106114ec576114ec614cb4565b016040516020016114fe929190614df6565b60405160208183030381529060405290505b9695505050505050565b6005546001600160a01b031633146115445760405162461bcd60e51b8152600401610de090614c6b565b6001611d2b5460ff16600381111561155e5761155e6148fb565b148061158157506000611d2b5460ff16600381111561157f5761157f6148fb565b145b61159d5760405162461bcd60e51b8152600401610de090614e21565b611b67611d2a54106115c15760405162461bcd60e51b8152600401610de090614e46565b6115ce81611d2a54613a24565b611d2a80549060006115df83614cf8565b919050555050565b6115f13382613b38565b61160d5760405162461bcd60e51b8152600401610de090614e73565b610f17838383613bf7565b6005546001600160a01b031633146116425760405162461bcd60e51b8152600401610de090614c6b565b610f17600083836144c0565b6001600160a01b0382166000908152611b70602052604081205482106116ca5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610de0565b6001600160a01b0383166000908152611b70602052604090208054839081106116f5576116f5614cb4565b9060005260206000200154905092915050565b60008054610cfa90614c30565b6005546040516001600160a01b03909116904780156108fc02916000818181858888f1935050505015801561174e573d6000803e3d6000fd5b50565b6005546001600160a01b0316331461177b5760405162461bcd60e51b8152600401610de090614c6b565b6006805460ff60a01b19169055565b600080600061179884613fc9565b9050600f8110156117ae57600194909350915050565b50600093849350915050565b610f17838383604051806020016040528060008152506122a3565b6005546001600160a01b031633146117ff5760405162461bcd60e51b8152600401610de090614c6b565b6001611e275460ff166002811115611819576118196148fb565b146118535760405162461bcd60e51b815260206004820152600a602482015269139bdd0810db1bdcd95960b21b6044820152606401610de0565b611e2780546000919060ff19166001835b0217905550565b600061187982611d2a541190565b6118955760405162461bcd60e51b8152600401610de090614ec4565b5090565b604080516b199b1a59da1d1b1a5cdd195960a21b60208201526bffffffffffffffffffffffff19606085901b16602c82015260009182910160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c01604051602081830303815290604052805190602001209050600080600085516041146119585760405162461bcd60e51b8152600401610de090614eef565b505050602083810151604080860151606080880151600654845160008082529781018087528990529190961a93810184905290810184905260808101829052919390916001600160a01b039091169060019060a0016020604051602081039080840390855afa1580156119cf573d6000803e3d6000fd5b505050602060405103516001600160a01b03161494505050505092915050565b60018054610cfa90614c30565b6000611a0a82611d2a541190565b611a265760405162461bcd60e51b8152600401610de090614ec4565b611d3b54821015611a3957506000919050565b611d3c54821015611a4c57506001919050565b506002919050565b6000600f611a6183613fc9565b1015611aa05760405162461bcd60e51b815260206004820152600e60248201526d21b7b9329021b430b930b1ba32b960911b6044820152606401610de0565b50611d2f54604080516020808201939093528082019390935280518084038201815260609093019052815191012090565b6005546001600160a01b03163314611afb5760405162461bcd60e51b8152600401610de090614c6b565b6005546040516370a0823160e01b815230600482015282916001600160a01b038084169263a9059cbb92919091169083906370a082319060240160206040518083038186803b158015611b4d57600080fd5b505afa158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b859190614f1b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611bcb57600080fd5b505af1158015611bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f179190614f34565b611c0b6144a2565b6003611d2b5460ff166003811115611c2557611c256148fb565b14611c425760405162461bcd60e51b8152600401610de090614c8e565b610ce7611c4e83611a54565b614024565b919050565b6005546001600160a01b03163314611c825760405162461bcd60e51b8152600401610de090614c6b565b611e2780546002919060ff1916600183611864565b6000611ca582611d2a541190565b611cf15760405162461bcd60e51b815260206004820152601960248201527f4552433732313a204e6f6e6578697374656e7420746f6b656e000000000000006044820152606401610de0565b600982611b678110611d0557611d05614cb4565b01546001600160a01b031692915050565b6005546001600160a01b03163314611d405760405162461bcd60e51b8152600401610de090614c6b565b6006805460ff60a01b1916600160a01b179055565b6005546001600160a01b03163314611d7f5760405162461bcd60e51b8152600401610de090614c6b565b611d3a55565b600a821115611d9357600a91505b6001611d2b5460ff166003811115611dad57611dad6148fb565b14611dca5760405162461bcd60e51b8152600401610de090614e21565b611dd761033e6008614d13565b611d2c54611de59190614ce0565b431015611e7657611df68382611899565b611e125760405162461bcd60e51b8152600401610de090614eef565b6001600160a01b0383166000908152611b70602052604090205415611e6d5760405162461bcd60e51b8152602060048201526011602482015270141c99599b1a59da1d0810db185a5b5959607a1b6044820152606401610de0565b60019150611f54565b611e8361033e6009614d13565b611d2c54611e919190614ce0565b431015611f3e57611ea28382611899565b611ebe5760405162461bcd60e51b8152600401610de090614eef565b600b82611ee1856001600160a01b03166000908152611b70602052604090205490565b611eeb9190614ce0565b1115611f395760405162461bcd60e51b815260206004820152601960248201527f466c6967687470617373206c696d6974206578636565646564000000000000006044820152606401610de0565b611f54565b611d3c54611f401415611f5457611d2a54611d3c555b611b6782611d2a54611f669190614ce0565b1115611f845760405162461bcd60e51b8152600401610de090614e46565b600082611d3a54611f959190614d13565b905080341015611fdc5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742046756e647360701b6044820152606401610de0565b60005b8381101561201157611fff8582611d2a54611ffa9190614ce0565b613a24565b8061200981614cf8565b915050611fdf565b5082611d2a60008282546120259190614ce0565b9091555050348110156120cc5760003361203f8334614f51565b604051600081818185875af1925050503d806000811461207b576040519150601f19603f3d011682016040523d82523d6000602084013e612080565b606091505b50509050806120ca5760405162461bcd60e51b81526020600482015260166024820152751499599d5b9908151c985b9cd9995c8811985a5b195960521b6044820152606401610de0565b505b50505050565b60088054610cfa90614c30565b60038054610cfa90614c30565b6005546001600160a01b031633146121165760405162461bcd60e51b8152600401610de090614c6b565b6001611d2b5460ff166003811115612130576121306148fb565b148061215357506002611d2b5460ff166003811115612151576121516148fb565b145b61218f5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420537461746560981b6044820152606401610de0565b611d2e5461219e9060c8614ce0565b43116121a957600080fd5b611d2b805460ff19166002908117909155611d2d86905543611d2e556121d09085856144c0565b50610fae600383836144c0565b336001600160a01b03831614156122365760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610de0565b336000818152611d29602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6122ad3383613b38565b6122c95760405162461bcd60e51b8152600401610de090614e73565b6120cc848484846140c9565b6003611d2b5460ff1660038111156122ef576122ef6148fb565b1461230c5760405162461bcd60e51b8152600401610de090614c8e565b3361231683611c97565b6001600160a01b0316146123585760405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b6044820152606401610de0565b60008160ff1611801561236f575060058160ff1611155b6123ac5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642043686f69636560901b6044820152606401610de0565b6000828152611e26602052604090205460ff16156123ff5760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e48115c5d5a5c1c195960821b6044820152606401610de0565b6000611e275460ff166002811115612419576124196148fb565b146124515760405162461bcd60e51b81526020600482015260086024820152672737ba1027b832b760c11b6044820152606401610de0565b6000918252611e266020526040909120805460ff191660ff909216919091179055565b6005546001600160a01b0316331461249e5760405162461bcd60e51b8152600401610de090614c6b565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031633146124ea5760405162461bcd60e51b8152600401610de090614c6b565b611d2e546124f9906004614ce0565b431180156125145750611d2e546125119060c8614ce0565b43105b61254e5760405162461bcd60e51b815260206004820152600b60248201526a426c6f636b2052616e676560a81b6044820152606401610de0565b6002611d2b5460ff166003811115612568576125686148fb565b146125a85760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e4814995d99585b195960821b6044820152606401610de0565b611d2d54604080516020810184905201604051602081830303815290604052805190602001201461260b5760405162461bcd60e51b815260206004820152600d60248201526c0a6cacac8409ad2e6dac2e8c6d609b1b6044820152606401610de0565b80611d2e54600161261c9190614ce0565b40611d2e54600261262d9190614ce0565b40611d2e54600361263e9190614ce0565b604080516020810195909552840192909252606083015240608082015260a00160408051601f198184030181529190528051602090910120611d2f55611d2a5461268a90600590614f51565b611d2f546126989190614f7e565b611d3955611d2f54611d31906126b090600890614f7e565b600881106126c0576126c0614cb4565b0154611d305550611d2b805460ff19166003179055565b611e1781600781106126e857600080fd5b018054909150610cfa90614c30565b6060611d2a5482106127635760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610de0565b6003611d2b5460ff16600381111561277d5761277d6148fb565b14156128c857600061278e83613fc9565b9050600f81101561284357611d3d54604051637bb7ca8760e11b8152600481018390526002916001600160a01b03169063f76f950e9060240160006040518083038186803b1580156127df57600080fd5b505afa1580156127f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261281b9190810190614f92565b60405160200161282c929190615000565b604051602081830303815290604052915050919050565b60048054604051636a93802960e01b81529182018590526001600160a01b031690636a9380299060240160006040518083038186803b15801561288557600080fd5b505afa158015612899573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128c19190810190614f92565b9392505050565b611d3d546001906001600160a01b031663f76f950e6128e6856119fc565b6040516001600160e01b031960e084901b16815260ff909116600482015260240160006040518083038186803b15801561291f57600080fd5b505afa158015612933573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261295b9190810190614f92565b60405160200161296c929190615000565b6040516020818303038152906040529050919050565b611e2181600581106126e857600080fd5b60606129a182611d2a541190565b6129bd5760405162461bcd60e51b8152600401610de090614ec4565b6003611d2b5460ff1660038111156129d7576129d76148fb565b1415612ab65760006129e883613fc9565b9050600f811015612a8657611d3d54604051637bb7ca8760e11b8152600481018390526002916001600160a01b03169063f76f950e9060240160006040518083038186803b158015612a3957600080fd5b505afa158015612a4d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a759190810190614f92565b60405160200161282c929190615054565b6000612a9184611a54565b90506000612a9f85836134f2565b5050509050612aad816140fc565b95945050505050565b611d3d546001906001600160a01b031663f76f950e612ad4856119fc565b6040516001600160e01b031960e084901b16815260ff909116600482015260240160006040518083038186803b158015612b0d57600080fd5b505afa158015612b21573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b499190810190614f92565b60405160200161296c929190615054565b6005546001600160a01b03163314612b845760405162461bcd60e51b8152600401610de090614c6b565b6001611d2b5460ff166003811115612b9e57612b9e6148fb565b1480612bc157506000611d2b5460ff166003811115612bbf57612bbf6148fb565b145b612bdd5760405162461bcd60e51b8152600401610de090614e21565b611d2a54611b6790612bf0908390614ce0565b1115612c0e5760405162461bcd60e51b8152600401610de090614e46565b60005b81811015612c6457612c52838383818110612c2e57612c2e614cb4565b9050602002016020810190612c4391906146f8565b82611d2a54611ffa9190614ce0565b80612c5c81614cf8565b915050612c11565b5081819050611d2a6000828254612c7b9190614ce0565b90915550505050565b611e2881601081106126e857600080fd5b612c9d614540565b612ca56144a2565b60606003611d2b5460ff166003811115612cc157612cc16148fb565b14612cde5760405162461bcd60e51b8152600401610de090614c8e565b6000612ce985611a54565b9050600080600080612cfb89866134f2565b92965090945092509050612d118585600c6110d3565b96508015612d2a57612d23600161132c565b8852612d37565b612d34600061132c565b88525b60005b600c811015612d9957612d668582600d8110612d5857612d58614cb4565b602002015161ffff1661132c565b89612d72836001614ce0565b60108110612d8257612d82614cb4565b602002015280612d9181614cf8565b915050612d3a565b5061018084015161ffff166000908152611e1e60209081526040808320815160808101909252805460ff1682526001810180549293919291840191612ddd90614c30565b80601f0160208091040260200160405190810160405280929190818152602001828054612e0990614c30565b8015612e565780601f10612e2b57610100808354040283529160200191612e56565b820191906000526020600020905b815481529060010190602001808311612e3957829003601f168201915b50505050508152602001600282018054612e6f90614c30565b80601f0160208091040260200160405190810160405280929190818152602001828054612e9b90614c30565b8015612ee85780601f10612ebd57610100808354040283529160200191612ee8565b820191906000526020600020905b815481529060010190602001808311612ecb57829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612f105790505050505050815250509050611e17816000015160ff1660078110612f6457612f64614cb4565b018054612f7090614c30565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9c90614c30565b8015612fe95780601f10612fbe57610100808354040283529160200191612fe9565b820191906000526020600020905b815481529060010190602001808311612fcc57829003601f168201915b505050505089600d6010811061300157613001614cb4565b6020020181905250806020015189600e6010811061302157613021614cb4565b602002015260408101516101e08a015261303a856140fc565b989a97995050505050505050565b6005546001600160a01b031633146130725760405162461bcd60e51b8152600401610de090614c6b565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b611d3e81600381106126e857600080fd5b6060806060600c84106130eb5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a590818da5d1e525960921b6044820152606401610de0565b6000848152611e1e60209081526040808320815160808101909252805460ff168252600181018054929391929184019161312490614c30565b80601f016020809104026020016040519081016040528092919081815260200182805461315090614c30565b801561319d5780601f106131725761010080835404028352916020019161319d565b820191906000526020600020905b81548152906001019060200180831161318057829003601f168201915b505050505081526020016002820180546131b690614c30565b80601f01602080910402602001604051908101604052809291908181526020018280546131e290614c30565b801561322f5780601f106132045761010080835404028352916020019161322f565b820191906000526020600020905b81548152906001019060200180831161321257829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116132575790505050505050815250509050611e17816000015160ff16600781106132ab576132ab614cb4565b0180546132b790614c30565b80601f01602080910402602001604051908101604052809291908181526020018280546132e390614c30565b80156133305780601f1061330557610100808354040283529160200191613330565b820191906000526020600020905b81548152906001019060200180831161331357829003601f168201915b505050505093508060200151925080604001519150509193909250565b611e1f816037811061335e57600080fd5b60209182820401919006915054906101000a900460ff1681565b6001600160a01b039182166000908152611d296020908152604080832093909416825291909152205460ff1690565b6005546001600160a01b031633146133d15760405162461bcd60e51b8152600401610de090614c6b565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b0316331461341d5760405162461bcd60e51b8152600401610de090614c6b565b6000611e275460ff166002811115613437576134376148fb565b1461346f5760405162461bcd60e51b81526020600482015260086024820152672737ba1027b832b760c11b6044820152606401610de0565b611e2780546001919060ff19168280611864565b6000818152611d286020526040902080546001600160a01b0319166001600160a01b03841690811790915581906134b982611c97565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6134fa614568565b600080600060fc85901c6001166001149050600060fd86901c6001166001149050600060fe87901c600116600114905060006135418860008060026001600260048061418e565b61ffff919091168852905061355681876150a7565b60008a8152611e26602052604090205490965060ff1680156135f257600061357d8a614024565b90508061358b6001846150cc565b60ff166005811061359e5761359e614cb4565b60200201519650600d6135b26001896150cc565b60ff166135bf91906150ef565b61ffff1660208a015285156135ec57600a896001602002018181516135e491906150ef565b61ffff169052505b506135fa565b606060208901525b602161360e600560ff60188d901c16614f7e565b6136189190614ce0565b61ffff16604089015284156136455760058860026020020181815161363d91906150ef565b61ffff169052505b821561367c5761366089866003602b6001600380600561418e565b61ffff919091166060808b019190915260808a015291506136a7565b613692898660046043600160026004600661418e565b61ffff9190911660808a01526060808a015291505b6136b182886150a7565b96506136c889866005605d6001600380600461418e565b61ffff9190911660a08a015291506136e082886150a7565b96506136f689866006607360018060048061418e565b61ffff9190911660c08a0152915061370e82886150a7565b9650613726898660076087600160046003600261418e565b61ffff9190911660e08a0152915061373e82886150a7565b965061375689866008609b600360046006600761418e565b61ffff919091166101008a0152915061376f82886150a7565b965083156137a95761378d8986600960c3600460056006600a61418e565b61ffff919091166101208a015260606101608a015291506137d9565b6137c08986600b610123600360046006600761418e565b61ffff919091166101608a015261014b6101208a015291505b6137e382886150a7565b96506137fb8986600a60f5600260046007600a61418e565b61ffff919091166101408a0152915061381482886150a7565b9650613825600c60608b901c615115565b61ffff166101808901525095989497509295509093505050565b6138476144a2565b61ffff84166000908152611e1e6020526040808220815160a0810192839052916003909101906005908285855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116138745790505050505050905060005b600a8110156139595760006138c2826002614d13565b6138cd906070614ce0565b88901c60031690505b60148482600581106138ea576138ea614cb4565b602002015160ff161061391a578060031415613908575060006138d6565b8061391281614cf8565b9150506138d6565b600584826005811061392e5761392e614cb4565b6020020181815161393f91906150a7565b60ff1690525081905061395181614cf8565b9150506138ac565b5060005b6005811015613a1957611e1f81613975866005615136565b60ff166139829190614ce0565b6037811061399257613992614cb4565b602081049091015460ff601f9092166101000a9004168282600581106139ba576139ba614cb4565b60200201516139ca87600a6150a7565b6139d491906150a7565b6139de91906150a7565b8382600581106139f0576139f0614cb4565b60200201818151613a0191906150a7565b60ff1690525080613a1181614cf8565b91505061395d565b50505b949350505050565b600654600160a01b900460ff1615613a675760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610de0565b6001600160a01b0382166000818152611b70602090815260408220805460018101825581845291832090910184905591905254611b7182611b678110613aaf57613aaf614cb4565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555081600982611b678110613ae957613ae9614cb4565b0180546001600160a01b0319166001600160a01b0392831617905560405182918416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000611d2a548210613ba15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610de0565b6000613bac83611c97565b9050806001600160a01b0316846001600160a01b03161480613be75750836001600160a01b0316613bdc84610d7b565b6001600160a01b0316145b80613a1c5750613a1c8185613378565b600654600160a01b900460ff1615613c3a5760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610de0565b826001600160a01b0316613c4d82611c97565b6001600160a01b031614613cb55760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610de0565b6001600160a01b038216613d175760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610de0565b613d2461033e6009614d13565b611d2c54613d329190614ce0565b4311613d745760405162461bcd60e51b8152602060048201526011602482015270466c696768746c6973742041637469766560781b6044820152606401610de0565b613d7f600082613483565b6000611b7182611b678110613d9657613d96614cb4565b601091828204019190066002029054906101000a900461ffff1690506000600182613dc1919061515f565b6001600160a01b0386166000908152611b70602052604081205461ffff92909216925090613df190600190614f51565b9050818114613eb3576001600160a01b0386166000908152611b7060205260408120805483908110613e2557613e25614cb4565b9060005260206000200154905080611b706000896001600160a01b03166001600160a01b031681526020019081526020016000208481548110613e6a57613e6a614cb4565b60009182526020909120015583611b7182611b678110613e8c57613e8c614cb4565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550505b6001600160a01b0386166000908152611b7060205260409020805480613edb57613edb615182565b6000828152602080822083016000199081018390559092019092556001600160a01b038716808352611b70825260408320805460018101825581855292842090920187905590915254611b7185611b678110613f3957613f39614cb4565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555084600985611b678110613f7357613f73614cb4565b0180546001600160a01b0319166001600160a01b03928316179055604051859187811691908916907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4505050505050565b60006005821015613fd8575090565b6005611d2a54613fe89190614f51565b611d3954613ff7600585614f51565b611d30546140059190614d13565b61400f9190614ce0565b6140199190614f7e565b610ce7906005614ce0565b61402c6144a2565b60ff601083901c1661403c6144a2565b60005b600a8160ff1610156140c1576000600a8461405b84600d615136565b60ff1661406891906150ef565b6140729190615115565b905060058160ff1610156140ae5761408b8260016150a7565b838260ff16600581106140a0576140a0614cb4565b60ff90921660209290920201525b50806140b981615198565b91505061403f565b509392505050565b6140d4848484613bf7565b6140e08484848461429f565b6120cc5760405162461bcd60e51b8152600401610de0906151b8565b606060006040518060a00160405280607b815260200161535f607b9139905060005b600c81101561417c57816141478583600d811061413d5761413d614cb4565b60200201516143a0565b60405160200161415892919061520a565b6040516020818303038152906040529150808061417490614cf8565b91505061411e565b508060405160200161282c9190615230565b6000808061419d896008615136565b60ff168b901c90506141ae8161443d565b91508792508160ff16600614156141dd576141c9878261525a565b6141d69060ff16846150ef565b925061425b565b8160ff16600514156141fe57866141f4878361525a565b6141c991906150a7565b8160ff1660041415614220578587614216878461525a565b6141f491906150a7565b84868861422d878561525a565b61423791906150a7565b61424191906150a7565b61424b91906150a7565b6142589060ff16846150ef565b92505b891561429157838561426d888a6150a7565b61427791906150a7565b61428191906150a7565b61428e9060ff16846150ef565b92505b509850989650505050505050565b6000833b1561439857604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906142da90339089908890889060040161527c565b602060405180830381600087803b1580156142f457600080fd5b505af1925050508015614324575060408051601f3d908101601f19168201909252614321918101906152af565b60015b61437e573d808015614352576040519150601f19603f3d011682016040523d82523d6000602084013e614357565b606091505b5080516143765760405162461bcd60e51b8152600401610de0906151b8565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613a1c565b506001613a1c565b611d3d54604051637bb7ca8760e11b815261ffff831660048201526060916000916003916001600160a01b03169063f76f950e9060240160006040518083038186803b1580156143ef57600080fd5b505afa158015614403573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261442b9190810190614f92565b60405160200161296c939291906152cc565b600060048260ff16101561445357506006919050565b60188260ff16101561446757506005919050565b60608260ff16101561447b57506004919050565b506003919050565b604051806101e00160405280600f906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b8280546144cc90614c30565b90600052602060002090601f0160209004810192826144ee5760008555614534565b82601f106145075782800160ff19823516178555614534565b82800160010185558215614534579182015b82811115614534578235825591602001919060010190614519565b50611895929150614587565b6040518061020001604052806010905b60608152602001906001900390816145505790505090565b604051806101a00160405280600d906020820280368337509192915050565b5b808211156118955760008155600101614588565b6000602082840312156145ae57600080fd5b5035919050565b6001600160e01b03198116811461174e57600080fd5b6000602082840312156145dd57600080fd5b81356128c1816145b5565b60005b838110156146035781810151838201526020016145eb565b838111156120cc5750506000910152565b6000815180845261462c8160208601602086016145e8565b601f01601f19169290920160200192915050565b6020815260006128c16020830184614614565b80356001600160a01b0381168114611c5357600080fd5b6000806040838503121561467d57600080fd5b61468683614653565b946020939093013593505050565b8060005b60058110156120cc57815160ff16845260209384019390910190600101614698565b6102808101818460005b600f8110156146e757815161ffff168352602092830192909101906001016146c4565b5050506128c16101e0830184614694565b60006020828403121561470a57600080fd5b6128c182614653565b60008060006060848603121561472857600080fd5b61473184614653565b925061473f60208501614653565b9150604084013590509250925092565b60008083601f84011261476157600080fd5b50813567ffffffffffffffff81111561477957600080fd5b60208301915083602082850101111561479157600080fd5b9250929050565b600080602083850312156147ab57600080fd5b823567ffffffffffffffff8111156147c257600080fd5b6147ce8582860161474f565b90969095509350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614819576148196147da565b604052919050565b600067ffffffffffffffff82111561483b5761483b6147da565b50601f01601f191660200190565b600082601f83011261485a57600080fd5b813561486d61486882614821565b6147f0565b81815284602083860101111561488257600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156148b257600080fd5b6148bb83614653565b9150602083013567ffffffffffffffff8111156148d757600080fd5b6148e385828601614849565b9150509250929050565b60a08101610ce78284614694565b634e487b7160e01b600052602160045260246000fd5b6020810160048310614925576149256148fb565b91905290565b60008060006060848603121561494057600080fd5b61494984614653565b925060208401359150604084013567ffffffffffffffff81111561496c57600080fd5b61497886828701614849565b9150509250925092565b60008060008060006060868803121561499a57600080fd5b85359450602086013567ffffffffffffffff808211156149b957600080fd5b6149c589838a0161474f565b909650945060408801359150808211156149de57600080fd5b506149eb8882890161474f565b969995985093965092949392505050565b801515811461174e57600080fd5b60008060408385031215614a1d57600080fd5b614a2683614653565b91506020830135614a36816149fc565b809150509250929050565b60008060008060808587031215614a5757600080fd5b614a6085614653565b9350614a6e60208601614653565b925060408501359150606085013567ffffffffffffffff811115614a9157600080fd5b614a9d87828801614849565b91505092959194509250565b60008060408385031215614abc57600080fd5b82359150602083013560ff81168114614a3657600080fd5b60008060208385031215614ae757600080fd5b823567ffffffffffffffff80821115614aff57600080fd5b818501915085601f830112614b1357600080fd5b813581811115614b2257600080fd5b8660208260051b8501011115614b3757600080fd5b60209290920196919550909350505050565b60e08082526000906102e0830190830186835b6010811015614b8e5760df19868503018352614b79848351614614565b93506020928301929190910190600101614b5c565b505050614b9e6020840186614694565b82810360c08401526115108185614614565b606081526000614bc36060830186614614565b8281036020840152614bd58186614614565b905082810360408401526115108185614614565b6020810160038310614925576149256148fb565b60008060408385031215614c1057600080fd5b614c1983614653565b9150614c2760208401614653565b90509250929050565b600181811c90821680614c4457607f821691505b60208210811415614c6557634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b6020808252600c908201526b139bdd0814995d99585b195960a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115614cf357614cf3614cca565b500190565b6000600019821415614d0c57614d0c614cca565b5060010190565b6000816000190483118215151615614d2d57614d2d614cca565b500290565b8054600090600181811c9080831680614d4c57607f831692505b6020808410821415614d6e57634e487b7160e01b600052602260045260246000fd5b818015614d825760018114614d9357614dc0565b60ff19861689528489019650614dc0565b60008881526020902060005b86811015614db85781548b820152908501908301614d9f565b505084890196505b50505050505092915050565b60008351614dde8184602088016145e8565b600160fd1b908301908152612aad6001820185614d32565b60008351614e088184602088016145e8565b6101d160f51b908301908152612aad6002820185614d32565b6020808252600b908201526a14d85b194810db1bdcd95960aa1b604082015260600190565b60208082526013908201527213585e0814dd5c1c1b1e48115e18d959591959606a1b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601190820152702737b732bc34b9ba32b73a102a37b5b2b760791b604082015260600190565b602080825260129082015271496e76616c696420466c696768747061737360701b604082015260600190565b600060208284031215614f2d57600080fd5b5051919050565b600060208284031215614f4657600080fd5b81516128c1816149fc565b600082821015614f6357614f63614cca565b500390565b634e487b7160e01b600052601260045260246000fd5b600082614f8d57614f8d614f68565b500690565b600060208284031215614fa457600080fd5b815167ffffffffffffffff811115614fbb57600080fd5b8201601f81018413614fcc57600080fd5b8051614fda61486882614821565b818152856020838501011115614fef57600080fd5b612aad8260208301602086016145e8565b66697066733a2f2f60c81b8152600061501c6007830185614d32565b602f60f81b815283516150368160018401602088016145e8565b64173539b7b760d91b60019290910191820152600601949350505050565b66697066733a2f2f60c81b815260006150706007830185614d32565b602f60f81b8152835161508a8160018401602088016145e8565b632e706e6760e01b60019290910191820152600501949350505050565b600060ff821660ff84168060ff038211156150c4576150c4614cca565b019392505050565b600060ff821660ff8416808210156150e6576150e6614cca565b90039392505050565b600061ffff80831681851680830382111561510c5761510c614cca565b01949350505050565b600061ffff8084168061512a5761512a614f68565b92169190910692915050565b600060ff821660ff84168160ff048111821515161561515757615157614cca565b029392505050565b600061ffff8381169083168181101561517a5761517a614cca565b039392505050565b634e487b7160e01b600052603160045260246000fd5b600060ff821660ff8114156151af576151af614cca565b60010192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000835161521c8184602088016145e8565b83519083019061510c8183602088016145e8565b600082516152428184602087016145e8565b651e17b9bb339f60d11b920191825250600601919050565b600060ff83168061526d5761526d614f68565b8060ff84160691505092915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061151090830184614614565b6000602082840312156152c157600080fd5b81516128c1816145b5565b7f3c696d61676520783d22302220793d2230222077696474683d2236303022206881527132b4b3b43a1e911b18181110343932b31e9160711b6020820152600061532261531c6032840187614d32565b85614d32565b602f60f81b8152835161533c8160018401602088016145e8565b67173837339110179f60c11b600192909101918201526009019594505050505056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d6964594d6964206d656574222076696577426f783d223020302036303020363030222077696474683d2236303022206865696768743d22363030223ea2646970667358221220429ce3c3d2fa2c88e340bde89d78547aadc7a8122cefcd4eea62607e058c8c3964736f6c6343000809003368747470733a2f2f737461726b6164652d6c6567696f6e2e6d7970696e6174612e636c6f75642f697066732f00000000000000000000000015081629f46a33dfe0f9b9da9e2d4ffce094108d0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e516d62563642416f62673644696676346e4541737a663956326d69424c6b43453761506456536242464842454239000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103ee5760003560e01c806366bb81c711610208578063c404811711610118578063e1dc0761116100ab578063e634cb091161007a578063e634cb0914610be3578063e64d2f6114610c03578063e985e9c514610c2b578063f2fde38b14610c4b578063fece9bc314610c6b57600080fd5b8063e1dc076114610b45578063e5187f4314610b74578063e541ed3414610b94578063e5bea43514610bb457600080fd5b8063cf348425116100e7578063cf34842514610ace578063d2560bbb14610aee578063d7dc9a7e14610b05578063e1a5bfa114610b2557600080fd5b8063c404811714610a4e578063c87b56dd14610a6e578063cac95fdb14610a8e578063ce606ee014610aae57600080fd5b80639c7afe8b1161019b578063b88d4fde1161016a578063b88d4fde1461099d578063b9da56a9146109bd578063be448206146109dd578063c27b335f14610a0e578063c2ca0ac514610a2e57600080fd5b80639c7afe8b1461092f578063a035b1fe1461094f578063a22cb46514610966578063b047570a1461098657600080fd5b806391b7f5ed116101d757806391b7f5ed146108d257806394d008ef146108f257806395d89b41146109055780639c5b470d1461091a57600080fd5b806366bb81c71461084757806370a082311461085e5780638456cb591461089557806385209ee0146108aa57600080fd5b80632f8e9f4211610303578063517c6876116102965780635c471995116102655780635c471995146107a45780635c975abb146107c457806360159abb146107e557806361e47b56146108125780636352211e1461082757600080fd5b8063517c68761461071d578063538cddb61461073d57806355e732da146107525780635bb209a51461078457600080fd5b806340bdce0d116102d257806340bdce0d1461069157806342842e0e146106c857806342ef1508146106e85780634f6ccce7146106fd57600080fd5b80632f8e9f421461063b57806332c2f7f8146106505780633ccfd60b146106675780633f4ba83a1461067c57600080fd5b8063167ff46f116103865780631d458bd1116103555780631d458bd11461059b57806320733880146105bb57806323b872dd146105db578063255a87fe146105fb5780632f745c591461061b57600080fd5b8063167ff46f146105215780631711862d1461053657806318160ddd146105565780631b7b87131461056d57600080fd5b8063081812fc116103c2578063081812fc14610492578063095ea7b3146104ca5780630ce06b68146104ec57806311f3a5941461050c57600080fd5b8062923f9e146103f357806301ffc9a71461042b57806304a7b8d21461044b57806306fdde0314610470575b600080fd5b3480156103ff57600080fd5b5061041661040e36600461459c565b611d2a541190565b60405190151581526020015b60405180910390f35b34801561043757600080fd5b506104166104463660046145cb565b610c80565b34801561045757600080fd5b50610462611d305481565b604051908152602001610422565b34801561047c57600080fd5b50610485610ced565b6040516104229190614640565b34801561049e57600080fd5b506104b26104ad36600461459c565b610d7b565b6040516001600160a01b039091168152602001610422565b3480156104d657600080fd5b506104ea6104e536600461466a565b610e06565b005b3480156104f857600080fd5b506104ea61050736600461466a565b610f1c565b34801561051857600080fd5b50610485610fb6565b34801561052d57600080fd5b506104ea610fc3565b34801561054257600080fd5b506004546104b2906001600160a01b031681565b34801561056257600080fd5b50610462611d2a5481565b34801561057957600080fd5b5061058d61058836600461459c565b61105d565b6040516104229291906146ba565b3480156105a757600080fd5b506104856105b636600461459c565b61132c565b3480156105c757600080fd5b506104ea6105d63660046146f8565b61151a565b3480156105e757600080fd5b506104ea6105f6366004614713565b6115e7565b34801561060757600080fd5b506104ea610616366004614798565b611618565b34801561062757600080fd5b5061046261063636600461466a565b61164e565b34801561064757600080fd5b50610485611708565b34801561065c57600080fd5b50610462611d2f5481565b34801561067357600080fd5b506104ea611715565b34801561068857600080fd5b506104ea611751565b34801561069d57600080fd5b506106b16106ac36600461459c565b61178a565b604080519215158352602083019190915201610422565b3480156106d457600080fd5b506104ea6106e3366004614713565b6117ba565b3480156106f457600080fd5b506104ea6117d5565b34801561070957600080fd5b5061046261071836600461459c565b61186b565b34801561072957600080fd5b5061041661073836600461489f565b611899565b34801561074957600080fd5b506104856119ef565b34801561075e57600080fd5b5061077261076d36600461459c565b6119fc565b60405160ff9091168152602001610422565b34801561079057600080fd5b5061046261079f36600461459c565b611a54565b3480156107b057600080fd5b506104ea6107bf3660046146f8565b611ad1565b3480156107d057600080fd5b5060065461041690600160a01b900460ff1681565b3480156107f157600080fd5b5061080561080036600461459c565b611c03565b60405161042291906148ed565b34801561081e57600080fd5b506104ea611c58565b34801561083357600080fd5b506104b261084236600461459c565b611c97565b34801561085357600080fd5b50610462611d2e5481565b34801561086a57600080fd5b506104626108793660046146f8565b6001600160a01b03166000908152611b70602052604090205490565b3480156108a157600080fd5b506104ea611d16565b3480156108b657600080fd5b50611d2b546108c59060ff1681565b6040516104229190614911565b3480156108de57600080fd5b506104ea6108ed36600461459c565b611d55565b6104ea61090036600461492b565b611d85565b34801561091157600080fd5b506104856120d2565b34801561092657600080fd5b506104856120df565b34801561093b57600080fd5b506104ea61094a366004614982565b6120ec565b34801561095b57600080fd5b50610462611d3a5481565b34801561097257600080fd5b506104ea610981366004614a0a565b6121dd565b34801561099257600080fd5b50610462611d2d5481565b3480156109a957600080fd5b506104ea6109b8366004614a41565b6122a3565b3480156109c957600080fd5b506104ea6109d8366004614aa9565b6122d5565b3480156109e957600080fd5b506107726109f836600461459c565b611e266020526000908152604090205460ff1681565b348015610a1a57600080fd5b506104ea610a293660046146f8565b612474565b348015610a3a57600080fd5b506104ea610a4936600461459c565b6124c0565b348015610a5a57600080fd5b50610485610a6936600461459c565b6126d7565b348015610a7a57600080fd5b50610485610a8936600461459c565b6126f7565b348015610a9a57600080fd5b50610485610aa936600461459c565b612982565b348015610aba57600080fd5b506005546104b2906001600160a01b031681565b348015610ada57600080fd5b50610485610ae936600461459c565b612993565b348015610afa57600080fd5b50610462611d2c5481565b348015610b1157600080fd5b506104ea610b20366004614ad4565b612b5a565b348015610b3157600080fd5b50610485610b4036600461459c565b612c84565b348015610b5157600080fd5b50610b65610b6036600461459c565b612c95565b60405161042293929190614b49565b348015610b8057600080fd5b506104ea610b8f3660046146f8565b613048565b348015610ba057600080fd5b50610485610baf36600461459c565b613094565b348015610bc057600080fd5b50610bd4610bcf36600461459c565b6130a5565b60405161042293929190614bb0565b348015610bef57600080fd5b50610772610bfe36600461459c565b61334d565b348015610c0f57600080fd5b50611e2754610c1e9060ff1681565b6040516104229190614be9565b348015610c3757600080fd5b50610416610c46366004614bfd565b613378565b348015610c5757600080fd5b506104ea610c663660046146f8565b6133a7565b348015610c7757600080fd5b506104ea6133f3565b60006001600160e01b031982166301ffc9a760e01b1480610cb157506001600160e01b031982166380ac58cd60e01b145b80610ccc57506001600160e01b03198216635b5e139f60e01b145b80610ce757506001600160e01b0319821663780e9d6360e01b145b92915050565b60078054610cfa90614c30565b80601f0160208091040260200160405190810160405280929190818152602001828054610d2690614c30565b8015610d735780601f10610d4857610100808354040283529160200191610d73565b820191906000526020600020905b815481529060010190602001808311610d5657829003601f168201915b505050505081565b6000611d2a548210610de95760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152611d2860205260409020546001600160a01b031690565b6000610e1182611c97565b9050806001600160a01b0316836001600160a01b03161415610e7f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610de0565b336001600160a01b0382161480610e9b5750610e9b8133613378565b610f0d5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610de0565b610f178383613483565b505050565b6005546001600160a01b03163314610f465760405162461bcd60e51b8152600401610de090614c6b565b600554604051632142170760e11b81523060048201526001600160a01b03918216602482015260448101839052908316906342842e0e90606401600060405180830381600087803b158015610f9a57600080fd5b505af1158015610fae573d6000803e3d6000fd5b505050505050565b60028054610cfa90614c30565b6005546001600160a01b03163314610fed5760405162461bcd60e51b8152600401610de090614c6b565b6000611d2b5460ff166003811115611007576110076148fb565b146110405760405162461bcd60e51b81526020600482015260096024820152684e6f7420526561647960b81b6044820152606401610de0565b611d2b805460ff1916600117905543611d2c55611d2a54611d3b55565b611065614483565b61106d6144a2565b6003611d2b5460ff166003811115611087576110876148fb565b146110a45760405162461bcd60e51b8152600401610de090614c8e565b60006110af84611a54565b90506000806000806110c188866134f2565b929650909450925090506110df8585600c5b6020020151858561383f565b955080156110f057600187526110f5565b600087525b60005b600c811015611154578481600d811061111357611113614cb4565b602002015188611124836001614ce0565b600f811061113457611134614cb4565b61ffff90921660209290920201528061114c81614cf8565b9150506110f8565b5061018084015161ffff166000908152611e1e60209081526040808320815160808101909252805460ff168252600181018054929391929184019161119890614c30565b80601f01602080910402602001604051908101604052809291908181526020018280546111c490614c30565b80156112115780601f106111e657610100808354040283529160200191611211565b820191906000526020600020905b8154815290600101906020018083116111f457829003601f168201915b5050505050815260200160028201805461122a90614c30565b80601f016020809104026020016040519081016040528092919081815260200182805461125690614c30565b80156112a35780601f10611278576101008083540402835291602001916112a3565b820191906000526020600020905b81548152906001019060200180831161128657829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116112cb57505050929093525050915160ff166101a08b01525050506101809093015161ffff166101c08701525093959294509192505050565b6060600061133b836003614d13565b90506000611df7826103e4811061135457611354614cb4565b602081049091015460ff601f9092166101000a90041690506000611df761137c846001614ce0565b6103e4811061138d5761138d614cb4565b602081049091015460ff601f9092166101000a90041690506000611df76113b5856002614ce0565b6103e481106113c6576113c6614cb4565b602091828204019190069054906101000a900460ff1690506000611d418460ff1660b681106113f7576113f7614cb4565b01805461140390614c30565b80601f016020809104026020016040519081016040528092919081815260200182805461142f90614c30565b801561147c5780601f106114515761010080835404028352916020019161147c565b820191906000526020600020905b81548152906001019060200180831161145f57829003601f168201915b5050505050905060008360ff1611156114cb5780611d418460ff1660b681106114a7576114a7614cb4565b016040516020016114b9929190614dcc565b60405160208183030381529060405290505b60ff8216156115105780611d418360ff1660b681106114ec576114ec614cb4565b016040516020016114fe929190614df6565b60405160208183030381529060405290505b9695505050505050565b6005546001600160a01b031633146115445760405162461bcd60e51b8152600401610de090614c6b565b6001611d2b5460ff16600381111561155e5761155e6148fb565b148061158157506000611d2b5460ff16600381111561157f5761157f6148fb565b145b61159d5760405162461bcd60e51b8152600401610de090614e21565b611b67611d2a54106115c15760405162461bcd60e51b8152600401610de090614e46565b6115ce81611d2a54613a24565b611d2a80549060006115df83614cf8565b919050555050565b6115f13382613b38565b61160d5760405162461bcd60e51b8152600401610de090614e73565b610f17838383613bf7565b6005546001600160a01b031633146116425760405162461bcd60e51b8152600401610de090614c6b565b610f17600083836144c0565b6001600160a01b0382166000908152611b70602052604081205482106116ca5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610de0565b6001600160a01b0383166000908152611b70602052604090208054839081106116f5576116f5614cb4565b9060005260206000200154905092915050565b60008054610cfa90614c30565b6005546040516001600160a01b03909116904780156108fc02916000818181858888f1935050505015801561174e573d6000803e3d6000fd5b50565b6005546001600160a01b0316331461177b5760405162461bcd60e51b8152600401610de090614c6b565b6006805460ff60a01b19169055565b600080600061179884613fc9565b9050600f8110156117ae57600194909350915050565b50600093849350915050565b610f17838383604051806020016040528060008152506122a3565b6005546001600160a01b031633146117ff5760405162461bcd60e51b8152600401610de090614c6b565b6001611e275460ff166002811115611819576118196148fb565b146118535760405162461bcd60e51b815260206004820152600a602482015269139bdd0810db1bdcd95960b21b6044820152606401610de0565b611e2780546000919060ff19166001835b0217905550565b600061187982611d2a541190565b6118955760405162461bcd60e51b8152600401610de090614ec4565b5090565b604080516b199b1a59da1d1b1a5cdd195960a21b60208201526bffffffffffffffffffffffff19606085901b16602c82015260009182910160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c01604051602081830303815290604052805190602001209050600080600085516041146119585760405162461bcd60e51b8152600401610de090614eef565b505050602083810151604080860151606080880151600654845160008082529781018087528990529190961a93810184905290810184905260808101829052919390916001600160a01b039091169060019060a0016020604051602081039080840390855afa1580156119cf573d6000803e3d6000fd5b505050602060405103516001600160a01b03161494505050505092915050565b60018054610cfa90614c30565b6000611a0a82611d2a541190565b611a265760405162461bcd60e51b8152600401610de090614ec4565b611d3b54821015611a3957506000919050565b611d3c54821015611a4c57506001919050565b506002919050565b6000600f611a6183613fc9565b1015611aa05760405162461bcd60e51b815260206004820152600e60248201526d21b7b9329021b430b930b1ba32b960911b6044820152606401610de0565b50611d2f54604080516020808201939093528082019390935280518084038201815260609093019052815191012090565b6005546001600160a01b03163314611afb5760405162461bcd60e51b8152600401610de090614c6b565b6005546040516370a0823160e01b815230600482015282916001600160a01b038084169263a9059cbb92919091169083906370a082319060240160206040518083038186803b158015611b4d57600080fd5b505afa158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b859190614f1b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611bcb57600080fd5b505af1158015611bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f179190614f34565b611c0b6144a2565b6003611d2b5460ff166003811115611c2557611c256148fb565b14611c425760405162461bcd60e51b8152600401610de090614c8e565b610ce7611c4e83611a54565b614024565b919050565b6005546001600160a01b03163314611c825760405162461bcd60e51b8152600401610de090614c6b565b611e2780546002919060ff1916600183611864565b6000611ca582611d2a541190565b611cf15760405162461bcd60e51b815260206004820152601960248201527f4552433732313a204e6f6e6578697374656e7420746f6b656e000000000000006044820152606401610de0565b600982611b678110611d0557611d05614cb4565b01546001600160a01b031692915050565b6005546001600160a01b03163314611d405760405162461bcd60e51b8152600401610de090614c6b565b6006805460ff60a01b1916600160a01b179055565b6005546001600160a01b03163314611d7f5760405162461bcd60e51b8152600401610de090614c6b565b611d3a55565b600a821115611d9357600a91505b6001611d2b5460ff166003811115611dad57611dad6148fb565b14611dca5760405162461bcd60e51b8152600401610de090614e21565b611dd761033e6008614d13565b611d2c54611de59190614ce0565b431015611e7657611df68382611899565b611e125760405162461bcd60e51b8152600401610de090614eef565b6001600160a01b0383166000908152611b70602052604090205415611e6d5760405162461bcd60e51b8152602060048201526011602482015270141c99599b1a59da1d0810db185a5b5959607a1b6044820152606401610de0565b60019150611f54565b611e8361033e6009614d13565b611d2c54611e919190614ce0565b431015611f3e57611ea28382611899565b611ebe5760405162461bcd60e51b8152600401610de090614eef565b600b82611ee1856001600160a01b03166000908152611b70602052604090205490565b611eeb9190614ce0565b1115611f395760405162461bcd60e51b815260206004820152601960248201527f466c6967687470617373206c696d6974206578636565646564000000000000006044820152606401610de0565b611f54565b611d3c54611f401415611f5457611d2a54611d3c555b611b6782611d2a54611f669190614ce0565b1115611f845760405162461bcd60e51b8152600401610de090614e46565b600082611d3a54611f959190614d13565b905080341015611fdc5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742046756e647360701b6044820152606401610de0565b60005b8381101561201157611fff8582611d2a54611ffa9190614ce0565b613a24565b8061200981614cf8565b915050611fdf565b5082611d2a60008282546120259190614ce0565b9091555050348110156120cc5760003361203f8334614f51565b604051600081818185875af1925050503d806000811461207b576040519150601f19603f3d011682016040523d82523d6000602084013e612080565b606091505b50509050806120ca5760405162461bcd60e51b81526020600482015260166024820152751499599d5b9908151c985b9cd9995c8811985a5b195960521b6044820152606401610de0565b505b50505050565b60088054610cfa90614c30565b60038054610cfa90614c30565b6005546001600160a01b031633146121165760405162461bcd60e51b8152600401610de090614c6b565b6001611d2b5460ff166003811115612130576121306148fb565b148061215357506002611d2b5460ff166003811115612151576121516148fb565b145b61218f5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420537461746560981b6044820152606401610de0565b611d2e5461219e9060c8614ce0565b43116121a957600080fd5b611d2b805460ff19166002908117909155611d2d86905543611d2e556121d09085856144c0565b50610fae600383836144c0565b336001600160a01b03831614156122365760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610de0565b336000818152611d29602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6122ad3383613b38565b6122c95760405162461bcd60e51b8152600401610de090614e73565b6120cc848484846140c9565b6003611d2b5460ff1660038111156122ef576122ef6148fb565b1461230c5760405162461bcd60e51b8152600401610de090614c8e565b3361231683611c97565b6001600160a01b0316146123585760405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b6044820152606401610de0565b60008160ff1611801561236f575060058160ff1611155b6123ac5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642043686f69636560901b6044820152606401610de0565b6000828152611e26602052604090205460ff16156123ff5760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e48115c5d5a5c1c195960821b6044820152606401610de0565b6000611e275460ff166002811115612419576124196148fb565b146124515760405162461bcd60e51b81526020600482015260086024820152672737ba1027b832b760c11b6044820152606401610de0565b6000918252611e266020526040909120805460ff191660ff909216919091179055565b6005546001600160a01b0316331461249e5760405162461bcd60e51b8152600401610de090614c6b565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031633146124ea5760405162461bcd60e51b8152600401610de090614c6b565b611d2e546124f9906004614ce0565b431180156125145750611d2e546125119060c8614ce0565b43105b61254e5760405162461bcd60e51b815260206004820152600b60248201526a426c6f636b2052616e676560a81b6044820152606401610de0565b6002611d2b5460ff166003811115612568576125686148fb565b146125a85760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e4814995d99585b195960821b6044820152606401610de0565b611d2d54604080516020810184905201604051602081830303815290604052805190602001201461260b5760405162461bcd60e51b815260206004820152600d60248201526c0a6cacac8409ad2e6dac2e8c6d609b1b6044820152606401610de0565b80611d2e54600161261c9190614ce0565b40611d2e54600261262d9190614ce0565b40611d2e54600361263e9190614ce0565b604080516020810195909552840192909252606083015240608082015260a00160408051601f198184030181529190528051602090910120611d2f55611d2a5461268a90600590614f51565b611d2f546126989190614f7e565b611d3955611d2f54611d31906126b090600890614f7e565b600881106126c0576126c0614cb4565b0154611d305550611d2b805460ff19166003179055565b611e1781600781106126e857600080fd5b018054909150610cfa90614c30565b6060611d2a5482106127635760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610de0565b6003611d2b5460ff16600381111561277d5761277d6148fb565b14156128c857600061278e83613fc9565b9050600f81101561284357611d3d54604051637bb7ca8760e11b8152600481018390526002916001600160a01b03169063f76f950e9060240160006040518083038186803b1580156127df57600080fd5b505afa1580156127f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261281b9190810190614f92565b60405160200161282c929190615000565b604051602081830303815290604052915050919050565b60048054604051636a93802960e01b81529182018590526001600160a01b031690636a9380299060240160006040518083038186803b15801561288557600080fd5b505afa158015612899573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128c19190810190614f92565b9392505050565b611d3d546001906001600160a01b031663f76f950e6128e6856119fc565b6040516001600160e01b031960e084901b16815260ff909116600482015260240160006040518083038186803b15801561291f57600080fd5b505afa158015612933573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261295b9190810190614f92565b60405160200161296c929190615000565b6040516020818303038152906040529050919050565b611e2181600581106126e857600080fd5b60606129a182611d2a541190565b6129bd5760405162461bcd60e51b8152600401610de090614ec4565b6003611d2b5460ff1660038111156129d7576129d76148fb565b1415612ab65760006129e883613fc9565b9050600f811015612a8657611d3d54604051637bb7ca8760e11b8152600481018390526002916001600160a01b03169063f76f950e9060240160006040518083038186803b158015612a3957600080fd5b505afa158015612a4d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a759190810190614f92565b60405160200161282c929190615054565b6000612a9184611a54565b90506000612a9f85836134f2565b5050509050612aad816140fc565b95945050505050565b611d3d546001906001600160a01b031663f76f950e612ad4856119fc565b6040516001600160e01b031960e084901b16815260ff909116600482015260240160006040518083038186803b158015612b0d57600080fd5b505afa158015612b21573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b499190810190614f92565b60405160200161296c929190615054565b6005546001600160a01b03163314612b845760405162461bcd60e51b8152600401610de090614c6b565b6001611d2b5460ff166003811115612b9e57612b9e6148fb565b1480612bc157506000611d2b5460ff166003811115612bbf57612bbf6148fb565b145b612bdd5760405162461bcd60e51b8152600401610de090614e21565b611d2a54611b6790612bf0908390614ce0565b1115612c0e5760405162461bcd60e51b8152600401610de090614e46565b60005b81811015612c6457612c52838383818110612c2e57612c2e614cb4565b9050602002016020810190612c4391906146f8565b82611d2a54611ffa9190614ce0565b80612c5c81614cf8565b915050612c11565b5081819050611d2a6000828254612c7b9190614ce0565b90915550505050565b611e2881601081106126e857600080fd5b612c9d614540565b612ca56144a2565b60606003611d2b5460ff166003811115612cc157612cc16148fb565b14612cde5760405162461bcd60e51b8152600401610de090614c8e565b6000612ce985611a54565b9050600080600080612cfb89866134f2565b92965090945092509050612d118585600c6110d3565b96508015612d2a57612d23600161132c565b8852612d37565b612d34600061132c565b88525b60005b600c811015612d9957612d668582600d8110612d5857612d58614cb4565b602002015161ffff1661132c565b89612d72836001614ce0565b60108110612d8257612d82614cb4565b602002015280612d9181614cf8565b915050612d3a565b5061018084015161ffff166000908152611e1e60209081526040808320815160808101909252805460ff1682526001810180549293919291840191612ddd90614c30565b80601f0160208091040260200160405190810160405280929190818152602001828054612e0990614c30565b8015612e565780601f10612e2b57610100808354040283529160200191612e56565b820191906000526020600020905b815481529060010190602001808311612e3957829003601f168201915b50505050508152602001600282018054612e6f90614c30565b80601f0160208091040260200160405190810160405280929190818152602001828054612e9b90614c30565b8015612ee85780601f10612ebd57610100808354040283529160200191612ee8565b820191906000526020600020905b815481529060010190602001808311612ecb57829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612f105790505050505050815250509050611e17816000015160ff1660078110612f6457612f64614cb4565b018054612f7090614c30565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9c90614c30565b8015612fe95780601f10612fbe57610100808354040283529160200191612fe9565b820191906000526020600020905b815481529060010190602001808311612fcc57829003601f168201915b505050505089600d6010811061300157613001614cb4565b6020020181905250806020015189600e6010811061302157613021614cb4565b602002015260408101516101e08a015261303a856140fc565b989a97995050505050505050565b6005546001600160a01b031633146130725760405162461bcd60e51b8152600401610de090614c6b565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b611d3e81600381106126e857600080fd5b6060806060600c84106130eb5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a590818da5d1e525960921b6044820152606401610de0565b6000848152611e1e60209081526040808320815160808101909252805460ff168252600181018054929391929184019161312490614c30565b80601f016020809104026020016040519081016040528092919081815260200182805461315090614c30565b801561319d5780601f106131725761010080835404028352916020019161319d565b820191906000526020600020905b81548152906001019060200180831161318057829003601f168201915b505050505081526020016002820180546131b690614c30565b80601f01602080910402602001604051908101604052809291908181526020018280546131e290614c30565b801561322f5780601f106132045761010080835404028352916020019161322f565b820191906000526020600020905b81548152906001019060200180831161321257829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116132575790505050505050815250509050611e17816000015160ff16600781106132ab576132ab614cb4565b0180546132b790614c30565b80601f01602080910402602001604051908101604052809291908181526020018280546132e390614c30565b80156133305780601f1061330557610100808354040283529160200191613330565b820191906000526020600020905b81548152906001019060200180831161331357829003601f168201915b505050505093508060200151925080604001519150509193909250565b611e1f816037811061335e57600080fd5b60209182820401919006915054906101000a900460ff1681565b6001600160a01b039182166000908152611d296020908152604080832093909416825291909152205460ff1690565b6005546001600160a01b031633146133d15760405162461bcd60e51b8152600401610de090614c6b565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b0316331461341d5760405162461bcd60e51b8152600401610de090614c6b565b6000611e275460ff166002811115613437576134376148fb565b1461346f5760405162461bcd60e51b81526020600482015260086024820152672737ba1027b832b760c11b6044820152606401610de0565b611e2780546001919060ff19168280611864565b6000818152611d286020526040902080546001600160a01b0319166001600160a01b03841690811790915581906134b982611c97565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6134fa614568565b600080600060fc85901c6001166001149050600060fd86901c6001166001149050600060fe87901c600116600114905060006135418860008060026001600260048061418e565b61ffff919091168852905061355681876150a7565b60008a8152611e26602052604090205490965060ff1680156135f257600061357d8a614024565b90508061358b6001846150cc565b60ff166005811061359e5761359e614cb4565b60200201519650600d6135b26001896150cc565b60ff166135bf91906150ef565b61ffff1660208a015285156135ec57600a896001602002018181516135e491906150ef565b61ffff169052505b506135fa565b606060208901525b602161360e600560ff60188d901c16614f7e565b6136189190614ce0565b61ffff16604089015284156136455760058860026020020181815161363d91906150ef565b61ffff169052505b821561367c5761366089866003602b6001600380600561418e565b61ffff919091166060808b019190915260808a015291506136a7565b613692898660046043600160026004600661418e565b61ffff9190911660808a01526060808a015291505b6136b182886150a7565b96506136c889866005605d6001600380600461418e565b61ffff9190911660a08a015291506136e082886150a7565b96506136f689866006607360018060048061418e565b61ffff9190911660c08a0152915061370e82886150a7565b9650613726898660076087600160046003600261418e565b61ffff9190911660e08a0152915061373e82886150a7565b965061375689866008609b600360046006600761418e565b61ffff919091166101008a0152915061376f82886150a7565b965083156137a95761378d8986600960c3600460056006600a61418e565b61ffff919091166101208a015260606101608a015291506137d9565b6137c08986600b610123600360046006600761418e565b61ffff919091166101608a015261014b6101208a015291505b6137e382886150a7565b96506137fb8986600a60f5600260046007600a61418e565b61ffff919091166101408a0152915061381482886150a7565b9650613825600c60608b901c615115565b61ffff166101808901525095989497509295509093505050565b6138476144a2565b61ffff84166000908152611e1e6020526040808220815160a0810192839052916003909101906005908285855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116138745790505050505050905060005b600a8110156139595760006138c2826002614d13565b6138cd906070614ce0565b88901c60031690505b60148482600581106138ea576138ea614cb4565b602002015160ff161061391a578060031415613908575060006138d6565b8061391281614cf8565b9150506138d6565b600584826005811061392e5761392e614cb4565b6020020181815161393f91906150a7565b60ff1690525081905061395181614cf8565b9150506138ac565b5060005b6005811015613a1957611e1f81613975866005615136565b60ff166139829190614ce0565b6037811061399257613992614cb4565b602081049091015460ff601f9092166101000a9004168282600581106139ba576139ba614cb4565b60200201516139ca87600a6150a7565b6139d491906150a7565b6139de91906150a7565b8382600581106139f0576139f0614cb4565b60200201818151613a0191906150a7565b60ff1690525080613a1181614cf8565b91505061395d565b50505b949350505050565b600654600160a01b900460ff1615613a675760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610de0565b6001600160a01b0382166000818152611b70602090815260408220805460018101825581845291832090910184905591905254611b7182611b678110613aaf57613aaf614cb4565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555081600982611b678110613ae957613ae9614cb4565b0180546001600160a01b0319166001600160a01b0392831617905560405182918416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000611d2a548210613ba15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610de0565b6000613bac83611c97565b9050806001600160a01b0316846001600160a01b03161480613be75750836001600160a01b0316613bdc84610d7b565b6001600160a01b0316145b80613a1c5750613a1c8185613378565b600654600160a01b900460ff1615613c3a5760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610de0565b826001600160a01b0316613c4d82611c97565b6001600160a01b031614613cb55760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610de0565b6001600160a01b038216613d175760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610de0565b613d2461033e6009614d13565b611d2c54613d329190614ce0565b4311613d745760405162461bcd60e51b8152602060048201526011602482015270466c696768746c6973742041637469766560781b6044820152606401610de0565b613d7f600082613483565b6000611b7182611b678110613d9657613d96614cb4565b601091828204019190066002029054906101000a900461ffff1690506000600182613dc1919061515f565b6001600160a01b0386166000908152611b70602052604081205461ffff92909216925090613df190600190614f51565b9050818114613eb3576001600160a01b0386166000908152611b7060205260408120805483908110613e2557613e25614cb4565b9060005260206000200154905080611b706000896001600160a01b03166001600160a01b031681526020019081526020016000208481548110613e6a57613e6a614cb4565b60009182526020909120015583611b7182611b678110613e8c57613e8c614cb4565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550505b6001600160a01b0386166000908152611b7060205260409020805480613edb57613edb615182565b6000828152602080822083016000199081018390559092019092556001600160a01b038716808352611b70825260408320805460018101825581855292842090920187905590915254611b7185611b678110613f3957613f39614cb4565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555084600985611b678110613f7357613f73614cb4565b0180546001600160a01b0319166001600160a01b03928316179055604051859187811691908916907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4505050505050565b60006005821015613fd8575090565b6005611d2a54613fe89190614f51565b611d3954613ff7600585614f51565b611d30546140059190614d13565b61400f9190614ce0565b6140199190614f7e565b610ce7906005614ce0565b61402c6144a2565b60ff601083901c1661403c6144a2565b60005b600a8160ff1610156140c1576000600a8461405b84600d615136565b60ff1661406891906150ef565b6140729190615115565b905060058160ff1610156140ae5761408b8260016150a7565b838260ff16600581106140a0576140a0614cb4565b60ff90921660209290920201525b50806140b981615198565b91505061403f565b509392505050565b6140d4848484613bf7565b6140e08484848461429f565b6120cc5760405162461bcd60e51b8152600401610de0906151b8565b606060006040518060a00160405280607b815260200161535f607b9139905060005b600c81101561417c57816141478583600d811061413d5761413d614cb4565b60200201516143a0565b60405160200161415892919061520a565b6040516020818303038152906040529150808061417490614cf8565b91505061411e565b508060405160200161282c9190615230565b6000808061419d896008615136565b60ff168b901c90506141ae8161443d565b91508792508160ff16600614156141dd576141c9878261525a565b6141d69060ff16846150ef565b925061425b565b8160ff16600514156141fe57866141f4878361525a565b6141c991906150a7565b8160ff1660041415614220578587614216878461525a565b6141f491906150a7565b84868861422d878561525a565b61423791906150a7565b61424191906150a7565b61424b91906150a7565b6142589060ff16846150ef565b92505b891561429157838561426d888a6150a7565b61427791906150a7565b61428191906150a7565b61428e9060ff16846150ef565b92505b509850989650505050505050565b6000833b1561439857604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906142da90339089908890889060040161527c565b602060405180830381600087803b1580156142f457600080fd5b505af1925050508015614324575060408051601f3d908101601f19168201909252614321918101906152af565b60015b61437e573d808015614352576040519150601f19603f3d011682016040523d82523d6000602084013e614357565b606091505b5080516143765760405162461bcd60e51b8152600401610de0906151b8565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613a1c565b506001613a1c565b611d3d54604051637bb7ca8760e11b815261ffff831660048201526060916000916003916001600160a01b03169063f76f950e9060240160006040518083038186803b1580156143ef57600080fd5b505afa158015614403573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261442b9190810190614f92565b60405160200161296c939291906152cc565b600060048260ff16101561445357506006919050565b60188260ff16101561446757506005919050565b60608260ff16101561447b57506004919050565b506003919050565b604051806101e00160405280600f906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b8280546144cc90614c30565b90600052602060002090601f0160209004810192826144ee5760008555614534565b82601f106145075782800160ff19823516178555614534565b82800160010185558215614534579182015b82811115614534578235825591602001919060010190614519565b50611895929150614587565b6040518061020001604052806010905b60608152602001906001900390816145505790505090565b604051806101a00160405280600d906020820280368337509192915050565b5b808211156118955760008155600101614588565b6000602082840312156145ae57600080fd5b5035919050565b6001600160e01b03198116811461174e57600080fd5b6000602082840312156145dd57600080fd5b81356128c1816145b5565b60005b838110156146035781810151838201526020016145eb565b838111156120cc5750506000910152565b6000815180845261462c8160208601602086016145e8565b601f01601f19169290920160200192915050565b6020815260006128c16020830184614614565b80356001600160a01b0381168114611c5357600080fd5b6000806040838503121561467d57600080fd5b61468683614653565b946020939093013593505050565b8060005b60058110156120cc57815160ff16845260209384019390910190600101614698565b6102808101818460005b600f8110156146e757815161ffff168352602092830192909101906001016146c4565b5050506128c16101e0830184614694565b60006020828403121561470a57600080fd5b6128c182614653565b60008060006060848603121561472857600080fd5b61473184614653565b925061473f60208501614653565b9150604084013590509250925092565b60008083601f84011261476157600080fd5b50813567ffffffffffffffff81111561477957600080fd5b60208301915083602082850101111561479157600080fd5b9250929050565b600080602083850312156147ab57600080fd5b823567ffffffffffffffff8111156147c257600080fd5b6147ce8582860161474f565b90969095509350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614819576148196147da565b604052919050565b600067ffffffffffffffff82111561483b5761483b6147da565b50601f01601f191660200190565b600082601f83011261485a57600080fd5b813561486d61486882614821565b6147f0565b81815284602083860101111561488257600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156148b257600080fd5b6148bb83614653565b9150602083013567ffffffffffffffff8111156148d757600080fd5b6148e385828601614849565b9150509250929050565b60a08101610ce78284614694565b634e487b7160e01b600052602160045260246000fd5b6020810160048310614925576149256148fb565b91905290565b60008060006060848603121561494057600080fd5b61494984614653565b925060208401359150604084013567ffffffffffffffff81111561496c57600080fd5b61497886828701614849565b9150509250925092565b60008060008060006060868803121561499a57600080fd5b85359450602086013567ffffffffffffffff808211156149b957600080fd5b6149c589838a0161474f565b909650945060408801359150808211156149de57600080fd5b506149eb8882890161474f565b969995985093965092949392505050565b801515811461174e57600080fd5b60008060408385031215614a1d57600080fd5b614a2683614653565b91506020830135614a36816149fc565b809150509250929050565b60008060008060808587031215614a5757600080fd5b614a6085614653565b9350614a6e60208601614653565b925060408501359150606085013567ffffffffffffffff811115614a9157600080fd5b614a9d87828801614849565b91505092959194509250565b60008060408385031215614abc57600080fd5b82359150602083013560ff81168114614a3657600080fd5b60008060208385031215614ae757600080fd5b823567ffffffffffffffff80821115614aff57600080fd5b818501915085601f830112614b1357600080fd5b813581811115614b2257600080fd5b8660208260051b8501011115614b3757600080fd5b60209290920196919550909350505050565b60e08082526000906102e0830190830186835b6010811015614b8e5760df19868503018352614b79848351614614565b93506020928301929190910190600101614b5c565b505050614b9e6020840186614694565b82810360c08401526115108185614614565b606081526000614bc36060830186614614565b8281036020840152614bd58186614614565b905082810360408401526115108185614614565b6020810160038310614925576149256148fb565b60008060408385031215614c1057600080fd5b614c1983614653565b9150614c2760208401614653565b90509250929050565b600181811c90821680614c4457607f821691505b60208210811415614c6557634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b6020808252600c908201526b139bdd0814995d99585b195960a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115614cf357614cf3614cca565b500190565b6000600019821415614d0c57614d0c614cca565b5060010190565b6000816000190483118215151615614d2d57614d2d614cca565b500290565b8054600090600181811c9080831680614d4c57607f831692505b6020808410821415614d6e57634e487b7160e01b600052602260045260246000fd5b818015614d825760018114614d9357614dc0565b60ff19861689528489019650614dc0565b60008881526020902060005b86811015614db85781548b820152908501908301614d9f565b505084890196505b50505050505092915050565b60008351614dde8184602088016145e8565b600160fd1b908301908152612aad6001820185614d32565b60008351614e088184602088016145e8565b6101d160f51b908301908152612aad6002820185614d32565b6020808252600b908201526a14d85b194810db1bdcd95960aa1b604082015260600190565b60208082526013908201527213585e0814dd5c1c1b1e48115e18d959591959606a1b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601190820152702737b732bc34b9ba32b73a102a37b5b2b760791b604082015260600190565b602080825260129082015271496e76616c696420466c696768747061737360701b604082015260600190565b600060208284031215614f2d57600080fd5b5051919050565b600060208284031215614f4657600080fd5b81516128c1816149fc565b600082821015614f6357614f63614cca565b500390565b634e487b7160e01b600052601260045260246000fd5b600082614f8d57614f8d614f68565b500690565b600060208284031215614fa457600080fd5b815167ffffffffffffffff811115614fbb57600080fd5b8201601f81018413614fcc57600080fd5b8051614fda61486882614821565b818152856020838501011115614fef57600080fd5b612aad8260208301602086016145e8565b66697066733a2f2f60c81b8152600061501c6007830185614d32565b602f60f81b815283516150368160018401602088016145e8565b64173539b7b760d91b60019290910191820152600601949350505050565b66697066733a2f2f60c81b815260006150706007830185614d32565b602f60f81b8152835161508a8160018401602088016145e8565b632e706e6760e01b60019290910191820152600501949350505050565b600060ff821660ff84168060ff038211156150c4576150c4614cca565b019392505050565b600060ff821660ff8416808210156150e6576150e6614cca565b90039392505050565b600061ffff80831681851680830382111561510c5761510c614cca565b01949350505050565b600061ffff8084168061512a5761512a614f68565b92169190910692915050565b600060ff821660ff84168160ff048111821515161561515757615157614cca565b029392505050565b600061ffff8381169083168181101561517a5761517a614cca565b039392505050565b634e487b7160e01b600052603160045260246000fd5b600060ff821660ff8114156151af576151af614cca565b60010192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000835161521c8184602088016145e8565b83519083019061510c8183602088016145e8565b600082516152428184602087016145e8565b651e17b9bb339f60d11b920191825250600601919050565b600060ff83168061526d5761526d614f68565b8060ff84160691505092915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061151090830184614614565b6000602082840312156152c157600080fd5b81516128c1816145b5565b7f3c696d61676520783d22302220793d2230222077696474683d2236303022206881527132b4b3b43a1e911b18181110343932b31e9160711b6020820152600061532261531c6032840187614d32565b85614d32565b602f60f81b8152835161533c8160018401602088016145e8565b67173837339110179f60c11b600192909101918201526009019594505050505056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d6964594d6964206d656574222076696577426f783d223020302036303020363030222077696474683d2236303022206865696768743d22363030223ea2646970667358221220429ce3c3d2fa2c88e340bde89d78547aadc7a8122cefcd4eea62607e058c8c3964736f6c63430008090033

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

00000000000000000000000015081629f46a33dfe0f9b9da9e2d4ffce094108d0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e516d62563642416f62673644696676346e4541737a663956326d69424c6b43453761506456536242464842454239000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : flightlistSigningAddress (address): 0x15081629f46a33Dfe0f9b9dA9e2D4FfcE094108d
Arg [1] : ipfsPass (string): QmbV6BAobg6Difv4nEAszf9V2miBLkCE7aPdVSbBFHBEB9

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000015081629f46a33dfe0f9b9da9e2d4ffce094108d
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 000000000000000000000000000000000000000000000000000000000000002e
Arg [3] : 516d62563642416f62673644696676346e4541737a663956326d69424c6b4345
Arg [4] : 3761506456536242464842454239000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.