ETH Price: $3,357.66 (+0.30%)

Token

STARKADE (💫)
 

Overview

Max Total Supply

315 💫

Holders

142

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
starkade.eth
Balance
2 💫
0x4eE737450AD45D239C4783e15EfC90709deFB22A
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
LostFighter

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 6 : LostFighters.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 Lost Fighters
 * @author Ponderware Ltd
 * @dev ERC-721 contract for Starkade Lost Fighters NFT
 * @notice license: https://starkade.com/licences/nft/starkade-legion/
 */
contract LostFighter 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 Lost Fighters 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 = 0;
    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 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");
        // 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 LostFighter.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 LostFighter.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":[{"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"}]

60e0604052602c6080818152906200ad2d60a039805162000029916000916020909101906200546a565b506040805160208101918290526000908190526200004a916001916200546a565b506040805160208101918290526000908190526200006b916002916200546a565b506040805160208101918290526000908190526200008c916003916200546a565b506006805460ff60a01b1916600160a01b17905560408051808201909152600880825267535441524b41444560c01b6020909201918252620000d1916007916200546a565b5060408051808201909152600480825263f09f92ab60e01b6020909201918252620000ff916008916200546a565b506000611d2a55611d2b805460ff191690556040805161010081018252680470d97cab4ce6941b81526803f152450bb2614a1d602082015268010c0b8a29c45d5455918101919091526802192c51675e44dc6160608201526802f3a9edfbc0e5641f608082015267eb8a9d5d2cba591f60a0820152680269f314d5a7b96e7b60c08201526802c71b4caeed02993d60e0820152620001a390611d31906008620054f9565b5067011c37937e080000611d3a556000611d3b55611f40611d3c55611d3d80546001600160a01b03191673b39c61fe6281324a23e079464f7e697f8ba6968f1790556040805160a081018252600b606082018181526a5369676e616c6e6f69736560a81b60808401528252825180840184529081526a119b1a59da1d08131a5cdd60aa1b60208281019190915280830191909152825180840184526008815267535441524b41444560c01b91810191909152918101919091526200026d90611d3e90600362005535565b50604080516116e08101825260006116c082019081528152815180830183526004808252634e6f6e6560e01b6020838101919091528084019290925283518085018552600680825265244d61676e6160d01b8285015284860191909152845180860186528281526320b2b7b760e11b818501526060850152845180860186526005808252644167696c6560d81b82860152608086019190915285518087018752600280825261416960f01b8287015260a0870191909152865180880188528381526541726361646560d01b8187015260c08701528651808801885260038082526241726d60e81b8288015260e088019190915287518089018952600780825266105c9b58985b9960ca1b828901526101008901919091528851808a018a528681526341726d7360e01b818901526101208901528851808a018a52858152654172726f777360d01b818901526101408901528851808a018a526008808252674174686c6574696360c01b828a01526101608a01919091528951808b018b528181526741766961746f727360c01b818a01526101808a01528951808b018b5282815266417765736f6d6560c81b818a01526101a08a01528951808b018b52878152634261636b60e01b818a01526101c08a01528951808b018b528581526442616e677360d81b818a01526101e08a01528951808b018b52868152652130b9b432b960d11b818a01526102008a01528951808b018b5285815264426565667960d81b818a01526102208a01528951808b018b52858152642134b5b2b960d91b818a01526102408a01528951808b018b5285815264426c61636b60d81b818a01526102608a01528951808b018b5282815266213630b9ba32b960c91b818a01526102808a01528951808b018b5286815265426c6f6e646560d01b818a01526102a08a01528951808b018b5287815263426c756560e01b818a01526102c08a01528951808b018b5286815265426f756e747960d01b818a01526102e08a01528951808b018b528681526542726169647360d01b818a01526103008a01528951808b018b528681526542726f6e636f60d01b818a01526103208a01528951808b018b528781526343616d6f60e01b818a01526103408a01528951808b018b528381526204361760ec1b818a01526103608a01528951808b018b52858152644368616f7360d81b818a01526103808a01528951808b018b528681526521b437b5b2b960d11b818a01526103a08a01528951808b018b5282815266436c617373696360c81b818a01526103c08a01528951808b018b528181526710db195b98da195960c21b818a01526103e08a01528951808b018b5285815264436f6d6d7360d81b818a01526104008a01528951808b018b5285815264086e4c2e6d60db1b818a01526104208a01528951808b018b52600a80825269043726f737353747261760b41b828b01526104408b01919091528a51808c018c528881526321bcb0b760e11b818b01526104608b01528a51808c018c528681526421bcb132b960d91b818b01526104808b01528a51808c018c5281815269437962657242616e677360b01b818b01526104a08b01528a51808c018c5260098082526821bcb132b92bb7b63360b91b828c01526104c08c01919091528b51808d018d5284815266111a59da5d185b60ca1b818c01526104e08c01528b51808d018d5283815267446f6f6d7364617960c01b818c01526105008c01528b51808d018d5288815265446f75626c6560d01b818c01526105208c01528b51808d018d528281526944726561646c6f636b7360b01b818c01526105408c01528b51808d018d528481526645617272696e6760c81b818c01526105608c01528b51808d018d528581526222b63b60e91b818c01526105808c01528b51808d018d5289815263115d9a5b60e21b818c01526105a08c01528b51808d018d528581526245796560e81b818c01526105c08c01528b51808d018d52898152634579657360e01b818c01526105e08c01528b51808d018d528781526446616e677360d81b818c01526106008c01528b51808d018d5287815264119a595b1960da1b818c01526106208c01528b51808d018d52838152672334b734b9b432b960c11b818c01526106408c01528b51808d018d52898152634669726560e01b818c01526106608c01528b51808d018d5284815266466c616d696e6760c81b818c01526106808c01528b51808d018d528781526408cd8c2e6d60db1b818c01526106a08c01528b51808d018d5283815267119bd8dd5cdcd95960c21b818c01526106c08c01528b51808d018d5287815264466f72636560d81b818c01526106e08c01528b51808d018d5283815267466f72747265737360c01b818c01526107008c01528b51808d018d528181526846726f73747761726560b81b818c01526107208c01528b51808d018d528881526546757475726560d01b818c01526107408c01528b51808d018d5286815261474d60f01b818c01526107608c01528b51808d018d528581526247656d60e81b818c01526107808c01528b51808d018d528781526423b932b2b760d91b818c01526107a08c01528b51808d018d52878152644772696d6d60d81b818c01526107c08c01528b51808d018d528981526323b934b760e11b818c01526107e08c01528b51808d018d528781526411dc9bdddb60da1b818c01526108008c01528b51808d018d528781526404772756d760dc1b818c01526108208c01528b51808d018d52600c8082526b48616c662d736c656576657360a01b828d01526108408d01919091528c51808e018e528681526212185d60ea1b818d01526108608d01528c51808e018e52838152694865616470686f6e657360b01b818d01526108808d01528c51808e018e528981526512195b1b595d60d21b818d01526108a08d01528c51808e018e5286815262090caf60eb1b818d01526108c08d01528c51808e018e528a815263121bdbd960e21b818d01526108e08d01528c51808e018e528681526249636560e81b818d01526109008d01528c51808e018e528a8152634a61634b60e01b818d01526109208d01528c51808e018e5289815265129858dad95d60d21b818d01526109408d01528c51808e018e528681526212995d60ea1b818d01526109608d01528c51808e018e52858152664b656e7461726f60c81b818d01526109808d01528c51808e018e5288815264098c2eaced60db1b818d01526109a08d01528c51808e018e52848152674c6176617761726560c01b818d01526109c08d01528c51808e018e52858152662632b0ba3432b960c91b818d01526109e08d01528c51808e018e52898152652632b3b4b7b760d11b818d0152610a008d01528c51808e018e528581526613195bdc185c9960ca1b818d0152610a208d01528c51808e018e52828152684c696768746e696e6760b81b818d0152610a408d01528c51808e018e528a8152634c696e6560e01b818d0152610a608d01528c51808e018e528a8152634c6f6e6760e01b818d0152610a808d01528c51808e018e52888152644d6167696360d81b818d0152610aa08d01528c51808e018e52888152644d61676e6160d81b818d0152610ac08d01528c51808e018e528481526726b0b3b730ba37b760c11b818d0152610ae08d01528c51808e018e528a8152634d61736b60e01b818d0152610b008d01528c51808e018e52888152644d6175766560d81b818d0152610b208d01528c51808e018e528a81526309acac6d60e31b818d0152610b408d01528c51808e018e528681526209acad60eb1b818d0152610b608d01528c51808e018e528a8152634d65726360e01b818d0152610b808d01528c51808e018e52898152654d6f6861776b60d01b818d0152610ba08d01528c51808e018e52600b81526a26b7b93734b733b9ba30b960a91b818d0152610bc08d01528c51808e018e52888152644d756c746960d81b818d0152610be08d01528c51808e018e52888152644e6563726f60d81b818d0152610c008d01528c51808e018e52848152674e656f6e4669726560c01b818d0152610c208d01528c51808e018e528981526509ceaa8cac6d60d31b818d0152610c408d01528c51808e018e52878152614f4760f01b818d0152610c608d01528c51808e018e528481526727b13930b5b4b0b760c11b818d0152610c808d01528c51808e018e52888152644f6368726560d81b818d0152610ca08d01528c51808e018e52888152644f6d62726560d81b818d0152610cc08d01528c51808e018e52898152654f72616e676560d01b818d0152610ce08d01528c51808e018e528a8152635061647360e01b818d0152610d008d01528c51808e018e52858152662830b73a3432b960c91b818d0152610d208d01528c51808e018e5284815267506172616469736560c01b818d0152610d408d01528c51808e018e52888152640a0c2e8c6d60db1b818d0152610d608d01528c51808e018e528a81526350696e6b60e01b818d0152610d808d01528c51808e018e528a815263506f647360e01b818d0152610da08d01528c51808e018e5283815269506f6e6465727761726560b01b818d0152610dc08d01528c51808e018e5284815267141bdb9e5d185a5b60c21b818d0152610de08d01528c51808e018e528a815263141bdd5d60e21b818d0152610e008d01528c51808e018e52888152642837bbb2b960d91b818d0152610e208d01528c51808e018e528a81526350756e6b60e01b818d0152610e408d01528c51808e018e5289815265507572706c6560d01b818d0152610e608d01528c51808e018e528681526214985960ea1b818d0152610e808d01528c51808e018e528a8152632930b4b760e11b818d0152610ea08d01528c51808e018e52858152665261696e626f7760c81b818d0152610ec08d01528c51808e018e52868152622932bb60e91b818d0152610ee08d01528c51808e018e5289815265149a5c1c195960d21b818d0152610f008d01528c51808e018e528a815263526f626f60e01b818d0152610f208d01528c51808e018e52898152652937b1b5b2b960d11b818d0152610f408d01528c51808e018e528781526129a760f11b818d0152610f608d01528c51808e018e528581526653616d7572616960c81b818d0152610f808d01528c51808e018e528981526553617661676560d01b818d0152610fa08d01528c51808e018e5288815264536861646560d81b818d0152610fc08d01528c51808e018e528981526553686164657360d01b818d0152610fe08d01528c51808e018e529081526b29b430b93829b437b7ba32b960a11b818c01526110008c01528b51808d018d5287815264536861766560d81b818c01526110208c01528b51808d018d528781526414da1bdc9d60da1b818c01526110408c01528b51808d018d528381526753686f776861776b60c01b818c01526110608c01528b51808d018d52898152635369646560e01b818c01526110808c01528b51808d018d528881526529b4b63b32b960d11b818c01526110a08c01528b51808d018d528781526414dadd5b1b60da1b818c01526110c08c01528b51808d018d5284815266536c656576657360c81b818c01526110e08c01528b51808d018d5287815264536d696c6560d81b818c01526111008c01528b51808d018d528781526429b732b2b960d91b818c01526111208c01528b51808d018d528781526429b832b0b960d91b818c01526111408c01528b51808d018d528881526553706561727360d01b818c01526111608c01528b51808d018d528381526729b832b1ba3930b760c11b818c01526111808c01528b51808d018d528881526514dc1a5ad95960d21b818c01526111a08c01528b51808d018d52888152655370696b657360d01b818c01526111c08c01528b51808d018d528781526429ba30b33360d91b818c01526111e08c01528b51808d018d528881526553746166667360d01b818c01526112008c01528b51808d018d528281526929ba30b935b0b234b0b760b11b818c01526112208c01528b51808d018d52898152635374617960e01b818c01526112408c01528b51808d018d52848152660a6e8cac2d8e8d60cb1b818c01526112608c01528b51808d018d529283526714dd1c985c1c195960c21b838b01526112808b01929092528a51808c018c5287815265537472696b6560d01b818b01526112a08b01528a51808c018c528781526553747269706560d01b818b01526112c08b01528a51808c018c52838152665374726970657360c81b818b01526112e08b01528a51808c018c528381526653747562626c6560c81b818b01526113008b01528a51808c018c528381526653756e4669726560c81b818b01526113208b01528a51808c018c5286815264053776565760dc1b818b01526113408b01528a51808c018c52878152650a6eededee6d60d31b818b01526113608b01528a51808c018c528681526414dddbdc9960da1b818b01526113808b01528a51808c018c528281526853796e64696361746560b81b818b01526113a08b01528a51808c018c5283815266546174746f6f7360c81b818b01526113c08b01528a51808c018c52868152645461776e7960d81b818b01526113e08b01528a51808c018c52838152662a32bd3ab5b0b760c91b818b01526114008b01528a51808c018c5287815265546f6e67756560d01b818b01526114208b01528a51808c018c5287815265546f6f74687960d01b818b01526114408b01528a51808c018c5286815264547269626560d81b818b01526114608b01528a51808c018c52948552612b2960f11b858a01526114808a01949094528951808b018b52868152652b30b837bab960d11b818a01526114a08a01528951808b018b528781526315995cdd60e21b818a01526114c08a01528951808b018b52858152642b34b9b7b960d91b818a01526114e08a01528951808b018b52938452692b34b9bab0b634b9b2b960b11b848901526115008901939093528851808a018a5284815264566f6c746160d81b818901526115208901528851808a018a5285815265566f6c756d6560d01b818901526115408901528851808a018a52908152662bb0b93934b7b960c91b8188015261156088015287518089018952858152635761766560e01b8188015261158088015287518089018952858152630576869760e41b818801526115a08801528751808901895283815264576869746560d81b818801526115c0880152875180890189529081526257696760e81b818701526115e0870152865180880188528481526315da5b1960e21b8187015261160087015286518088018852908152682bb4b732313637bbb760b91b81860152611620860152855180870187528381526357696e6b60e01b81860152611640860152855180870187529283526316595b1b60e21b8385015261166085019290925284518086018652918252645a6562726160d81b82840152611680840191909152835180850190945283526514da185d995960d21b908301526116a0810191909152620017d690611d419060b662005588565b5060405180617c800160405280601160ff168152602001600060ff168152602001600060ff168152602001600b60ff168152602001600060ff168152602001600060ff168152602001605660ff168152602001607560ff168152602001600060ff168152602001603360ff168152602001600060ff168152602001600060ff168152602001605260ff168152602001600060ff168152602001600060ff168152602001601c60ff168152602001600060ff168152602001606760ff168152602001601c60ff168152602001600060ff168152602001606c60ff168152602001601c60ff168152602001600060ff168152602001601660ff168152602001601c60ff168152602001600060ff168152602001607360ff168152602001607160ff168152602001600060ff168152602001606760ff168152602001607160ff168152602001600060ff168152602001606c60ff168152602001607160ff168152602001600060ff168152602001601660ff168152602001607160ff168152602001600060ff168152602001607360ff168152602001605660ff168152602001608f60ff168152602001600060ff16815260200160ad60ff168152602001600060ff168152602001600060ff168152602001601460ff168152602001600060ff168152602001600060ff168152602001604b60ff168152602001606d60ff168152602001600060ff168152602001605e60ff168152602001600060ff168152602001600060ff168152602001602960ff168152602001608b60ff168152602001600060ff168152602001603760ff168152602001603160ff168152602001600060ff168152602001600a60ff168152602001600060ff168152602001600060ff168152602001608a60ff168152602001600060ff168152602001600060ff168152602001609c60ff168152602001600060ff168152602001600060ff168152602001605660ff168152602001608f60ff168152602001600060ff16815260200160ad60ff168152602001600060ff168152602001600060ff168152602001601460ff168152602001600060ff168152602001600060ff168152602001604b60ff168152602001606d60ff168152602001600060ff168152602001605e60ff168152602001600060ff168152602001600060ff168152602001602960ff168152602001608b60ff168152602001600060ff168152602001609060ff168152602001600060ff168152602001600060ff168152602001600a60ff168152602001600060ff168152602001600060ff168152602001608a60ff168152602001600060ff168152602001600060ff168152602001609c60ff168152602001600060ff168152602001600060ff168152602001605960ff168152602001600060ff168152602001600060ff168152602001602360ff168152602001600060ff168152602001600060ff168152602001602c60ff168152602001600060ff168152602001600060ff168152602001606560ff168152602001600060ff168152602001600060ff168152602001609f60ff168152602001600060ff168152602001600060ff168152602001605960ff168152602001600060ff168152602001600060ff168152602001602360ff168152602001600060ff168152602001600060ff168152602001602c60ff168152602001600060ff168152602001600060ff168152602001606560ff168152602001600060ff168152602001600060ff168152602001609f60ff168152602001600060ff168152602001600060ff168152602001600d60ff168152602001600060ff168152602001600060ff168152602001602760ff168152602001606a60ff168152602001600060ff168152602001609d60ff168152602001600060ff168152602001600060ff168152602001607b60ff168152602001608660ff168152602001600060ff16815260200160b460ff168152602001600060ff168152602001601660ff168152602001609160ff168152602001600060ff168152602001600060ff168152602001600260ff168152602001600060ff168152602001600060ff168152602001603b60ff168152602001600060ff168152602001600060ff16815260200160b460ff168152602001600060ff168152602001606c60ff168152602001605060ff168152602001600060ff168152602001600060ff168152602001609260ff168152602001607460ff168152602001600060ff168152602001601a60ff168152602001600060ff168152602001600060ff16815260200160a960ff168152602001603e60ff168152602001600060ff168152602001602760ff168152602001606a60ff168152602001600060ff168152602001606260ff168152602001600060ff168152602001600060ff168152602001607b60ff168152602001608660ff168152602001600060ff168152602001605160ff168152602001600060ff168152602001600060ff168152602001609160ff168152602001600060ff168152602001600060ff168152602001600260ff168152602001600060ff168152602001600060ff168152602001606960ff168152602001600060ff168152602001600060ff16815260200160b460ff168152602001600060ff168152602001606c60ff168152602001605060ff168152602001600060ff168152602001600060ff168152602001609760ff168152602001600060ff168152602001600060ff168152602001601a60ff168152602001600060ff168152602001600060ff168152602001600560ff168152602001600060ff168152602001600060ff168152602001609160ff168152602001600060ff168152602001600060ff168152602001602660ff168152602001600060ff168152602001600060ff168152602001608060ff168152602001600060ff168152602001600060ff168152602001607e60ff168152602001600060ff168152602001600060ff168152602001603960ff168152602001600060ff168152602001600060ff168152602001606360ff168152602001600060ff168152602001600060ff168152602001602260ff168152602001600060ff168152602001600060ff16815260200160a060ff168152602001600060ff168152602001600060ff168152602001605060ff168152602001600060ff168152602001607360ff168152602001605060ff168152602001600060ff16815260200160ae60ff168152602001606460ff168152602001600060ff168152602001601660ff168152602001606460ff168152602001600060ff168152602001603d60ff168152602001600560ff168152602001600060ff168152602001600060ff168152602001609160ff168152602001600060ff168152602001600060ff168152602001603c60ff168152602001600060ff168152602001600060ff168152602001608060ff168152602001600060ff168152602001600060ff168152602001607e60ff168152602001600060ff168152602001600060ff168152602001603960ff168152602001600060ff168152602001600060ff168152602001601760ff168152602001600060ff168152602001600060ff168152602001602260ff168152602001600060ff168152602001600060ff168152602001609360ff168152602001600060ff168152602001600060ff168152602001605060ff168152602001600060ff16815260200160ae60ff168152602001604e60ff168152602001600060ff168152602001600060ff168152602001605760ff168152602001600060ff168152602001600060ff168152602001606460ff168152602001600060ff168152602001603d60ff168152602001603560ff168152602001600060ff168152602001600060ff168152602001600360ff168152602001600060ff168152602001606c60ff168152602001600360ff168152602001600060ff16815260200160ae60ff168152602001600160ff168152602001600060ff168152602001600060ff168152602001602860ff168152602001600060ff168152602001600060ff168152602001601060ff168152602001600060ff168152602001601360ff168152602001601060ff168152602001600060ff168152602001606c60ff168152602001601060ff168152602001600060ff168152602001607360ff168152602001609860ff168152602001600060ff168152602001600060ff168152602001602460ff16815260200160a360ff168152602001606c60ff168152602001602460ff16815260200160a360ff168152602001607360ff168152602001603560ff168152602001600060ff168152602001600060ff168152602001600360ff168152602001600060ff168152602001606c60ff168152602001600360ff168152602001600060ff16815260200160ae60ff168152602001600160ff168152602001600060ff168152602001600060ff16815260200160ab60ff168152602001602f60ff168152602001600060ff168152602001609660ff168152602001600060ff168152602001600060ff168152602001601060ff168152602001600060ff168152602001601660ff168152602001601060ff168152602001600060ff168152602001607360ff168152602001601060ff168152602001600060ff16815260200160ae60ff168152602001602460ff16815260200160a360ff168152602001606c60ff168152602001602460ff16815260200160a360ff168152602001607360ff168152602001603060ff168152602001600060ff168152602001600060ff16815260200160a160ff168152602001600060ff168152602001600060ff16815260200160a260ff168152602001608860ff168152602001600060ff168152602001605b60ff168152602001600060ff168152602001600060ff168152602001601f60ff168152602001600060ff168152602001600060ff168152602001604160ff168152602001600060ff168152602001600060ff168152602001604d60ff168152602001600060ff168152602001600060ff168152602001608960ff168152602001600060ff168152602001600060ff168152602001603f60ff168152602001600060ff168152602001600060ff16815260200160b360ff168152602001600060ff168152602001600060ff168152602001603060ff168152602001600060ff168152602001600060ff16815260200160a160ff168152602001600060ff168152602001600060ff16815260200160a260ff168152602001608860ff168152602001600060ff168152602001607060ff168152602001600060ff168152602001600060ff168152602001601f60ff168152602001600060ff168152602001600060ff168152602001608960ff168152602001600060ff168152602001601360ff168152602001604060ff168152602001600060ff168152602001600060ff168152602001608960ff168152602001600060ff168152602001600060ff168152602001608860ff168152602001600060ff168152602001600060ff16815260200160b360ff168152602001600060ff168152602001600060ff168152602001605a60ff168152602001600060ff168152602001600060ff168152602001609960ff168152602001600060ff168152602001600060ff168152602001604860ff168152602001600060ff168152602001600060ff168152602001606160ff168152602001600060ff168152602001600060ff168152602001606060ff168152602001600060ff168152602001600060ff168152602001602d60ff168152602001600060ff168152602001600060ff168152602001605560ff168152602001600060ff168152602001600060ff16815260200160b260ff168152602001600060ff168152602001600060ff168152602001601e60ff168152602001600060ff168152602001600060ff168152602001603660ff168152602001600060ff168152602001600060ff168152602001605a60ff168152602001600060ff168152602001600060ff168152602001609960ff168152602001600060ff168152602001600060ff168152602001604860ff168152602001600060ff168152602001600060ff168152602001606160ff168152602001600060ff168152602001600060ff168152602001606060ff168152602001600060ff168152602001600060ff168152602001602d60ff168152602001600060ff168152602001600060ff168152602001605560ff168152602001600060ff168152602001600060ff16815260200160b260ff168152602001600060ff168152602001600060ff168152602001601e60ff168152602001600060ff168152602001600060ff168152602001603660ff168152602001600060ff168152602001600060ff168152602001602460ff168152602001602e60ff168152602001600060ff168152602001607660ff16815260200160a760ff168152602001600060ff168152602001607c60ff168152602001605860ff168152602001606c60ff168152602001608660ff168152602001605860ff168152602001606c60ff16815260200160a460ff16815260200160a760ff168152602001600060ff168152602001602e60ff168152602001606b60ff168152602001600060ff168152602001607c60ff168152602001605860ff168152602001603d60ff168152602001605360ff168152602001607f60ff168152602001600060ff168152602001608660ff168152602001605860ff16815260200160ae60ff16815260200160a860ff168152602001600060ff168152602001600060ff168152602001603c60ff168152602001600060ff168152602001600060ff168152602001602160ff168152602001605860ff168152602001600060ff168152602001607960ff16815260200160a760ff168152602001606c60ff168152602001607f60ff168152602001600060ff168152602001608560ff168152602001607f60ff168152602001600060ff168152602001601360ff168152602001607f60ff168152602001600060ff168152602001606c60ff168152602001600c60ff168152602001600060ff168152602001600060ff168152602001603260ff168152602001605860ff168152602001601660ff168152602001603260ff168152602001605860ff168152602001607360ff168152602001602b60ff168152602001600060ff168152602001600060ff168152602001602460ff168152602001602e60ff168152602001600060ff168152602001607660ff16815260200160a760ff168152602001600060ff168152602001607c60ff168152602001605860ff168152602001606760ff168152602001608660ff168152602001605860ff168152602001607360ff16815260200160a460ff16815260200160a760ff168152602001600060ff168152602001602e60ff168152602001606b60ff168152602001600060ff168152602001603960ff168152602001605860ff168152602001600060ff168152602001605360ff168152602001607f60ff168152602001600060ff168152602001608660ff168152602001605860ff168152602001606760ff16815260200160a860ff168152602001600060ff168152602001600060ff168152602001603c60ff168152602001600060ff168152602001600060ff168152602001607960ff16815260200160a760ff168152602001601360ff168152602001607960ff16815260200160a760ff16815260200160ae60ff168152602001607f60ff168152602001600060ff168152602001608560ff168152602001607f60ff168152602001600060ff168152602001601360ff168152602001607d60ff168152602001607f60ff168152602001600060ff168152602001600c60ff168152602001600060ff168152602001600060ff168152602001603260ff168152602001605860ff168152602001606760ff168152602001603260ff168152602001605860ff168152602001603d60ff168152602001602b60ff168152602001600060ff168152602001600060ff168152602001605d60ff168152602001600060ff168152602001606c60ff168152602001607c60ff168152602001605460ff168152602001601660ff168152602001609b60ff168152602001600060ff16815260200160ae60ff168152602001602a60ff168152602001600060ff168152602001607360ff16815260200160b060ff168152602001600060ff168152602001601360ff16815260200160b060ff168152602001600060ff16815260200160ae60ff168152602001607c60ff168152602001600060ff16815260200160ae60ff168152602001605d60ff168152602001600060ff168152602001601360ff16815260200160ac60ff168152602001600060ff168152602001607360ff168152602001605d60ff168152602001600060ff16815260200160ae60ff168152602001607c60ff168152602001605460ff16815260200160ae60ff16815260200160ac60ff168152602001600060ff16815260200160ae60ff168152602001609b60ff168152602001600060ff168152602001601360ff168152602001602a60ff168152602001600060ff16815260200160ae60ff16815260200160b160ff168152602001600060ff168152602001601360ff168152602001608360ff168152602001600060ff168152602001601360ff16815260200160b160ff168152602001600060ff168152602001606c60ff168152602001608d60ff168152602001600060ff168152602001601360ff168152602001608d60ff168152602001600060ff168152602001601560ff168152602001608260ff168152602001608e60ff168152602001601360ff168152602001608260ff168152602001608e60ff168152602001601560ff168152602001607c60ff168152602001600060ff168152602001601360ff168152602001607c60ff168152602001605460ff168152602001601360ff168152602001609b60ff168152602001600060ff168152602001601560ff16815260200160ac60ff168152602001600060ff168152602001601360ff168152602001606660ff168152602001600060ff168152602001600060ff168152602001605d60ff168152602001600060ff168152602001607360ff168152602001601860ff168152602001600060ff168152602001607360ff168152602001608d60ff168152602001600e60ff168152602001601660ff168152602001608460ff168152602001608160ff16815260200160ae60ff168152602001602560ff168152602001600060ff168152602001601660ff168152602001602560ff168152602001600060ff168152602001607360ff168152602001609a60ff168152602001600060ff168152602001606c60ff168152602001608260ff168152602001600060ff168152602001607360ff168152602001606f60ff168152602001600060ff168152602001606c60ff168152602001608d60ff168152602001608260ff168152602001602360ff168152602001608d60ff168152602001605460ff168152602001602360ff168152602001608d60ff168152602001605460ff16815260200160ae60ff168152602001608260ff168152602001600060ff16815260200160ae60ff168152602001601860ff168152602001600060ff168152602001601660ff168152602001608460ff168152602001608160ff168152602001601360ff168152602001606f60ff168152602001600060ff168152602001601360ff16815260200160aa60ff168152602001600060ff168152602001600060ff168152602001608d60ff168152602001600e60ff168152602001601360ff168152602001608d60ff168152602001608260ff16815260200160ae60ff168152602001608d60ff168152602001605460ff168152602001601360ff168152602001600f60ff168152602001600060ff168152602001606c60ff168152602001600f60ff168152602001600060ff16815260200160ae60ff168152602001605d60ff168152602001600060ff168152602001601360ff168152602001609a60ff168152602001600060ff168152602001601360ff168152602001604c60ff168152602001604a60ff168152602001606c60ff168152602001600660ff168152602001604a60ff168152602001600060ff168152602001603260ff168152602001606860ff168152602001607360ff168152602001602460ff168152602001600760ff168152602001600060ff168152602001608060ff168152602001600960ff168152602001600060ff168152602001600560ff168152602001600960ff168152602001600060ff168152602001607e60ff168152602001600960ff168152602001600060ff168152602001604c60ff168152602001604a60ff168152602001601660ff168152602001605c60ff168152602001606860ff168152602001607360ff168152602001602860ff168152602001606860ff168152602001606c60ff168152602001602860ff168152602001606860ff168152602001607360ff168152602001602460ff168152602001609e60ff168152602001600060ff168152602001604960ff168152602001600960ff16815260200160ae60ff168152602001601260ff16815260200160a660ff168152602001600060ff168152602001604f60ff168152602001604a60ff168152602001601360ff168152602001609460ff168152602001606860ff168152602001600060ff168152602001609560ff168152602001606860ff168152602001606c60ff168152602001609560ff168152602001606860ff168152602001601660ff168152602001603260ff168152602001606860ff168152602001601660ff168152602001609160ff168152602001600960ff168152602001600060ff168152602001604960ff168152602001600960ff168152602001607360ff168152602001604660ff168152602001600960ff168152602001606760ff168152602001607860ff168152602001608760ff168152602001600060ff168152602001604c60ff168152602001604a60ff168152602001605f60ff168152602001600660ff168152602001604a60ff168152602001600060ff168152602001607260ff16815260200160a660ff168152602001600060ff168152602001602460ff168152602001600760ff168152602001600060ff168152602001608060ff168152602001600960ff168152602001600060ff168152602001600560ff168152602001600960ff168152602001600060ff168152602001607e60ff168152602001600960ff168152602001600060ff168152602001605c60ff168152602001606860ff168152602001605f60ff168152602001608d60ff168152602001606860ff168152602001600060ff168152602001602860ff168152602001606860ff168152602001601360ff168152602001602460ff168152602001609e60ff168152602001600060ff168152602001604960ff168152602001600960ff16815260200160ae60ff168152602001601d60ff168152602001600060ff168152602001607360ff168152602001603860ff168152602001606860ff168152602001600060ff168152602001604f60ff168152602001604a60ff16815260200160ae60ff168152602001604260ff168152602001600060ff168152602001600060ff168152602001609560ff168152602001606860ff168152602001606c60ff168152602001600460ff168152602001606860ff168152602001600060ff168152602001609160ff168152602001600960ff168152602001600060ff168152602001604960ff168152602001600960ff168152602001607360ff168152602001601d60ff168152602001600060ff168152602001601360ff168152602001607860ff168152602001608760ff168152602001600060ff168152602001600860ff168152602001600060ff168152602001600060ff168152602001608060ff168152602001604560ff168152602001600060ff168152602001602660ff168152602001604560ff168152602001600060ff168152602001603460ff168152602001608660ff168152602001600060ff168152602001604960ff168152602001604560ff16815260200160ae60ff168152602001600560ff168152602001604560ff168152602001600060ff168152602001607960ff168152602001604560ff168152602001600060ff168152602001606e60ff168152602001604560ff168152602001606c60ff168152602001604960ff168152602001604560ff168152602001601360ff168152602001607e60ff168152602001604560ff168152602001600060ff168152602001607760ff168152602001604560ff168152602001601360ff168152602001606e60ff168152602001604560ff168152602001601660ff168152602001607760ff168152602001604560ff168152602001607360ff168152602001601960ff168152602001604360ff168152602001600060ff168152602001607a60ff16815260200160af60ff168152602001600060ff168152602001604760ff168152602001600060ff168152602001601660ff168152602001604760ff168152602001600060ff168152602001607360ff168152602001605060ff168152602001601b60ff168152602001600060ff168152602001604460ff168152602001600060ff168152602001600060ff168152602001602060ff168152602001600060ff168152602001600060ff168152602001603a60ff16815260200160a760ff168152602001600060ff168152602001608060ff168152602001604560ff168152602001600060ff168152602001603960ff168152602001604560ff168152602001600060ff168152602001603460ff168152602001608660ff168152602001600060ff168152602001604960ff168152602001604560ff16815260200160ae60ff168152602001600560ff168152602001604560ff168152602001600060ff168152602001604e60ff168152602001604560ff168152602001600060ff168152602001606e60ff168152602001604560ff168152602001606c60ff168152602001604960ff168152602001604560ff168152602001601360ff168152602001607e60ff168152602001604560ff168152602001600060ff168152602001607760ff168152602001604560ff168152602001601360ff168152602001606e60ff168152602001604560ff168152602001601660ff168152602001607760ff168152602001604560ff168152602001607360ff16815260200160a560ff168152602001605860ff168152602001600060ff168152602001601960ff168152602001604360ff168152602001600060ff168152602001608c60ff168152602001604560ff168152602001600060ff168152602001604760ff168152602001600060ff168152602001601660ff168152602001604760ff168152602001600060ff16815260200160ae60ff168152602001605060ff168152602001601b60ff168152602001600060ff168152602001604460ff168152602001600060ff168152602001600060ff168152602001602060ff168152602001600060ff168152602001600060ff16815260200160b560ff168152602001600060ff168152602001600060ff16815250611df7906103e462003edd929190620055cd565b506040805161012081018252600a60e082018181526953686f7265726964676560b01b6101008401528252825180840184526011815270536b79726f6172204d6f756e7461696e7360781b60208281019190915280840191909152835180850185529182526941726b2054656b6e6f7360b01b828201528284019190915282518084018452600c81526b546865205761696c616e647360a01b81830152606083015282518084018452600b81526a41656f6e204d6f72726f7760a81b81830152608083015282518084018452600e81526d13995bddd85d994811195cd95c9d60921b8183015260a08301528251808401909352601083526f4772696e6665726e6f20506c61696e7360801b9083015260c08101919091526200400590611e1790600762005662565b50604080516106e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052600f610120820181905260056101408301819052610160830181905261018083018190526101a083018490526101c083018490526101e08301829052610200830184905261022083018490526102408301849052610260830184905261028083018490526102a083018490526102c08301919091526102e082018390526103008201839052610320820181905261034082018390526103608201839052600a61038083018190526103a083018490526103c083018190526103e08301849052610400830184905261042083018290526104408301849052610460830184905261048083018490526104a083018290526104c083018190526104e08301849052610500830184905261052083018290526105408301819052610560830184905261058083018490526105a083018290526105c083018490526105e083018290526106008301829052610620830184905261064083015261066082018390526106808201526106a081018290526106c0810191909152620041d390611e1f906037620056a7565b506040805160e081018252600560a08201818152642837bbb2b960d91b60c08401528252825180840184526006815265456e6572677960d01b60208281019190915280840191909152835180850185528281526414dc19595960da1b8183015283850152835180850185526007815266446566656e636560c81b8183015260608401528351808501909452818452644368616f7360d81b9084015260808201929092526200428691611e219190620056fd565b50611e27805460ff1916600117905560408051610240810182526009610200820181815268426f6479205479706560b81b610220840152825282518084018452600a80825269109858dad9dc9bdd5b9960b21b602080840191909152808501929092528451808601865283815268115c5d5a5c1b595b9d60ba1b81840152848601528451808601865283815268536b696e20546f6e6560b81b8184015260608501528451808601865260058082526414da1a5c9d60da1b8285015260808601919091528551808701875260068082526520b936b7bab960d11b8286015260a08701919091528651808801885292835269119858d94814185a5b9d60b21b8385015260c0860192909252855180870187529081526409adeeae8d60db1b8184015260e0850152845180860186526004808252634579657360e01b8285015261010086019190915285518087018752848152682330b1b29023b2b0b960b91b8185015261012086015285518087018752818152632430b4b960e11b81850152610140860152855180870187528181526323b2b0b960e11b8185015261016086015285518087018752938452682432b0b21023b2b0b960b91b8484015261018085019390935284518086018652908152652932b3b4b7b760d11b818301526101a084015283518085018552918252634369747960e01b828201526101c08301919091528251808401909352600e83526d436861726163746572697374696360901b908301526101e0810191909152620044c290611e2890601062005742565b50348015620044d057600080fd5b506040516200ad593803806200ad59833981016040819052620044f3916200586d565b60058054336001600160a01b03199182168117909255600680549091166001600160a01b038516179055604051630f41a04d60e11b8152600481019190915273084b1c3c81545d370f3634392de611caabff814890631e83409a90602401602060405180830381600087803b1580156200456c57600080fd5b505af115801562004581573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620045a791906200596d565b50620045b2620045d0565b8051620045c79060019060208401906200546a565b505050620059c4565b6040805160808082018352600080835283518085018552600a8082526946656c6c627265657a6560b01b6020808401919091528086019283528651808801885291825269496465616c697374696360b01b8282015285870191909152855160a081018752838152600f818301529586018390526060808701849052938601839052928401949094528052611e1e815281517f7ee5b629881c3c2d5bc2a77f863e700ce29107715e36dda86584d4ab241a8b78805460ff191660ff90921691909117815592518051929392620046c9927f7ee5b629881c3c2d5bc2a77f863e700ce29107715e36dda86584d4ab241a8b799201906200546a565b5060408201518051620046e79160028401916020909101906200546a565b506060820151620046ff906003830190600562005787565b50506040805160808082018352600180835283518085018552600e81526d4472696674776f6f64205175617960901b602080830191909152808501918252855180870187526008815267496d706f73696e6760c01b8183015285870152855160a0810187526000808252818301819052968101879052600f606080830191909152948101879052938501939093529352611e1e815281517f4024c42b59ef1ee82b0af9257e97dd419404d615ee9e3f29f4f67acadbd30495805460ff191660ff9092169190911781559251805192945062004801927f4024c42b59ef1ee82b0af9257e97dd419404d615ee9e3f29f4f67acadbd304969291909101906200546a565b50604082015180516200481f9160028401916020909101906200546a565b50606082015162004837906003830190600562005787565b50506040805160808082018352600280835283518085018552600981526857657374666f72676560b81b60208083019190915280850191825285518087018752600b81526a496e6475737472696f757360a81b8183015285870152855160a081018752600f815260008183018190529681018790526060808201889052948101879052938501939093529352611e1e815281517f2616c2f5e6f6f2bfe69aef3348e359699dfdff2adee7e4a77427946068cecc6c805460ff191660ff9092169190911781559251805192945062004935927f2616c2f5e6f6f2bfe69aef3348e359699dfdff2adee7e4a77427946068cecc6d9291909101906200546a565b5060408201518051620049539160028401916020909101906200546a565b5060608201516200496b906003830190600562005787565b50506040805160808082018352600380835283518085018552600a8082526953746f6e65627269676760b01b6020808401919091528086019283528651808801885291825269149959da5b595b9d195960b21b8282015285870191909152855160a08101875260058082526000828401819052978201889052606080830182905295820152938501939093529352611e1e815281517fdae7c609cb86fb9d13709dbf3bbd98fbf3c9bfbeb42091f0a876870dbe27ccea805460ff191660ff9092169190911781559251805192945062004a6b927fdae7c609cb86fb9d13709dbf3bbd98fbf3c9bfbeb42091f0a876870dbe27cceb9291909101906200546a565b506040820151805162004a899160028401916020909101906200546a565b50606082015162004aa1906003830190600562005787565b50506040805160808082018352600382528251808401845260128152714b696e67646f6d206f66205370656374726160701b60208083019190915280840191825284518086018652600b81526a11985b9d185cdd1a58d85b60aa1b8183015284860152845160a08101865260008082528183018190529581018690526060808201879052600f94820194909452928401929092526004909352611e1e815281517fc92508ee1ec491843f236f063e58a8f5a8f90ce9c06d48027221daa864aa8ea9805460ff191660ff9092169190911781559251805192945062004bac927fc92508ee1ec491843f236f063e58a8f5a8f90ce9c06d48027221daa864aa8eaa9291909101906200546a565b506040820151805162004bca9160028401916020909101906200546a565b50606082015162004be2906003830190600562005787565b505060408051608080820183526004825282518084018452600d81526c4d61676e61746f6e204369747960981b60208083019190915280840191825284518086018652600580825264141c9bdd5960da1b8284015285870191909152855160a081018752818152600a81840152600096810187905260608082018890529481018790529385019390935291909352611e1e815281517ffbaa6904266f7d64e86ecc2d78d69d1daff6f556f3e3f59727585d81fa7ad083805460ff191660ff9092169190911781559251805192945062004ce2927ffbaa6904266f7d64e86ecc2d78d69d1daff6f556f3e3f59727585d81fa7ad0849291909101906200546a565b506040820151805162004d009160028401916020909101906200546a565b50606082015162004d18906003830190600562005787565b50506040805160808082018352600482528251808401845260098152684c6f7320417374726160b81b60208083019190915280840191825284518086018652600a80825269426f69737465726f757360b01b8284015285870191909152855160a0810187526000808252818401929092529586018190526005606080880191909152938601819052928401949094526006909152611e1e835281517f6dcb5983c95ad9f90f94739878bb57be91181c3fee24eaa20dfcb6d2f6ce7471805460ff191660ff90921691909117815590518051929450909262004e1f927f6dcb5983c95ad9f90f94739878bb57be91181c3fee24eaa20dfcb6d2f6ce747292909101906200546a565b506040820151805162004e3d9160028401916020909101906200546a565b50606082015162004e55906003830190600562005787565b50506040805160808082018352600580835283518085018552600681526554657a756b6160d01b602080830191909152808501918252855180870187526009815268416461707461626c6560b81b8183015285870152855160a0810187526000808252600a82840152968101879052606080820194909452938401869052918401929092526007909352611e1e835281517f5e2fcab25bf8366ff98eedb229a45fed42a648d7c1e7f607bbf6d216336d4c7f805460ff191660ff90921691909117815590518051929450909262004f52927f5e2fcab25bf8366ff98eedb229a45fed42a648d7c1e7f607bbf6d216336d4c8092909101906200546a565b506040820151805162004f709160028401916020909101906200546a565b50606082015162004f88906003830190600562005787565b505060408051608080820183526006825282518084018452600c8082526b436173746f72204c6f636b6560a01b602080840191909152808501928352855180870187529182526b21b7b9b6b7b837b634ba30b760a11b8282015284860191909152845160a08101865260058082528183018190529581019590955260006060808701829052938601819052928401949094526008909152611e1e835281517f657543772a14ce42569cd93d524d75ea14073e7ba7cd1135231593c07870a944805460ff191660ff90921691909117815590518051929450909262005092927f657543772a14ce42569cd93d524d75ea14073e7ba7cd1135231593c07870a94592909101906200546a565b5060408201518051620050b09160028401916020909101906200546a565b506060820151620050c8906003830190600562005787565b5050604080516080808201835260068252825180840184526005808252644f6272616b60d81b60208084019190915280850192835285518087018752600b81526a14995cdbdd5c98d9599d5b60aa1b8183015285870152855160a0810187526000808252818301849052968101839052606080820188905294810192909252928401526009909352611e1e815281517f40460841f2e1aaaa7891b7d693d6254ba60e668b6b0196357e9aebea418b0885805460ff191660ff90921691909117815592518051929450620051c2927f40460841f2e1aaaa7891b7d693d6254ba60e668b6b0196357e9aebea418b08869291909101906200546a565b5060408201518051620051e09160028401916020909101906200546a565b506060820151620051f8906003830190600562005787565b505060408051608080820183526006825282518084018452600b81526a57617272656e204c616b6560a81b6020808301919091528084019182528451808601865260048152634772696d60e01b8183015284860152845160a0810186526005808252600082840181905296820181905260608083019190915293810186905292840192909252600a909352611e1e815281517f989fa6094b8c990594a3db5422a258ae685f4be5851f77c93aaaef9c52ff215e805460ff191660ff90921691909117815592518051929450620052f5927f989fa6094b8c990594a3db5422a258ae685f4be5851f77c93aaaef9c52ff215f9291909101906200546a565b5060408201518051620053139160028401916020909101906200546a565b5060608201516200532b906003830190600562005787565b5050604080516080808201835260068083528351808501855290815265427261776e6160d01b60208083019190915280840191825284518086018652600a808252694f7074696d697374696360b01b8284015285870191909152855160a081018752600080825281840192909252600596810196909652606080870182905293860181905292840194909452600b909152611e1e835281517fd58ae58c0ef2b7b6b56f30c71842da04ea18f7d23b87a7ac8a7b462e21d0a988805460ff191660ff9092169190911781559051805192945090926200542f927fd58ae58c0ef2b7b6b56f30c71842da04ea18f7d23b87a7ac8a7b462e21d0a98992909101906200546a565b50604082015180516200544d9160028401916020909101906200546a565b50606082015162005465906003830190600562005787565b505050565b828054620054789062005987565b90600052602060002090601f0160209004810192826200549c5760008555620054e7565b82601f10620054b757805160ff1916838001178555620054e7565b82800160010185558215620054e7579182015b82811115620054e7578251825591602001919060010190620054ca565b50620054f5929150620057dd565b5090565b8260088101928215620054e7579160200282015b82811115620054e757825182906001600160481b03169055916020019190600101906200550d565b82600381019282156200557a579160200282015b828111156200557a5782518051620055699184916020909101906200546a565b509160200191906001019062005549565b50620054f5929150620057f4565b8260b681019282156200557a579160200282015b828111156200557a5782518051620055bc9184916020909101906200546a565b50916020019190600101906200559c565b602083019183908215620054e75791602002820160005b838211156200562457835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302620055e4565b8015620056535782816101000a81549060ff021916905560010160208160000104928301926001030262005624565b5050620054f5929150620057dd565b82600781019282156200557a579160200282015b828111156200557a5782518051620056969184916020909101906200546a565b509160200191906001019062005676565b600283019183908215620054e7579160200282016000838211156200562457835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302620055e4565b82600581019282156200557a579160200282015b828111156200557a5782518051620057319184916020909101906200546a565b509160200191906001019062005711565b82601081019282156200557a579160200282015b828111156200557a5782518051620057769184916020909101906200546a565b509160200191906001019062005756565b600183019183908215620054e7579160200282016000838211156200562457835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302620055e4565b5b80821115620054f55760008155600101620057de565b80821115620054f55760006200580b828262005815565b50600101620057f4565b508054620058239062005987565b6000825580601f1062005834575050565b601f016020900490600052602060002090810190620058549190620057dd565b50565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200588157600080fd5b82516001600160a01b03811681146200589957600080fd5b602084810151919350906001600160401b0380821115620058b957600080fd5b818601915086601f830112620058ce57600080fd5b815181811115620058e357620058e362005857565b604051601f8201601f19908116603f011681019083821181831017156200590e576200590e62005857565b8160405282815289868487010111156200592757600080fd5b600093505b828410156200594b57848401860151818501870152928501926200592c565b828411156200595d5760008684830101525b8096505050505050509250929050565b6000602082840312156200598057600080fd5b5051919050565b600181811c908216806200599c57607f821691505b60208210811415620059be57634e487b7160e01b600052602260045260246000fd5b50919050565b61535980620059d46000396000f3fe6080604052600436106103e35760003560e01c806366bb81c711610208578063c404811711610118578063e1dc0761116100ab578063e634cb091161007a578063e634cb0914610bc3578063e64d2f6114610be3578063e985e9c514610c0b578063f2fde38b14610c2b578063fece9bc314610c4b57600080fd5b8063e1dc076114610b25578063e5187f4314610b54578063e541ed3414610b74578063e5bea43514610b9457600080fd5b8063cf348425116100e7578063cf34842514610aae578063d2560bbb14610ace578063d7dc9a7e14610ae5578063e1a5bfa114610b0557600080fd5b8063c404811714610a2e578063c87b56dd14610a4e578063cac95fdb14610a6e578063ce606ee014610a8e57600080fd5b80639c7afe8b1161019b578063b88d4fde1161016a578063b88d4fde1461097d578063b9da56a91461099d578063be448206146109bd578063c27b335f146109ee578063c2ca0ac514610a0e57600080fd5b80639c7afe8b1461090f578063a035b1fe1461092f578063a22cb46514610946578063b047570a1461096657600080fd5b806391b7f5ed116101d757806391b7f5ed146108b257806394d008ef146108d257806395d89b41146108e55780639c5b470d146108fa57600080fd5b806366bb81c71461082757806370a082311461083e5780638456cb591461087557806385209ee01461088a57600080fd5b80632f745c5911610303578063517c6876116102965780635c471995116102655780635c471995146107845780635c975abb146107a457806360159abb146107c557806361e47b56146107f25780636352211e1461080757600080fd5b8063517c6876146106fd578063538cddb61461071d57806355e732da146107325780635bb209a51461076457600080fd5b806340bdce0d116102d257806340bdce0d1461067157806342842e0e146106a857806342ef1508146106c85780634f6ccce7146106dd57600080fd5b80632f745c59146106105780632f8e9f421461063057806332c2f7f8146106455780633f4ba83a1461065c57600080fd5b8063167ff46f1161037b5780631d458bd11161034a5780631d458bd11461059057806320733880146105b057806323b872dd146105d0578063255a87fe146105f057600080fd5b8063167ff46f146105165780631711862d1461052b57806318160ddd1461054b5780631b7b87131461056257600080fd5b8063081812fc116103b7578063081812fc14610487578063095ea7b3146104bf5780630ce06b68146104e157806311f3a5941461050157600080fd5b8062923f9e146103e857806301ffc9a71461042057806304a7b8d21461044057806306fdde0314610465575b600080fd5b3480156103f457600080fd5b5061040b6104033660046144e3565b611d2a541190565b60405190151581526020015b60405180910390f35b34801561042c57600080fd5b5061040b61043b366004614515565b610c60565b34801561044c57600080fd5b50610457611d305481565b604051908152602001610417565b34801561047157600080fd5b5061047a610ccd565b604051610417919061458a565b34801561049357600080fd5b506104a76104a23660046144e3565b610d5b565b6040516001600160a01b039091168152602001610417565b3480156104cb57600080fd5b506104df6104da3660046145b4565b610de6565b005b3480156104ed57600080fd5b506104df6104fc3660046145b4565b610efc565b34801561050d57600080fd5b5061047a610f96565b34801561052257600080fd5b506104df610fa3565b34801561053757600080fd5b506004546104a7906001600160a01b031681565b34801561055757600080fd5b50610457611d2a5481565b34801561056e57600080fd5b5061058261057d3660046144e3565b61103d565b604051610417929190614604565b34801561059c57600080fd5b5061047a6105ab3660046144e3565b61130c565b3480156105bc57600080fd5b506104df6105cb366004614642565b6114fa565b3480156105dc57600080fd5b506104df6105eb36600461465d565b6115c7565b3480156105fc57600080fd5b506104df61060b3660046146e2565b6115f8565b34801561061c57600080fd5b5061045761062b3660046145b4565b61162e565b34801561063c57600080fd5b5061047a6116e8565b34801561065157600080fd5b50610457611d2f5481565b34801561066857600080fd5b506104df6116f5565b34801561067d57600080fd5b5061069161068c3660046144e3565b61172e565b604080519215158352602083019190915201610417565b3480156106b457600080fd5b506104df6106c336600461465d565b61175e565b3480156106d457600080fd5b506104df611779565b3480156106e957600080fd5b506104576106f83660046144e3565b61180f565b34801561070957600080fd5b5061040b6107183660046147e9565b61183d565b34801561072957600080fd5b5061047a611993565b34801561073e57600080fd5b5061075261074d3660046144e3565b6119a0565b60405160ff9091168152602001610417565b34801561077057600080fd5b5061045761077f3660046144e3565b6119f8565b34801561079057600080fd5b506104df61079f366004614642565b611a75565b3480156107b057600080fd5b5060065461040b90600160a01b900460ff1681565b3480156107d157600080fd5b506107e56107e03660046144e3565b611ba7565b6040516104179190614837565b3480156107fe57600080fd5b506104df611bfc565b34801561081357600080fd5b506104a76108223660046144e3565b611c3b565b34801561083357600080fd5b50610457611d2e5481565b34801561084a57600080fd5b50610457610859366004614642565b6001600160a01b03166000908152611b70602052604090205490565b34801561088157600080fd5b506104df611cba565b34801561089657600080fd5b50611d2b546108a59060ff1681565b604051610417919061485b565b3480156108be57600080fd5b506104df6108cd3660046144e3565b611cf9565b6104df6108e0366004614875565b611d29565b3480156108f157600080fd5b5061047a612076565b34801561090657600080fd5b5061047a612083565b34801561091b57600080fd5b506104df61092a3660046148cc565b612090565b34801561093b57600080fd5b50610457611d3a5481565b34801561095257600080fd5b506104df610961366004614954565b612181565b34801561097257600080fd5b50610457611d2d5481565b34801561098957600080fd5b506104df61099836600461498b565b612247565b3480156109a957600080fd5b506104df6109b83660046149f3565b612279565b3480156109c957600080fd5b506107526109d83660046144e3565b611e266020526000908152604090205460ff1681565b3480156109fa57600080fd5b506104df610a09366004614642565b612418565b348015610a1a57600080fd5b506104df610a293660046144e3565b612464565b348015610a3a57600080fd5b5061047a610a493660046144e3565b61267b565b348015610a5a57600080fd5b5061047a610a693660046144e3565b61269b565b348015610a7a57600080fd5b5061047a610a893660046144e3565b612926565b348015610a9a57600080fd5b506005546104a7906001600160a01b031681565b348015610aba57600080fd5b5061047a610ac93660046144e3565b612937565b348015610ada57600080fd5b50610457611d2c5481565b348015610af157600080fd5b506104df610b00366004614a1e565b612afe565b348015610b1157600080fd5b5061047a610b203660046144e3565b612c28565b348015610b3157600080fd5b50610b45610b403660046144e3565b612c39565b60405161041793929190614a93565b348015610b6057600080fd5b506104df610b6f366004614642565b612fec565b348015610b8057600080fd5b5061047a610b8f3660046144e3565b613038565b348015610ba057600080fd5b50610bb4610baf3660046144e3565b613049565b60405161041793929190614afa565b348015610bcf57600080fd5b50610752610bde3660046144e3565b6132f1565b348015610bef57600080fd5b50611e2754610bfe9060ff1681565b6040516104179190614b33565b348015610c1757600080fd5b5061040b610c26366004614b47565b61331c565b348015610c3757600080fd5b506104df610c46366004614642565b61334b565b348015610c5757600080fd5b506104df613397565b60006001600160e01b031982166301ffc9a760e01b1480610c9157506001600160e01b031982166380ac58cd60e01b145b80610cac57506001600160e01b03198216635b5e139f60e01b145b80610cc757506001600160e01b0319821663780e9d6360e01b145b92915050565b60078054610cda90614b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054610d0690614b7a565b8015610d535780601f10610d2857610100808354040283529160200191610d53565b820191906000526020600020905b815481529060010190602001808311610d3657829003601f168201915b505050505081565b6000611d2a548210610dc95760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152611d2860205260409020546001600160a01b031690565b6000610df182611c3b565b9050806001600160a01b0316836001600160a01b03161415610e5f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610dc0565b336001600160a01b0382161480610e7b5750610e7b813361331c565b610eed5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610dc0565b610ef78383613427565b505050565b6005546001600160a01b03163314610f265760405162461bcd60e51b8152600401610dc090614bb5565b600554604051632142170760e11b81523060048201526001600160a01b03918216602482015260448101839052908316906342842e0e90606401600060405180830381600087803b158015610f7a57600080fd5b505af1158015610f8e573d6000803e3d6000fd5b505050505050565b60028054610cda90614b7a565b6005546001600160a01b03163314610fcd5760405162461bcd60e51b8152600401610dc090614bb5565b6000611d2b5460ff166003811115610fe757610fe7614845565b146110205760405162461bcd60e51b81526020600482015260096024820152684e6f7420526561647960b81b6044820152606401610dc0565b611d2b805460ff1916600117905543611d2c55611d2a54611d3b55565b6110456143ca565b61104d6143e9565b6003611d2b5460ff16600381111561106757611067614845565b146110845760405162461bcd60e51b8152600401610dc090614bd8565b600061108f846119f8565b90506000806000806110a18886613496565b929650909450925090506110bf8585600c5b602002015185856137e3565b955080156110d057600187526110d5565b600087525b60005b600c811015611134578481600d81106110f3576110f3614bfe565b602002015188611104836001614c2a565b600f811061111457611114614bfe565b61ffff90921660209290920201528061112c81614c42565b9150506110d8565b5061018084015161ffff166000908152611e1e60209081526040808320815160808101909252805460ff168252600181018054929391929184019161117890614b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546111a490614b7a565b80156111f15780601f106111c6576101008083540402835291602001916111f1565b820191906000526020600020905b8154815290600101906020018083116111d457829003601f168201915b5050505050815260200160028201805461120a90614b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461123690614b7a565b80156112835780601f1061125857610100808354040283529160200191611283565b820191906000526020600020905b81548152906001019060200180831161126657829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116112ab57505050929093525050915160ff166101a08b01525050506101809093015161ffff166101c08701525093959294509192505050565b6060600061131b836003614c5d565b90506000611df7826103e4811061133457611334614bfe565b602081049091015460ff601f9092166101000a90041690506000611df761135c846001614c2a565b6103e4811061136d5761136d614bfe565b602081049091015460ff601f9092166101000a90041690506000611df7611395856002614c2a565b6103e481106113a6576113a6614bfe565b602091828204019190069054906101000a900460ff1690506000611d418460ff1660b681106113d7576113d7614bfe565b0180546113e390614b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461140f90614b7a565b801561145c5780601f106114315761010080835404028352916020019161145c565b820191906000526020600020905b81548152906001019060200180831161143f57829003601f168201915b5050505050905060008360ff1611156114ab5780611d418460ff1660b6811061148757611487614bfe565b01604051602001611499929190614d16565b60405160208183030381529060405290505b60ff8216156114f05780611d418360ff1660b681106114cc576114cc614bfe565b016040516020016114de929190614d40565b60405160208183030381529060405290505b9695505050505050565b6005546001600160a01b031633146115245760405162461bcd60e51b8152600401610dc090614bb5565b6001611d2b5460ff16600381111561153e5761153e614845565b148061156157506000611d2b5460ff16600381111561155f5761155f614845565b145b61157d5760405162461bcd60e51b8152600401610dc090614d6b565b611b67611d2a54106115a15760405162461bcd60e51b8152600401610dc090614d90565b6115ae81611d2a546139c8565b611d2a80549060006115bf83614c42565b919050555050565b6115d13382613adc565b6115ed5760405162461bcd60e51b8152600401610dc090614dbd565b610ef7838383613b9b565b6005546001600160a01b031633146116225760405162461bcd60e51b8152600401610dc090614bb5565b610ef760008383614407565b6001600160a01b0382166000908152611b70602052604081205482106116aa5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610dc0565b6001600160a01b0383166000908152611b70602052604090208054839081106116d5576116d5614bfe565b9060005260206000200154905092915050565b60008054610cda90614b7a565b6005546001600160a01b0316331461171f5760405162461bcd60e51b8152600401610dc090614bb5565b6006805460ff60a01b19169055565b600080600061173c84613f10565b9050600f81101561175257600194909350915050565b50600093849350915050565b610ef783838360405180602001604052806000815250612247565b6005546001600160a01b031633146117a35760405162461bcd60e51b8152600401610dc090614bb5565b6001611e275460ff1660028111156117bd576117bd614845565b146117f75760405162461bcd60e51b815260206004820152600a602482015269139bdd0810db1bdcd95960b21b6044820152606401610dc0565b611e2780546000919060ff19166001835b0217905550565b600061181d82611d2a541190565b6118395760405162461bcd60e51b8152600401610dc090614e0e565b5090565b604080516b199b1a59da1d1b1a5cdd195960a21b60208201526bffffffffffffffffffffffff19606085901b16602c82015260009182910160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c01604051602081830303815290604052805190602001209050600080600085516041146118fc5760405162461bcd60e51b8152600401610dc090614e39565b505050602083810151604080860151606080880151600654845160008082529781018087528990529190961a93810184905290810184905260808101829052919390916001600160a01b039091169060019060a0016020604051602081039080840390855afa158015611973573d6000803e3d6000fd5b505050602060405103516001600160a01b03161494505050505092915050565b60018054610cda90614b7a565b60006119ae82611d2a541190565b6119ca5760405162461bcd60e51b8152600401610dc090614e0e565b611d3b548210156119dd57506000919050565b611d3c548210156119f057506001919050565b506002919050565b6000600f611a0583613f10565b1015611a445760405162461bcd60e51b815260206004820152600e60248201526d21b7b9329021b430b930b1ba32b960911b6044820152606401610dc0565b50611d2f54604080516020808201939093528082019390935280518084038201815260609093019052815191012090565b6005546001600160a01b03163314611a9f5760405162461bcd60e51b8152600401610dc090614bb5565b6005546040516370a0823160e01b815230600482015282916001600160a01b038084169263a9059cbb92919091169083906370a082319060240160206040518083038186803b158015611af157600080fd5b505afa158015611b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b299190614e65565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611b6f57600080fd5b505af1158015611b83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef79190614e7e565b611baf6143e9565b6003611d2b5460ff166003811115611bc957611bc9614845565b14611be65760405162461bcd60e51b8152600401610dc090614bd8565b610cc7611bf2836119f8565b613f6b565b919050565b6005546001600160a01b03163314611c265760405162461bcd60e51b8152600401610dc090614bb5565b611e2780546002919060ff1916600183611808565b6000611c4982611d2a541190565b611c955760405162461bcd60e51b815260206004820152601960248201527f4552433732313a204e6f6e6578697374656e7420746f6b656e000000000000006044820152606401610dc0565b600982611b678110611ca957611ca9614bfe565b01546001600160a01b031692915050565b6005546001600160a01b03163314611ce45760405162461bcd60e51b8152600401610dc090614bb5565b6006805460ff60a01b1916600160a01b179055565b6005546001600160a01b03163314611d235760405162461bcd60e51b8152600401610dc090614bb5565b611d3a55565b600a821115611d3757600a91505b6001611d2b5460ff166003811115611d5157611d51614845565b14611d6e5760405162461bcd60e51b8152600401610dc090614d6b565b611d7b61033e6008614c5d565b611d2c54611d899190614c2a565b431015611e1a57611d9a838261183d565b611db65760405162461bcd60e51b8152600401610dc090614e39565b6001600160a01b0383166000908152611b70602052604090205415611e115760405162461bcd60e51b8152602060048201526011602482015270141c99599b1a59da1d0810db185a5b5959607a1b6044820152606401610dc0565b60019150611ef8565b611e2761033e6009614c5d565b611d2c54611e359190614c2a565b431015611ee257611e46838261183d565b611e625760405162461bcd60e51b8152600401610dc090614e39565b600b82611e85856001600160a01b03166000908152611b70602052604090205490565b611e8f9190614c2a565b1115611edd5760405162461bcd60e51b815260206004820152601960248201527f466c6967687470617373206c696d6974206578636565646564000000000000006044820152606401610dc0565b611ef8565b611d3c54611f401415611ef857611d2a54611d3c555b611b6782611d2a54611f0a9190614c2a565b1115611f285760405162461bcd60e51b8152600401610dc090614d90565b600082611d3a54611f399190614c5d565b905080341015611f805760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742046756e647360701b6044820152606401610dc0565b60005b83811015611fb557611fa38582611d2a54611f9e9190614c2a565b6139c8565b80611fad81614c42565b915050611f83565b5082611d2a6000828254611fc99190614c2a565b90915550503481101561207057600033611fe38334614e9b565b604051600081818185875af1925050503d806000811461201f576040519150601f19603f3d011682016040523d82523d6000602084013e612024565b606091505b505090508061206e5760405162461bcd60e51b81526020600482015260166024820152751499599d5b9908151c985b9cd9995c8811985a5b195960521b6044820152606401610dc0565b505b50505050565b60088054610cda90614b7a565b60038054610cda90614b7a565b6005546001600160a01b031633146120ba5760405162461bcd60e51b8152600401610dc090614bb5565b6001611d2b5460ff1660038111156120d4576120d4614845565b14806120f757506002611d2b5460ff1660038111156120f5576120f5614845565b145b6121335760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420537461746560981b6044820152606401610dc0565b611d2e546121429060c8614c2a565b431161214d57600080fd5b611d2b805460ff19166002908117909155611d2d86905543611d2e55612174908585614407565b50610f8e60038383614407565b336001600160a01b03831614156121da5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610dc0565b336000818152611d29602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6122513383613adc565b61226d5760405162461bcd60e51b8152600401610dc090614dbd565b61207084848484614010565b6003611d2b5460ff16600381111561229357612293614845565b146122b05760405162461bcd60e51b8152600401610dc090614bd8565b336122ba83611c3b565b6001600160a01b0316146122fc5760405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b6044820152606401610dc0565b60008160ff16118015612313575060058160ff1611155b6123505760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642043686f69636560901b6044820152606401610dc0565b6000828152611e26602052604090205460ff16156123a35760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e48115c5d5a5c1c195960821b6044820152606401610dc0565b6000611e275460ff1660028111156123bd576123bd614845565b146123f55760405162461bcd60e51b81526020600482015260086024820152672737ba1027b832b760c11b6044820152606401610dc0565b6000918252611e266020526040909120805460ff191660ff909216919091179055565b6005546001600160a01b031633146124425760405162461bcd60e51b8152600401610dc090614bb5565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b0316331461248e5760405162461bcd60e51b8152600401610dc090614bb5565b611d2e5461249d906004614c2a565b431180156124b85750611d2e546124b59060c8614c2a565b43105b6124f25760405162461bcd60e51b815260206004820152600b60248201526a426c6f636b2052616e676560a81b6044820152606401610dc0565b6002611d2b5460ff16600381111561250c5761250c614845565b1461254c5760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e4814995d99585b195960821b6044820152606401610dc0565b611d2d5460408051602081018490520160405160208183030381529060405280519060200120146125af5760405162461bcd60e51b815260206004820152600d60248201526c0a6cacac8409ad2e6dac2e8c6d609b1b6044820152606401610dc0565b80611d2e5460016125c09190614c2a565b40611d2e5460026125d19190614c2a565b40611d2e5460036125e29190614c2a565b604080516020810195909552840192909252606083015240608082015260a00160408051601f198184030181529190528051602090910120611d2f55611d2a5461262e90600590614e9b565b611d2f5461263c9190614ec8565b611d3955611d2f54611d319061265490600890614ec8565b6008811061266457612664614bfe565b0154611d305550611d2b805460ff19166003179055565b611e17816007811061268c57600080fd5b018054909150610cda90614b7a565b6060611d2a5482106127075760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610dc0565b6003611d2b5460ff16600381111561272157612721614845565b141561286c57600061273283613f10565b9050600f8110156127e757611d3d54604051637bb7ca8760e11b8152600481018390526002916001600160a01b03169063f76f950e9060240160006040518083038186803b15801561278357600080fd5b505afa158015612797573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127bf9190810190614edc565b6040516020016127d0929190614f4a565b604051602081830303815290604052915050919050565b60048054604051636a93802960e01b81529182018590526001600160a01b031690636a9380299060240160006040518083038186803b15801561282957600080fd5b505afa15801561283d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128659190810190614edc565b9392505050565b611d3d546001906001600160a01b031663f76f950e61288a856119a0565b6040516001600160e01b031960e084901b16815260ff909116600482015260240160006040518083038186803b1580156128c357600080fd5b505afa1580156128d7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128ff9190810190614edc565b604051602001612910929190614f4a565b6040516020818303038152906040529050919050565b611e21816005811061268c57600080fd5b606061294582611d2a541190565b6129615760405162461bcd60e51b8152600401610dc090614e0e565b6003611d2b5460ff16600381111561297b5761297b614845565b1415612a5a57600061298c83613f10565b9050600f811015612a2a57611d3d54604051637bb7ca8760e11b8152600481018390526002916001600160a01b03169063f76f950e9060240160006040518083038186803b1580156129dd57600080fd5b505afa1580156129f1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a199190810190614edc565b6040516020016127d0929190614f9e565b6000612a35846119f8565b90506000612a438583613496565b5050509050612a5181614043565b95945050505050565b611d3d546001906001600160a01b031663f76f950e612a78856119a0565b6040516001600160e01b031960e084901b16815260ff909116600482015260240160006040518083038186803b158015612ab157600080fd5b505afa158015612ac5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612aed9190810190614edc565b604051602001612910929190614f9e565b6005546001600160a01b03163314612b285760405162461bcd60e51b8152600401610dc090614bb5565b6001611d2b5460ff166003811115612b4257612b42614845565b1480612b6557506000611d2b5460ff166003811115612b6357612b63614845565b145b612b815760405162461bcd60e51b8152600401610dc090614d6b565b611d2a54611b6790612b94908390614c2a565b1115612bb25760405162461bcd60e51b8152600401610dc090614d90565b60005b81811015612c0857612bf6838383818110612bd257612bd2614bfe565b9050602002016020810190612be79190614642565b82611d2a54611f9e9190614c2a565b80612c0081614c42565b915050612bb5565b5081819050611d2a6000828254612c1f9190614c2a565b90915550505050565b611e28816010811061268c57600080fd5b612c41614487565b612c496143e9565b60606003611d2b5460ff166003811115612c6557612c65614845565b14612c825760405162461bcd60e51b8152600401610dc090614bd8565b6000612c8d856119f8565b9050600080600080612c9f8986613496565b92965090945092509050612cb58585600c6110b3565b96508015612cce57612cc7600161130c565b8852612cdb565b612cd8600061130c565b88525b60005b600c811015612d3d57612d0a8582600d8110612cfc57612cfc614bfe565b602002015161ffff1661130c565b89612d16836001614c2a565b60108110612d2657612d26614bfe565b602002015280612d3581614c42565b915050612cde565b5061018084015161ffff166000908152611e1e60209081526040808320815160808101909252805460ff1682526001810180549293919291840191612d8190614b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054612dad90614b7a565b8015612dfa5780601f10612dcf57610100808354040283529160200191612dfa565b820191906000526020600020905b815481529060010190602001808311612ddd57829003601f168201915b50505050508152602001600282018054612e1390614b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054612e3f90614b7a565b8015612e8c5780601f10612e6157610100808354040283529160200191612e8c565b820191906000526020600020905b815481529060010190602001808311612e6f57829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612eb45790505050505050815250509050611e17816000015160ff1660078110612f0857612f08614bfe565b018054612f1490614b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054612f4090614b7a565b8015612f8d5780601f10612f6257610100808354040283529160200191612f8d565b820191906000526020600020905b815481529060010190602001808311612f7057829003601f168201915b505050505089600d60108110612fa557612fa5614bfe565b6020020181905250806020015189600e60108110612fc557612fc5614bfe565b602002015260408101516101e08a0152612fde85614043565b989a97995050505050505050565b6005546001600160a01b031633146130165760405162461bcd60e51b8152600401610dc090614bb5565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b611d3e816003811061268c57600080fd5b6060806060600c841061308f5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a590818da5d1e525960921b6044820152606401610dc0565b6000848152611e1e60209081526040808320815160808101909252805460ff16825260018101805492939192918401916130c890614b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546130f490614b7a565b80156131415780601f1061311657610100808354040283529160200191613141565b820191906000526020600020905b81548152906001019060200180831161312457829003601f168201915b5050505050815260200160028201805461315a90614b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461318690614b7a565b80156131d35780601f106131a8576101008083540402835291602001916131d3565b820191906000526020600020905b8154815290600101906020018083116131b657829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116131fb5790505050505050815250509050611e17816000015160ff166007811061324f5761324f614bfe565b01805461325b90614b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461328790614b7a565b80156132d45780601f106132a9576101008083540402835291602001916132d4565b820191906000526020600020905b8154815290600101906020018083116132b757829003601f168201915b505050505093508060200151925080604001519150509193909250565b611e1f816037811061330257600080fd5b60209182820401919006915054906101000a900460ff1681565b6001600160a01b039182166000908152611d296020908152604080832093909416825291909152205460ff1690565b6005546001600160a01b031633146133755760405162461bcd60e51b8152600401610dc090614bb5565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031633146133c15760405162461bcd60e51b8152600401610dc090614bb5565b6000611e275460ff1660028111156133db576133db614845565b146134135760405162461bcd60e51b81526020600482015260086024820152672737ba1027b832b760c11b6044820152606401610dc0565b611e2780546001919060ff19168280611808565b6000818152611d286020526040902080546001600160a01b0319166001600160a01b038416908117909155819061345d82611c3b565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61349e6144af565b600080600060fc85901c6001166001149050600060fd86901c6001166001149050600060fe87901c600116600114905060006134e5886000806002600160026004806140d5565b61ffff91909116885290506134fa8187614ff1565b60008a8152611e26602052604090205490965060ff1680156135965760006135218a613f6b565b90508061352f600184615016565b60ff166005811061354257613542614bfe565b60200201519650600d613556600189615016565b60ff166135639190615039565b61ffff1660208a0152851561359057600a896001602002018181516135889190615039565b61ffff169052505b5061359e565b606060208901525b60216135b2600560ff60188d901c16614ec8565b6135bc9190614c2a565b61ffff16604089015284156135e9576005886002602002018181516135e19190615039565b61ffff169052505b82156136205761360489866003602b600160038060056140d5565b61ffff919091166060808b019190915260808a0152915061364b565b61363689866004604360016002600460066140d5565b61ffff9190911660808a01526060808a015291505b6136558288614ff1565b965061366c89866005605d600160038060046140d5565b61ffff9190911660a08a015291506136848288614ff1565b965061369a8986600660736001806004806140d5565b61ffff9190911660c08a015291506136b28288614ff1565b96506136ca89866007608760016004600360026140d5565b61ffff9190911660e08a015291506136e28288614ff1565b96506136fa89866008609b60036004600660076140d5565b61ffff919091166101008a015291506137138288614ff1565b9650831561374d576137318986600960c3600460056006600a6140d5565b61ffff919091166101208a015260606101608a0152915061377d565b6137648986600b61012360036004600660076140d5565b61ffff919091166101608a015261014b6101208a015291505b6137878288614ff1565b965061379f8986600a60f5600260046007600a6140d5565b61ffff919091166101408a015291506137b88288614ff1565b96506137c9600c60608b901c61505f565b61ffff166101808901525095989497509295509093505050565b6137eb6143e9565b61ffff84166000908152611e1e6020526040808220815160a0810192839052916003909101906005908285855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116138185790505050505050905060005b600a8110156138fd576000613866826002614c5d565b613871906070614c2a565b88901c60031690505b601484826005811061388e5761388e614bfe565b602002015160ff16106138be5780600314156138ac5750600061387a565b806138b681614c42565b91505061387a565b60058482600581106138d2576138d2614bfe565b602002018181516138e39190614ff1565b60ff169052508190506138f581614c42565b915050613850565b5060005b60058110156139bd57611e1f81613919866005615080565b60ff166139269190614c2a565b6037811061393657613936614bfe565b602081049091015460ff601f9092166101000a90041682826005811061395e5761395e614bfe565b602002015161396e87600a614ff1565b6139789190614ff1565b6139829190614ff1565b83826005811061399457613994614bfe565b602002018181516139a59190614ff1565b60ff16905250806139b581614c42565b915050613901565b50505b949350505050565b600654600160a01b900460ff1615613a0b5760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610dc0565b6001600160a01b0382166000818152611b70602090815260408220805460018101825581845291832090910184905591905254611b7182611b678110613a5357613a53614bfe565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555081600982611b678110613a8d57613a8d614bfe565b0180546001600160a01b0319166001600160a01b0392831617905560405182918416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000611d2a548210613b455760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610dc0565b6000613b5083611c3b565b9050806001600160a01b0316846001600160a01b03161480613b8b5750836001600160a01b0316613b8084610d5b565b6001600160a01b0316145b806139c057506139c0818561331c565b600654600160a01b900460ff1615613bde5760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610dc0565b826001600160a01b0316613bf182611c3b565b6001600160a01b031614613c595760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610dc0565b6001600160a01b038216613cbb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610dc0565b613cc6600082613427565b6000611b7182611b678110613cdd57613cdd614bfe565b601091828204019190066002029054906101000a900461ffff1690506000600182613d0891906150a9565b6001600160a01b0386166000908152611b70602052604081205461ffff92909216925090613d3890600190614e9b565b9050818114613dfa576001600160a01b0386166000908152611b7060205260408120805483908110613d6c57613d6c614bfe565b9060005260206000200154905080611b706000896001600160a01b03166001600160a01b031681526020019081526020016000208481548110613db157613db1614bfe565b60009182526020909120015583611b7182611b678110613dd357613dd3614bfe565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550505b6001600160a01b0386166000908152611b7060205260409020805480613e2257613e226150cc565b6000828152602080822083016000199081018390559092019092556001600160a01b038716808352611b70825260408320805460018101825581855292842090920187905590915254611b7185611b678110613e8057613e80614bfe565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555084600985611b678110613eba57613eba614bfe565b0180546001600160a01b0319166001600160a01b03928316179055604051859187811691908916907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4505050505050565b60006005821015613f1f575090565b6005611d2a54613f2f9190614e9b565b611d3954613f3e600585614e9b565b611d3054613f4c9190614c5d565b613f569190614c2a565b613f609190614ec8565b610cc7906005614c2a565b613f736143e9565b60ff601083901c16613f836143e9565b60005b600a8160ff161015614008576000600a84613fa284600d615080565b60ff16613faf9190615039565b613fb9919061505f565b905060058160ff161015613ff557613fd2826001614ff1565b838260ff1660058110613fe757613fe7614bfe565b60ff90921660209290920201525b5080614000816150e2565b915050613f86565b509392505050565b61401b848484613b9b565b614027848484846141e6565b6120705760405162461bcd60e51b8152600401610dc090615102565b606060006040518060a00160405280607b81526020016152a9607b9139905060005b600c8110156140c3578161408e8583600d811061408457614084614bfe565b60200201516142e7565b60405160200161409f929190615154565b604051602081830303815290604052915080806140bb90614c42565b915050614065565b50806040516020016127d0919061517a565b600080806140e4896008615080565b60ff168b901c90506140f581614384565b91508792508160ff16600614156141245761411087826151a4565b61411d9060ff1684615039565b92506141a2565b8160ff1660051415614145578661413b87836151a4565b6141109190614ff1565b8160ff166004141561416757858761415d87846151a4565b61413b9190614ff1565b84868861417487856151a4565b61417e9190614ff1565b6141889190614ff1565b6141929190614ff1565b61419f9060ff1684615039565b92505b89156141d85783856141b4888a614ff1565b6141be9190614ff1565b6141c89190614ff1565b6141d59060ff1684615039565b92505b509850989650505050505050565b6000833b156142df57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906142219033908990889088906004016151c6565b602060405180830381600087803b15801561423b57600080fd5b505af192505050801561426b575060408051601f3d908101601f19168201909252614268918101906151f9565b60015b6142c5573d808015614299576040519150601f19603f3d011682016040523d82523d6000602084013e61429e565b606091505b5080516142bd5760405162461bcd60e51b8152600401610dc090615102565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506139c0565b5060016139c0565b611d3d54604051637bb7ca8760e11b815261ffff831660048201526060916000916003916001600160a01b03169063f76f950e9060240160006040518083038186803b15801561433657600080fd5b505afa15801561434a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526143729190810190614edc565b60405160200161291093929190615216565b600060048260ff16101561439a57506006919050565b60188260ff1610156143ae57506005919050565b60608260ff1610156143c257506004919050565b506003919050565b604051806101e00160405280600f906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b82805461441390614b7a565b90600052602060002090601f016020900481019282614435576000855561447b565b82601f1061444e5782800160ff1982351617855561447b565b8280016001018555821561447b579182015b8281111561447b578235825591602001919060010190614460565b506118399291506144ce565b6040518061020001604052806010905b60608152602001906001900390816144975790505090565b604051806101a00160405280600d906020820280368337509192915050565b5b8082111561183957600081556001016144cf565b6000602082840312156144f557600080fd5b5035919050565b6001600160e01b03198116811461451257600080fd5b50565b60006020828403121561452757600080fd5b8135612865816144fc565b60005b8381101561454d578181015183820152602001614535565b838111156120705750506000910152565b60008151808452614576816020860160208601614532565b601f01601f19169290920160200192915050565b602081526000612865602083018461455e565b80356001600160a01b0381168114611bf757600080fd5b600080604083850312156145c757600080fd5b6145d08361459d565b946020939093013593505050565b8060005b600581101561207057815160ff168452602093840193909101906001016145e2565b6102808101818460005b600f81101561463157815161ffff1683526020928301929091019060010161460e565b5050506128656101e08301846145de565b60006020828403121561465457600080fd5b6128658261459d565b60008060006060848603121561467257600080fd5b61467b8461459d565b92506146896020850161459d565b9150604084013590509250925092565b60008083601f8401126146ab57600080fd5b50813567ffffffffffffffff8111156146c357600080fd5b6020830191508360208285010111156146db57600080fd5b9250929050565b600080602083850312156146f557600080fd5b823567ffffffffffffffff81111561470c57600080fd5b61471885828601614699565b90969095509350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561476357614763614724565b604052919050565b600067ffffffffffffffff82111561478557614785614724565b50601f01601f191660200190565b600082601f8301126147a457600080fd5b81356147b76147b28261476b565b61473a565b8181528460208386010111156147cc57600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156147fc57600080fd5b6148058361459d565b9150602083013567ffffffffffffffff81111561482157600080fd5b61482d85828601614793565b9150509250929050565b60a08101610cc782846145de565b634e487b7160e01b600052602160045260246000fd5b602081016004831061486f5761486f614845565b91905290565b60008060006060848603121561488a57600080fd5b6148938461459d565b925060208401359150604084013567ffffffffffffffff8111156148b657600080fd5b6148c286828701614793565b9150509250925092565b6000806000806000606086880312156148e457600080fd5b85359450602086013567ffffffffffffffff8082111561490357600080fd5b61490f89838a01614699565b9096509450604088013591508082111561492857600080fd5b5061493588828901614699565b969995985093965092949392505050565b801515811461451257600080fd5b6000806040838503121561496757600080fd5b6149708361459d565b9150602083013561498081614946565b809150509250929050565b600080600080608085870312156149a157600080fd5b6149aa8561459d565b93506149b86020860161459d565b925060408501359150606085013567ffffffffffffffff8111156149db57600080fd5b6149e787828801614793565b91505092959194509250565b60008060408385031215614a0657600080fd5b82359150602083013560ff8116811461498057600080fd5b60008060208385031215614a3157600080fd5b823567ffffffffffffffff80821115614a4957600080fd5b818501915085601f830112614a5d57600080fd5b813581811115614a6c57600080fd5b8660208260051b8501011115614a8157600080fd5b60209290920196919550909350505050565b60e08082526000906102e0830190830186835b6010811015614ad85760df19868503018352614ac384835161455e565b93506020928301929190910190600101614aa6565b505050614ae860208401866145de565b82810360c08401526114f0818561455e565b606081526000614b0d606083018661455e565b8281036020840152614b1f818661455e565b905082810360408401526114f0818561455e565b602081016003831061486f5761486f614845565b60008060408385031215614b5a57600080fd5b614b638361459d565b9150614b716020840161459d565b90509250929050565b600181811c90821680614b8e57607f821691505b60208210811415614baf57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b6020808252600c908201526b139bdd0814995d99585b195960a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115614c3d57614c3d614c14565b500190565b6000600019821415614c5657614c56614c14565b5060010190565b6000816000190483118215151615614c7757614c77614c14565b500290565b8054600090600181811c9080831680614c9657607f831692505b6020808410821415614cb857634e487b7160e01b600052602260045260246000fd5b818015614ccc5760018114614cdd57614d0a565b60ff19861689528489019650614d0a565b60008881526020902060005b86811015614d025781548b820152908501908301614ce9565b505084890196505b50505050505092915050565b60008351614d28818460208801614532565b600160fd1b908301908152612a516001820185614c7c565b60008351614d52818460208801614532565b6101d160f51b908301908152612a516002820185614c7c565b6020808252600b908201526a14d85b194810db1bdcd95960aa1b604082015260600190565b60208082526013908201527213585e0814dd5c1c1b1e48115e18d959591959606a1b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601190820152702737b732bc34b9ba32b73a102a37b5b2b760791b604082015260600190565b602080825260129082015271496e76616c696420466c696768747061737360701b604082015260600190565b600060208284031215614e7757600080fd5b5051919050565b600060208284031215614e9057600080fd5b815161286581614946565b600082821015614ead57614ead614c14565b500390565b634e487b7160e01b600052601260045260246000fd5b600082614ed757614ed7614eb2565b500690565b600060208284031215614eee57600080fd5b815167ffffffffffffffff811115614f0557600080fd5b8201601f81018413614f1657600080fd5b8051614f246147b28261476b565b818152856020838501011115614f3957600080fd5b612a51826020830160208601614532565b66697066733a2f2f60c81b81526000614f666007830185614c7c565b602f60f81b81528351614f80816001840160208801614532565b64173539b7b760d91b60019290910191820152600601949350505050565b66697066733a2f2f60c81b81526000614fba6007830185614c7c565b602f60f81b81528351614fd4816001840160208801614532565b632e706e6760e01b60019290910191820152600501949350505050565b600060ff821660ff84168060ff0382111561500e5761500e614c14565b019392505050565b600060ff821660ff84168082101561503057615030614c14565b90039392505050565b600061ffff80831681851680830382111561505657615056614c14565b01949350505050565b600061ffff8084168061507457615074614eb2565b92169190910692915050565b600060ff821660ff84168160ff04811182151516156150a1576150a1614c14565b029392505050565b600061ffff838116908316818110156150c4576150c4614c14565b039392505050565b634e487b7160e01b600052603160045260246000fd5b600060ff821660ff8114156150f9576150f9614c14565b60010192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351615166818460208801614532565b835190830190615056818360208801614532565b6000825161518c818460208701614532565b651e17b9bb339f60d11b920191825250600601919050565b600060ff8316806151b7576151b7614eb2565b8060ff84160691505092915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906114f09083018461455e565b60006020828403121561520b57600080fd5b8151612865816144fc565b7f3c696d61676520783d22302220793d2230222077696474683d2236303022206881527132b4b3b43a1e911b18181110343932b31e9160711b6020820152600061526c6152666032840187614c7c565b85614c7c565b602f60f81b81528351615286816001840160208801614532565b67173837339110179f60c11b600192909101918201526009019594505050505056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d6964594d6964206d656574222076696577426f783d223020302036303020363030222077696474683d2236303022206865696768743d22363030223ea2646970667358221220fd7badd15e25a61b91ad843600e6b16739ee518a2797bd995a72b4409cf8dc9e64736f6c6343000809003368747470733a2f2f737461726b6164652d6c6567696f6e2e6d7970696e6174612e636c6f75642f697066732f00000000000000000000000015081629f46a33dfe0f9b9da9e2d4ffce094108d0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e516d62563642416f62673644696676346e4541737a663956326d69424c6b43453761506456536242464842454239000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103e35760003560e01c806366bb81c711610208578063c404811711610118578063e1dc0761116100ab578063e634cb091161007a578063e634cb0914610bc3578063e64d2f6114610be3578063e985e9c514610c0b578063f2fde38b14610c2b578063fece9bc314610c4b57600080fd5b8063e1dc076114610b25578063e5187f4314610b54578063e541ed3414610b74578063e5bea43514610b9457600080fd5b8063cf348425116100e7578063cf34842514610aae578063d2560bbb14610ace578063d7dc9a7e14610ae5578063e1a5bfa114610b0557600080fd5b8063c404811714610a2e578063c87b56dd14610a4e578063cac95fdb14610a6e578063ce606ee014610a8e57600080fd5b80639c7afe8b1161019b578063b88d4fde1161016a578063b88d4fde1461097d578063b9da56a91461099d578063be448206146109bd578063c27b335f146109ee578063c2ca0ac514610a0e57600080fd5b80639c7afe8b1461090f578063a035b1fe1461092f578063a22cb46514610946578063b047570a1461096657600080fd5b806391b7f5ed116101d757806391b7f5ed146108b257806394d008ef146108d257806395d89b41146108e55780639c5b470d146108fa57600080fd5b806366bb81c71461082757806370a082311461083e5780638456cb591461087557806385209ee01461088a57600080fd5b80632f745c5911610303578063517c6876116102965780635c471995116102655780635c471995146107845780635c975abb146107a457806360159abb146107c557806361e47b56146107f25780636352211e1461080757600080fd5b8063517c6876146106fd578063538cddb61461071d57806355e732da146107325780635bb209a51461076457600080fd5b806340bdce0d116102d257806340bdce0d1461067157806342842e0e146106a857806342ef1508146106c85780634f6ccce7146106dd57600080fd5b80632f745c59146106105780632f8e9f421461063057806332c2f7f8146106455780633f4ba83a1461065c57600080fd5b8063167ff46f1161037b5780631d458bd11161034a5780631d458bd11461059057806320733880146105b057806323b872dd146105d0578063255a87fe146105f057600080fd5b8063167ff46f146105165780631711862d1461052b57806318160ddd1461054b5780631b7b87131461056257600080fd5b8063081812fc116103b7578063081812fc14610487578063095ea7b3146104bf5780630ce06b68146104e157806311f3a5941461050157600080fd5b8062923f9e146103e857806301ffc9a71461042057806304a7b8d21461044057806306fdde0314610465575b600080fd5b3480156103f457600080fd5b5061040b6104033660046144e3565b611d2a541190565b60405190151581526020015b60405180910390f35b34801561042c57600080fd5b5061040b61043b366004614515565b610c60565b34801561044c57600080fd5b50610457611d305481565b604051908152602001610417565b34801561047157600080fd5b5061047a610ccd565b604051610417919061458a565b34801561049357600080fd5b506104a76104a23660046144e3565b610d5b565b6040516001600160a01b039091168152602001610417565b3480156104cb57600080fd5b506104df6104da3660046145b4565b610de6565b005b3480156104ed57600080fd5b506104df6104fc3660046145b4565b610efc565b34801561050d57600080fd5b5061047a610f96565b34801561052257600080fd5b506104df610fa3565b34801561053757600080fd5b506004546104a7906001600160a01b031681565b34801561055757600080fd5b50610457611d2a5481565b34801561056e57600080fd5b5061058261057d3660046144e3565b61103d565b604051610417929190614604565b34801561059c57600080fd5b5061047a6105ab3660046144e3565b61130c565b3480156105bc57600080fd5b506104df6105cb366004614642565b6114fa565b3480156105dc57600080fd5b506104df6105eb36600461465d565b6115c7565b3480156105fc57600080fd5b506104df61060b3660046146e2565b6115f8565b34801561061c57600080fd5b5061045761062b3660046145b4565b61162e565b34801561063c57600080fd5b5061047a6116e8565b34801561065157600080fd5b50610457611d2f5481565b34801561066857600080fd5b506104df6116f5565b34801561067d57600080fd5b5061069161068c3660046144e3565b61172e565b604080519215158352602083019190915201610417565b3480156106b457600080fd5b506104df6106c336600461465d565b61175e565b3480156106d457600080fd5b506104df611779565b3480156106e957600080fd5b506104576106f83660046144e3565b61180f565b34801561070957600080fd5b5061040b6107183660046147e9565b61183d565b34801561072957600080fd5b5061047a611993565b34801561073e57600080fd5b5061075261074d3660046144e3565b6119a0565b60405160ff9091168152602001610417565b34801561077057600080fd5b5061045761077f3660046144e3565b6119f8565b34801561079057600080fd5b506104df61079f366004614642565b611a75565b3480156107b057600080fd5b5060065461040b90600160a01b900460ff1681565b3480156107d157600080fd5b506107e56107e03660046144e3565b611ba7565b6040516104179190614837565b3480156107fe57600080fd5b506104df611bfc565b34801561081357600080fd5b506104a76108223660046144e3565b611c3b565b34801561083357600080fd5b50610457611d2e5481565b34801561084a57600080fd5b50610457610859366004614642565b6001600160a01b03166000908152611b70602052604090205490565b34801561088157600080fd5b506104df611cba565b34801561089657600080fd5b50611d2b546108a59060ff1681565b604051610417919061485b565b3480156108be57600080fd5b506104df6108cd3660046144e3565b611cf9565b6104df6108e0366004614875565b611d29565b3480156108f157600080fd5b5061047a612076565b34801561090657600080fd5b5061047a612083565b34801561091b57600080fd5b506104df61092a3660046148cc565b612090565b34801561093b57600080fd5b50610457611d3a5481565b34801561095257600080fd5b506104df610961366004614954565b612181565b34801561097257600080fd5b50610457611d2d5481565b34801561098957600080fd5b506104df61099836600461498b565b612247565b3480156109a957600080fd5b506104df6109b83660046149f3565b612279565b3480156109c957600080fd5b506107526109d83660046144e3565b611e266020526000908152604090205460ff1681565b3480156109fa57600080fd5b506104df610a09366004614642565b612418565b348015610a1a57600080fd5b506104df610a293660046144e3565b612464565b348015610a3a57600080fd5b5061047a610a493660046144e3565b61267b565b348015610a5a57600080fd5b5061047a610a693660046144e3565b61269b565b348015610a7a57600080fd5b5061047a610a893660046144e3565b612926565b348015610a9a57600080fd5b506005546104a7906001600160a01b031681565b348015610aba57600080fd5b5061047a610ac93660046144e3565b612937565b348015610ada57600080fd5b50610457611d2c5481565b348015610af157600080fd5b506104df610b00366004614a1e565b612afe565b348015610b1157600080fd5b5061047a610b203660046144e3565b612c28565b348015610b3157600080fd5b50610b45610b403660046144e3565b612c39565b60405161041793929190614a93565b348015610b6057600080fd5b506104df610b6f366004614642565b612fec565b348015610b8057600080fd5b5061047a610b8f3660046144e3565b613038565b348015610ba057600080fd5b50610bb4610baf3660046144e3565b613049565b60405161041793929190614afa565b348015610bcf57600080fd5b50610752610bde3660046144e3565b6132f1565b348015610bef57600080fd5b50611e2754610bfe9060ff1681565b6040516104179190614b33565b348015610c1757600080fd5b5061040b610c26366004614b47565b61331c565b348015610c3757600080fd5b506104df610c46366004614642565b61334b565b348015610c5757600080fd5b506104df613397565b60006001600160e01b031982166301ffc9a760e01b1480610c9157506001600160e01b031982166380ac58cd60e01b145b80610cac57506001600160e01b03198216635b5e139f60e01b145b80610cc757506001600160e01b0319821663780e9d6360e01b145b92915050565b60078054610cda90614b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054610d0690614b7a565b8015610d535780601f10610d2857610100808354040283529160200191610d53565b820191906000526020600020905b815481529060010190602001808311610d3657829003601f168201915b505050505081565b6000611d2a548210610dc95760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152611d2860205260409020546001600160a01b031690565b6000610df182611c3b565b9050806001600160a01b0316836001600160a01b03161415610e5f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610dc0565b336001600160a01b0382161480610e7b5750610e7b813361331c565b610eed5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610dc0565b610ef78383613427565b505050565b6005546001600160a01b03163314610f265760405162461bcd60e51b8152600401610dc090614bb5565b600554604051632142170760e11b81523060048201526001600160a01b03918216602482015260448101839052908316906342842e0e90606401600060405180830381600087803b158015610f7a57600080fd5b505af1158015610f8e573d6000803e3d6000fd5b505050505050565b60028054610cda90614b7a565b6005546001600160a01b03163314610fcd5760405162461bcd60e51b8152600401610dc090614bb5565b6000611d2b5460ff166003811115610fe757610fe7614845565b146110205760405162461bcd60e51b81526020600482015260096024820152684e6f7420526561647960b81b6044820152606401610dc0565b611d2b805460ff1916600117905543611d2c55611d2a54611d3b55565b6110456143ca565b61104d6143e9565b6003611d2b5460ff16600381111561106757611067614845565b146110845760405162461bcd60e51b8152600401610dc090614bd8565b600061108f846119f8565b90506000806000806110a18886613496565b929650909450925090506110bf8585600c5b602002015185856137e3565b955080156110d057600187526110d5565b600087525b60005b600c811015611134578481600d81106110f3576110f3614bfe565b602002015188611104836001614c2a565b600f811061111457611114614bfe565b61ffff90921660209290920201528061112c81614c42565b9150506110d8565b5061018084015161ffff166000908152611e1e60209081526040808320815160808101909252805460ff168252600181018054929391929184019161117890614b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546111a490614b7a565b80156111f15780601f106111c6576101008083540402835291602001916111f1565b820191906000526020600020905b8154815290600101906020018083116111d457829003601f168201915b5050505050815260200160028201805461120a90614b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461123690614b7a565b80156112835780601f1061125857610100808354040283529160200191611283565b820191906000526020600020905b81548152906001019060200180831161126657829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116112ab57505050929093525050915160ff166101a08b01525050506101809093015161ffff166101c08701525093959294509192505050565b6060600061131b836003614c5d565b90506000611df7826103e4811061133457611334614bfe565b602081049091015460ff601f9092166101000a90041690506000611df761135c846001614c2a565b6103e4811061136d5761136d614bfe565b602081049091015460ff601f9092166101000a90041690506000611df7611395856002614c2a565b6103e481106113a6576113a6614bfe565b602091828204019190069054906101000a900460ff1690506000611d418460ff1660b681106113d7576113d7614bfe565b0180546113e390614b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461140f90614b7a565b801561145c5780601f106114315761010080835404028352916020019161145c565b820191906000526020600020905b81548152906001019060200180831161143f57829003601f168201915b5050505050905060008360ff1611156114ab5780611d418460ff1660b6811061148757611487614bfe565b01604051602001611499929190614d16565b60405160208183030381529060405290505b60ff8216156114f05780611d418360ff1660b681106114cc576114cc614bfe565b016040516020016114de929190614d40565b60405160208183030381529060405290505b9695505050505050565b6005546001600160a01b031633146115245760405162461bcd60e51b8152600401610dc090614bb5565b6001611d2b5460ff16600381111561153e5761153e614845565b148061156157506000611d2b5460ff16600381111561155f5761155f614845565b145b61157d5760405162461bcd60e51b8152600401610dc090614d6b565b611b67611d2a54106115a15760405162461bcd60e51b8152600401610dc090614d90565b6115ae81611d2a546139c8565b611d2a80549060006115bf83614c42565b919050555050565b6115d13382613adc565b6115ed5760405162461bcd60e51b8152600401610dc090614dbd565b610ef7838383613b9b565b6005546001600160a01b031633146116225760405162461bcd60e51b8152600401610dc090614bb5565b610ef760008383614407565b6001600160a01b0382166000908152611b70602052604081205482106116aa5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610dc0565b6001600160a01b0383166000908152611b70602052604090208054839081106116d5576116d5614bfe565b9060005260206000200154905092915050565b60008054610cda90614b7a565b6005546001600160a01b0316331461171f5760405162461bcd60e51b8152600401610dc090614bb5565b6006805460ff60a01b19169055565b600080600061173c84613f10565b9050600f81101561175257600194909350915050565b50600093849350915050565b610ef783838360405180602001604052806000815250612247565b6005546001600160a01b031633146117a35760405162461bcd60e51b8152600401610dc090614bb5565b6001611e275460ff1660028111156117bd576117bd614845565b146117f75760405162461bcd60e51b815260206004820152600a602482015269139bdd0810db1bdcd95960b21b6044820152606401610dc0565b611e2780546000919060ff19166001835b0217905550565b600061181d82611d2a541190565b6118395760405162461bcd60e51b8152600401610dc090614e0e565b5090565b604080516b199b1a59da1d1b1a5cdd195960a21b60208201526bffffffffffffffffffffffff19606085901b16602c82015260009182910160408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c01604051602081830303815290604052805190602001209050600080600085516041146118fc5760405162461bcd60e51b8152600401610dc090614e39565b505050602083810151604080860151606080880151600654845160008082529781018087528990529190961a93810184905290810184905260808101829052919390916001600160a01b039091169060019060a0016020604051602081039080840390855afa158015611973573d6000803e3d6000fd5b505050602060405103516001600160a01b03161494505050505092915050565b60018054610cda90614b7a565b60006119ae82611d2a541190565b6119ca5760405162461bcd60e51b8152600401610dc090614e0e565b611d3b548210156119dd57506000919050565b611d3c548210156119f057506001919050565b506002919050565b6000600f611a0583613f10565b1015611a445760405162461bcd60e51b815260206004820152600e60248201526d21b7b9329021b430b930b1ba32b960911b6044820152606401610dc0565b50611d2f54604080516020808201939093528082019390935280518084038201815260609093019052815191012090565b6005546001600160a01b03163314611a9f5760405162461bcd60e51b8152600401610dc090614bb5565b6005546040516370a0823160e01b815230600482015282916001600160a01b038084169263a9059cbb92919091169083906370a082319060240160206040518083038186803b158015611af157600080fd5b505afa158015611b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b299190614e65565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611b6f57600080fd5b505af1158015611b83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef79190614e7e565b611baf6143e9565b6003611d2b5460ff166003811115611bc957611bc9614845565b14611be65760405162461bcd60e51b8152600401610dc090614bd8565b610cc7611bf2836119f8565b613f6b565b919050565b6005546001600160a01b03163314611c265760405162461bcd60e51b8152600401610dc090614bb5565b611e2780546002919060ff1916600183611808565b6000611c4982611d2a541190565b611c955760405162461bcd60e51b815260206004820152601960248201527f4552433732313a204e6f6e6578697374656e7420746f6b656e000000000000006044820152606401610dc0565b600982611b678110611ca957611ca9614bfe565b01546001600160a01b031692915050565b6005546001600160a01b03163314611ce45760405162461bcd60e51b8152600401610dc090614bb5565b6006805460ff60a01b1916600160a01b179055565b6005546001600160a01b03163314611d235760405162461bcd60e51b8152600401610dc090614bb5565b611d3a55565b600a821115611d3757600a91505b6001611d2b5460ff166003811115611d5157611d51614845565b14611d6e5760405162461bcd60e51b8152600401610dc090614d6b565b611d7b61033e6008614c5d565b611d2c54611d899190614c2a565b431015611e1a57611d9a838261183d565b611db65760405162461bcd60e51b8152600401610dc090614e39565b6001600160a01b0383166000908152611b70602052604090205415611e115760405162461bcd60e51b8152602060048201526011602482015270141c99599b1a59da1d0810db185a5b5959607a1b6044820152606401610dc0565b60019150611ef8565b611e2761033e6009614c5d565b611d2c54611e359190614c2a565b431015611ee257611e46838261183d565b611e625760405162461bcd60e51b8152600401610dc090614e39565b600b82611e85856001600160a01b03166000908152611b70602052604090205490565b611e8f9190614c2a565b1115611edd5760405162461bcd60e51b815260206004820152601960248201527f466c6967687470617373206c696d6974206578636565646564000000000000006044820152606401610dc0565b611ef8565b611d3c54611f401415611ef857611d2a54611d3c555b611b6782611d2a54611f0a9190614c2a565b1115611f285760405162461bcd60e51b8152600401610dc090614d90565b600082611d3a54611f399190614c5d565b905080341015611f805760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742046756e647360701b6044820152606401610dc0565b60005b83811015611fb557611fa38582611d2a54611f9e9190614c2a565b6139c8565b80611fad81614c42565b915050611f83565b5082611d2a6000828254611fc99190614c2a565b90915550503481101561207057600033611fe38334614e9b565b604051600081818185875af1925050503d806000811461201f576040519150601f19603f3d011682016040523d82523d6000602084013e612024565b606091505b505090508061206e5760405162461bcd60e51b81526020600482015260166024820152751499599d5b9908151c985b9cd9995c8811985a5b195960521b6044820152606401610dc0565b505b50505050565b60088054610cda90614b7a565b60038054610cda90614b7a565b6005546001600160a01b031633146120ba5760405162461bcd60e51b8152600401610dc090614bb5565b6001611d2b5460ff1660038111156120d4576120d4614845565b14806120f757506002611d2b5460ff1660038111156120f5576120f5614845565b145b6121335760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420537461746560981b6044820152606401610dc0565b611d2e546121429060c8614c2a565b431161214d57600080fd5b611d2b805460ff19166002908117909155611d2d86905543611d2e55612174908585614407565b50610f8e60038383614407565b336001600160a01b03831614156121da5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610dc0565b336000818152611d29602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6122513383613adc565b61226d5760405162461bcd60e51b8152600401610dc090614dbd565b61207084848484614010565b6003611d2b5460ff16600381111561229357612293614845565b146122b05760405162461bcd60e51b8152600401610dc090614bd8565b336122ba83611c3b565b6001600160a01b0316146122fc5760405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b6044820152606401610dc0565b60008160ff16118015612313575060058160ff1611155b6123505760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642043686f69636560901b6044820152606401610dc0565b6000828152611e26602052604090205460ff16156123a35760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e48115c5d5a5c1c195960821b6044820152606401610dc0565b6000611e275460ff1660028111156123bd576123bd614845565b146123f55760405162461bcd60e51b81526020600482015260086024820152672737ba1027b832b760c11b6044820152606401610dc0565b6000918252611e266020526040909120805460ff191660ff909216919091179055565b6005546001600160a01b031633146124425760405162461bcd60e51b8152600401610dc090614bb5565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b0316331461248e5760405162461bcd60e51b8152600401610dc090614bb5565b611d2e5461249d906004614c2a565b431180156124b85750611d2e546124b59060c8614c2a565b43105b6124f25760405162461bcd60e51b815260206004820152600b60248201526a426c6f636b2052616e676560a81b6044820152606401610dc0565b6002611d2b5460ff16600381111561250c5761250c614845565b1461254c5760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e4814995d99585b195960821b6044820152606401610dc0565b611d2d5460408051602081018490520160405160208183030381529060405280519060200120146125af5760405162461bcd60e51b815260206004820152600d60248201526c0a6cacac8409ad2e6dac2e8c6d609b1b6044820152606401610dc0565b80611d2e5460016125c09190614c2a565b40611d2e5460026125d19190614c2a565b40611d2e5460036125e29190614c2a565b604080516020810195909552840192909252606083015240608082015260a00160408051601f198184030181529190528051602090910120611d2f55611d2a5461262e90600590614e9b565b611d2f5461263c9190614ec8565b611d3955611d2f54611d319061265490600890614ec8565b6008811061266457612664614bfe565b0154611d305550611d2b805460ff19166003179055565b611e17816007811061268c57600080fd5b018054909150610cda90614b7a565b6060611d2a5482106127075760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610dc0565b6003611d2b5460ff16600381111561272157612721614845565b141561286c57600061273283613f10565b9050600f8110156127e757611d3d54604051637bb7ca8760e11b8152600481018390526002916001600160a01b03169063f76f950e9060240160006040518083038186803b15801561278357600080fd5b505afa158015612797573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127bf9190810190614edc565b6040516020016127d0929190614f4a565b604051602081830303815290604052915050919050565b60048054604051636a93802960e01b81529182018590526001600160a01b031690636a9380299060240160006040518083038186803b15801561282957600080fd5b505afa15801561283d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128659190810190614edc565b9392505050565b611d3d546001906001600160a01b031663f76f950e61288a856119a0565b6040516001600160e01b031960e084901b16815260ff909116600482015260240160006040518083038186803b1580156128c357600080fd5b505afa1580156128d7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128ff9190810190614edc565b604051602001612910929190614f4a565b6040516020818303038152906040529050919050565b611e21816005811061268c57600080fd5b606061294582611d2a541190565b6129615760405162461bcd60e51b8152600401610dc090614e0e565b6003611d2b5460ff16600381111561297b5761297b614845565b1415612a5a57600061298c83613f10565b9050600f811015612a2a57611d3d54604051637bb7ca8760e11b8152600481018390526002916001600160a01b03169063f76f950e9060240160006040518083038186803b1580156129dd57600080fd5b505afa1580156129f1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a199190810190614edc565b6040516020016127d0929190614f9e565b6000612a35846119f8565b90506000612a438583613496565b5050509050612a5181614043565b95945050505050565b611d3d546001906001600160a01b031663f76f950e612a78856119a0565b6040516001600160e01b031960e084901b16815260ff909116600482015260240160006040518083038186803b158015612ab157600080fd5b505afa158015612ac5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612aed9190810190614edc565b604051602001612910929190614f9e565b6005546001600160a01b03163314612b285760405162461bcd60e51b8152600401610dc090614bb5565b6001611d2b5460ff166003811115612b4257612b42614845565b1480612b6557506000611d2b5460ff166003811115612b6357612b63614845565b145b612b815760405162461bcd60e51b8152600401610dc090614d6b565b611d2a54611b6790612b94908390614c2a565b1115612bb25760405162461bcd60e51b8152600401610dc090614d90565b60005b81811015612c0857612bf6838383818110612bd257612bd2614bfe565b9050602002016020810190612be79190614642565b82611d2a54611f9e9190614c2a565b80612c0081614c42565b915050612bb5565b5081819050611d2a6000828254612c1f9190614c2a565b90915550505050565b611e28816010811061268c57600080fd5b612c41614487565b612c496143e9565b60606003611d2b5460ff166003811115612c6557612c65614845565b14612c825760405162461bcd60e51b8152600401610dc090614bd8565b6000612c8d856119f8565b9050600080600080612c9f8986613496565b92965090945092509050612cb58585600c6110b3565b96508015612cce57612cc7600161130c565b8852612cdb565b612cd8600061130c565b88525b60005b600c811015612d3d57612d0a8582600d8110612cfc57612cfc614bfe565b602002015161ffff1661130c565b89612d16836001614c2a565b60108110612d2657612d26614bfe565b602002015280612d3581614c42565b915050612cde565b5061018084015161ffff166000908152611e1e60209081526040808320815160808101909252805460ff1682526001810180549293919291840191612d8190614b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054612dad90614b7a565b8015612dfa5780601f10612dcf57610100808354040283529160200191612dfa565b820191906000526020600020905b815481529060010190602001808311612ddd57829003601f168201915b50505050508152602001600282018054612e1390614b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054612e3f90614b7a565b8015612e8c5780601f10612e6157610100808354040283529160200191612e8c565b820191906000526020600020905b815481529060010190602001808311612e6f57829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612eb45790505050505050815250509050611e17816000015160ff1660078110612f0857612f08614bfe565b018054612f1490614b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054612f4090614b7a565b8015612f8d5780601f10612f6257610100808354040283529160200191612f8d565b820191906000526020600020905b815481529060010190602001808311612f7057829003601f168201915b505050505089600d60108110612fa557612fa5614bfe565b6020020181905250806020015189600e60108110612fc557612fc5614bfe565b602002015260408101516101e08a0152612fde85614043565b989a97995050505050505050565b6005546001600160a01b031633146130165760405162461bcd60e51b8152600401610dc090614bb5565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b611d3e816003811061268c57600080fd5b6060806060600c841061308f5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a590818da5d1e525960921b6044820152606401610dc0565b6000848152611e1e60209081526040808320815160808101909252805460ff16825260018101805492939192918401916130c890614b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546130f490614b7a565b80156131415780601f1061311657610100808354040283529160200191613141565b820191906000526020600020905b81548152906001019060200180831161312457829003601f168201915b5050505050815260200160028201805461315a90614b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461318690614b7a565b80156131d35780601f106131a8576101008083540402835291602001916131d3565b820191906000526020600020905b8154815290600101906020018083116131b657829003601f168201915b50505091835250506040805160a0810191829052602090920191906003840190600590826000855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116131fb5790505050505050815250509050611e17816000015160ff166007811061324f5761324f614bfe565b01805461325b90614b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461328790614b7a565b80156132d45780601f106132a9576101008083540402835291602001916132d4565b820191906000526020600020905b8154815290600101906020018083116132b757829003601f168201915b505050505093508060200151925080604001519150509193909250565b611e1f816037811061330257600080fd5b60209182820401919006915054906101000a900460ff1681565b6001600160a01b039182166000908152611d296020908152604080832093909416825291909152205460ff1690565b6005546001600160a01b031633146133755760405162461bcd60e51b8152600401610dc090614bb5565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031633146133c15760405162461bcd60e51b8152600401610dc090614bb5565b6000611e275460ff1660028111156133db576133db614845565b146134135760405162461bcd60e51b81526020600482015260086024820152672737ba1027b832b760c11b6044820152606401610dc0565b611e2780546001919060ff19168280611808565b6000818152611d286020526040902080546001600160a01b0319166001600160a01b038416908117909155819061345d82611c3b565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61349e6144af565b600080600060fc85901c6001166001149050600060fd86901c6001166001149050600060fe87901c600116600114905060006134e5886000806002600160026004806140d5565b61ffff91909116885290506134fa8187614ff1565b60008a8152611e26602052604090205490965060ff1680156135965760006135218a613f6b565b90508061352f600184615016565b60ff166005811061354257613542614bfe565b60200201519650600d613556600189615016565b60ff166135639190615039565b61ffff1660208a0152851561359057600a896001602002018181516135889190615039565b61ffff169052505b5061359e565b606060208901525b60216135b2600560ff60188d901c16614ec8565b6135bc9190614c2a565b61ffff16604089015284156135e9576005886002602002018181516135e19190615039565b61ffff169052505b82156136205761360489866003602b600160038060056140d5565b61ffff919091166060808b019190915260808a0152915061364b565b61363689866004604360016002600460066140d5565b61ffff9190911660808a01526060808a015291505b6136558288614ff1565b965061366c89866005605d600160038060046140d5565b61ffff9190911660a08a015291506136848288614ff1565b965061369a8986600660736001806004806140d5565b61ffff9190911660c08a015291506136b28288614ff1565b96506136ca89866007608760016004600360026140d5565b61ffff9190911660e08a015291506136e28288614ff1565b96506136fa89866008609b60036004600660076140d5565b61ffff919091166101008a015291506137138288614ff1565b9650831561374d576137318986600960c3600460056006600a6140d5565b61ffff919091166101208a015260606101608a0152915061377d565b6137648986600b61012360036004600660076140d5565b61ffff919091166101608a015261014b6101208a015291505b6137878288614ff1565b965061379f8986600a60f5600260046007600a6140d5565b61ffff919091166101408a015291506137b88288614ff1565b96506137c9600c60608b901c61505f565b61ffff166101808901525095989497509295509093505050565b6137eb6143e9565b61ffff84166000908152611e1e6020526040808220815160a0810192839052916003909101906005908285855b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116138185790505050505050905060005b600a8110156138fd576000613866826002614c5d565b613871906070614c2a565b88901c60031690505b601484826005811061388e5761388e614bfe565b602002015160ff16106138be5780600314156138ac5750600061387a565b806138b681614c42565b91505061387a565b60058482600581106138d2576138d2614bfe565b602002018181516138e39190614ff1565b60ff169052508190506138f581614c42565b915050613850565b5060005b60058110156139bd57611e1f81613919866005615080565b60ff166139269190614c2a565b6037811061393657613936614bfe565b602081049091015460ff601f9092166101000a90041682826005811061395e5761395e614bfe565b602002015161396e87600a614ff1565b6139789190614ff1565b6139829190614ff1565b83826005811061399457613994614bfe565b602002018181516139a59190614ff1565b60ff16905250806139b581614c42565b915050613901565b50505b949350505050565b600654600160a01b900460ff1615613a0b5760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610dc0565b6001600160a01b0382166000818152611b70602090815260408220805460018101825581845291832090910184905591905254611b7182611b678110613a5357613a53614bfe565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555081600982611b678110613a8d57613a8d614bfe565b0180546001600160a01b0319166001600160a01b0392831617905560405182918416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000611d2a548210613b455760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610dc0565b6000613b5083611c3b565b9050806001600160a01b0316846001600160a01b03161480613b8b5750836001600160a01b0316613b8084610d5b565b6001600160a01b0316145b806139c057506139c0818561331c565b600654600160a01b900460ff1615613bde5760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610dc0565b826001600160a01b0316613bf182611c3b565b6001600160a01b031614613c595760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610dc0565b6001600160a01b038216613cbb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610dc0565b613cc6600082613427565b6000611b7182611b678110613cdd57613cdd614bfe565b601091828204019190066002029054906101000a900461ffff1690506000600182613d0891906150a9565b6001600160a01b0386166000908152611b70602052604081205461ffff92909216925090613d3890600190614e9b565b9050818114613dfa576001600160a01b0386166000908152611b7060205260408120805483908110613d6c57613d6c614bfe565b9060005260206000200154905080611b706000896001600160a01b03166001600160a01b031681526020019081526020016000208481548110613db157613db1614bfe565b60009182526020909120015583611b7182611b678110613dd357613dd3614bfe565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550505b6001600160a01b0386166000908152611b7060205260409020805480613e2257613e226150cc565b6000828152602080822083016000199081018390559092019092556001600160a01b038716808352611b70825260408320805460018101825581855292842090920187905590915254611b7185611b678110613e8057613e80614bfe565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555084600985611b678110613eba57613eba614bfe565b0180546001600160a01b0319166001600160a01b03928316179055604051859187811691908916907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4505050505050565b60006005821015613f1f575090565b6005611d2a54613f2f9190614e9b565b611d3954613f3e600585614e9b565b611d3054613f4c9190614c5d565b613f569190614c2a565b613f609190614ec8565b610cc7906005614c2a565b613f736143e9565b60ff601083901c16613f836143e9565b60005b600a8160ff161015614008576000600a84613fa284600d615080565b60ff16613faf9190615039565b613fb9919061505f565b905060058160ff161015613ff557613fd2826001614ff1565b838260ff1660058110613fe757613fe7614bfe565b60ff90921660209290920201525b5080614000816150e2565b915050613f86565b509392505050565b61401b848484613b9b565b614027848484846141e6565b6120705760405162461bcd60e51b8152600401610dc090615102565b606060006040518060a00160405280607b81526020016152a9607b9139905060005b600c8110156140c3578161408e8583600d811061408457614084614bfe565b60200201516142e7565b60405160200161409f929190615154565b604051602081830303815290604052915080806140bb90614c42565b915050614065565b50806040516020016127d0919061517a565b600080806140e4896008615080565b60ff168b901c90506140f581614384565b91508792508160ff16600614156141245761411087826151a4565b61411d9060ff1684615039565b92506141a2565b8160ff1660051415614145578661413b87836151a4565b6141109190614ff1565b8160ff166004141561416757858761415d87846151a4565b61413b9190614ff1565b84868861417487856151a4565b61417e9190614ff1565b6141889190614ff1565b6141929190614ff1565b61419f9060ff1684615039565b92505b89156141d85783856141b4888a614ff1565b6141be9190614ff1565b6141c89190614ff1565b6141d59060ff1684615039565b92505b509850989650505050505050565b6000833b156142df57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906142219033908990889088906004016151c6565b602060405180830381600087803b15801561423b57600080fd5b505af192505050801561426b575060408051601f3d908101601f19168201909252614268918101906151f9565b60015b6142c5573d808015614299576040519150601f19603f3d011682016040523d82523d6000602084013e61429e565b606091505b5080516142bd5760405162461bcd60e51b8152600401610dc090615102565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506139c0565b5060016139c0565b611d3d54604051637bb7ca8760e11b815261ffff831660048201526060916000916003916001600160a01b03169063f76f950e9060240160006040518083038186803b15801561433657600080fd5b505afa15801561434a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526143729190810190614edc565b60405160200161291093929190615216565b600060048260ff16101561439a57506006919050565b60188260ff1610156143ae57506005919050565b60608260ff1610156143c257506004919050565b506003919050565b604051806101e00160405280600f906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b82805461441390614b7a565b90600052602060002090601f016020900481019282614435576000855561447b565b82601f1061444e5782800160ff1982351617855561447b565b8280016001018555821561447b579182015b8281111561447b578235825591602001919060010190614460565b506118399291506144ce565b6040518061020001604052806010905b60608152602001906001900390816144975790505090565b604051806101a00160405280600d906020820280368337509192915050565b5b8082111561183957600081556001016144cf565b6000602082840312156144f557600080fd5b5035919050565b6001600160e01b03198116811461451257600080fd5b50565b60006020828403121561452757600080fd5b8135612865816144fc565b60005b8381101561454d578181015183820152602001614535565b838111156120705750506000910152565b60008151808452614576816020860160208601614532565b601f01601f19169290920160200192915050565b602081526000612865602083018461455e565b80356001600160a01b0381168114611bf757600080fd5b600080604083850312156145c757600080fd5b6145d08361459d565b946020939093013593505050565b8060005b600581101561207057815160ff168452602093840193909101906001016145e2565b6102808101818460005b600f81101561463157815161ffff1683526020928301929091019060010161460e565b5050506128656101e08301846145de565b60006020828403121561465457600080fd5b6128658261459d565b60008060006060848603121561467257600080fd5b61467b8461459d565b92506146896020850161459d565b9150604084013590509250925092565b60008083601f8401126146ab57600080fd5b50813567ffffffffffffffff8111156146c357600080fd5b6020830191508360208285010111156146db57600080fd5b9250929050565b600080602083850312156146f557600080fd5b823567ffffffffffffffff81111561470c57600080fd5b61471885828601614699565b90969095509350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561476357614763614724565b604052919050565b600067ffffffffffffffff82111561478557614785614724565b50601f01601f191660200190565b600082601f8301126147a457600080fd5b81356147b76147b28261476b565b61473a565b8181528460208386010111156147cc57600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156147fc57600080fd5b6148058361459d565b9150602083013567ffffffffffffffff81111561482157600080fd5b61482d85828601614793565b9150509250929050565b60a08101610cc782846145de565b634e487b7160e01b600052602160045260246000fd5b602081016004831061486f5761486f614845565b91905290565b60008060006060848603121561488a57600080fd5b6148938461459d565b925060208401359150604084013567ffffffffffffffff8111156148b657600080fd5b6148c286828701614793565b9150509250925092565b6000806000806000606086880312156148e457600080fd5b85359450602086013567ffffffffffffffff8082111561490357600080fd5b61490f89838a01614699565b9096509450604088013591508082111561492857600080fd5b5061493588828901614699565b969995985093965092949392505050565b801515811461451257600080fd5b6000806040838503121561496757600080fd5b6149708361459d565b9150602083013561498081614946565b809150509250929050565b600080600080608085870312156149a157600080fd5b6149aa8561459d565b93506149b86020860161459d565b925060408501359150606085013567ffffffffffffffff8111156149db57600080fd5b6149e787828801614793565b91505092959194509250565b60008060408385031215614a0657600080fd5b82359150602083013560ff8116811461498057600080fd5b60008060208385031215614a3157600080fd5b823567ffffffffffffffff80821115614a4957600080fd5b818501915085601f830112614a5d57600080fd5b813581811115614a6c57600080fd5b8660208260051b8501011115614a8157600080fd5b60209290920196919550909350505050565b60e08082526000906102e0830190830186835b6010811015614ad85760df19868503018352614ac384835161455e565b93506020928301929190910190600101614aa6565b505050614ae860208401866145de565b82810360c08401526114f0818561455e565b606081526000614b0d606083018661455e565b8281036020840152614b1f818661455e565b905082810360408401526114f0818561455e565b602081016003831061486f5761486f614845565b60008060408385031215614b5a57600080fd5b614b638361459d565b9150614b716020840161459d565b90509250929050565b600181811c90821680614b8e57607f821691505b60208210811415614baf57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b6020808252600c908201526b139bdd0814995d99585b195960a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115614c3d57614c3d614c14565b500190565b6000600019821415614c5657614c56614c14565b5060010190565b6000816000190483118215151615614c7757614c77614c14565b500290565b8054600090600181811c9080831680614c9657607f831692505b6020808410821415614cb857634e487b7160e01b600052602260045260246000fd5b818015614ccc5760018114614cdd57614d0a565b60ff19861689528489019650614d0a565b60008881526020902060005b86811015614d025781548b820152908501908301614ce9565b505084890196505b50505050505092915050565b60008351614d28818460208801614532565b600160fd1b908301908152612a516001820185614c7c565b60008351614d52818460208801614532565b6101d160f51b908301908152612a516002820185614c7c565b6020808252600b908201526a14d85b194810db1bdcd95960aa1b604082015260600190565b60208082526013908201527213585e0814dd5c1c1b1e48115e18d959591959606a1b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601190820152702737b732bc34b9ba32b73a102a37b5b2b760791b604082015260600190565b602080825260129082015271496e76616c696420466c696768747061737360701b604082015260600190565b600060208284031215614e7757600080fd5b5051919050565b600060208284031215614e9057600080fd5b815161286581614946565b600082821015614ead57614ead614c14565b500390565b634e487b7160e01b600052601260045260246000fd5b600082614ed757614ed7614eb2565b500690565b600060208284031215614eee57600080fd5b815167ffffffffffffffff811115614f0557600080fd5b8201601f81018413614f1657600080fd5b8051614f246147b28261476b565b818152856020838501011115614f3957600080fd5b612a51826020830160208601614532565b66697066733a2f2f60c81b81526000614f666007830185614c7c565b602f60f81b81528351614f80816001840160208801614532565b64173539b7b760d91b60019290910191820152600601949350505050565b66697066733a2f2f60c81b81526000614fba6007830185614c7c565b602f60f81b81528351614fd4816001840160208801614532565b632e706e6760e01b60019290910191820152600501949350505050565b600060ff821660ff84168060ff0382111561500e5761500e614c14565b019392505050565b600060ff821660ff84168082101561503057615030614c14565b90039392505050565b600061ffff80831681851680830382111561505657615056614c14565b01949350505050565b600061ffff8084168061507457615074614eb2565b92169190910692915050565b600060ff821660ff84168160ff04811182151516156150a1576150a1614c14565b029392505050565b600061ffff838116908316818110156150c4576150c4614c14565b039392505050565b634e487b7160e01b600052603160045260246000fd5b600060ff821660ff8114156150f9576150f9614c14565b60010192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351615166818460208801614532565b835190830190615056818360208801614532565b6000825161518c818460208701614532565b651e17b9bb339f60d11b920191825250600601919050565b600060ff8316806151b7576151b7614eb2565b8060ff84160691505092915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906114f09083018461455e565b60006020828403121561520b57600080fd5b8151612865816144fc565b7f3c696d61676520783d22302220793d2230222077696474683d2236303022206881527132b4b3b43a1e911b18181110343932b31e9160711b6020820152600061526c6152666032840187614c7c565b85614c7c565b602f60f81b81528351615286816001840160208801614532565b67173837339110179f60c11b600192909101918201526009019594505050505056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d6964594d6964206d656574222076696577426f783d223020302036303020363030222077696474683d2236303022206865696768743d22363030223ea2646970667358221220fd7badd15e25a61b91ad843600e6b16739ee518a2797bd995a72b4409cf8dc9e64736f6c63430008090033

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


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.