ETH Price: $3,296.28 (-3.78%)
Gas: 9 Gwei

Token

On-Chain Alpha V2 (OCAv2)
 

Overview

Max Total Supply

270 OCAv2

Holders

131

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
4 OCAv2
0x573cd2ed0e42ab76c11f39db3c749cd9dd37745b
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
OnChainAlphaV2

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 1 runs

Other Settings:
default evmVersion, MIT license
File 1 of 22 : onChainAlphaV2.sol
/* SPDX-License-Identifier: MIT

   ██████     ░░░░░░     ▒▒▒▒▒▒
 ██████████ ░░░░░░░░░░ ▒▒▒▒▒▒▒▒▒▒
 ███    ███ ░░░░       ▒▒▒▒  ▒▒▒▒
 ██████████ ░░░░░░░░░░ ▒▒▒▒  ▒▒▒▒
   ██████     ░░░░░░    ▒▒▒  ▒▒▒

 ********************************
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░██████████████████████░░░ *
 * ░░░██░░░░░░██░░░░░░████░░░░░ *
 * ░░░██░░░░░░██░░░░░░██░░░░░░░ *
 * ░░░██████████████████░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 ************************♥tt****/

// onChainAlphaV2.sol is a fork of 
// IndelibleERC721A.sol by 0xHirch.eth
// With modifications by ogkenobi.eth

pragma solidity 0.8.17;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Multicall.sol";
import "@openzeppelin/contracts/utils/Base64.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./helpers/SSTORE2.sol";
import "./helpers/DynamicBuffer.sol";
import "./helpers/HelperLib.sol";
import "./helpers/ERC721A.sol";


contract OnChainAlphaV2 is ERC721A, IERC721Receiver, Multicall, ReentrancyGuard, Ownable {
    using HelperLib for uint256;
    using DynamicBuffer for bytes;

    event AttributesUpdated(
        uint256 tokenId,
        string userName,
        string social,
        string website,
        string profileName
    );
    event LabelsValuesUpdated(
        uint256 tokenId,
        uint256 labelId,
        string customLabels,
        string customValues
    );
    event LayersUpdated(uint256 tokenId, bool[] layerIsHidden);
    event LayersRevealed(uint256 tokenId, uint layerRevealed);
    event ImagePhlipped(uint256 tokenId, bool isPhlipped);
    event bgChanged(uint256 tokenId, string color);

    struct TraitDTO {
        string name;
        string mimetype;
        bytes data;
    }

    struct Trait {
        string name;
        string mimetype;
    }

    struct AlphaToken {
        Profile AlphaProfile;
        mapping(uint => string) labels;
        mapping(uint => string) values;
        uint256 labelcount;
    }

    struct Profile {
        string userName;
        string social;
        string website;
        string profileName;
    }

    struct ContractData {
        string name;
        string description;
        string image;
        string banner;
        string website;
        uint256 royalties;
        string royaltiesRecipient;
    }

    mapping(uint256 => address[]) internal _traitDataPointers;
    mapping(uint256 => mapping(uint256 => Trait)) internal _traitDetails;
    mapping(uint256 => bool) internal _renderTokenOffChain;
    mapping(uint256 => mapping(uint256 => bool)) internal _hideLayer;
    mapping(uint256 => mapping(uint256 => bool)) internal _revealLayer;
    mapping(uint256 => bool) internal _phlipImage;
    mapping(uint256 => AlphaToken) idValues;
    mapping(uint256 => string) bgColor;
    mapping(address => uint256) rebates;
    mapping(uint256 => bool) ogMints;
    mapping(uint256 => bool) ocaClaims;
    mapping(address => uint256) mints;

    uint256 private constant NUM_LAYERS = 15;
    uint256 private constant MAX_BATCH_MINT = 20;
    uint256[][NUM_LAYERS] private TIERS;
    string[] private LAYER_NAMES = [
        unicode"Special",
        unicode"1",
        unicode"Mouth Special",
        unicode"3",
        unicode"Headwear",
        unicode"5",
        unicode"Eyewear",
        unicode"7",
        unicode"Eyes",
        unicode"9",
        unicode"Mouth",
        unicode"11",
        unicode"Ears",
        unicode"13",
        unicode"Body"
    ];

    address public faContract = 0x89d92A754FD1A672c21b5fc2a347198D1A9456b3;
    address public ocaContract = 0x6A04d2443Be907DD7E83236398c985688acB796E;
    uint256 public constant maxSupply = 7262;
    uint256 public mintPrice = 0.05 ether;
    uint256 public rebateAmt = 0.02 ether;
    string public baseURI = "https://static.flooredApe.io/oca/";
    bool public isPublicMintActive = false;

    ContractData public contractData =
        ContractData(
            unicode"On-Chain Alpha V2",
            unicode"On-Chain Alpha is a collection of 7777 customizable digital identity tokens stored entirely on the Ethereum blockchain. Token holders can visit https://oca.gg to enable/disable existing traits, change background color, flip the image, enable Twitter hex, and more as well as reveal new trait drops to be released in the future.",
            "https://ipfs.io/ipfs/Qmdbq7N5izrazoYcbwSuxcms2dBemxuxbrLaFtw2dufdV6/collection.gif",
            "https://ipfs.io/ipfs/Qmdbq7N5izrazoYcbwSuxcms2dBemxuxbrLaFtw2dufdV6/banner.png",
            "https://oca.gg",
            500,
            "0x957356F9412830c992D465FF8CDb9b0AA023020b"
        );

    constructor() ERC721A("On-Chain Alpha V2", "OCAv2") {
        TIERS[0] = [10,15,25,50,75,100,7225];
        TIERS[1] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600];
        TIERS[2] = [50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,1500];
        TIERS[3] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600];
        TIERS[4] = [10,20,30,40,50,70,100,120,140,160,180,200,220,240,260,280,300,320,340,360,380,400,420,440,460,480,500,980];
        TIERS[5] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600];
        TIERS[6] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600];
        TIERS[7] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600];
        TIERS[8] = [20,40,60,80,100,120,140,160,180,200,240,280,320,360,400,440,480,520,560,600,640,1560];
        TIERS[9] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600];
        TIERS[10] = [25,50,75,100,125,150,175,200,225,300,450,600,750,900,1050,2850];
        TIERS[11] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600];
        TIERS[12] = [50,100,150,200,300,400,500,600,700,900,1000,1200,2600];
        TIERS[13] = [35,65,100,130,160,190,220,250,280,310,340,370,400,430,460,490,520,550,600,1600];
        TIERS[14] = [75,100,150,200,250,300,350,400,450,500,550,600,700,800,900,1175,0];
    }
    
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) public override returns (bytes4) {
        require(
            msg.sender == faContract ||
                ERC721(faContract).ownerOf(
                    tokenId
                ) ==
                from
        );

        rebates[from]++;
        return this.onERC721Received.selector;
    }

    function publicMint(uint256 _count) external payable nonReentrant whenMintActive returns (uint256) {
        uint256 totalMinted = _totalMinted();
        require(mints[msg.sender] + _count <= 100);
        require(_count <= MAX_BATCH_MINT && _count > 0);
        require(totalMinted + _count <= maxSupply);
        require(msg.sender == tx.origin);

        uint256 discount;
        uint256 numDisc = rebates[msg.sender];
        if (numDisc > 0) {
            if (numDisc <= _count) {
                discount = rebateAmt * numDisc;
                require(msg.value >= (_count * mintPrice) - discount);
                rebates[msg.sender] = 0;
            } else {
                discount = rebateAmt * _count;
                require(msg.value >= (_count * mintPrice) - discount);
                rebates[msg.sender] -= _count;
            }
        } else {
            require(msg.value >= _count * mintPrice);
        }

        mints[msg.sender] += _count;
        _mint(msg.sender, _count);

        return totalMinted;
    }

    function freeClaim(uint256 _tokenId, bool _isOcaClaim) external nonReentrant whenMintActive returns (uint256) {
        uint256 totalMinted = _totalMinted();
        if(_isOcaClaim){
            require(ocaClaims[_tokenId] == false);
            require(msg.sender == ERC721(ocaContract).ownerOf(_tokenId));
            require(totalMinted + 1 <= maxSupply);

            ocaClaims[_tokenId] = true;
            _mint(msg.sender, 1);
        
        }

        if(!_isOcaClaim){
            require(_tokenId <= 1000);
            require(ogMints[_tokenId] == false);
            require(msg.sender == ERC721(faContract).ownerOf(_tokenId));
            require(totalMinted + 1 <= maxSupply);

            ogMints[_tokenId] = true;
            _mint(msg.sender, 1);
            
        }
        return totalMinted;
    }

    function getClaimed(uint256 _tokenId, bool _isOcaClaim) public view returns (bool){
        if(_isOcaClaim){
            return ocaClaims[_tokenId];
        } else {
            return ogMints[_tokenId];
        }
    }

    function getRebates(address _address) public view returns (uint256) {
        return rebates[_address];
    }

    function rarityGen(uint256 _randinput, uint256 _rarityTier)
        internal
        view
        returns (uint256)
    {
        uint256 currentLowerBound = 0;
        for (uint256 i = 0; i < TIERS[_rarityTier].length; i++) {
            uint256 thisPercentage = TIERS[_rarityTier][i];
            if (
                _randinput >= currentLowerBound &&
                _randinput < currentLowerBound + thisPercentage
            ) return i;
            currentLowerBound = currentLowerBound + thisPercentage;
        }

        return TIERS[_rarityTier].length - 1;
    }

    function entropyForExtraData() internal view returns (uint24) {
        uint256 randomNumber = uint256(
            keccak256(
                abi.encodePacked(
                    tx.gasprice,
                    block.number,
                    block.timestamp,
                    block.difficulty,
                    blockhash(block.number - 1),
                    msg.sender
                )
            )
        );
        return uint24(randomNumber);
    }

    function reRollDuplicate(uint256 tokenIdA, uint256 tokenIdB)
        public onlyOwner
    {
        uint256 largerTokenId = tokenIdA > tokenIdB ? tokenIdA : tokenIdB;

        _initializeOwnershipAt(largerTokenId);
        if (_exists(largerTokenId + 1)) {
            _initializeOwnershipAt(largerTokenId + 1);
        }

        _setExtraDataAt(largerTokenId, entropyForExtraData());
    }

    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual override returns (uint24) {
        return from == address(0) ? entropyForExtraData() : previousExtraData;
    }

    function tokenIdToHash(uint256 _tokenId)
        public
        view
        returns (string memory)
    {
        require(_exists(_tokenId));
        // This will generate a NUM_LAYERS * 3 character string.
        bytes memory hashBytes = DynamicBuffer.allocate(NUM_LAYERS * 4);

        uint256[] memory hash = new uint256[](NUM_LAYERS);

        for (uint256 i = 0; i < NUM_LAYERS; i++) {
            uint256 traitIndex = hash[i];
            if(i % 2 > 0 && _revealLayer[_tokenId][i] == false){
                hash[i] = TIERS[i].length - 1;
            } else {
                uint256 tokenExtraData = uint24(_ownershipOf(_tokenId).extraData);
                uint256 _randinput = uint256(
                    keccak256(
                        abi.encodePacked(
                            tokenExtraData,
                            _tokenId,
                            _tokenId + i
                        )
                    )
                ) % maxSupply;

                traitIndex = rarityGen(_randinput, i);
                hash[i] = traitIndex;
                uint blank = TIERS[i].length - 1;

                if (_hideLayer[_tokenId][i] == true){
                    if (i == 10 && hash[i] == 10){
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][2] == false){hash[2] = 15;}

                    } else if (i == 14 && hash[i] == 0) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 5;}
                        
                    } else if (i == 14 && hash[i] == 2) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 1;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 0;}
                        if(_hideLayer[_tokenId][4] == false){hash[4] = 1;}
                        
                    } else if (i == 14 && hash[i] == 4) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 8;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 9;}

                    } else if (i == 14 && hash[i] == 5) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 6;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 7;}

                    } else if (i == 14 && hash[i] == 6) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 7;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 8;}
                        
                    } else if (i == 14 && hash[i] == 7) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 2;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 4;}

                    } else if (i == 14 && hash[i] == 9) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 5;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 1;}

                    } else if (i == 14 && hash[i] == 10) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 4;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 2;}

                    } else if (i == 14 && hash[i] == 11) {
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 3;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 3;}

                    } else {
                        hash[i] = blank;
                    }
                    
                } else {

                    if (i == 10 && hash[10] == 10){
                        if(_hideLayer[_tokenId][2] == false){hash[2] = 15;}
                    }
                    if (i == 14){
                        if (hash[14] == 0) {
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 5;}
                        } else if (hash[14] == 2) {
                            if(_hideLayer[_tokenId][10] == false){hash[10] = 1;}
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 0;}
                            if(_hideLayer[_tokenId][4] == false){hash[4] = 1;}

                        } else if (hash[14] == 4) {
                            if(_hideLayer[_tokenId][10] == false){hash[10] = 8;}
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 9;}

                        } else if (hash[14] == 5) {
                            if(_hideLayer[_tokenId][10] == false){hash[10] = 6;}
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 7;}

                        } else if (hash[14] == 6) {
                            if(_hideLayer[_tokenId][10] == false){hash[10] = 7;}
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 8;}

                        } else if (hash[14] == 7) {
                            if(_hideLayer[_tokenId][10] == false){hash[10] = 2;}
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 4;}

                        } else if (hash[14] == 9) {
                            if(_hideLayer[_tokenId][10] == false){hash[10] = 5;}
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 1;}

                        } else if (hash[14] == 10) {
                            if(_hideLayer[_tokenId][10] == false){hash[10] = 4;}
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 2;}

                        } else if (hash[14] == 11) {
                            if(_hideLayer[_tokenId][10] == false){hash[10] = 3;}
                            if(_hideLayer[_tokenId][8] == false){hash[8] = 3;}

                        }
                    }
                }
            }
        }

        for (uint256 i = 0; i < hash.length; i++) {
            if (hash[i] < 10) {
                hashBytes.appendSafe("00");
            } else if (hash[i] < 100) {
                hashBytes.appendSafe("0");
            }
            if (hash[i] > 999) {
                hashBytes.appendSafe("999");
            } else {
                hashBytes.appendSafe(bytes(_toString(hash[i])));
            }
        }

        return string(hashBytes);
    }

    function hashToSVG(string memory _hash, uint256 _tokenId)
        public
        view
        returns (string memory)
    {
        uint256 thisTraitIndex;
        string memory _bgColor = "1C1531";

        if (bytes(bgColor[_tokenId]).length > 0) {
            _bgColor = bgColor[_tokenId];
        }

        bytes memory svgBytes = DynamicBuffer.allocate(1024 * 128);
        svgBytes.appendSafe(
            '<svg width="1600" height="1600" viewBox="0 0 1600 1600" version="1.2" xmlns="http://www.w3.org/2000/svg" style="background-color: #'
        );
        svgBytes.appendSafe(
            abi.encodePacked(_bgColor, ";background-image:url(")
        );
        for (uint256 i = 0; i < NUM_LAYERS - 1; i++) {
            if(!(i % 2 > 0 && _revealLayer[_tokenId][i] == false)){
                thisTraitIndex = HelperLib.parseInt(
                    HelperLib._substring(_hash, (i * 3), (i * 3) + 3)
                );
                svgBytes.appendSafe(
                    abi.encodePacked(
                        "data:",
                        _traitDetails[i][thisTraitIndex].mimetype,
                        ";base64,",
                        Base64.encode(
                            SSTORE2.read(_traitDataPointers[i][thisTraitIndex])
                        ),
                        "),url("
                    )
                );
            }
        }

        thisTraitIndex = HelperLib.parseInt(
            HelperLib._substring(_hash, (NUM_LAYERS * 3) - 3, NUM_LAYERS * 3)
        );

        svgBytes.appendSafe(
            abi.encodePacked(
                "data:",
                _traitDetails[NUM_LAYERS - 1][thisTraitIndex].mimetype,
                ";base64,",
                Base64.encode(
                    SSTORE2.read(
                        _traitDataPointers[NUM_LAYERS - 1][thisTraitIndex]
                    )
                ),
                ');background-repeat:no-repeat;background-size:contain;background-position:center;image-rendering:-webkit-optimize-contrast;-ms-interpolation-mode:nearest-neighbor;image-rendering:-moz-crisp-edges;image-rendering:pixelated;"></svg>'
            )
        );

        return
            string(
                abi.encodePacked(
                    "data:image/svg+xml;base64,",
                    Base64.encode(svgBytes)
                )
            );
    }

    function hashToMetadata(string memory _hash)
        public
        view
        returns (string memory)
    {
        bytes memory metadataBytes = DynamicBuffer.allocate(1024 * 128);
        metadataBytes.appendSafe("[");

        bool trait11 = bytes(_traitDetails[11][HelperLib.parseInt(HelperLib._substring(_hash, 33, 36))].name).length < 3;
        bool trait12 = bytes(_traitDetails[12][HelperLib.parseInt(HelperLib._substring(_hash, 36, 39))].name).length < 3;
        bool trait13 = bytes(_traitDetails[13][HelperLib.parseInt(HelperLib._substring(_hash, 39, 42))].name).length < 3;
        bool trait14 = bytes(_traitDetails[14][HelperLib.parseInt(HelperLib._substring(_hash, 42, 45))].name).length < 3;

        for (uint256 i = 0; i < NUM_LAYERS; i++) {
            uint256 thisTraitIndex = HelperLib.parseInt(
                HelperLib._substring(_hash, (i * 3), (i * 3) + 3)
            );
            if (bytes(_traitDetails[i][thisTraitIndex].name).length > 2 ) {
                metadataBytes.appendSafe(
                    abi.encodePacked(
                        '{"trait_type":"',
                        LAYER_NAMES[i],
                        '","value":"',
                        _traitDetails[i][thisTraitIndex].name,
                        '"}'
                    )
                );

                if (i == 10 && (trait11 && trait12 && trait13 && trait14)){
                    metadataBytes.appendSafe("]");
                } else if (i == 11 && (trait12 && trait13 && trait14)){
                    metadataBytes.appendSafe("]");
                } else if (i == 12 && (trait13 && trait14)){
                    metadataBytes.appendSafe("]");
                } else if (i == 13 && trait14){
                    metadataBytes.appendSafe("]");
                } else if (i == 14) {
                    metadataBytes.appendSafe("]");
                } else {
                    metadataBytes.appendSafe(",");
                }
            } 
        }

        return string(metadataBytes);
    }

    function tokenURI(uint256 _tokenId)
        public
        view
        override
        returns (string memory)
    {
        require(_exists(_tokenId));
        require(_traitDataPointers[0].length > 0);

        string memory tokenHash = tokenIdToHash(_tokenId);

        bytes memory jsonBytes = DynamicBuffer.allocate(1024 * 128);
        if (bytes(idValues[_tokenId].AlphaProfile.userName).length > 0) {
            jsonBytes.appendSafe(
                abi.encodePacked(
                    unicode'{"name":"',
                    idValues[_tokenId].AlphaProfile.userName
                )
            );
        } else {
            jsonBytes.appendSafe(unicode'{"name":"OnChainAlpha');
        }

        jsonBytes.appendSafe(
            abi.encodePacked(
                "#",
                _toString(_tokenId),
                '","description":"',
                contractData.description,
                '",'
            )
        );

        if (bytes(baseURI).length > 0 && _renderTokenOffChain[_tokenId]) {
            jsonBytes.appendSafe(
                abi.encodePacked('"image":"', baseURI, _toString(_tokenId))
            );
        } else {
            string memory svgCode = "";
            if (_phlipImage[_tokenId]) {
                string memory svgString = hashToSVG(tokenHash, _tokenId);
                svgCode = string(
                    abi.encodePacked(
                        "data:image/svg+xml;base64,",
                        Base64.encode(
                            abi.encodePacked(
                                '<svg width="100%" height="100%" viewBox="0 0 1200 1200" style="display: block; transform: scale(-1,1)" version="1.2" xmlns="http://www.w3.org/2000/svg"><image width="1200" height="1200" href="',
                                svgString,
                                '"></image></svg>'
                            )
                        )
                    )
                );
                jsonBytes.appendSafe(
                    abi.encodePacked('"svg_image_data":"', svgString, '",')
                );
            } else {
                string memory svgString = hashToSVG(tokenHash, _tokenId);
                svgCode = string(
                    abi.encodePacked(
                        "data:image/svg+xml;base64,",
                        Base64.encode(
                            abi.encodePacked(
                                '<svg width="100%" height="100%" viewBox="0 0 1200 1200" version="1.2" xmlns="http://www.w3.org/2000/svg"><image width="1200" height="1200" href="',
                                svgString,
                                '"></image></svg>'
                            )
                        )
                    )
                );
                jsonBytes.appendSafe(
                    abi.encodePacked('"svg_image_data":"', svgString, '",')
                );
            }

            jsonBytes.appendSafe(
                abi.encodePacked('"image_data":"', svgCode, '",')
            );
        }

        jsonBytes.appendSafe(
            abi.encodePacked('"attributes":', hashToMetadata(tokenHash), "}")
        );

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

    function contractURI() public view returns (string memory) {
        return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    Base64.encode(
                        abi.encodePacked(
                            '{"name":"',
                            contractData.name,
                            '","description":"',
                            contractData.description,
                            '","image":"',
                            contractData.image,
                            '","banner":"',
                            contractData.banner,
                            '","external_link":"',
                            contractData.website,
                            '","seller_fee_basis_points":',
                            _toString(contractData.royalties),
                            ',"fee_recipient":"',
                            contractData.royaltiesRecipient,
                            '"}'
                        )
                    )
                )
            );
    }

    function setRenderOfTokenId(uint256 _tokenId, bool _renderOffChain)
        external
    {
        require(msg.sender == ownerOf(_tokenId));
        _renderTokenOffChain[_tokenId] = _renderOffChain;
    }

    modifier whenMintActive() {
        require(isMintActive());
        _;
    }

    function isMintActive() public view returns (bool) {
        return _totalMinted() < maxSupply && isPublicMintActive;
    }

    function togglePublicMint() external onlyOwner {
        isPublicMintActive = !isPublicMintActive;
    }

    //metadata URI
    function setBaseURI(string memory _baseURI) external onlyOwner {
        baseURI = _baseURI;
    }

    function setContractData(ContractData memory _contractData)
        external
        onlyOwner
    {
        contractData = _contractData;
    }

    //address info
    address private helper = 0x95c0a28443F4897Bf718243A539fd018B6C16F63;

    //withdraw to helper address
    function withdraw() external {
        uint256 balance = address(this).balance;
        require(balance > 0);
        Address.sendValue(payable(helper), balance);
    }

    //oca profile functions
    function setBgColor(uint256 _tokenId, string memory _bgColor) public {
        require(ownerOf(_tokenId) == msg.sender);
        bgColor[_tokenId] = _bgColor;

        emit bgChanged(_tokenId, _bgColor);
    }

    function setProfile(
        uint256 _tokenId,
        string memory _username,
        string memory _social,
        string memory _website
    ) public {
        require(ownerOf(_tokenId) == msg.sender);

        idValues[_tokenId].AlphaProfile.userName = _username;
        idValues[_tokenId].AlphaProfile.social = _social;
        idValues[_tokenId].AlphaProfile.website = _website;

        string memory str = string(abi.encodePacked(_username,"#",_toString(_tokenId)));
        idValues[_tokenId].AlphaProfile.profileName = str;

        emit AttributesUpdated(
            _tokenId,
            _username,
            _social,
            _website,
            str
        );
    }

    function setLabelsValues(uint256 _tokenId, uint _labelNum, string memory _label, string memory _value) external {
        require(msg.sender == ownerOf(_tokenId));
        uint count = idValues[_tokenId].labelcount;
        if(_labelNum >= count){
            _labelNum = count;
            idValues[_tokenId].labelcount++;
        }

        idValues[_tokenId].labels[_labelNum] = _label;
        idValues[_tokenId].values[_labelNum] = _value;

        emit LabelsValuesUpdated(_tokenId, _labelNum, _label, _value);
    }

    function toggleLayers(uint256 _tokenId, bool[] memory states) public {
        require(msg.sender == ownerOf(_tokenId));
        for (uint256 i = 0; i < NUM_LAYERS; i++) {
            _hideLayer[_tokenId][i] = states[i];
        }

        emit LayersUpdated(_tokenId, states);
    }

    function togglePhlipPFP(uint256 _tokenId, bool _flipped) public {
        require(msg.sender == ownerOf(_tokenId));
        _phlipImage[_tokenId] = _flipped;

        emit ImagePhlipped(_tokenId, _flipped);
    }

    //layers
    function addLayer(uint256 _layerIndex, TraitDTO[] memory traits)
        public
        onlyOwner
    {
        require(TIERS[_layerIndex].length == traits.length);
        address[] memory dataPointers = new address[](traits.length);
        for (uint256 i = 0; i < traits.length; i++) {
            dataPointers[i] = SSTORE2.write(traits[i].data);
            _traitDetails[_layerIndex][i] = Trait(
                traits[i].name,
                traits[i].mimetype
            );
        }
        _traitDataPointers[_layerIndex] = dataPointers;
        return;
    }

    function setLayerNames(uint _layerNum, string memory _value) public onlyOwner {
        LAYER_NAMES[_layerNum] = _value;
    }

    function revealLayers(uint256 _tokenId, uint _layer) public {
        require(_layer < 15);
        require(msg.sender == ownerOf(_tokenId));

        _revealLayer[_tokenId][_layer] = true;

        emit LayersRevealed(_tokenId, _layer);
    }
}

File 2 of 22 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

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

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

File 3 of 22 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 4 of 22 : ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

        _owners[tokenId] = to;

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

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

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

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

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

        // Clear approvals
        delete _tokenApprovals[tokenId];

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId, 1);

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

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

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

        emit Transfer(from, to, tokenId);

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

File 6 of 22 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

File 8 of 22 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

File 9 of 22 : Base64.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}

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

pragma solidity ^0.8.0;

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

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

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 12 of 22 : 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 13 of 22 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 14 of 22 : Multicall.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Multicall.sol)

pragma solidity ^0.8.0;

import "./Address.sol";

/**
 * @dev Provides a function to batch together multiple calls in a single external call.
 *
 * _Available since v4.1._
 */
abstract contract Multicall {
    /**
     * @dev Receives and executes a batch of function calls on this contract.
     */
    function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            results[i] = Address.functionDelegateCall(address(this), data[i]);
        }
        return results;
    }
}

File 15 of 22 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";

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

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

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

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

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

File 16 of 22 : Bytecode.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


library Bytecode {
  error InvalidCodeAtRange(uint256 _size, uint256 _start, uint256 _end);

  /**
    @notice Generate a creation code that results on a contract with `_code` as bytecode
    @param _code The returning value of the resulting `creationCode`
    @return creationCode (constructor) for new contract
  */
  function creationCodeFor(bytes memory _code) internal pure returns (bytes memory) {
    /*
      0x00    0x63         0x63XXXXXX  PUSH4 _code.length  size
      0x01    0x80         0x80        DUP1                size size
      0x02    0x60         0x600e      PUSH1 14            14 size size
      0x03    0x60         0x6000      PUSH1 00            0 14 size size
      0x04    0x39         0x39        CODECOPY            size
      0x05    0x60         0x6000      PUSH1 00            0 size
      0x06    0xf3         0xf3        RETURN
      <CODE>
    */

    return abi.encodePacked(
      hex"63",
      uint32(_code.length),
      hex"80_60_0E_60_00_39_60_00_F3",
      _code
    );
  }

  /**
    @notice Returns the size of the code on a given address
    @param _addr Address that may or may not contain code
    @return size of the code on the given `_addr`
  */
  function codeSize(address _addr) internal view returns (uint256 size) {
    assembly { size := extcodesize(_addr) }
  }

  /**
    @notice Returns the code of a given address
    @dev It will fail if `_end < _start`
    @param _addr Address that may or may not contain code
    @param _start number of bytes of code to skip on read
    @param _end index before which to end extraction
    @return oCode read from `_addr` deployed bytecode

    Forked from: https://gist.github.com/KardanovIR/fe98661df9338c842b4a30306d507fbd
  */
  function codeAt(address _addr, uint256 _start, uint256 _end) internal view returns (bytes memory oCode) {
    uint256 csize = codeSize(_addr);
    if (csize == 0) return bytes("");

    if (_start > csize) return bytes("");
    if (_end < _start) revert InvalidCodeAtRange(csize, _start, _end); 

    unchecked {
      uint256 reqSize = _end - _start;
      uint256 maxSize = csize - _start;

      uint256 size = maxSize < reqSize ? maxSize : reqSize;

      assembly {
        // allocate output byte array - this could also be done without assembly
        // by using o_code = new bytes(size)
        oCode := mload(0x40)
        // new "memory end" including padding
        mstore(0x40, add(oCode, and(add(add(size, 0x20), 0x1f), not(0x1f))))
        // store length in memory
        mstore(oCode, size)
        // actually retrieve the code, this needs assembly
        extcodecopy(_addr, add(oCode, 0x20), _start, size)
      }
    }
  }
}

File 17 of 22 : DynamicBuffer.sol
// SPDX-License-Identifier: MIT
// Copyright (c) 2021 the ethier authors (github.com/divergencetech/ethier)

pragma solidity >=0.8.0;

/// @title DynamicBuffer
/// @author David Huber (@cxkoda) and Simon Fremaux (@dievardump). See also
///         https://raw.githubusercontent.com/dievardump/solidity-dynamic-buffer
/// @notice This library is used to allocate a big amount of container memory
//          which will be subsequently filled without needing to reallocate
///         memory.
/// @dev First, allocate memory.
///      Then use `buffer.appendUnchecked(theBytes)` or `appendSafe()` if
///      bounds checking is required.
library DynamicBuffer {
    /// @notice Allocates container space for the DynamicBuffer
    /// @param capacity The intended max amount of bytes in the buffer
    /// @return buffer The memory location of the buffer
    /// @dev Allocates `capacity + 0x60` bytes of space
    ///      The buffer array starts at the first container data position,
    ///      (i.e. `buffer = container + 0x20`)
    function allocate(uint256 capacity)
        internal
        pure
        returns (bytes memory buffer)
    {
        assembly {
            // Get next-free memory address
            let container := mload(0x40)

            // Allocate memory by setting a new next-free address
            {
                // Add 2 x 32 bytes in size for the two length fields
                // Add 32 bytes safety space for 32B chunked copy
                let size := add(capacity, 0x60)
                let newNextFree := add(container, size)
                mstore(0x40, newNextFree)
            }

            // Set the correct container length
            {
                let length := add(capacity, 0x40)
                mstore(container, length)
            }

            // The buffer starts at idx 1 in the container (0 is length)
            buffer := add(container, 0x20)

            // Init content with length 0
            mstore(buffer, 0)
        }

        return buffer;
    }

    /// @notice Appends data to buffer, and update buffer length
    /// @param buffer the buffer to append the data to
    /// @param data the data to append
    /// @dev Does not perform out-of-bound checks (container capacity)
    ///      for efficiency.
    function appendUnchecked(bytes memory buffer, bytes memory data)
        internal
        pure
    {
        assembly {
            let length := mload(data)
            for {
                data := add(data, 0x20)
                let dataEnd := add(data, length)
                let copyTo := add(buffer, add(mload(buffer), 0x20))
            } lt(data, dataEnd) {
                data := add(data, 0x20)
                copyTo := add(copyTo, 0x20)
            } {
                // Copy 32B chunks from data to buffer.
                // This may read over data array boundaries and copy invalid
                // bytes, which doesn't matter in the end since we will
                // later set the correct buffer length, and have allocated an
                // additional word to avoid buffer overflow.
                mstore(copyTo, mload(data))
            }

            // Update buffer length
            mstore(buffer, add(mload(buffer), length))
        }
    }

    /// @notice Appends data to buffer, and update buffer length
    /// @param buffer the buffer to append the data to
    /// @param data the data to append
    /// @dev Performs out-of-bound checks and calls `appendUnchecked`.
    function appendSafe(bytes memory buffer, bytes memory data) internal pure {
        uint256 capacity;
        uint256 length;
        assembly {
            capacity := sub(mload(sub(buffer, 0x20)), 0x40)
            length := mload(buffer)
        }

        require(
            length + data.length <= capacity,
            "DynamicBuffer: Appending out of bounds."
        );
        appendUnchecked(buffer, data);
    }
}

File 18 of 22 : ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.1.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev ERC721 token receiver interface.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard,
 * including the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at `_startTokenId()`
 * (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Mask of an entry in packed address data.
    uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with `_mintERC2309`.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to `_mintERC2309`
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The tokenId of the next token to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See `_packedOwnershipOf` implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

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

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

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 262;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see `_totalMinted`.
     */
    function totalSupply() public view override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to `_startTokenId()`
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view returns (uint256) {
        return _burnCounter;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes of the XOR of
        // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165
        // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
        ownership.burned = packed & BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> BITPOS_EXTRA_DATA);
    }

    /**
     * Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, BITMASK_ADDRESS)
            // `owner | (block.timestamp << BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

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

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

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

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

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

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << BITPOS_NEXT_INITIALIZED`.
            result := shl(BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = ownerOf(tokenId);

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 tokenId = startTokenId;
            uint256 end = startTokenId + quantity;
            do {
                emit Transfer(address(0), to, tokenId++);
            } while (tokenId < end);

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals;
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`.
        assembly {
            // Compute the slot.
            mstore(0x00, tokenId)
            mstore(0x20, tokenApprovalsPtr.slot)
            approvedAddressSlot := keccak256(0x00, 0x40)
            // Load the slot's value from storage.
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    /**
     * @dev Returns whether the `approvedAddress` is equals to `from` or `msgSender`.
     */
    function _isOwnerOrApproved(
        address approvedAddress,
        address from,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
            from := and(from, BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, BITMASK_ADDRESS)
            // `msgSender == from || msgSender == approvedAddress`.
            result := or(eq(msgSender, from), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (BITMASK_BURNED | BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << BITPOS_EXTRA_DATA;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred.
     * This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred.
     * This includes minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function _toString(uint256 value) internal pure returns (string memory ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

            // Cache the end of the memory to calculate the length later.
            let end := ptr

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for {
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp {
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } {
                // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }

            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}

File 19 of 22 : HelperLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;

library HelperLib {
    function parseInt(string memory _a)
        internal
        pure
        returns (uint8 _parsedInt)
    {
        bytes memory bresult = bytes(_a);
        uint8 mint = 0;
        for (uint8 i = 0; i < bresult.length; i++) {
            if (
                (uint8(uint8(bresult[i])) >= 48) &&
                (uint8(uint8(bresult[i])) <= 57)
            ) {
                mint *= 10;
                mint += uint8(bresult[i]) - 48;
            }
        }
        return mint;
    }

    function _substring(
        string memory str,
        uint256 startIndex,
        uint256 endIndex
    ) internal pure returns (string memory) {
        bytes memory strBytes = bytes(str);
        bytes memory result = new bytes(endIndex - startIndex);
        for (uint256 i = startIndex; i < endIndex; i++) {
            result[i - startIndex] = strBytes[i];
        }
        return string(result);
    }
}

File 20 of 22 : IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.1.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set through `_extraData`.
        uint24 extraData;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

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

    // ==============================
    //            IERC721
    // ==============================

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must 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 Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

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

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

    // ==============================
    //        IERC721Metadata
    // ==============================

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

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

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

    // ==============================
    //            IERC2309
    // ==============================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId` (inclusive) is transferred from `from` to `to`,
     * as defined in the ERC2309 standard. See `_mintERC2309` for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

File 21 of 22 : SSTORE2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../helpers/Bytecode.sol";

/**
  @title A key-value storage with auto-generated keys for storing chunks of data with a lower write & read cost.
  @author Agustin Aguilar <[email protected]>

  Readme: https://github.com/0xsequence/sstore2#readme
*/
library SSTORE2 {
  error WriteError();

  /**
    @notice Stores `_data` and returns `pointer` as key for later retrieval
    @dev The pointer is a contract address with `_data` as code
    @param _data to be written
    @return pointer Pointer to the written `_data`
  */
  function write(bytes memory _data) internal returns (address pointer) {
    // Append 00 to _data so contract can't be called
    // Build init code
    bytes memory code = Bytecode.creationCodeFor(
      abi.encodePacked(
        hex'00',
        _data
      )
    );

    // Deploy contract using create
    assembly { pointer := create(0, add(code, 32), mload(code)) }

    // Address MUST be non-zero
    if (pointer == address(0)) revert WriteError();
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @return data read from `_pointer` contract
  */
  function read(address _pointer) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, 1, type(uint256).max);
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @param _start number of bytes to skip
    @return data read from `_pointer` contract
  */
  function read(address _pointer, uint256 _start) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, _start + 1, type(uint256).max);
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @param _start number of bytes to skip
    @param _end index before which to end extraction
    @return data read from `_pointer` contract
  */
  function read(address _pointer, uint256 _start, uint256 _end) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, _start + 1, _end + 1);
  }
}

File 22 of 22 : ocaV1.sol
/* SPDX-License-Identifier: MIT

   ██████     ░░░░░░     ▒▒▒▒▒▒
 ██████████ ░░░░░░░░░░ ▒▒▒▒▒▒▒▒▒▒
 ███    ███ ░░░░       ▒▒▒▒  ▒▒▒▒
 ██████████ ░░░░░░░░░░ ▒▒▒▒  ▒▒▒▒
   ██████     ░░░░░░    ▒▒▒  ▒▒▒

 ********************************
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░██████████████████████░░░ *
 * ░░░██░░░░░░██░░░░░░████░░░░░ *
 * ░░░██░░░░░░██░░░░░░██░░░░░░░ *
 * ░░░██████████████████░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 ************************♥tt****/

// onChainAlpha.sol is a fork of 
// IndelibleERC721A.sol by 0xHirch.eth
// With modifications by ogkenobi.eth

pragma solidity 0.8.17;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Multicall.sol";
import "@openzeppelin/contracts/utils/Base64.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./helpers/SSTORE2.sol";
import "./helpers/DynamicBuffer.sol";
import "./helpers/HelperLib.sol";
import "./helpers/ERC721A.sol";


contract OnChainAlphaV1 is ERC721A, IERC721Receiver, Multicall, ReentrancyGuard, Ownable {
    using HelperLib for uint256;
    using DynamicBuffer for bytes;

    event AttributesUpdated(
        uint256 tokenId,
        string userName,
        string social,
        string website,
        string profileName
    );
    event LabelsValuesUpdated(
        uint256 tokenId,
        uint256 labelId,
        string customLabels,
        string customValues
    );
    event LayersUpdated(uint256 tokenId, bool[] layerIsHidden);
    event LayersRevealed(uint256 tokenId, uint layerRevealed);
    event ImagePhlipped(uint256 tokenId, bool isPhlipped);
    event bgChanged(uint256 tokenId, string color);

    struct TraitDTO {
        string name;
        string mimetype;
        bytes data;
    }

    struct Trait {
        string name;
        string mimetype;
    }

    struct AlphaToken {
        Profile AlphaProfile;
        mapping(uint => string) labels;
        mapping(uint => string) values;
        uint256 labelcount;
    }

    struct Profile {
        string userName;
        string social;
        string website;
        string profileName;
    }

    struct ContractData {
        string name;
        string description;
        string image;
        string banner;
        string website;
        uint256 royalties;
        string royaltiesRecipient;
    }

    mapping(uint256 => address[]) internal _traitDataPointers;
    mapping(uint256 => mapping(uint256 => Trait)) internal _traitDetails;
    mapping(uint256 => bool) internal _renderTokenOffChain;
    mapping(uint256 => mapping(uint256 => bool)) internal _hideLayer;
    mapping(uint256 => mapping(uint256 => bool)) internal _revealLayer;
    mapping(uint256 => bool) internal _phlipImage;
    mapping(uint256 => AlphaToken) idValues;
    mapping(uint256 => string) bgColor;
    mapping(address => uint256) rebates;
    mapping(uint256 => bool) ogMints;
    mapping(address => uint256) mints;

    uint256 private constant NUM_LAYERS = 15;
    uint256 private constant MAX_BATCH_MINT = 10;
    uint256[][NUM_LAYERS] private TIERS;
    string[] private LAYER_NAMES = [
        unicode"Special",
        unicode"-",
        unicode"Mouth Special",
        unicode"-",
        unicode"Headwear",
        unicode"-",
        unicode"Eyewear",
        unicode"-",
        unicode"Eyes",
        unicode"-",
        unicode"Mouth",
        unicode"-",
        unicode"Ears",
        unicode"-",
        unicode"Body"
    ];

    function setLayerNames(uint _layerNum, string memory _value) public onlyOwner {
        LAYER_NAMES[_layerNum] = _value;
    }

    address public reRollDuplicateRole = 0x957356F9412830c992D465FF8CDb9b0AA023020b;
    address public faContract = 0xbD2075e820FD448A3AD7b2A6a593BAC56534a950; //testnet
    uint256 public constant maxSupply = 7777;
    uint256 public mintPrice = 0.0 ether;
    uint256 public rebateAmt = 0.0 ether;
    string public baseURI = "https://static.flooredApe.io/oca/";
    bool public isPublicMintActive = false;

    ContractData public contractData =
        ContractData(
            unicode"On-Chain Alpha",
            unicode"On-Chain Alpha is a collection of 7777 customizable digital identity tokens stored entirely on the Ethereum blockchain. Token holders can visit https://oca.gg to enable/disable existing traits, change background color, flip the image, enable Twitter hex, and more as well as reveal new trait drops to be released in the future.",
            "https://ipfs.io/ipfs/Qmdbq7N5izrazoYcbwSuxcms2dBemxuxbrLaFtw2dufdV6/collection.gif",
            "https://ipfs.io/ipfs/Qmdbq7N5izrazoYcbwSuxcms2dBemxuxbrLaFtw2dufdV6/banner.png",
            "https://oca.gg",
            500,
            "0x957356F9412830c992D465FF8CDb9b0AA023020b"
        );

    constructor() ERC721A("On-Chain Alpha", "OCA") {
        TIERS[0] = [10,15,25,50,75,100,7502]; //special 0
        TIERS[1] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027];
        TIERS[2] = [50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,1777]; //mouth special 1
        TIERS[3] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027];
        TIERS[4] = [10,20,40,60,80,100,120,140,160,180,200,220,240,260,280,300,320,340,360,380,400,420,440,460,480,500,520,747]; //headwear 2
        TIERS[5] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027];
        TIERS[6] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027]; //eyewear 3
        TIERS[7] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027];
        TIERS[8] = [25,40,80,110,140,170,200,230,260,290,320,350,380,410,440,470,500,530,570,610,650,1002]; //eyes 4
        TIERS[9] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027];
        TIERS[10] = [100,200,250,300,350,400,450,500,550,600,650,700,750,850,1000,1727]; //mouth 5
        TIERS[11] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027];
        TIERS[12] = [200,300,400,500,600,700,800,900,1000,1100,1200,1300,1477]; //ears 6
        TIERS[13] = [35,65,100,130,160,190,220,250,280,310,340,370,400,450,500,650,700,750,850,1027];
        TIERS[14] = [75,100,150,200,250,300,350,400,450,500,550,600,700,800,900,1452,0]; //body 7
    }

    function _startTokenId() internal view virtual override returns (uint256) {
        return 0;
    }

    function rarityGen(uint256 _randinput, uint256 _rarityTier)
        internal
        view
        returns (uint256)
    {
        uint256 currentLowerBound = 0;
        for (uint256 i = 0; i < TIERS[_rarityTier].length; i++) {
            uint256 thisPercentage = TIERS[_rarityTier][i];
            if (
                _randinput >= currentLowerBound &&
                _randinput < currentLowerBound + thisPercentage
            ) return i;
            currentLowerBound = currentLowerBound + thisPercentage;
        }

        return TIERS[_rarityTier].length - 1;
    }

    modifier whenMintActive() {
        require(isMintActive());
        _;
    }

    function entropyForExtraData() internal view returns (uint24) {
        uint256 randomNumber = uint256(
            keccak256(
                abi.encodePacked(
                    tx.gasprice,
                    block.number,
                    block.timestamp,
                    block.difficulty,
                    blockhash(block.number - 1),
                    msg.sender
                )
            )
        );
        return uint24(randomNumber);
    }

    function reRollDuplicate(uint256 tokenIdA, uint256 tokenIdB)
        public
    {
        require(msg.sender == reRollDuplicateRole);

        uint256 largerTokenId = tokenIdA > tokenIdB ? tokenIdA : tokenIdB;

        _initializeOwnershipAt(largerTokenId);
        if (_exists(largerTokenId + 1)) {
            _initializeOwnershipAt(largerTokenId + 1);
        }

        _setExtraDataAt(largerTokenId, entropyForExtraData());
    }

    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual override returns (uint24) {
        return from == address(0) ? entropyForExtraData() : previousExtraData;
    }

    function tokenIdToHash(uint256 _tokenId)
        public
        view
        returns (string memory)
    {
        require(_exists(_tokenId));
        // This will generate a NUM_LAYERS * 3 character string.
        bytes memory hashBytes = DynamicBuffer.allocate(NUM_LAYERS * 4);

        uint256[] memory hash = new uint256[](NUM_LAYERS);

        for (uint256 i = 0; i < NUM_LAYERS; i++) {
            uint256 traitIndex = hash[i];
            if(i % 2 > 0 && _revealLayer[_tokenId][i] == false){
                hash[i] = TIERS[i].length - 1;
            } else {
                uint256 tokenExtraData = uint24(_ownershipOf(_tokenId).extraData);
                uint256 _randinput = uint256(
                    keccak256(
                        abi.encodePacked(
                            tokenExtraData,
                            _tokenId,
                            _tokenId + i
                        )
                    )
                ) % maxSupply;

                traitIndex = rarityGen(_randinput, i);
                hash[i] = traitIndex;
                uint blank = TIERS[i].length - 1;

                if (_hideLayer[_tokenId][i] == true){
                    if (i == 10 && hash[i] == 10){ //astonished -> blank
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][2] == false){hash[2] = 15;}

                    } else if (i == 14 && hash[i] == 0) {
                        //ghost
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 5;}
                        
                    } else if (i == 14 && hash[i] == 2) {
                        //robot
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 1;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 0;}
                        if(_hideLayer[_tokenId][4] == false){hash[4] = 1;}
                        
                    } else if (i == 14 && hash[i] == 4) {
                        //skull
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 8;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 9;}

                    } else if (i == 14 && hash[i] == 5) {
                        //vampire
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 6;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 7;}

                    } else if (i == 14 && hash[i] == 6) {
                        //monster
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 7;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 8;}
                        if (hash[6] == 8 && _hideLayer[_tokenId][6] == false) {hash[6] = 19;}
                    } else if (i == 14 && hash[i] == 7) {
                        //clown
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 2;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 4;}

                    } else if (i == 14 && hash[i] == 9) {
                        //pepe
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 5;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 1;}

                    } else if (i == 14 && hash[i] == 10) {
                        //doge
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 4;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 2;}

                    } else if (i == 14 && hash[i] == 11) {
                        //cat
                        hash[i] = blank;
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 3;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 3;}

                    } else {
                        hash[i] = blank;
                    }
                    
                } else {

                    if (hash[10] == 10){ //astonished -> blank
                        if(_hideLayer[_tokenId][2] == false){hash[2] = 15;}
                    }

                    if (hash[14] == 0) {
                        //ghost
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 5;}
                    } else if (hash[14] == 2) {
                        //robot
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 1;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 0;}
                        if(_hideLayer[_tokenId][4] == false){hash[4] = 1;}

                    } else if (hash[14] == 4) {
                        //skull
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 8;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 9;}

                    } else if (hash[14] == 5) {
                        //vampire
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 6;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 7;}

                    } else if (hash[14] == 6) {
                        //monster
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 7;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 8;}
                        if (hash[6] == 8 && _hideLayer[_tokenId][6] == false) {hash[6] = 19;}

                    } else if (hash[14] == 7) {
                        //clown
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 2;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 4;}

                    } else if (hash[14] == 9) {
                        //pepe
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 5;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 1;}

                    } else if (hash[14] == 10) {
                        //doge
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 4;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 2;}

                    } else if (hash[14] == 11) {
                        //cat
                        if(_hideLayer[_tokenId][10] == false){hash[10] = 3;}
                        if(_hideLayer[_tokenId][8] == false){hash[8] = 3;}

                    }

                }
            }
        }

        for (uint256 i = 0; i < hash.length; i++) {
            if (hash[i] < 10) {
                hashBytes.appendSafe("00");
            } else if (hash[i] < 100) {
                hashBytes.appendSafe("0");
            }
            if (hash[i] > 999) {
                hashBytes.appendSafe("999");
            } else {
                hashBytes.appendSafe(bytes(_toString(hash[i])));
            }
        }

        return string(hashBytes);
    }

    function publicMint(uint256 _count) external payable nonReentrant whenMintActive returns (uint256) {
        uint256 totalMinted = _totalMinted();
        require(mints[msg.sender] + _count <= 100);
        require(_count <= MAX_BATCH_MINT && _count > 0);
        require(totalMinted + _count <= maxSupply);
        require(msg.sender == tx.origin);

        uint256 discount;
        uint256 numDisc = rebates[msg.sender];
        if (numDisc > 0) {
            if (numDisc <= _count) {
                discount = rebateAmt * numDisc;
                require(msg.value >= (_count * mintPrice) - discount);
                rebates[msg.sender] = 0;
            } else {
                discount = rebateAmt * _count;
                require(msg.value >= (_count * mintPrice) - discount);
                rebates[msg.sender] -= _count;
            }
        } else {
            require(msg.value >= _count * mintPrice);
        }

        mints[msg.sender] += _count;
        _mint(msg.sender, _count);

        return totalMinted;
    }

    function ogMint(uint256 _ogTokenId) external nonReentrant whenMintActive returns (uint256) {
        uint256 totalMinted = _totalMinted();
        require(_ogTokenId <= 1000);
        require(ogMints[_ogTokenId] == false);
        require(msg.sender == ERC721(faContract).ownerOf(_ogTokenId));
        require(totalMinted + 1 <= maxSupply);

        ogMints[_ogTokenId] = true;
        _mint(msg.sender, 1);
        return totalMinted;
    }

    function ogClaimed(uint256 _ogTokenId) public view returns (bool){
        return ogMints[_ogTokenId];
    }

    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) public override returns (bytes4) {
        require(
            msg.sender == faContract ||
                ERC721(faContract).ownerOf(
                    tokenId
                ) ==
                from
        );

        rebates[from]++;
        return this.onERC721Received.selector;
    }

    function getRebates(address _address) public view returns (uint256) {
        return rebates[_address];
    }

    function hashToSVG(string memory _hash, uint256 _tokenId)
        public
        view
        returns (string memory)
    {
        uint256 thisTraitIndex;
        string memory _bgColor = "1C1531";

        if (bytes(bgColor[_tokenId]).length > 0) {
            _bgColor = bgColor[_tokenId];
        }

        bytes memory svgBytes = DynamicBuffer.allocate(1024 * 128);
        svgBytes.appendSafe(
            '<svg width="1600" height="1600" viewBox="0 0 1600 1600" version="1.2" xmlns="http://www.w3.org/2000/svg" style="background-color: #'
        );
        svgBytes.appendSafe(
            abi.encodePacked(_bgColor, ";background-image:url(")
        );
        for (uint256 i = 0; i < NUM_LAYERS - 1; i++) {
            if(!(i % 2 > 0 && _revealLayer[_tokenId][i] == false)){
            // if(_traitDataPointers[i].length > 0){
                thisTraitIndex = HelperLib.parseInt(
                    HelperLib._substring(_hash, (i * 3), (i * 3) + 3)
                );
                svgBytes.appendSafe(
                    abi.encodePacked(
                        "data:",
                        _traitDetails[i][thisTraitIndex].mimetype,
                        ";base64,",
                        Base64.encode(
                            SSTORE2.read(_traitDataPointers[i][thisTraitIndex])
                        ),
                        "),url("
                    )
                );
            }
        }

        thisTraitIndex = HelperLib.parseInt(
            HelperLib._substring(_hash, (NUM_LAYERS * 3) - 3, NUM_LAYERS * 3)
        );

        svgBytes.appendSafe(
            abi.encodePacked(
                "data:",
                _traitDetails[NUM_LAYERS - 1][thisTraitIndex].mimetype,
                ";base64,",
                Base64.encode(
                    SSTORE2.read(
                        _traitDataPointers[NUM_LAYERS - 1][thisTraitIndex]
                    )
                ),
                ');background-repeat:no-repeat;background-size:contain;background-position:center;image-rendering:-webkit-optimize-contrast;-ms-interpolation-mode:nearest-neighbor;image-rendering:-moz-crisp-edges;image-rendering:pixelated;"></svg>'
            )
        );

        return
            string(
                abi.encodePacked(
                    "data:image/svg+xml;base64,",
                    Base64.encode(svgBytes)
                )
            );
    }

    function hashToMetadata(string memory _hash, uint256 _tokenId)
        public
        view
        returns (string memory)
    {
        bytes memory metadataBytes = DynamicBuffer.allocate(1024 * 128);
        metadataBytes.appendSafe("[");

        for (uint256 i = 0; i < NUM_LAYERS; i++) {
            uint256 thisTraitIndex = HelperLib.parseInt(
                HelperLib._substring(_hash, (i * 3), (i * 3) + 3)
            );
            if (bytes(_traitDetails[i][thisTraitIndex].name).length > 2 ) {
                metadataBytes.appendSafe(
                    abi.encodePacked(
                        '{"trait_type":"',
                        LAYER_NAMES[i],
                        '","value":"',
                        _traitDetails[i][thisTraitIndex].name,
                        '"}'
                    )
                );

                if (i == 10 && ((_hideLayer[_tokenId][11] || _revealLayer[_tokenId][11] == false) && _hideLayer[_tokenId][12] && (_hideLayer[_tokenId][13] || _revealLayer[_tokenId][13] == false) && _hideLayer[_tokenId][14])){
                    metadataBytes.appendSafe("]");
                } else if (i == 11 && (_hideLayer[_tokenId][12] && (_hideLayer[_tokenId][13] || _revealLayer[_tokenId][13] == false) && _hideLayer[_tokenId][14])){
                    metadataBytes.appendSafe("]");
                } else if (i == 12 && ((_hideLayer[_tokenId][13] || _revealLayer[_tokenId][13] == false) && _hideLayer[_tokenId][14])){
                    metadataBytes.appendSafe("]");
                } else if (i == 13 && _hideLayer[_tokenId][14]){
                    metadataBytes.appendSafe("]");
                } else if (i == 14) {
                    metadataBytes.appendSafe("]");
                } else {
                    metadataBytes.appendSafe(",");
                }

            } 
        }

        return string(metadataBytes);
    }

    function tokenURI(uint256 _tokenId)
        public
        view
        override
        returns (string memory)
    {
        require(_exists(_tokenId));
        require(_traitDataPointers[0].length > 0);

        string memory tokenHash = tokenIdToHash(_tokenId);

        bytes memory jsonBytes = DynamicBuffer.allocate(1024 * 128);
        if (bytes(idValues[_tokenId].AlphaProfile.userName).length > 0) {
            jsonBytes.appendSafe(
                abi.encodePacked(
                    unicode'{"name":"',
                    idValues[_tokenId].AlphaProfile.userName
                )
            );
        } else {
            jsonBytes.appendSafe(unicode'{"name":"OnChainAlpha');
        }

        jsonBytes.appendSafe(
            abi.encodePacked(
                "#",
                _toString(_tokenId),
                '","description":"',
                contractData.description,
                '",'
            )
        );

        if (bytes(baseURI).length > 0 && _renderTokenOffChain[_tokenId]) {
            jsonBytes.appendSafe(
                abi.encodePacked('"image":"', baseURI, _toString(_tokenId))
            );
        } else {
            string memory svgCode = "";
            if (_phlipImage[_tokenId]) {
                string memory svgString = hashToSVG(tokenHash, _tokenId);
                svgCode = string(
                    abi.encodePacked(
                        "data:image/svg+xml;base64,",
                        Base64.encode(
                            abi.encodePacked(
                                '<svg width="100%" height="100%" viewBox="0 0 1200 1200" style="display: block; transform: scale(-1,1)" version="1.2" xmlns="http://www.w3.org/2000/svg"><image width="1200" height="1200" href="',
                                svgString,
                                '"></image></svg>'
                            )
                        )
                    )
                );
                jsonBytes.appendSafe(
                    abi.encodePacked('"svg_image_data":"', svgString, '",')
                );
            } else {
                string memory svgString = hashToSVG(tokenHash, _tokenId);
                svgCode = string(
                    abi.encodePacked(
                        "data:image/svg+xml;base64,",
                        Base64.encode(
                            abi.encodePacked(
                                '<svg width="100%" height="100%" viewBox="0 0 1200 1200" version="1.2" xmlns="http://www.w3.org/2000/svg"><image width="1200" height="1200" href="',
                                svgString,
                                '"></image></svg>'
                            )
                        )
                    )
                );
                jsonBytes.appendSafe(
                    abi.encodePacked('"svg_image_data":"', svgString, '",')
                );
            }

            jsonBytes.appendSafe(
                abi.encodePacked('"image_data":"', svgCode, '",')
            );
        }

        jsonBytes.appendSafe(
            abi.encodePacked('"attributes":', hashToMetadata(tokenHash, _tokenId), "}")
        );

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

    function contractURI() public view returns (string memory) {
        return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    Base64.encode(
                        abi.encodePacked(
                            '{"name":"',
                            contractData.name,
                            '","description":"',
                            contractData.description,
                            '","image":"',
                            contractData.image,
                            '","banner":"',
                            contractData.banner,
                            '","external_link":"',
                            contractData.website,
                            '","seller_fee_basis_points":',
                            _toString(contractData.royalties),
                            ',"fee_recipient":"',
                            contractData.royaltiesRecipient,
                            '"}'
                        )
                    )
                )
            );
    }

    function addLayer(uint256 _layerIndex, TraitDTO[] memory traits)
        public
        onlyOwner
    {
        require(TIERS[_layerIndex].length == traits.length);
        address[] memory dataPointers = new address[](traits.length);
        for (uint256 i = 0; i < traits.length; i++) {
            dataPointers[i] = SSTORE2.write(traits[i].data);
            _traitDetails[_layerIndex][i] = Trait(
                traits[i].name,
                traits[i].mimetype
            );
        }
        _traitDataPointers[_layerIndex] = dataPointers;
        return;
    }

    function setRenderOfTokenId(uint256 _tokenId, bool _renderOffChain)
        external
    {
        require(msg.sender == ownerOf(_tokenId));
        _renderTokenOffChain[_tokenId] = _renderOffChain;
    }

    function isMintActive() public view returns (bool) {
        return _totalMinted() < maxSupply && isPublicMintActive;
    }

    function togglePublicMint() external onlyOwner {
        isPublicMintActive = !isPublicMintActive;
    }

    //metadata URI
    function setBaseURI(string memory _baseURI) external onlyOwner {
        baseURI = _baseURI;
    }

    function setContractData(ContractData memory _contractData)
        external
        onlyOwner
    {
        contractData = _contractData;
    }

    //address info
    address private helper = 0x95c0a28443F4897Bf718243A539fd018B6C16F63;

    //withdraw to helper address
    function withdraw() external {
        uint256 balance = address(this).balance;
        require(balance > 0);
        Address.sendValue(payable(helper), balance);
    }

    function setBgColor(uint256 _tokenId, string memory _bgColor) public {
        require(ownerOf(_tokenId) == msg.sender);
        bgColor[_tokenId] = _bgColor;

        emit bgChanged(_tokenId, _bgColor);
    }

    function setProfile(
        uint256 _tokenId,
        string memory _username,
        string memory _social,
        string memory _website
    ) public {
        require(ownerOf(_tokenId) == msg.sender);

        idValues[_tokenId].AlphaProfile.userName = _username;
        idValues[_tokenId].AlphaProfile.social = _social;
        idValues[_tokenId].AlphaProfile.website = _website;

        string memory str = string(abi.encodePacked(_username,"#",_toString(_tokenId)));
        idValues[_tokenId].AlphaProfile.profileName = str;

        emit AttributesUpdated(
            _tokenId,
            _username,
            _social,
            _website,
            str
        );
    }

    function setLabelsValues(uint256 _tokenId, uint _labelNum, string memory _label, string memory _value) external {
        require(msg.sender == ownerOf(_tokenId));
        uint count = idValues[_tokenId].labelcount;
        if(_labelNum >= count){
            _labelNum = count;
            idValues[_tokenId].labelcount++;
        }

        idValues[_tokenId].labels[_labelNum] = _label;
        idValues[_tokenId].values[_labelNum] = _value;

        emit LabelsValuesUpdated(_tokenId, _labelNum, _label, _value);
    }

    function toggleLayers(uint256 _tokenId, bool[] memory states) public {
        require(msg.sender == ownerOf(_tokenId));
        for (uint256 i = 0; i < NUM_LAYERS; i++) {
            _hideLayer[_tokenId][i] = states[i];
        }

        emit LayersUpdated(_tokenId, states);
    }

    function revealLayers(uint256 _tokenId, uint _layer) public {
        require(_layer < 15);
        require(msg.sender == ownerOf(_tokenId));

        _revealLayer[_tokenId][_layer] = true;

        emit LayersRevealed(_tokenId, _layer);
    }

    function togglePhlipPFP(uint256 _tokenId, bool _flipped) public {
        require(msg.sender == ownerOf(_tokenId));
        _phlipImage[_tokenId] = _flipped;

        emit ImagePhlipped(_tokenId, _flipped);
    }

}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"_size","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"InvalidCodeAtRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"WriteError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"userName","type":"string"},{"indexed":false,"internalType":"string","name":"social","type":"string"},{"indexed":false,"internalType":"string","name":"website","type":"string"},{"indexed":false,"internalType":"string","name":"profileName","type":"string"}],"name":"AttributesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isPhlipped","type":"bool"}],"name":"ImagePhlipped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"labelId","type":"uint256"},{"indexed":false,"internalType":"string","name":"customLabels","type":"string"},{"indexed":false,"internalType":"string","name":"customValues","type":"string"}],"name":"LabelsValuesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"layerRevealed","type":"uint256"}],"name":"LayersRevealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bool[]","name":"layerIsHidden","type":"bool[]"}],"name":"LayersUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"color","type":"string"}],"name":"bgChanged","type":"event"},{"inputs":[{"internalType":"uint256","name":"_layerIndex","type":"uint256"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"mimetype","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct OnChainAlphaV2.TraitDTO[]","name":"traits","type":"tuple[]"}],"name":"addLayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractData","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"image","type":"string"},{"internalType":"string","name":"banner","type":"string"},{"internalType":"string","name":"website","type":"string"},{"internalType":"uint256","name":"royalties","type":"uint256"},{"internalType":"string","name":"royaltiesRecipient","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"faContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_isOcaClaim","type":"bool"}],"name":"freeClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","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"},{"internalType":"bool","name":"_isOcaClaim","type":"bool"}],"name":"getClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getRebates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"}],"name":"hashToMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"hashToSVG","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ocaContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"publicMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenIdA","type":"uint256"},{"internalType":"uint256","name":"tokenIdB","type":"uint256"}],"name":"reRollDuplicate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebateAmt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_layer","type":"uint256"}],"name":"revealLayers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_bgColor","type":"string"}],"name":"setBgColor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"image","type":"string"},{"internalType":"string","name":"banner","type":"string"},{"internalType":"string","name":"website","type":"string"},{"internalType":"uint256","name":"royalties","type":"uint256"},{"internalType":"string","name":"royaltiesRecipient","type":"string"}],"internalType":"struct OnChainAlphaV2.ContractData","name":"_contractData","type":"tuple"}],"name":"setContractData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_labelNum","type":"uint256"},{"internalType":"string","name":"_label","type":"string"},{"internalType":"string","name":"_value","type":"string"}],"name":"setLabelsValues","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_layerNum","type":"uint256"},{"internalType":"string","name":"_value","type":"string"}],"name":"setLayerNames","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_username","type":"string"},{"internalType":"string","name":"_social","type":"string"},{"internalType":"string","name":"_website","type":"string"}],"name":"setProfile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_renderOffChain","type":"bool"}],"name":"setRenderOfTokenId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool[]","name":"states","type":"bool[]"}],"name":"toggleLayers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_flipped","type":"bool"}],"name":"togglePhlipPFP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenIdToHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60076102608181526614dc1958da585b60ca1b61028052608090815260016102a0818152603160f81b6102c05260a052600d6102e09081526c135bdd5d1a0814dc1958da585b609a1b6103005260c052610320818152603360f81b6103405260e0526008610360908152672432b0b23bb2b0b960c11b61038052610100526103a0818152603560f81b6103c052610120526103e09283526622bcb2bbb2b0b960c91b6104005261014092909252610420828152603760f81b61044052610160526004610460818152634579657360e01b61048052610180526104a0928352603960f81b6104c0526101a09290925260056104e09081526409adeeae8d60db1b610500526101c052600261052081815261313160f01b610540526101e052610560838152634561727360e01b61058052610200526105a090815261313360f01b6105c052610220526106206040526105e091825263426f647960e01b61060052610240919091526200017590602590600f62000f15565b50602680546001600160a01b03199081167389d92a754fd1a672c21b5fc2a347198d1a9456b31790915560278054909116736a04d2443be907dd7e83236398c985688acb796e17905566b1a2bc2ec5000060285566470de4df82000060295560408051606081019091526021808252620072926020830139602a90620001fc9082620010e3565b50602b805460ff191690556040805161012081018252601160e082019081527027b716a1b430b4b71020b6383430902b1960791b6101008301528152815161018081019092526101478083529091602080840192906200714b9083013981526020016040518060800160405280605281526020016200732b6052913981526020016040518060800160405280604e8152602001620072b3604e913981526020016040518060400160405280600e81526020016d68747470733a2f2f6f63612e676760901b81525081526020016101f481526020016040518060600160405280602a815260200162007301602a913990528051602c908190620002ff9082620010e3565b5060208201516001820190620003169082620010e3565b50604082015160028201906200032d9082620010e3565b5060608201516003820190620003449082620010e3565b50608082015160048201906200035b9082620010e3565b5060a0820151600582015560c082015160068201906200037c9082620010e3565b5050603380546001600160a01b0319167395c0a28443f4897bf718243a539fd018b6c16f6317905550348015620003b257600080fd5b506040518060400160405280601181526020017027b716a1b430b4b71020b6383430902b1960791b8152506040518060400160405280600581526020016427a1a0bb1960d91b81525081600290816200040c9190620010e3565b5060036200041b8282620010e3565b5061010660005550506001600855620004343362000ec3565b6040805160e081018252600a8152600f602082015260199181019190915260326060820152604b6080820152606460a0820152611c3960c08201526200047f90601690600762000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e08201526102086102008201526102266102208201526102586102408201526106406102608201526200053f90601790601462000f72565b506040805161020081018252603281526064602082015260969181019190915260c8606082015260fa608082015261012c60a082015261015e60c082015261019060e08201526101c26101008201526101f461012082015261022661014082015261025861016082015261028a6101808201526102bc6101a08201526102ee6101c08201526105dc6101e0820152620005dd90601890601062000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e08201526102086102008201526102266102208201526102586102408201526106406102608201526200069d90601990601462000f72565b506040805161038081018252600a815260146020820152601e918101919091526028606082015260326080820152604660a080830191909152606460c0830152607860e0830152608c61010083015261012082015260b46101408083019190915260c861016083015260dc61018083015260f06101a08301526101046101c08301526101186101e08084019190915261012c61020084015261022083019190915261015461024083015261016861026083015261017c6102808301526101906102a08301526101a46102c08301526101b86102e08301526101cc6103008301526103208201526101f46103408201526103d4610360820152620007a590601a90601c62000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e08201526102086102008201526102266102208201526102586102408201526106406102608201526200086590601b90601462000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e08201526102086102008201526102266102208201526102586102408201526106406102608201526200092590601c90601462000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e0820152610208610200820152610226610220820152610258610240820152610640610260820152620009e590601d90601462000f72565b50604080516102c0810182526014815260286020820152603c918101919091526050606082015260646080820152607860a080830191909152608c60c083015260e082015260b461010082015260c861012082015260f0610140808301919091526101186101608301526101808201526101686101a08201526101906101c08201526101b86101e080830191909152610200820152610208610220820152610230610240820152610258610260820152610280808201526106186102a082015262000ab590601e90601662000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e082015261020861020082015261022661022082015261025861024082015261064061026082015262000b7590601f90601462000f72565b5060408051610200810182526019815260326020820152604b9181019190915260646060820152607d6080820152609660a082015260af60c082015260c860e082015260e161010082015261012c6101208201526101c26101408201526102586101608201526102ee6101808201526103846101a082015261041a6101c0820152610b226101e08201526016600a62000c1392910190601062000f72565b50604080516102808101825260238152604160208201526064918101919091526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e082015261020861020082015261022661022082015261025861024082015261064061026082015262000cd390602190601462000f72565b50604080516101a081018252603281526064602082015260969181019190915260c8606082015261012c608082015261019060a08201526101f460c082015261025860e08201526102bc6101008201526103846101208201526103e86101408201526104b0610160820152610a2861018082015262000d5790602290600d62000f72565b5060408051610280810182526023808252604160208301526064928201929092526082606082015260a06080820181905260be9082015260dc60c082015260fa60e08201526101186101008201526101366101208201526101546101408201526101726101608201526101906101808201526101ae6101a08201526101cc6101c08201526101ea6101e082015261020861020082015261022661022082015261025861024082015261064061026082015262000e169190601462000f72565b506040805161022081018252604b81526064602082015260969181019190915260c8606082015260fa608082015261012c60a082015261015e60c082015261019060e08201526101c26101008201526101f46101208201526102266101408201526102586101608201526102bc6101808201526103206101a08201526103846101c08201526104976101e0820152600061020082015262000ebc90602490601162000f72565b50620011af565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805482825590600052602060002090810192821562000f60579160200282015b8281111562000f60578251829062000f4f9082620010e3565b509160200191906001019062000f36565b5062000f6e92915062000fc4565b5090565b82805482825590600052602060002090810192821562000fb6579160200282015b8281111562000fb6578251829061ffff1690559160200191906001019062000f93565b5062000f6e92915062000fe5565b8082111562000f6e57600062000fdb828262000ffc565b5060010162000fc4565b5b8082111562000f6e576000815560010162000fe6565b5080546200100a9062001054565b6000825580601f106200101b575050565b601f0160209004906000526020600020908101906200103b919062000fe5565b50565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200106957607f821691505b6020821081036200108a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620010de57600081815260208120601f850160051c81016020861015620010b95750805b601f850160051c820191505b81811015620010da57828155600101620010c5565b5050505b505050565b81516001600160401b03811115620010ff57620010ff6200103e565b620011178162001110845462001054565b8462001090565b602080601f8311600181146200114f5760008415620011365750858301515b600019600386901b1c1916600185901b178555620010da565b600085815260208120601f198616915b8281101562001180578886015182559484019460019091019084016200115f565b50858210156200119f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b615f8c80620011bf6000396000f3fe6080604052600436106102395760003560e01c806301ffc9a71461023e57806306fdde0314610273578063081812fc14610295578063095ea7b3146102cd5780630ea71cfc146102ef5780630f3debbe1461030f578063150b7a021461032f57806318160ddd1461036857806319c841fd1461039057806323b872dd146103b05780632437013d146103d05780632d6b6224146103f05780632db115441461040a5780633cca24201461041d5780633ccfd60b146104455780634047638d1461045a57806342842e0e1461046f57806355f804b31461048f57806357380daa146104af5780635b92ac0d146104cf578063621a1f74146104e45780636352211e1461050457806366e33870146105245780636817c76c146105445780636c0360eb1461055a57806370a082311461056f578063715018a61461058f578063716e43d7146105a45780637a75353a146105c45780638a8c0e0c146105e45780638da5cb5b1461060457806395d89b411461061957806397e2155d1461062e578063a22cb4651461064e578063a78c8a7a1461066e578063ac9650d814610684578063ad9adfe3146106b1578063b88d4fde146106d1578063c406ec72146106f1578063c87b56dd14610711578063d5abeb0114610731578063dbe9875f14610747578063e488627314610767578063e8a3d48514610787578063e985e9c51461079c578063ed39d98d146107e5578063f2f0dc0514610805578063f2fde38b1461083b578063fb38d2111461085b578063fd6b3cf51461087b575b600080fd5b34801561024a57600080fd5b5061025e610259366004614756565b61089b565b60405190151581526020015b60405180910390f35b34801561027f57600080fd5b506102886108ed565b60405161026a91906147c3565b3480156102a157600080fd5b506102b56102b03660046147d6565b61097f565b6040516001600160a01b03909116815260200161026a565b3480156102d957600080fd5b506102ed6102e8366004614804565b6109c3565b005b3480156102fb57600080fd5b506102ed61030a36600461492f565b610a63565b34801561031b57600080fd5b506102ed61032a3660046149c0565b610b60565b34801561033b57600080fd5b5061034f61034a366004614aea565b610bf4565b6040516001600160e01b0319909116815260200161026a565b34801561037457600080fd5b506001546000540361010519015b60405190815260200161026a565b34801561039c57600080fd5b506102ed6103ab366004614b98565b610cc9565b3480156103bc57600080fd5b506102ed6103cb366004614bc4565b610d49565b3480156103dc57600080fd5b506102ed6103eb366004614c28565b610edc565b3480156103fc57600080fd5b50602b5461025e9060ff1681565b6103826104183660046147d6565b610f97565b34801561042957600080fd5b50610432611146565b60405161026a9796959493929190614cd0565b34801561045157600080fd5b506102ed6114a4565b34801561046657600080fd5b506102ed6114c8565b34801561047b57600080fd5b506102ed61048a366004614bc4565b6114e4565b34801561049b57600080fd5b506102ed6104aa366004614d59565b611504565b3480156104bb57600080fd5b5061025e6104ca366004614b98565b61151c565b3480156104db57600080fd5b5061025e611553565b3480156104f057600080fd5b506102886104ff3660046147d6565b611574565b34801561051057600080fd5b506102b561051f3660046147d6565b6124b5565b34801561053057600080fd5b5061028861053f366004614d59565b6124c0565b34801561055057600080fd5b5061038260285481565b34801561056657600080fd5b506102886128e2565b34801561057b57600080fd5b5061038261058a366004614d8d565b612970565b34801561059b57600080fd5b506102ed6129be565b3480156105b057600080fd5b506102ed6105bf366004614daa565b6129d2565b3480156105d057600080fd5b506102ed6105df366004614ee8565b612b67565b3480156105f057600080fd5b506103826105ff366004614b98565b612bce565b34801561061057600080fd5b506102b5612de7565b34801561062557600080fd5b50610288612df6565b34801561063a57600080fd5b506102ed610649366004614f2e565b612e05565b34801561065a57600080fd5b506102ed610669366004614f50565b612e90565b34801561067a57600080fd5b5061038260295481565b34801561069057600080fd5b506106a461069f366004614f7c565b612f25565b60405161026a9190614ff0565b3480156106bd57600080fd5b506102886106cc366004615052565b613019565b3480156106dd57600080fd5b506102ed6106ec366004615096565b61335c565b3480156106fd57600080fd5b506026546102b5906001600160a01b031681565b34801561071d57600080fd5b5061028861072c3660046147d6565b6133a0565b34801561073d57600080fd5b50610382611c5e81565b34801561075357600080fd5b506102ed610762366004614b98565b613666565b34801561077357600080fd5b506102ed6107823660046150f5565b6136ac565b34801561079357600080fd5b50610288613796565b3480156107a857600080fd5b5061025e6107b7366004615130565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156107f157600080fd5b506027546102b5906001600160a01b031681565b34801561081157600080fd5b50610382610820366004614d8d565b6001600160a01b031660009081526012602052604090205490565b34801561084757600080fd5b506102ed610856366004614d8d565b6137f4565b34801561086757600080fd5b506102ed610876366004614ee8565b61386f565b34801561088757600080fd5b506102ed610896366004614f2e565b6138a1565b60006301ffc9a760e01b6001600160e01b0319831614806108cc57506380ac58cd60e01b6001600160e01b03198316145b806108e75750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600280546108fc90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461092890615169565b80156109755780601f1061094a57610100808354040283529160200191610975565b820191906000526020600020905b81548152906001019060200180831161095857829003601f168201915b5050505050905090565b600061098a82613901565b6109a7576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b60006109ce826124b5565b9050336001600160a01b03821614610a07576109ea81336107b7565b610a07576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b33610a6d856124b5565b6001600160a01b031614610a8057600080fd5b6000848152601060205260409020610a9884826151e3565b506000848152601060205260409020600101610ab483826151e3565b506000848152601060205260409020600201610ad082826151e3565b50600083610add86613937565b604051602001610aee9291906152a2565b60408051601f198184030181529181526000878152601060205220909150600301610b1982826151e3565b507fb8981c9fcfec39b56f5caf88846acca9b61e75401e68da165ef541e81991d8b68585858585604051610b519594939291906152de565b60405180910390a15050505050565b610b68613986565b80518190602c908190610b7b90826151e3565b5060208201516001820190610b9090826151e3565b5060408201516002820190610ba590826151e3565b5060608201516003820190610bba90826151e3565b5060808201516004820190610bcf90826151e3565b5060a0820151600582015560c08201516006820190610bee90826151e3565b50505050565b6026546000906001600160a01b0316331480610c8557506026546040516331a9108f60e11b8152600481018690526001600160a01b03878116921690636352211e90602401602060405180830381865afa158015610c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7a919061533d565b6001600160a01b0316145b610c8e57600080fd5b6001600160a01b0385166000908152601260205260408120805491610cb283615370565b90915550630a85bd0160e11b979650505050505050565b610cd2826124b5565b6001600160a01b0316336001600160a01b031614610cef57600080fd5b6000828152600f6020908152604091829020805460ff19168415159081179091558251858152918201527fafec4b400a28d8bdfacc6b65e3c25cc07399c2c20eeb817256f6413c7e84687c91015b60405180910390a15050565b6000610d54826139e5565b9050836001600160a01b0316816001600160a01b031614610d875760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610dd457610db786336107b7565b610dd457604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610dfb57604051633a954ecd60e21b815260040160405180910390fd5b8015610e0657600082555b6001600160a01b03808716600090815260056020526040808220805460001901905591871681522080546001019055610e4f85610e44888287613a5c565b600160e11b17613a7f565b600085815260046020526040812091909155600160e11b84169003610ea457600184016000818152600460205260408120549003610ea2576000548114610ea25760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b0316600080516020615f1783398151915260405160405180910390a45b505050505050565b610ee5826124b5565b6001600160a01b0316336001600160a01b031614610f0257600080fd5b60005b600f811015610f6557818181518110610f2057610f20615389565b6020908102919091018101516000858152600d8352604080822085835290935291909120805460ff191691151591909117905580610f5d81615370565b915050610f05565b507f6feffc52172e0d2f7273caf08349169b161ca5e8e463fa548b2dc2258c54cce38282604051610d3d92919061539f565b6000610fa1613a94565b610fa9611553565b610fb257600080fd5b6000610fbc613aed565b33600090815260156020526040902054909150606490610fdd9085906153ef565b1115610fe857600080fd5b60148311158015610ff95750600083115b61100257600080fd5b611c5e61100f84836153ef565b111561101a57600080fd5b33321461102657600080fd5b3360009081526012602052604081205480156110ec5784811161108d57806029546110519190615402565b915081602854866110629190615402565b61106c9190615419565b34101561107857600080fd5b33600090815260126020526040812055611105565b8460295461109b9190615402565b915081602854866110ac9190615402565b6110b69190615419565b3410156110c257600080fd5b33600090815260126020526040812080548792906110e1908490615419565b909155506111059050565b6028546110f99086615402565b34101561110557600080fd5b33600090815260156020526040812080548792906111249084906153ef565b9091555061113490503386613af8565b5050600160085592915050565b919050565b602c8054819061115590615169565b80601f016020809104026020016040519081016040528092919081815260200182805461118190615169565b80156111ce5780601f106111a3576101008083540402835291602001916111ce565b820191906000526020600020905b8154815290600101906020018083116111b157829003601f168201915b5050505050908060010180546111e390615169565b80601f016020809104026020016040519081016040528092919081815260200182805461120f90615169565b801561125c5780601f106112315761010080835404028352916020019161125c565b820191906000526020600020905b81548152906001019060200180831161123f57829003601f168201915b50505050509080600201805461127190615169565b80601f016020809104026020016040519081016040528092919081815260200182805461129d90615169565b80156112ea5780601f106112bf576101008083540402835291602001916112ea565b820191906000526020600020905b8154815290600101906020018083116112cd57829003601f168201915b5050505050908060030180546112ff90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461132b90615169565b80156113785780601f1061134d57610100808354040283529160200191611378565b820191906000526020600020905b81548152906001019060200180831161135b57829003601f168201915b50505050509080600401805461138d90615169565b80601f01602080910402602001604051908101604052809291908181526020018280546113b990615169565b80156114065780601f106113db57610100808354040283529160200191611406565b820191906000526020600020905b8154815290600101906020018083116113e957829003601f168201915b50505050509080600501549080600601805461142190615169565b80601f016020809104026020016040519081016040528092919081815260200182805461144d90615169565b801561149a5780601f1061146f5761010080835404028352916020019161149a565b820191906000526020600020905b81548152906001019060200180831161147d57829003601f168201915b5050505050905087565b47806114af57600080fd5b6033546114c5906001600160a01b031682613bd5565b50565b6114d0613986565b602b805460ff19811660ff90911615179055565b6114ff8383836040518060200160405280600081525061335c565b505050565b61150c613986565b602a61151882826151e3565b5050565b6000811561153c575060008281526014602052604090205460ff166108e7565b505060009081526013602052604090205460ff1690565b6000611c5e611560613aed565b10801561156f5750602b5460ff165b905090565b606061157f82613901565b61158857600080fd5b600061159e611599600f6004615402565b613ceb565b60408051600f808252610200820190925291925060009190602082016101e08036833701905050905060005b600f8110156123845760008282815181106115e7576115e7615389565b6020026020010151905060006002836116009190615442565b11801561162757506000868152600e6020908152604080832085845290915290205460ff16155b15611670576001601683600f811061164157611641615389565b015461164d9190615419565b83838151811061165f5761165f615389565b602002602001018181525050612371565b600061167b87613d08565b6060015162ffffff1690506000611c5e828961169787826153ef565b60408051602081019490945283019190915260608201526080016040516020818303038152906040528051906020012060001c6116d49190615442565b90506116e08185613d21565b9250828585815181106116f5576116f5615389565b60200260200101818152505060006001601686600f811061171857611718615389565b01546117249190615419565b60008a8152600d6020908152604080832089845290915290205490915060ff161515600103611f545784600a148015611776575085858151811061176a5761176a615389565b6020026020010151600a145b156117e8578086868151811061178e5761178e615389565b60209081029190910181019190915260008a8152600d82526040808220600283529092529081205460ff16151590036117e357600f866002815181106117d6576117d6615389565b6020026020010181815250505b61236d565b84600e148015611811575085858151811061180557611805615389565b60200260200101516000145b15611871578086868151811061182957611829615389565b60209081029190910181019190915260008a8152600d82526040808220600883529092529081205460ff16151590036117e3576005866008815181106117d6576117d6615389565b84600e14801561189a575085858151811061188e5761188e615389565b60200260200101516002145b1561198a57808686815181106118b2576118b2615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff161515900361190757600186600a815181106118fa576118fa615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff161515900361194f5760008660088151811061194257611942615389565b6020026020010181815250505b6000898152600d602090815260408083206004845290915281205460ff16151590036117e3576001866004815181106117d6576117d6615389565b84600e1480156119b357508585815181106119a7576119a7615389565b60200260200101516004145b15611a5b57808686815181106119cb576119cb615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611a2057600886600a81518110611a1357611a13615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576009866008815181106117d6576117d6615389565b84600e148015611a845750858581518110611a7857611a78615389565b60200260200101516005145b15611b2c5780868681518110611a9c57611a9c615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611af157600686600a81518110611ae457611ae4615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576007866008815181106117d6576117d6615389565b84600e148015611b555750858581518110611b4957611b49615389565b60200260200101516006145b15611bfd5780868681518110611b6d57611b6d615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611bc257600786600a81518110611bb557611bb5615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576008866008815181106117d6576117d6615389565b84600e148015611c265750858581518110611c1a57611c1a615389565b60200260200101516007145b15611cce5780868681518110611c3e57611c3e615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611c9357600286600a81518110611c8657611c86615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576004866008815181106117d6576117d6615389565b84600e148015611cf75750858581518110611ceb57611ceb615389565b60200260200101516009145b15611d9f5780868681518110611d0f57611d0f615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611d6457600586600a81518110611d5757611d57615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576001866008815181106117d6576117d6615389565b84600e148015611dc85750858581518110611dbc57611dbc615389565b6020026020010151600a145b15611e705780868681518110611de057611de0615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611e3557600486600a81518110611e2857611e28615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576002866008815181106117d6576117d6615389565b84600e148015611e995750858581518110611e8d57611e8d615389565b6020026020010151600b145b15611f415780868681518110611eb157611eb1615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611f0657600386600a81518110611ef957611ef9615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576003866008815181106117d6576117d6615389565b808686815181106117d6576117d6615389565b84600a148015611f7e575085600a81518110611f7257611f72615389565b6020026020010151600a145b15611fcb576000898152600d602090815260408083206002845290915281205460ff1615159003611fcb57600f86600281518110611fbe57611fbe615389565b6020026020010181815250505b84600e0361236d5785600e81518110611fe657611fe6615389565b6020026020010151600003612030576000898152600d602090815260408083206008845290915281205460ff16151590036117e3576005866008815181106117d6576117d6615389565b85600e8151811061204357612043615389565b602002602001015160020361208d576000898152600d60209081526040808320600a845290915281205460ff161515900361190757600186600a815181106118fa576118fa615389565b85600e815181106120a0576120a0615389565b60200260200101516004036120ea576000898152600d60209081526040808320600a845290915281205460ff1615159003611a2057600886600a81518110611a1357611a13615389565b85600e815181106120fd576120fd615389565b6020026020010151600503612147576000898152600d60209081526040808320600a845290915281205460ff1615159003611af157600686600a81518110611ae457611ae4615389565b85600e8151811061215a5761215a615389565b60200260200101516006036121a4576000898152600d60209081526040808320600a845290915281205460ff1615159003611bc257600786600a81518110611bb557611bb5615389565b85600e815181106121b7576121b7615389565b6020026020010151600703612201576000898152600d60209081526040808320600a845290915281205460ff1615159003611c9357600286600a81518110611c8657611c86615389565b85600e8151811061221457612214615389565b602002602001015160090361225e576000898152600d60209081526040808320600a845290915281205460ff1615159003611d6457600586600a81518110611d5757611d57615389565b85600e8151811061227157612271615389565b6020026020010151600a036122bb576000898152600d60209081526040808320600a845290915281205460ff1615159003611e3557600486600a81518110611e2857611e28615389565b85600e815181106122ce576122ce615389565b6020026020010151600b0361236d576000898152600d60209081526040808320600a845290915281205460ff161515900361232557600386600a8151811061231857612318615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff161515900361236d5760038660088151811061236057612360615389565b6020026020010181815250505b5050505b508061237c81615370565b9150506115ca565b5060005b81518110156124ac57600a8282815181106123a5576123a5615389565b602002602001015110156123dc57604080518082019091526002815261030360f41b60208201526123d7908490613de7565b612421565b60648282815181106123f0576123f0615389565b60200260200101511015612421576040805180820190915260018152600360fc1b6020820152612421908490613de7565b6103e782828151811061243657612436615389565b6020026020010151111561246e5760408051808201909152600381526239393960e81b6020820152612469908490613de7565b61249a565b61249a61249383838151811061248657612486615389565b6020026020010151613937565b8490613de7565b806124a481615370565b915050612388565b50909392505050565b60006108e7826139e5565b606060006124d062020000613ceb565b90506124fe604051806040016040528060018152602001605b60f81b81525082613de790919063ffffffff16565b600b600081815260209190915260037fe8056e2ed8943b7f61a5f0dc88c79a5a6cec2bb36a7bd11ce130f2961c6320b98261254461253f8860216024613e6c565b613f38565b60ff168152602001908152602001600020600001805461256390615169565b600c6000908152600b60205292119250600390507f765e72d9703c9804ad76c7d0af52f5313041ea56bb31a328e17fea205151b5ea826125a961253f8960246027613e6c565b60ff16815260200190815260200160002060000180546125c890615169565b600d6000908152600b60205292119250600390507f0a2216aa9bbf8764f3bfb9fafcef7f625aba82383c1a9d14d721124ff30595818261260e61253f8a6027602a613e6c565b60ff168152602001908152602001600020600001805461262d90615169565b600e6000908152600b60205292119250600390507f7ae97ffc8b2fe6ed730ad82f8c44cc0285c7a97ac189e2d88c56200fe9a501ab8261267361253f8b602a602d613e6c565b60ff168152602001908152602001600020600001805461269290615169565b905010905060005b600f8110156128d65760006126d261253f8a6126b7856003615402565b6126c2866003615402565b6126cd9060036153ef565b613e6c565b6000838152600b6020908152604080832060ff94909416808452939091529020805491925060029161270390615169565b905011156128c3576127696025838154811061272157612721615389565b60009182526020808320868452600b82526040808520878652835293849020935161275294939091019291016154c9565b60408051601f198184030181529190528890613de7565b81600a148015612790575085801561277e5750845b80156127875750835b80156127905750825b156127bd576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b6128c3565b81600b1480156127db57508480156127d25750835b80156127db5750825b15612803576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600c14801561281857508380156128185750825b15612840576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600d14801561284d5750825b15612875576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600e036128a0576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b6040805180820190915260018152600b60fa1b60208201526128c3908890613de7565b50806128ce81615370565b91505061269a565b50939695505050505050565b602a80546128ef90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461291b90615169565b80156129685780601f1061293d57610100808354040283529160200191612968565b820191906000526020600020905b81548152906001019060200180831161294b57829003601f168201915b505050505081565b60006001600160a01b038216612999576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6129c6613986565b6129d06000613ff6565b565b6129da613986565b8051601683600f81106129ef576129ef615389565b0154146129fb57600080fd5b600081516001600160401b03811115612a1657612a16614830565b604051908082528060200260200182016040528015612a3f578160200160208202803683370190505b50905060005b8251811015612b4757612a74838281518110612a6357612a63615389565b602002602001015160400151614048565b828281518110612a8657612a86615389565b60200260200101906001600160a01b031690816001600160a01b0316815250506040518060400160405280848381518110612ac357612ac3615389565b6020026020010151600001518152602001848381518110612ae657612ae6615389565b6020908102919091018101518101519091526000868152600b825260408082208583529092522081518190612b1b90826151e3565b5060208201516001820190612b3090826151e3565b509050508080612b3f90615370565b915050612a45565b506000838152600a602090815260409091208251610bee9284019061469f565b33612b71836124b5565b6001600160a01b031614612b8457600080fd5b6000828152601160205260409020612b9c82826151e3565b507f81b1bf653f53dc046b08a20dc605eed2195235db792f342a6a722e1b5480f9548282604051610d3d92919061551f565b6000612bd8613a94565b612be0611553565b612be957600080fd5b6000612bf3613aed565b90508215612ce15760008481526014602052604090205460ff1615612c1757600080fd5b6027546040516331a9108f60e11b8152600481018690526001600160a01b0390911690636352211e90602401602060405180830381865afa158015612c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c84919061533d565b6001600160a01b0316336001600160a01b031614612ca157600080fd5b611c5e612caf8260016153ef565b1115612cba57600080fd5b6000848152601460205260409020805460ff19166001908117909155612ce1903390613af8565b82612ddb576103e8841115612cf557600080fd5b60008481526013602052604090205460ff1615612d1157600080fd5b6026546040516331a9108f60e11b8152600481018690526001600160a01b0390911690636352211e90602401602060405180830381865afa158015612d5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d7e919061533d565b6001600160a01b0316336001600160a01b031614612d9b57600080fd5b611c5e612da98260016153ef565b1115612db457600080fd5b6000848152601360205260409020805460ff19166001908117909155612ddb903390613af8565b90506108e76001600855565b6009546001600160a01b031690565b6060600380546108fc90615169565b600f8110612e1257600080fd5b612e1b826124b5565b6001600160a01b0316336001600160a01b031614612e3857600080fd5b6000828152600e60209081526040808320848452825291829020805460ff1916600117905581518481529081018390527f4c652a0da724e2e441d4269d925eb66c004118aea8f9d00f7cfd6c906f908d229101610d3d565b336001600160a01b03831603612eb95760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6060816001600160401b03811115612f3f57612f3f614830565b604051908082528060200260200182016040528015612f7257816020015b6060815260200190600190039081612f5d5790505b50905060005b8281101561301257612fe230858584818110612f9657612f96615389565b9050602002810190612fa89190615538565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506140ad92505050565b828281518110612ff457612ff4615389565b6020026020010181905250808061300a90615370565b915050612f78565b5092915050565b60606000806040518060400160405280600681526020016531433135333160d01b8152509050600060116000868152602001908152602001600020805461305f90615169565b90501115613101576000848152601160205260409020805461308090615169565b80601f01602080910402602001604051908101604052809291908181526020018280546130ac90615169565b80156130f95780601f106130ce576101008083540402835291602001916130f9565b820191906000526020600020905b8154815290600101906020018083116130dc57829003601f168201915b505050505090505b600061310f62020000613ceb565b90506131346040518060c0016040528060838152602001615e2d608391398290613de7565b61315f826040516020016131489190615585565b60408051601f198184030181529190528290613de7565b60005b61316e6001600f615419565b81101561327c576000613182600283615442565b1180156131a957506000868152600e6020908152604080832084845290915290205460ff16155b61326a576131ca61253f886131bf846003615402565b6126c2856003615402565b60ff16935061326a600b6000838152602001908152602001600020600086815260200190815260200160002060010161324261323d600a6000868152602001908152602001600020888154811061322357613223615389565b6000918252602090912001546001600160a01b03166140d2565b6140e2565b6040516020016132539291906155bf565b60408051601f198184030181529190528390613de7565b8061327481615370565b915050613162565b506132a761253f876003613291600f82615402565b61329b9190615419565b6126cd600f6003615402565b60ff169250613329600b60006132bf6001600f615419565b8152602001908152602001600020600085815260200190815260200160002060010161331861323d600a60006001600f6132f99190615419565b8152602001908152602001600020878154811061322357613223615389565b604051602001613148929190615619565b613332816140e2565b604051602001613342919061577d565b604051602081830303815290604052935050505092915050565b613367848484610d49565b6001600160a01b0383163b15610bee5761338384848484614234565b610bee576040516368d2bf6b60e11b815260040160405180910390fd5b60606133ab82613901565b6133b457600080fd5b60008052600a6020527f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e3546133e857600080fd5b60006133f383611574565b9050600061340362020000613ceb565b60008581526010602052604081208054929350909161342190615169565b9050111561345257600084815260106020908152604091829020915161344d92613148929091016157bf565b613489565b6040805180820190915260158152747b226e616d65223a224f6e436861696e416c70686160581b6020820152613489908290613de7565b6134a861349585613937565b6040516131489190602d906020016157dd565b6000602a80546134b790615169565b90501180156134d457506000848152600c602052604090205460ff165b156134fd576134f8602a6134e786613937565b604051602001613148929190615838565b613619565b60408051602080820183526000808352878152600f909152919091205460ff16156135aa57600061352e8487613019565b905061355881604051602001613544919061586f565b6040516020818303038152906040526140e2565b604051602001613568919061577d565b60405160208183030381529060405291506135a48160405160200161358d919061597a565b60408051601f198184030181529190528490613de7565b50613603565b60006135b68487613019565b90506135cc8160405160200161354491906159c1565b6040516020016135dc919061577d565b60405160208183030381529060405291506136018160405160200161358d919061597a565b505b613617816040516020016132539190615a9a565b505b613635613625836124c0565b6040516020016131489190615add565b61363e816140e2565b60405160200161364e9190615b1e565b60405160208183030381529060405292505050919050565b61366f826124b5565b6001600160a01b0316336001600160a01b03161461368c57600080fd5b6000918252600c6020526040909120805460ff1916911515919091179055565b6136b5846124b5565b6001600160a01b0316336001600160a01b0316146136d257600080fd5b600084815260106020526040902060060154808410613713576000858152601060205260408120600601805492955085929161370d83615370565b91905055505b6000858152601060209081526040808320878452600401909152902061373984826151e3565b506000858152601060209081526040808320878452600501909152902061376083826151e3565b507fca3ccd3f553ac426b514af81e9a960872e7c86a7a0260f8e8b244ce916776e7285858585604051610b519493929190615b63565b6031546060906137d090602c90602d90602e90602f906030906137b890613937565b60405161354496959493929190603290602001615b9f565b6040516020016137e09190615b1e565b604051602081830303815290604052905090565b6137fc613986565b6001600160a01b0381166138665760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6114c581613ff6565b613877613986565b806025838154811061388b5761388b615389565b9060005260206000200190816114ff91906151e3565b6138a9613986565b60008183116138b857816138ba565b825b90506138c58161431f565b6138d86138d38260016153ef565b613901565b156138f0576138f06138eb8260016153ef565b61431f565b6114ff816138fc61434f565b6143bb565b60008161010611158015613916575060005482105b80156108e7575050600090815260046020526040902054600160e01b161590565b604080516080810191829052607f0190826030600a8206018353600a90045b801561397457600183039250600a81066030018353600a9004613956565b50819003601f19909101908152919050565b3361398f612de7565b6001600160a01b0316146129d05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161385d565b6000818061010611613a4357600054811015613a435760008181526004602052604081205490600160e01b82169003613a41575b80600003613a3a575060001901600081815260046020526040902054613a19565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600060e882811c90613a6f868684614410565b62ffffff16901b95945050505050565b4260a01b176001600160a01b03919091161790565b600260085403613ae65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161385d565b6002600855565b600054610105190190565b6000546001600160a01b038316613b2157604051622e076360e81b815260040160405180910390fd5b81600003613b425760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040812080546001600160401b018502019055613b87908490613b7a908281613a5c565b6001851460e11b17613a7f565b600082815260046020526040902055808281015b6040516001830192906001600160a01b03871690600090600080516020615f17833981519152908290a4808210613b9b5760005550505050565b80471015613c255760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161385d565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c72576040519150601f19603f3d011682016040523d82523d6000602084013e613c77565b606091505b50509050806114ff5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c20726044820152791958da5c1a595b9d081b585e481a185d99481c995d995c9d195960321b606482015260840161385d565b604080518281016060018252910181526000602090910190815290565b613d10614704565b6108e7613d1c836139e5565b61442f565b600080805b601684600f8110613d3957613d39615389565b0154811015613dbd576000601685600f8110613d5757613d57615389565b018281548110613d6957613d69615389565b90600052602060002001549050828610158015613d8e5750613d8b81846153ef565b86105b15613d9d575091506108e79050565b613da781846153ef565b9250508080613db590615370565b915050613d26565b506001601684600f8110613dd357613dd3615389565b0154613ddf9190615419565b949350505050565b601f1982015182518251603f19909201918290613e0490836153ef565b1115613e625760405162461bcd60e51b815260206004820152602760248201527f44796e616d69634275666665723a20417070656e64696e67206f7574206f66206044820152663137bab732399760c91b606482015260840161385d565b610bee8484614472565b6060836000613e7b8585615419565b6001600160401b03811115613e9257613e92614830565b6040519080825280601f01601f191660200182016040528015613ebc576020820181803683370190505b509050845b84811015613f2e57828181518110613edb57613edb615389565b01602001516001600160f81b03191682613ef58884615419565b81518110613f0557613f05615389565b60200101906001600160f81b031916908160001a90535080613f2681615370565b915050613ec1565b5095945050505050565b60008181805b82518160ff161015613fee576030838260ff1681518110613f6157613f61615389565b016020015160f81c10801590613f9457506039838260ff1681518110613f8957613f89615389565b016020015160f81c11155b15613fdc57613fa4600a83615cc8565b91506030838260ff1681518110613fbd57613fbd615389565b0160200151613fcf919060f81c615ce4565b613fd99083615cfd565b91505b80613fe681615d16565b915050613f3e565b509392505050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806140738360405160200161405f9190615d35565b6040516020818303038152906040526144a8565b90508051602082016000f091506001600160a01b0382166140a75760405163046a55db60e11b815260040160405180910390fd5b50919050565b6060613a3a8383604051806060016040528060278152602001615ef0602791396144d4565b60606108e782600160001961454c565b6060815160000361410157505060408051602081019091526000815290565b6000604051806060016040528060408152602001615eb0604091399050600060038451600261413091906153ef565b61413a9190615d5b565b614145906004615402565b6001600160401b0381111561415c5761415c614830565b6040519080825280601f01601f191660200182016040528015614186576020820181803683370190505b509050600182016020820185865187015b808210156141f2576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250614197565b505060038651066001811461420e576002811461422157614229565b603d6001830353603d6002830353614229565b603d60018303535b509195945050505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290614269903390899088908890600401615d6f565b6020604051808303816000875af19250505080156142a4575060408051601f3d908101601f191682019092526142a191810190615da2565b60015b614302573d8080156142d2576040519150601f19603f3d011682016040523d82523d6000602084013e6142d7565b606091505b5080516000036142fa576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b60008181526004602052604081205490036114c55761433d816139e5565b60008281526004602052604090205550565b6000803a434244614361600184615419565b6040805160208101969096528501939093526060808501929092526080840152904060a083015233901b6001600160601b03191660c082015260d40160408051601f19818403018152919052805160209091012092915050565b600082815260046020526040812054908190036143ea5760405162d5815360e01b815260040160405180910390fd5b6000928352600460205260409092206001600160e81b039290921660e89190911b179055565b60006001600160a01b038416156144275781613ddf565b613ddf61434f565b614437614704565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b8051602082019150808201602084510184015b8184101561449d578351815260209384019301614485565b505082510190915250565b60608151826040516020016144be929190615dbf565b6040516020818303038152906040529050919050565b6060600080856001600160a01b0316856040516144f19190615e10565b600060405180830381855af49150503d806000811461452c576040519150601f19603f3d011682016040523d82523d6000602084013e614531565b606091505b509150915061454286838387614601565b9695505050505050565b6060833b600081900361456f575050604080516020810190915260008152613a3a565b8084111561458d575050604080516020810190915260008152613a3a565b838310156145bf5760405163162544fd60e11b815260048101829052602481018590526044810184905260640161385d565b83830384820360008282106145d457826145d6565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b60608315614670578251600003614669576001600160a01b0385163b6146695760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161385d565b5081613ddf565b613ddf83838151156146855781518083602001fd5b8060405162461bcd60e51b815260040161385d91906147c3565b8280548282559060005260206000209081019282156146f4579160200282015b828111156146f457825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906146bf565b5061470092915061472b565b5090565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5b80821115614700576000815560010161472c565b6001600160e01b0319811681146114c557600080fd5b60006020828403121561476857600080fd5b8135613a3a81614740565b60005b8381101561478e578181015183820152602001614776565b50506000910152565b600081518084526147af816020860160208601614773565b601f01601f19169290920160200192915050565b602081526000613a3a6020830184614797565b6000602082840312156147e857600080fd5b5035919050565b6001600160a01b03811681146114c557600080fd5b6000806040838503121561481757600080fd5b8235614822816147ef565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171561486857614868614830565b60405290565b604051606081016001600160401b038111828210171561486857614868614830565b604051601f8201601f191681016001600160401b03811182821017156148b8576148b8614830565b604052919050565b600082601f8301126148d157600080fd5b81356001600160401b038111156148ea576148ea614830565b6148fd601f8201601f1916602001614890565b81815284602083860101111561491257600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561494557600080fd5b8435935060208501356001600160401b038082111561496357600080fd5b61496f888389016148c0565b9450604087013591508082111561498557600080fd5b614991888389016148c0565b935060608701359150808211156149a757600080fd5b506149b4878288016148c0565b91505092959194509250565b6000602082840312156149d257600080fd5b81356001600160401b03808211156149e957600080fd5b9083019060e082860312156149fd57600080fd5b614a05614846565b823582811115614a1457600080fd5b614a20878286016148c0565b825250602083013582811115614a3557600080fd5b614a41878286016148c0565b602083015250604083013582811115614a5957600080fd5b614a65878286016148c0565b604083015250606083013582811115614a7d57600080fd5b614a89878286016148c0565b606083015250608083013582811115614aa157600080fd5b614aad878286016148c0565b60808301525060a083013560a082015260c083013582811115614acf57600080fd5b614adb878286016148c0565b60c08301525095945050505050565b600080600080600060808688031215614b0257600080fd5b8535614b0d816147ef565b94506020860135614b1d816147ef565b93506040860135925060608601356001600160401b0380821115614b4057600080fd5b818801915088601f830112614b5457600080fd5b813581811115614b6357600080fd5b896020828501011115614b7557600080fd5b9699959850939650602001949392505050565b8035801515811461114157600080fd5b60008060408385031215614bab57600080fd5b82359150614bbb60208401614b88565b90509250929050565b600080600060608486031215614bd957600080fd5b8335614be4816147ef565b92506020840135614bf4816147ef565b929592945050506040919091013590565b60006001600160401b03821115614c1e57614c1e614830565b5060051b60200190565b60008060408385031215614c3b57600080fd5b823591506020808401356001600160401b03811115614c5957600080fd5b8401601f81018613614c6a57600080fd5b8035614c7d614c7882614c05565b614890565b81815260059190911b82018301908381019088831115614c9c57600080fd5b928401925b82841015614cc157614cb284614b88565b82529284019290840190614ca1565b80955050505050509250929050565b60e081526000614ce360e083018a614797565b8281036020840152614cf5818a614797565b90508281036040840152614d098189614797565b90508281036060840152614d1d8188614797565b90508281036080840152614d318187614797565b90508460a084015282810360c0840152614d4b8185614797565b9a9950505050505050505050565b600060208284031215614d6b57600080fd5b81356001600160401b03811115614d8157600080fd5b613ddf848285016148c0565b600060208284031215614d9f57600080fd5b8135613a3a816147ef565b60008060408385031215614dbd57600080fd5b823591506020808401356001600160401b0380821115614ddc57600080fd5b818601915086601f830112614df057600080fd5b8135614dfe614c7882614c05565b81815260059190911b83018401908481019089831115614e1d57600080fd5b8585015b83811015614ed757803585811115614e395760008081fd5b86016060818d03601f1901811315614e515760008081fd5b614e5961486e565b8983013588811115614e6b5760008081fd5b614e798f8c838701016148c0565b825250604083013588811115614e8f5760008081fd5b614e9d8f8c838701016148c0565b828c015250908201359087821115614eb55760008081fd5b614ec38e8b848601016148c0565b604082015285525050918601918601614e21565b508096505050505050509250929050565b60008060408385031215614efb57600080fd5b8235915060208301356001600160401b03811115614f1857600080fd5b614f24858286016148c0565b9150509250929050565b60008060408385031215614f4157600080fd5b50508035926020909101359150565b60008060408385031215614f6357600080fd5b8235614f6e816147ef565b9150614bbb60208401614b88565b60008060208385031215614f8f57600080fd5b82356001600160401b0380821115614fa657600080fd5b818501915085601f830112614fba57600080fd5b813581811115614fc957600080fd5b8660208260051b8501011115614fde57600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561504557603f19888603018452615033858351614797565b94509285019290850190600101615017565b5092979650505050505050565b6000806040838503121561506557600080fd5b82356001600160401b0381111561507b57600080fd5b615087858286016148c0565b95602094909401359450505050565b600080600080608085870312156150ac57600080fd5b84356150b7816147ef565b935060208501356150c7816147ef565b92506040850135915060608501356001600160401b038111156150e957600080fd5b6149b4878288016148c0565b6000806000806080858703121561510b57600080fd5b843593506020850135925060408501356001600160401b038082111561498557600080fd5b6000806040838503121561514357600080fd5b823561514e816147ef565b9150602083013561515e816147ef565b809150509250929050565b600181811c9082168061517d57607f821691505b6020821081036140a757634e487b7160e01b600052602260045260246000fd5b601f8211156114ff57600081815260208120601f850160051c810160208610156151c45750805b601f850160051c820191505b81811015610ed4578281556001016151d0565b81516001600160401b038111156151fc576151fc614830565b6152108161520a8454615169565b8461519d565b602080601f831160018114615245576000841561522d5750858301515b600019600386901b1c1916600185901b178555610ed4565b600085815260208120601f198616915b8281101561527457888601518255948401946001909101908401615255565b50858210156152925787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600083516152b4818460208801614773565b602360f81b90830190815283516152d2816001840160208801614773565b01600101949350505050565b85815260a0602082015260006152f760a0830187614797565b82810360408401526153098187614797565b9050828103606084015261531d8186614797565b905082810360808401526153318185614797565b98975050505050505050565b60006020828403121561534f57600080fd5b8151613a3a816147ef565b634e487b7160e01b600052601160045260246000fd5b6000600182016153825761538261535a565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156153e25784511515835293830193918301916001016153c4565b5090979650505050505050565b808201808211156108e7576108e761535a565b80820281158282048414176108e7576108e761535a565b818103818111156108e7576108e761535a565b634e487b7160e01b600052601260045260246000fd5b6000826154515761545161542c565b500690565b6000815461546381615169565b6001828116801561547b5760018114615490576154bf565b60ff19841687528215158302870194506154bf565b8560005260208060002060005b858110156154b65781548a82015290840190820161549d565b50505082870194505b5050505092915050565b6e3d913a3930b4ba2fba3cb832911d1160891b815260006154ed600f830185615456565b6a1116113b30b63ab2911d1160a91b815261550b600b820185615456565b61227d60f01b815260020195945050505050565b828152604060208201526000613ddf6040830184614797565b6000808335601e1984360301811261554f57600080fd5b8301803591506001600160401b0382111561556957600080fd5b60200191503681900382131561557e57600080fd5b9250929050565b60008251615597818460208701614773565b75076c4c2c6d6cee4deeadcc85ad2dac2ceca74eae4d8560531b920191825250601601919050565b643230ba309d60d91b815260006155d96005830185615456565b670ed8985cd94d8d0b60c21b815283516155fa816008840160208801614773565b6505258eae4d8560d31b60089290910191820152600e01949350505050565b643230ba309d60d91b815260006156336005830185615456565b670ed8985cd94d8d0b60c21b81528351615654816008840160208801614773565b7f293b6261636b67726f756e642d7265706561743a6e6f2d7265706561743b6261600892909101918201527f636b67726f756e642d73697a653a636f6e7461696e3b6261636b67726f756e6460288201527f2d706f736974696f6e3a63656e7465723b696d6167652d72656e646572696e6760488201527f3a2d7765626b69742d6f7074696d697a652d636f6e74726173743b2d6d732d6960688201527f6e746572706f6c6174696f6e2d6d6f64653a6e6561726573742d6e656967686260888201527f6f723b696d6167652d72656e646572696e673a2d6d6f7a2d63726973702d656460a88201527f6765733b696d6167652d72656e646572696e673a706978656c617465643b223e60c8820152651e17b9bb339f60d11b60e882015260ee01949350505050565b7919185d184e9a5b5859d94bdcdd99cade1b5b0ed8985cd94d8d0b60321b8152600082516157b281601a850160208701614773565b91909101601a0192915050565b683d913730b6b2911d1160b91b81526000613a3a6009830184615456565b602360f81b8152600083516157f9816001850160208801614773565b701116113232b9b1b934b83a34b7b7111d1160791b6001918401918201526158246012820185615456565b61088b60f21b815260020195945050505050565b681134b6b0b3b2911d1160b91b815260006158566009830185615456565b8351615866818360208801614773565b01949350505050565b600080516020615f3783398151915281527f76696577426f783d223020302031323030203132303022207374796c653d226460208201527f6973706c61793a20626c6f636b3b207472616e73666f726d3a207363616c652860408201527f2d312c3129222076657273696f6e3d22312e322220786d6c6e733d226874747060608201527f3a2f2f7777772e77332e6f72672f323030302f737667223e3c696d616765207760808201527f696474683d223132303022206865696768743d22313230302220687265663d2260a0820152600082516159538160c0850160208701614773565b6f111f1e17b4b6b0b3b29f1e17b9bb339f60811b60c093909101928301525060d001919050565b711139bb33afb4b6b0b3b2afb230ba30911d1160711b815281516000906159a8816012850160208701614773565b61088b60f21b6012939091019283015250601401919050565b600080516020615f3783398151915281527f76696577426f783d2230203020313230302031323030222076657273696f6e3d60208201527f22312e322220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f3260408201527f3030302f737667223e3c696d6167652077696474683d2231323030222068656960608201527033b43a1e91189918181110343932b31e9160791b608082015260008251615a73816091850160208701614773565b6f111f1e17b4b6b0b3b29f1e17b9bb339f60811b609193909101928301525060a101919050565b6d1134b6b0b3b2afb230ba30911d1160911b81528151600090615ac481600e850160208701614773565b61088b60f21b600e939091019283015250601001919050565b6c1130ba3a3934b13aba32b9911d60991b81528151600090615b0681600d850160208701614773565b607d60f81b600d939091019283015250600e01919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251615b5681601d850160208701614773565b91909101601d0192915050565b848152836020820152608060408201526000615b826080830185614797565b8281036060840152615b948185614797565b979650505050505050565b683d913730b6b2911d1160b91b81526000615bbd600983018a615456565b701116113232b9b1b934b83a34b7b7111d1160791b8152615be1601182018a615456565b6a11161134b6b0b3b2911d1160a91b81529050615c01600b820189615456565b6b1116113130b73732b9111d1160a11b81529050615c22600c820188615456565b7211161132bc3a32b93730b62fb634b735911d1160691b81529050615c4a6013820187615456565b7b11161139b2b63632b92fb332b2afb130b9b4b9afb837b4b73a39911d60211b81528551909150615c8281601c840160208901614773565b7116113332b2afb932b1b4b834b2b73a111d1160711b601c9290910191820152615caf602e820185615456565b61227d60f01b81526002019a9950505050505050505050565b60ff81811683821602908116908181146130125761301261535a565b60ff82811682821603908111156108e7576108e761535a565b60ff81811683821601908111156108e7576108e761535a565b600060ff821660ff8103615d2c57615d2c61535a565b60010192915050565b6000815260008251615d4e816001850160208701614773565b9190910160010192915050565b600082615d6a57615d6a61542c565b500490565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061454290830184614797565b600060208284031215615db457600080fd5b8151613a3a81614740565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201528151600090615e0281600e850160208701614773565b91909101600e019392505050565b60008251615e22818460208701614773565b919091019291505056fe3c7376672077696474683d223136303022206865696768743d2231363030222076696577426f783d2230203020313630302031363030222076657273696f6e3d22312e322220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207374796c653d226261636b67726f756e642d636f6c6f723a20234142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef3c7376672077696474683d223130302522206865696768743d22313030252220a264697066735822122020ca10d25cc2579867a12aa3307559f37a93dd8bba2ce9793f5ce20ade52099564736f6c634300081100334f6e2d436861696e20416c706861206973206120636f6c6c656374696f6e206f66203737373720637573746f6d697a61626c65206469676974616c206964656e7469747920746f6b656e732073746f72656420656e746972656c79206f6e2074686520457468657265756d20626c6f636b636861696e2e20546f6b656e20686f6c646572732063616e2076697369742068747470733a2f2f6f63612e676720746f20656e61626c652f64697361626c65206578697374696e67207472616974732c206368616e6765206261636b67726f756e6420636f6c6f722c20666c69702074686520696d6167652c20656e61626c652054776974746572206865782c20616e64206d6f72652061732077656c6c2061732072657665616c206e65772074726169742064726f707320746f2062652072656c656173656420696e20746865206675747572652e68747470733a2f2f7374617469632e666c6f6f7265644170652e696f2f6f63612f68747470733a2f2f697066732e696f2f697066732f516d646271374e35697a72617a6f59636277537578636d73326442656d78757862724c61467477326475666456362f62616e6e65722e706e6730783935373335364639343132383330633939324434363546463843446239623041413032333032306268747470733a2f2f697066732e696f2f697066732f516d646271374e35697a72617a6f59636277537578636d73326442656d78757862724c61467477326475666456362f636f6c6c656374696f6e2e676966

Deployed Bytecode

0x6080604052600436106102395760003560e01c806301ffc9a71461023e57806306fdde0314610273578063081812fc14610295578063095ea7b3146102cd5780630ea71cfc146102ef5780630f3debbe1461030f578063150b7a021461032f57806318160ddd1461036857806319c841fd1461039057806323b872dd146103b05780632437013d146103d05780632d6b6224146103f05780632db115441461040a5780633cca24201461041d5780633ccfd60b146104455780634047638d1461045a57806342842e0e1461046f57806355f804b31461048f57806357380daa146104af5780635b92ac0d146104cf578063621a1f74146104e45780636352211e1461050457806366e33870146105245780636817c76c146105445780636c0360eb1461055a57806370a082311461056f578063715018a61461058f578063716e43d7146105a45780637a75353a146105c45780638a8c0e0c146105e45780638da5cb5b1461060457806395d89b411461061957806397e2155d1461062e578063a22cb4651461064e578063a78c8a7a1461066e578063ac9650d814610684578063ad9adfe3146106b1578063b88d4fde146106d1578063c406ec72146106f1578063c87b56dd14610711578063d5abeb0114610731578063dbe9875f14610747578063e488627314610767578063e8a3d48514610787578063e985e9c51461079c578063ed39d98d146107e5578063f2f0dc0514610805578063f2fde38b1461083b578063fb38d2111461085b578063fd6b3cf51461087b575b600080fd5b34801561024a57600080fd5b5061025e610259366004614756565b61089b565b60405190151581526020015b60405180910390f35b34801561027f57600080fd5b506102886108ed565b60405161026a91906147c3565b3480156102a157600080fd5b506102b56102b03660046147d6565b61097f565b6040516001600160a01b03909116815260200161026a565b3480156102d957600080fd5b506102ed6102e8366004614804565b6109c3565b005b3480156102fb57600080fd5b506102ed61030a36600461492f565b610a63565b34801561031b57600080fd5b506102ed61032a3660046149c0565b610b60565b34801561033b57600080fd5b5061034f61034a366004614aea565b610bf4565b6040516001600160e01b0319909116815260200161026a565b34801561037457600080fd5b506001546000540361010519015b60405190815260200161026a565b34801561039c57600080fd5b506102ed6103ab366004614b98565b610cc9565b3480156103bc57600080fd5b506102ed6103cb366004614bc4565b610d49565b3480156103dc57600080fd5b506102ed6103eb366004614c28565b610edc565b3480156103fc57600080fd5b50602b5461025e9060ff1681565b6103826104183660046147d6565b610f97565b34801561042957600080fd5b50610432611146565b60405161026a9796959493929190614cd0565b34801561045157600080fd5b506102ed6114a4565b34801561046657600080fd5b506102ed6114c8565b34801561047b57600080fd5b506102ed61048a366004614bc4565b6114e4565b34801561049b57600080fd5b506102ed6104aa366004614d59565b611504565b3480156104bb57600080fd5b5061025e6104ca366004614b98565b61151c565b3480156104db57600080fd5b5061025e611553565b3480156104f057600080fd5b506102886104ff3660046147d6565b611574565b34801561051057600080fd5b506102b561051f3660046147d6565b6124b5565b34801561053057600080fd5b5061028861053f366004614d59565b6124c0565b34801561055057600080fd5b5061038260285481565b34801561056657600080fd5b506102886128e2565b34801561057b57600080fd5b5061038261058a366004614d8d565b612970565b34801561059b57600080fd5b506102ed6129be565b3480156105b057600080fd5b506102ed6105bf366004614daa565b6129d2565b3480156105d057600080fd5b506102ed6105df366004614ee8565b612b67565b3480156105f057600080fd5b506103826105ff366004614b98565b612bce565b34801561061057600080fd5b506102b5612de7565b34801561062557600080fd5b50610288612df6565b34801561063a57600080fd5b506102ed610649366004614f2e565b612e05565b34801561065a57600080fd5b506102ed610669366004614f50565b612e90565b34801561067a57600080fd5b5061038260295481565b34801561069057600080fd5b506106a461069f366004614f7c565b612f25565b60405161026a9190614ff0565b3480156106bd57600080fd5b506102886106cc366004615052565b613019565b3480156106dd57600080fd5b506102ed6106ec366004615096565b61335c565b3480156106fd57600080fd5b506026546102b5906001600160a01b031681565b34801561071d57600080fd5b5061028861072c3660046147d6565b6133a0565b34801561073d57600080fd5b50610382611c5e81565b34801561075357600080fd5b506102ed610762366004614b98565b613666565b34801561077357600080fd5b506102ed6107823660046150f5565b6136ac565b34801561079357600080fd5b50610288613796565b3480156107a857600080fd5b5061025e6107b7366004615130565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156107f157600080fd5b506027546102b5906001600160a01b031681565b34801561081157600080fd5b50610382610820366004614d8d565b6001600160a01b031660009081526012602052604090205490565b34801561084757600080fd5b506102ed610856366004614d8d565b6137f4565b34801561086757600080fd5b506102ed610876366004614ee8565b61386f565b34801561088757600080fd5b506102ed610896366004614f2e565b6138a1565b60006301ffc9a760e01b6001600160e01b0319831614806108cc57506380ac58cd60e01b6001600160e01b03198316145b806108e75750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600280546108fc90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461092890615169565b80156109755780601f1061094a57610100808354040283529160200191610975565b820191906000526020600020905b81548152906001019060200180831161095857829003601f168201915b5050505050905090565b600061098a82613901565b6109a7576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b60006109ce826124b5565b9050336001600160a01b03821614610a07576109ea81336107b7565b610a07576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b33610a6d856124b5565b6001600160a01b031614610a8057600080fd5b6000848152601060205260409020610a9884826151e3565b506000848152601060205260409020600101610ab483826151e3565b506000848152601060205260409020600201610ad082826151e3565b50600083610add86613937565b604051602001610aee9291906152a2565b60408051601f198184030181529181526000878152601060205220909150600301610b1982826151e3565b507fb8981c9fcfec39b56f5caf88846acca9b61e75401e68da165ef541e81991d8b68585858585604051610b519594939291906152de565b60405180910390a15050505050565b610b68613986565b80518190602c908190610b7b90826151e3565b5060208201516001820190610b9090826151e3565b5060408201516002820190610ba590826151e3565b5060608201516003820190610bba90826151e3565b5060808201516004820190610bcf90826151e3565b5060a0820151600582015560c08201516006820190610bee90826151e3565b50505050565b6026546000906001600160a01b0316331480610c8557506026546040516331a9108f60e11b8152600481018690526001600160a01b03878116921690636352211e90602401602060405180830381865afa158015610c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7a919061533d565b6001600160a01b0316145b610c8e57600080fd5b6001600160a01b0385166000908152601260205260408120805491610cb283615370565b90915550630a85bd0160e11b979650505050505050565b610cd2826124b5565b6001600160a01b0316336001600160a01b031614610cef57600080fd5b6000828152600f6020908152604091829020805460ff19168415159081179091558251858152918201527fafec4b400a28d8bdfacc6b65e3c25cc07399c2c20eeb817256f6413c7e84687c91015b60405180910390a15050565b6000610d54826139e5565b9050836001600160a01b0316816001600160a01b031614610d875760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610dd457610db786336107b7565b610dd457604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610dfb57604051633a954ecd60e21b815260040160405180910390fd5b8015610e0657600082555b6001600160a01b03808716600090815260056020526040808220805460001901905591871681522080546001019055610e4f85610e44888287613a5c565b600160e11b17613a7f565b600085815260046020526040812091909155600160e11b84169003610ea457600184016000818152600460205260408120549003610ea2576000548114610ea25760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b0316600080516020615f1783398151915260405160405180910390a45b505050505050565b610ee5826124b5565b6001600160a01b0316336001600160a01b031614610f0257600080fd5b60005b600f811015610f6557818181518110610f2057610f20615389565b6020908102919091018101516000858152600d8352604080822085835290935291909120805460ff191691151591909117905580610f5d81615370565b915050610f05565b507f6feffc52172e0d2f7273caf08349169b161ca5e8e463fa548b2dc2258c54cce38282604051610d3d92919061539f565b6000610fa1613a94565b610fa9611553565b610fb257600080fd5b6000610fbc613aed565b33600090815260156020526040902054909150606490610fdd9085906153ef565b1115610fe857600080fd5b60148311158015610ff95750600083115b61100257600080fd5b611c5e61100f84836153ef565b111561101a57600080fd5b33321461102657600080fd5b3360009081526012602052604081205480156110ec5784811161108d57806029546110519190615402565b915081602854866110629190615402565b61106c9190615419565b34101561107857600080fd5b33600090815260126020526040812055611105565b8460295461109b9190615402565b915081602854866110ac9190615402565b6110b69190615419565b3410156110c257600080fd5b33600090815260126020526040812080548792906110e1908490615419565b909155506111059050565b6028546110f99086615402565b34101561110557600080fd5b33600090815260156020526040812080548792906111249084906153ef565b9091555061113490503386613af8565b5050600160085592915050565b919050565b602c8054819061115590615169565b80601f016020809104026020016040519081016040528092919081815260200182805461118190615169565b80156111ce5780601f106111a3576101008083540402835291602001916111ce565b820191906000526020600020905b8154815290600101906020018083116111b157829003601f168201915b5050505050908060010180546111e390615169565b80601f016020809104026020016040519081016040528092919081815260200182805461120f90615169565b801561125c5780601f106112315761010080835404028352916020019161125c565b820191906000526020600020905b81548152906001019060200180831161123f57829003601f168201915b50505050509080600201805461127190615169565b80601f016020809104026020016040519081016040528092919081815260200182805461129d90615169565b80156112ea5780601f106112bf576101008083540402835291602001916112ea565b820191906000526020600020905b8154815290600101906020018083116112cd57829003601f168201915b5050505050908060030180546112ff90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461132b90615169565b80156113785780601f1061134d57610100808354040283529160200191611378565b820191906000526020600020905b81548152906001019060200180831161135b57829003601f168201915b50505050509080600401805461138d90615169565b80601f01602080910402602001604051908101604052809291908181526020018280546113b990615169565b80156114065780601f106113db57610100808354040283529160200191611406565b820191906000526020600020905b8154815290600101906020018083116113e957829003601f168201915b50505050509080600501549080600601805461142190615169565b80601f016020809104026020016040519081016040528092919081815260200182805461144d90615169565b801561149a5780601f1061146f5761010080835404028352916020019161149a565b820191906000526020600020905b81548152906001019060200180831161147d57829003601f168201915b5050505050905087565b47806114af57600080fd5b6033546114c5906001600160a01b031682613bd5565b50565b6114d0613986565b602b805460ff19811660ff90911615179055565b6114ff8383836040518060200160405280600081525061335c565b505050565b61150c613986565b602a61151882826151e3565b5050565b6000811561153c575060008281526014602052604090205460ff166108e7565b505060009081526013602052604090205460ff1690565b6000611c5e611560613aed565b10801561156f5750602b5460ff165b905090565b606061157f82613901565b61158857600080fd5b600061159e611599600f6004615402565b613ceb565b60408051600f808252610200820190925291925060009190602082016101e08036833701905050905060005b600f8110156123845760008282815181106115e7576115e7615389565b6020026020010151905060006002836116009190615442565b11801561162757506000868152600e6020908152604080832085845290915290205460ff16155b15611670576001601683600f811061164157611641615389565b015461164d9190615419565b83838151811061165f5761165f615389565b602002602001018181525050612371565b600061167b87613d08565b6060015162ffffff1690506000611c5e828961169787826153ef565b60408051602081019490945283019190915260608201526080016040516020818303038152906040528051906020012060001c6116d49190615442565b90506116e08185613d21565b9250828585815181106116f5576116f5615389565b60200260200101818152505060006001601686600f811061171857611718615389565b01546117249190615419565b60008a8152600d6020908152604080832089845290915290205490915060ff161515600103611f545784600a148015611776575085858151811061176a5761176a615389565b6020026020010151600a145b156117e8578086868151811061178e5761178e615389565b60209081029190910181019190915260008a8152600d82526040808220600283529092529081205460ff16151590036117e357600f866002815181106117d6576117d6615389565b6020026020010181815250505b61236d565b84600e148015611811575085858151811061180557611805615389565b60200260200101516000145b15611871578086868151811061182957611829615389565b60209081029190910181019190915260008a8152600d82526040808220600883529092529081205460ff16151590036117e3576005866008815181106117d6576117d6615389565b84600e14801561189a575085858151811061188e5761188e615389565b60200260200101516002145b1561198a57808686815181106118b2576118b2615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff161515900361190757600186600a815181106118fa576118fa615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff161515900361194f5760008660088151811061194257611942615389565b6020026020010181815250505b6000898152600d602090815260408083206004845290915281205460ff16151590036117e3576001866004815181106117d6576117d6615389565b84600e1480156119b357508585815181106119a7576119a7615389565b60200260200101516004145b15611a5b57808686815181106119cb576119cb615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611a2057600886600a81518110611a1357611a13615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576009866008815181106117d6576117d6615389565b84600e148015611a845750858581518110611a7857611a78615389565b60200260200101516005145b15611b2c5780868681518110611a9c57611a9c615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611af157600686600a81518110611ae457611ae4615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576007866008815181106117d6576117d6615389565b84600e148015611b555750858581518110611b4957611b49615389565b60200260200101516006145b15611bfd5780868681518110611b6d57611b6d615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611bc257600786600a81518110611bb557611bb5615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576008866008815181106117d6576117d6615389565b84600e148015611c265750858581518110611c1a57611c1a615389565b60200260200101516007145b15611cce5780868681518110611c3e57611c3e615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611c9357600286600a81518110611c8657611c86615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576004866008815181106117d6576117d6615389565b84600e148015611cf75750858581518110611ceb57611ceb615389565b60200260200101516009145b15611d9f5780868681518110611d0f57611d0f615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611d6457600586600a81518110611d5757611d57615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576001866008815181106117d6576117d6615389565b84600e148015611dc85750858581518110611dbc57611dbc615389565b6020026020010151600a145b15611e705780868681518110611de057611de0615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611e3557600486600a81518110611e2857611e28615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576002866008815181106117d6576117d6615389565b84600e148015611e995750858581518110611e8d57611e8d615389565b6020026020010151600b145b15611f415780868681518110611eb157611eb1615389565b60209081029190910181019190915260008a8152600d82526040808220600a83529092529081205460ff1615159003611f0657600386600a81518110611ef957611ef9615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff16151590036117e3576003866008815181106117d6576117d6615389565b808686815181106117d6576117d6615389565b84600a148015611f7e575085600a81518110611f7257611f72615389565b6020026020010151600a145b15611fcb576000898152600d602090815260408083206002845290915281205460ff1615159003611fcb57600f86600281518110611fbe57611fbe615389565b6020026020010181815250505b84600e0361236d5785600e81518110611fe657611fe6615389565b6020026020010151600003612030576000898152600d602090815260408083206008845290915281205460ff16151590036117e3576005866008815181106117d6576117d6615389565b85600e8151811061204357612043615389565b602002602001015160020361208d576000898152600d60209081526040808320600a845290915281205460ff161515900361190757600186600a815181106118fa576118fa615389565b85600e815181106120a0576120a0615389565b60200260200101516004036120ea576000898152600d60209081526040808320600a845290915281205460ff1615159003611a2057600886600a81518110611a1357611a13615389565b85600e815181106120fd576120fd615389565b6020026020010151600503612147576000898152600d60209081526040808320600a845290915281205460ff1615159003611af157600686600a81518110611ae457611ae4615389565b85600e8151811061215a5761215a615389565b60200260200101516006036121a4576000898152600d60209081526040808320600a845290915281205460ff1615159003611bc257600786600a81518110611bb557611bb5615389565b85600e815181106121b7576121b7615389565b6020026020010151600703612201576000898152600d60209081526040808320600a845290915281205460ff1615159003611c9357600286600a81518110611c8657611c86615389565b85600e8151811061221457612214615389565b602002602001015160090361225e576000898152600d60209081526040808320600a845290915281205460ff1615159003611d6457600586600a81518110611d5757611d57615389565b85600e8151811061227157612271615389565b6020026020010151600a036122bb576000898152600d60209081526040808320600a845290915281205460ff1615159003611e3557600486600a81518110611e2857611e28615389565b85600e815181106122ce576122ce615389565b6020026020010151600b0361236d576000898152600d60209081526040808320600a845290915281205460ff161515900361232557600386600a8151811061231857612318615389565b6020026020010181815250505b6000898152600d602090815260408083206008845290915281205460ff161515900361236d5760038660088151811061236057612360615389565b6020026020010181815250505b5050505b508061237c81615370565b9150506115ca565b5060005b81518110156124ac57600a8282815181106123a5576123a5615389565b602002602001015110156123dc57604080518082019091526002815261030360f41b60208201526123d7908490613de7565b612421565b60648282815181106123f0576123f0615389565b60200260200101511015612421576040805180820190915260018152600360fc1b6020820152612421908490613de7565b6103e782828151811061243657612436615389565b6020026020010151111561246e5760408051808201909152600381526239393960e81b6020820152612469908490613de7565b61249a565b61249a61249383838151811061248657612486615389565b6020026020010151613937565b8490613de7565b806124a481615370565b915050612388565b50909392505050565b60006108e7826139e5565b606060006124d062020000613ceb565b90506124fe604051806040016040528060018152602001605b60f81b81525082613de790919063ffffffff16565b600b600081815260209190915260037fe8056e2ed8943b7f61a5f0dc88c79a5a6cec2bb36a7bd11ce130f2961c6320b98261254461253f8860216024613e6c565b613f38565b60ff168152602001908152602001600020600001805461256390615169565b600c6000908152600b60205292119250600390507f765e72d9703c9804ad76c7d0af52f5313041ea56bb31a328e17fea205151b5ea826125a961253f8960246027613e6c565b60ff16815260200190815260200160002060000180546125c890615169565b600d6000908152600b60205292119250600390507f0a2216aa9bbf8764f3bfb9fafcef7f625aba82383c1a9d14d721124ff30595818261260e61253f8a6027602a613e6c565b60ff168152602001908152602001600020600001805461262d90615169565b600e6000908152600b60205292119250600390507f7ae97ffc8b2fe6ed730ad82f8c44cc0285c7a97ac189e2d88c56200fe9a501ab8261267361253f8b602a602d613e6c565b60ff168152602001908152602001600020600001805461269290615169565b905010905060005b600f8110156128d65760006126d261253f8a6126b7856003615402565b6126c2866003615402565b6126cd9060036153ef565b613e6c565b6000838152600b6020908152604080832060ff94909416808452939091529020805491925060029161270390615169565b905011156128c3576127696025838154811061272157612721615389565b60009182526020808320868452600b82526040808520878652835293849020935161275294939091019291016154c9565b60408051601f198184030181529190528890613de7565b81600a148015612790575085801561277e5750845b80156127875750835b80156127905750825b156127bd576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b6128c3565b81600b1480156127db57508480156127d25750835b80156127db5750825b15612803576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600c14801561281857508380156128185750825b15612840576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600d14801561284d5750825b15612875576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b81600e036128a0576040805180820190915260018152605d60f81b60208201526127b8908890613de7565b6040805180820190915260018152600b60fa1b60208201526128c3908890613de7565b50806128ce81615370565b91505061269a565b50939695505050505050565b602a80546128ef90615169565b80601f016020809104026020016040519081016040528092919081815260200182805461291b90615169565b80156129685780601f1061293d57610100808354040283529160200191612968565b820191906000526020600020905b81548152906001019060200180831161294b57829003601f168201915b505050505081565b60006001600160a01b038216612999576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6129c6613986565b6129d06000613ff6565b565b6129da613986565b8051601683600f81106129ef576129ef615389565b0154146129fb57600080fd5b600081516001600160401b03811115612a1657612a16614830565b604051908082528060200260200182016040528015612a3f578160200160208202803683370190505b50905060005b8251811015612b4757612a74838281518110612a6357612a63615389565b602002602001015160400151614048565b828281518110612a8657612a86615389565b60200260200101906001600160a01b031690816001600160a01b0316815250506040518060400160405280848381518110612ac357612ac3615389565b6020026020010151600001518152602001848381518110612ae657612ae6615389565b6020908102919091018101518101519091526000868152600b825260408082208583529092522081518190612b1b90826151e3565b5060208201516001820190612b3090826151e3565b509050508080612b3f90615370565b915050612a45565b506000838152600a602090815260409091208251610bee9284019061469f565b33612b71836124b5565b6001600160a01b031614612b8457600080fd5b6000828152601160205260409020612b9c82826151e3565b507f81b1bf653f53dc046b08a20dc605eed2195235db792f342a6a722e1b5480f9548282604051610d3d92919061551f565b6000612bd8613a94565b612be0611553565b612be957600080fd5b6000612bf3613aed565b90508215612ce15760008481526014602052604090205460ff1615612c1757600080fd5b6027546040516331a9108f60e11b8152600481018690526001600160a01b0390911690636352211e90602401602060405180830381865afa158015612c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c84919061533d565b6001600160a01b0316336001600160a01b031614612ca157600080fd5b611c5e612caf8260016153ef565b1115612cba57600080fd5b6000848152601460205260409020805460ff19166001908117909155612ce1903390613af8565b82612ddb576103e8841115612cf557600080fd5b60008481526013602052604090205460ff1615612d1157600080fd5b6026546040516331a9108f60e11b8152600481018690526001600160a01b0390911690636352211e90602401602060405180830381865afa158015612d5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d7e919061533d565b6001600160a01b0316336001600160a01b031614612d9b57600080fd5b611c5e612da98260016153ef565b1115612db457600080fd5b6000848152601360205260409020805460ff19166001908117909155612ddb903390613af8565b90506108e76001600855565b6009546001600160a01b031690565b6060600380546108fc90615169565b600f8110612e1257600080fd5b612e1b826124b5565b6001600160a01b0316336001600160a01b031614612e3857600080fd5b6000828152600e60209081526040808320848452825291829020805460ff1916600117905581518481529081018390527f4c652a0da724e2e441d4269d925eb66c004118aea8f9d00f7cfd6c906f908d229101610d3d565b336001600160a01b03831603612eb95760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6060816001600160401b03811115612f3f57612f3f614830565b604051908082528060200260200182016040528015612f7257816020015b6060815260200190600190039081612f5d5790505b50905060005b8281101561301257612fe230858584818110612f9657612f96615389565b9050602002810190612fa89190615538565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506140ad92505050565b828281518110612ff457612ff4615389565b6020026020010181905250808061300a90615370565b915050612f78565b5092915050565b60606000806040518060400160405280600681526020016531433135333160d01b8152509050600060116000868152602001908152602001600020805461305f90615169565b90501115613101576000848152601160205260409020805461308090615169565b80601f01602080910402602001604051908101604052809291908181526020018280546130ac90615169565b80156130f95780601f106130ce576101008083540402835291602001916130f9565b820191906000526020600020905b8154815290600101906020018083116130dc57829003601f168201915b505050505090505b600061310f62020000613ceb565b90506131346040518060c0016040528060838152602001615e2d608391398290613de7565b61315f826040516020016131489190615585565b60408051601f198184030181529190528290613de7565b60005b61316e6001600f615419565b81101561327c576000613182600283615442565b1180156131a957506000868152600e6020908152604080832084845290915290205460ff16155b61326a576131ca61253f886131bf846003615402565b6126c2856003615402565b60ff16935061326a600b6000838152602001908152602001600020600086815260200190815260200160002060010161324261323d600a6000868152602001908152602001600020888154811061322357613223615389565b6000918252602090912001546001600160a01b03166140d2565b6140e2565b6040516020016132539291906155bf565b60408051601f198184030181529190528390613de7565b8061327481615370565b915050613162565b506132a761253f876003613291600f82615402565b61329b9190615419565b6126cd600f6003615402565b60ff169250613329600b60006132bf6001600f615419565b8152602001908152602001600020600085815260200190815260200160002060010161331861323d600a60006001600f6132f99190615419565b8152602001908152602001600020878154811061322357613223615389565b604051602001613148929190615619565b613332816140e2565b604051602001613342919061577d565b604051602081830303815290604052935050505092915050565b613367848484610d49565b6001600160a01b0383163b15610bee5761338384848484614234565b610bee576040516368d2bf6b60e11b815260040160405180910390fd5b60606133ab82613901565b6133b457600080fd5b60008052600a6020527f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e3546133e857600080fd5b60006133f383611574565b9050600061340362020000613ceb565b60008581526010602052604081208054929350909161342190615169565b9050111561345257600084815260106020908152604091829020915161344d92613148929091016157bf565b613489565b6040805180820190915260158152747b226e616d65223a224f6e436861696e416c70686160581b6020820152613489908290613de7565b6134a861349585613937565b6040516131489190602d906020016157dd565b6000602a80546134b790615169565b90501180156134d457506000848152600c602052604090205460ff165b156134fd576134f8602a6134e786613937565b604051602001613148929190615838565b613619565b60408051602080820183526000808352878152600f909152919091205460ff16156135aa57600061352e8487613019565b905061355881604051602001613544919061586f565b6040516020818303038152906040526140e2565b604051602001613568919061577d565b60405160208183030381529060405291506135a48160405160200161358d919061597a565b60408051601f198184030181529190528490613de7565b50613603565b60006135b68487613019565b90506135cc8160405160200161354491906159c1565b6040516020016135dc919061577d565b60405160208183030381529060405291506136018160405160200161358d919061597a565b505b613617816040516020016132539190615a9a565b505b613635613625836124c0565b6040516020016131489190615add565b61363e816140e2565b60405160200161364e9190615b1e565b60405160208183030381529060405292505050919050565b61366f826124b5565b6001600160a01b0316336001600160a01b03161461368c57600080fd5b6000918252600c6020526040909120805460ff1916911515919091179055565b6136b5846124b5565b6001600160a01b0316336001600160a01b0316146136d257600080fd5b600084815260106020526040902060060154808410613713576000858152601060205260408120600601805492955085929161370d83615370565b91905055505b6000858152601060209081526040808320878452600401909152902061373984826151e3565b506000858152601060209081526040808320878452600501909152902061376083826151e3565b507fca3ccd3f553ac426b514af81e9a960872e7c86a7a0260f8e8b244ce916776e7285858585604051610b519493929190615b63565b6031546060906137d090602c90602d90602e90602f906030906137b890613937565b60405161354496959493929190603290602001615b9f565b6040516020016137e09190615b1e565b604051602081830303815290604052905090565b6137fc613986565b6001600160a01b0381166138665760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6114c581613ff6565b613877613986565b806025838154811061388b5761388b615389565b9060005260206000200190816114ff91906151e3565b6138a9613986565b60008183116138b857816138ba565b825b90506138c58161431f565b6138d86138d38260016153ef565b613901565b156138f0576138f06138eb8260016153ef565b61431f565b6114ff816138fc61434f565b6143bb565b60008161010611158015613916575060005482105b80156108e7575050600090815260046020526040902054600160e01b161590565b604080516080810191829052607f0190826030600a8206018353600a90045b801561397457600183039250600a81066030018353600a9004613956565b50819003601f19909101908152919050565b3361398f612de7565b6001600160a01b0316146129d05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161385d565b6000818061010611613a4357600054811015613a435760008181526004602052604081205490600160e01b82169003613a41575b80600003613a3a575060001901600081815260046020526040902054613a19565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600060e882811c90613a6f868684614410565b62ffffff16901b95945050505050565b4260a01b176001600160a01b03919091161790565b600260085403613ae65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161385d565b6002600855565b600054610105190190565b6000546001600160a01b038316613b2157604051622e076360e81b815260040160405180910390fd5b81600003613b425760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600090815260056020526040812080546001600160401b018502019055613b87908490613b7a908281613a5c565b6001851460e11b17613a7f565b600082815260046020526040902055808281015b6040516001830192906001600160a01b03871690600090600080516020615f17833981519152908290a4808210613b9b5760005550505050565b80471015613c255760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161385d565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c72576040519150601f19603f3d011682016040523d82523d6000602084013e613c77565b606091505b50509050806114ff5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c20726044820152791958da5c1a595b9d081b585e481a185d99481c995d995c9d195960321b606482015260840161385d565b604080518281016060018252910181526000602090910190815290565b613d10614704565b6108e7613d1c836139e5565b61442f565b600080805b601684600f8110613d3957613d39615389565b0154811015613dbd576000601685600f8110613d5757613d57615389565b018281548110613d6957613d69615389565b90600052602060002001549050828610158015613d8e5750613d8b81846153ef565b86105b15613d9d575091506108e79050565b613da781846153ef565b9250508080613db590615370565b915050613d26565b506001601684600f8110613dd357613dd3615389565b0154613ddf9190615419565b949350505050565b601f1982015182518251603f19909201918290613e0490836153ef565b1115613e625760405162461bcd60e51b815260206004820152602760248201527f44796e616d69634275666665723a20417070656e64696e67206f7574206f66206044820152663137bab732399760c91b606482015260840161385d565b610bee8484614472565b6060836000613e7b8585615419565b6001600160401b03811115613e9257613e92614830565b6040519080825280601f01601f191660200182016040528015613ebc576020820181803683370190505b509050845b84811015613f2e57828181518110613edb57613edb615389565b01602001516001600160f81b03191682613ef58884615419565b81518110613f0557613f05615389565b60200101906001600160f81b031916908160001a90535080613f2681615370565b915050613ec1565b5095945050505050565b60008181805b82518160ff161015613fee576030838260ff1681518110613f6157613f61615389565b016020015160f81c10801590613f9457506039838260ff1681518110613f8957613f89615389565b016020015160f81c11155b15613fdc57613fa4600a83615cc8565b91506030838260ff1681518110613fbd57613fbd615389565b0160200151613fcf919060f81c615ce4565b613fd99083615cfd565b91505b80613fe681615d16565b915050613f3e565b509392505050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806140738360405160200161405f9190615d35565b6040516020818303038152906040526144a8565b90508051602082016000f091506001600160a01b0382166140a75760405163046a55db60e11b815260040160405180910390fd5b50919050565b6060613a3a8383604051806060016040528060278152602001615ef0602791396144d4565b60606108e782600160001961454c565b6060815160000361410157505060408051602081019091526000815290565b6000604051806060016040528060408152602001615eb0604091399050600060038451600261413091906153ef565b61413a9190615d5b565b614145906004615402565b6001600160401b0381111561415c5761415c614830565b6040519080825280601f01601f191660200182016040528015614186576020820181803683370190505b509050600182016020820185865187015b808210156141f2576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250614197565b505060038651066001811461420e576002811461422157614229565b603d6001830353603d6002830353614229565b603d60018303535b509195945050505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290614269903390899088908890600401615d6f565b6020604051808303816000875af19250505080156142a4575060408051601f3d908101601f191682019092526142a191810190615da2565b60015b614302573d8080156142d2576040519150601f19603f3d011682016040523d82523d6000602084013e6142d7565b606091505b5080516000036142fa576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b60008181526004602052604081205490036114c55761433d816139e5565b60008281526004602052604090205550565b6000803a434244614361600184615419565b6040805160208101969096528501939093526060808501929092526080840152904060a083015233901b6001600160601b03191660c082015260d40160408051601f19818403018152919052805160209091012092915050565b600082815260046020526040812054908190036143ea5760405162d5815360e01b815260040160405180910390fd5b6000928352600460205260409092206001600160e81b039290921660e89190911b179055565b60006001600160a01b038416156144275781613ddf565b613ddf61434f565b614437614704565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b8051602082019150808201602084510184015b8184101561449d578351815260209384019301614485565b505082510190915250565b60608151826040516020016144be929190615dbf565b6040516020818303038152906040529050919050565b6060600080856001600160a01b0316856040516144f19190615e10565b600060405180830381855af49150503d806000811461452c576040519150601f19603f3d011682016040523d82523d6000602084013e614531565b606091505b509150915061454286838387614601565b9695505050505050565b6060833b600081900361456f575050604080516020810190915260008152613a3a565b8084111561458d575050604080516020810190915260008152613a3a565b838310156145bf5760405163162544fd60e11b815260048101829052602481018590526044810184905260640161385d565b83830384820360008282106145d457826145d6565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b60608315614670578251600003614669576001600160a01b0385163b6146695760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161385d565b5081613ddf565b613ddf83838151156146855781518083602001fd5b8060405162461bcd60e51b815260040161385d91906147c3565b8280548282559060005260206000209081019282156146f4579160200282015b828111156146f457825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906146bf565b5061470092915061472b565b5090565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5b80821115614700576000815560010161472c565b6001600160e01b0319811681146114c557600080fd5b60006020828403121561476857600080fd5b8135613a3a81614740565b60005b8381101561478e578181015183820152602001614776565b50506000910152565b600081518084526147af816020860160208601614773565b601f01601f19169290920160200192915050565b602081526000613a3a6020830184614797565b6000602082840312156147e857600080fd5b5035919050565b6001600160a01b03811681146114c557600080fd5b6000806040838503121561481757600080fd5b8235614822816147ef565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171561486857614868614830565b60405290565b604051606081016001600160401b038111828210171561486857614868614830565b604051601f8201601f191681016001600160401b03811182821017156148b8576148b8614830565b604052919050565b600082601f8301126148d157600080fd5b81356001600160401b038111156148ea576148ea614830565b6148fd601f8201601f1916602001614890565b81815284602083860101111561491257600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561494557600080fd5b8435935060208501356001600160401b038082111561496357600080fd5b61496f888389016148c0565b9450604087013591508082111561498557600080fd5b614991888389016148c0565b935060608701359150808211156149a757600080fd5b506149b4878288016148c0565b91505092959194509250565b6000602082840312156149d257600080fd5b81356001600160401b03808211156149e957600080fd5b9083019060e082860312156149fd57600080fd5b614a05614846565b823582811115614a1457600080fd5b614a20878286016148c0565b825250602083013582811115614a3557600080fd5b614a41878286016148c0565b602083015250604083013582811115614a5957600080fd5b614a65878286016148c0565b604083015250606083013582811115614a7d57600080fd5b614a89878286016148c0565b606083015250608083013582811115614aa157600080fd5b614aad878286016148c0565b60808301525060a083013560a082015260c083013582811115614acf57600080fd5b614adb878286016148c0565b60c08301525095945050505050565b600080600080600060808688031215614b0257600080fd5b8535614b0d816147ef565b94506020860135614b1d816147ef565b93506040860135925060608601356001600160401b0380821115614b4057600080fd5b818801915088601f830112614b5457600080fd5b813581811115614b6357600080fd5b896020828501011115614b7557600080fd5b9699959850939650602001949392505050565b8035801515811461114157600080fd5b60008060408385031215614bab57600080fd5b82359150614bbb60208401614b88565b90509250929050565b600080600060608486031215614bd957600080fd5b8335614be4816147ef565b92506020840135614bf4816147ef565b929592945050506040919091013590565b60006001600160401b03821115614c1e57614c1e614830565b5060051b60200190565b60008060408385031215614c3b57600080fd5b823591506020808401356001600160401b03811115614c5957600080fd5b8401601f81018613614c6a57600080fd5b8035614c7d614c7882614c05565b614890565b81815260059190911b82018301908381019088831115614c9c57600080fd5b928401925b82841015614cc157614cb284614b88565b82529284019290840190614ca1565b80955050505050509250929050565b60e081526000614ce360e083018a614797565b8281036020840152614cf5818a614797565b90508281036040840152614d098189614797565b90508281036060840152614d1d8188614797565b90508281036080840152614d318187614797565b90508460a084015282810360c0840152614d4b8185614797565b9a9950505050505050505050565b600060208284031215614d6b57600080fd5b81356001600160401b03811115614d8157600080fd5b613ddf848285016148c0565b600060208284031215614d9f57600080fd5b8135613a3a816147ef565b60008060408385031215614dbd57600080fd5b823591506020808401356001600160401b0380821115614ddc57600080fd5b818601915086601f830112614df057600080fd5b8135614dfe614c7882614c05565b81815260059190911b83018401908481019089831115614e1d57600080fd5b8585015b83811015614ed757803585811115614e395760008081fd5b86016060818d03601f1901811315614e515760008081fd5b614e5961486e565b8983013588811115614e6b5760008081fd5b614e798f8c838701016148c0565b825250604083013588811115614e8f5760008081fd5b614e9d8f8c838701016148c0565b828c015250908201359087821115614eb55760008081fd5b614ec38e8b848601016148c0565b604082015285525050918601918601614e21565b508096505050505050509250929050565b60008060408385031215614efb57600080fd5b8235915060208301356001600160401b03811115614f1857600080fd5b614f24858286016148c0565b9150509250929050565b60008060408385031215614f4157600080fd5b50508035926020909101359150565b60008060408385031215614f6357600080fd5b8235614f6e816147ef565b9150614bbb60208401614b88565b60008060208385031215614f8f57600080fd5b82356001600160401b0380821115614fa657600080fd5b818501915085601f830112614fba57600080fd5b813581811115614fc957600080fd5b8660208260051b8501011115614fde57600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561504557603f19888603018452615033858351614797565b94509285019290850190600101615017565b5092979650505050505050565b6000806040838503121561506557600080fd5b82356001600160401b0381111561507b57600080fd5b615087858286016148c0565b95602094909401359450505050565b600080600080608085870312156150ac57600080fd5b84356150b7816147ef565b935060208501356150c7816147ef565b92506040850135915060608501356001600160401b038111156150e957600080fd5b6149b4878288016148c0565b6000806000806080858703121561510b57600080fd5b843593506020850135925060408501356001600160401b038082111561498557600080fd5b6000806040838503121561514357600080fd5b823561514e816147ef565b9150602083013561515e816147ef565b809150509250929050565b600181811c9082168061517d57607f821691505b6020821081036140a757634e487b7160e01b600052602260045260246000fd5b601f8211156114ff57600081815260208120601f850160051c810160208610156151c45750805b601f850160051c820191505b81811015610ed4578281556001016151d0565b81516001600160401b038111156151fc576151fc614830565b6152108161520a8454615169565b8461519d565b602080601f831160018114615245576000841561522d5750858301515b600019600386901b1c1916600185901b178555610ed4565b600085815260208120601f198616915b8281101561527457888601518255948401946001909101908401615255565b50858210156152925787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600083516152b4818460208801614773565b602360f81b90830190815283516152d2816001840160208801614773565b01600101949350505050565b85815260a0602082015260006152f760a0830187614797565b82810360408401526153098187614797565b9050828103606084015261531d8186614797565b905082810360808401526153318185614797565b98975050505050505050565b60006020828403121561534f57600080fd5b8151613a3a816147ef565b634e487b7160e01b600052601160045260246000fd5b6000600182016153825761538261535a565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156153e25784511515835293830193918301916001016153c4565b5090979650505050505050565b808201808211156108e7576108e761535a565b80820281158282048414176108e7576108e761535a565b818103818111156108e7576108e761535a565b634e487b7160e01b600052601260045260246000fd5b6000826154515761545161542c565b500690565b6000815461546381615169565b6001828116801561547b5760018114615490576154bf565b60ff19841687528215158302870194506154bf565b8560005260208060002060005b858110156154b65781548a82015290840190820161549d565b50505082870194505b5050505092915050565b6e3d913a3930b4ba2fba3cb832911d1160891b815260006154ed600f830185615456565b6a1116113b30b63ab2911d1160a91b815261550b600b820185615456565b61227d60f01b815260020195945050505050565b828152604060208201526000613ddf6040830184614797565b6000808335601e1984360301811261554f57600080fd5b8301803591506001600160401b0382111561556957600080fd5b60200191503681900382131561557e57600080fd5b9250929050565b60008251615597818460208701614773565b75076c4c2c6d6cee4deeadcc85ad2dac2ceca74eae4d8560531b920191825250601601919050565b643230ba309d60d91b815260006155d96005830185615456565b670ed8985cd94d8d0b60c21b815283516155fa816008840160208801614773565b6505258eae4d8560d31b60089290910191820152600e01949350505050565b643230ba309d60d91b815260006156336005830185615456565b670ed8985cd94d8d0b60c21b81528351615654816008840160208801614773565b7f293b6261636b67726f756e642d7265706561743a6e6f2d7265706561743b6261600892909101918201527f636b67726f756e642d73697a653a636f6e7461696e3b6261636b67726f756e6460288201527f2d706f736974696f6e3a63656e7465723b696d6167652d72656e646572696e6760488201527f3a2d7765626b69742d6f7074696d697a652d636f6e74726173743b2d6d732d6960688201527f6e746572706f6c6174696f6e2d6d6f64653a6e6561726573742d6e656967686260888201527f6f723b696d6167652d72656e646572696e673a2d6d6f7a2d63726973702d656460a88201527f6765733b696d6167652d72656e646572696e673a706978656c617465643b223e60c8820152651e17b9bb339f60d11b60e882015260ee01949350505050565b7919185d184e9a5b5859d94bdcdd99cade1b5b0ed8985cd94d8d0b60321b8152600082516157b281601a850160208701614773565b91909101601a0192915050565b683d913730b6b2911d1160b91b81526000613a3a6009830184615456565b602360f81b8152600083516157f9816001850160208801614773565b701116113232b9b1b934b83a34b7b7111d1160791b6001918401918201526158246012820185615456565b61088b60f21b815260020195945050505050565b681134b6b0b3b2911d1160b91b815260006158566009830185615456565b8351615866818360208801614773565b01949350505050565b600080516020615f3783398151915281527f76696577426f783d223020302031323030203132303022207374796c653d226460208201527f6973706c61793a20626c6f636b3b207472616e73666f726d3a207363616c652860408201527f2d312c3129222076657273696f6e3d22312e322220786d6c6e733d226874747060608201527f3a2f2f7777772e77332e6f72672f323030302f737667223e3c696d616765207760808201527f696474683d223132303022206865696768743d22313230302220687265663d2260a0820152600082516159538160c0850160208701614773565b6f111f1e17b4b6b0b3b29f1e17b9bb339f60811b60c093909101928301525060d001919050565b711139bb33afb4b6b0b3b2afb230ba30911d1160711b815281516000906159a8816012850160208701614773565b61088b60f21b6012939091019283015250601401919050565b600080516020615f3783398151915281527f76696577426f783d2230203020313230302031323030222076657273696f6e3d60208201527f22312e322220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f3260408201527f3030302f737667223e3c696d6167652077696474683d2231323030222068656960608201527033b43a1e91189918181110343932b31e9160791b608082015260008251615a73816091850160208701614773565b6f111f1e17b4b6b0b3b29f1e17b9bb339f60811b609193909101928301525060a101919050565b6d1134b6b0b3b2afb230ba30911d1160911b81528151600090615ac481600e850160208701614773565b61088b60f21b600e939091019283015250601001919050565b6c1130ba3a3934b13aba32b9911d60991b81528151600090615b0681600d850160208701614773565b607d60f81b600d939091019283015250600e01919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251615b5681601d850160208701614773565b91909101601d0192915050565b848152836020820152608060408201526000615b826080830185614797565b8281036060840152615b948185614797565b979650505050505050565b683d913730b6b2911d1160b91b81526000615bbd600983018a615456565b701116113232b9b1b934b83a34b7b7111d1160791b8152615be1601182018a615456565b6a11161134b6b0b3b2911d1160a91b81529050615c01600b820189615456565b6b1116113130b73732b9111d1160a11b81529050615c22600c820188615456565b7211161132bc3a32b93730b62fb634b735911d1160691b81529050615c4a6013820187615456565b7b11161139b2b63632b92fb332b2afb130b9b4b9afb837b4b73a39911d60211b81528551909150615c8281601c840160208901614773565b7116113332b2afb932b1b4b834b2b73a111d1160711b601c9290910191820152615caf602e820185615456565b61227d60f01b81526002019a9950505050505050505050565b60ff81811683821602908116908181146130125761301261535a565b60ff82811682821603908111156108e7576108e761535a565b60ff81811683821601908111156108e7576108e761535a565b600060ff821660ff8103615d2c57615d2c61535a565b60010192915050565b6000815260008251615d4e816001850160208701614773565b9190910160010192915050565b600082615d6a57615d6a61542c565b500490565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061454290830184614797565b600060208284031215615db457600080fd5b8151613a3a81614740565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201528151600090615e0281600e850160208701614773565b91909101600e019392505050565b60008251615e22818460208701614773565b919091019291505056fe3c7376672077696474683d223136303022206865696768743d2231363030222076696577426f783d2230203020313630302031363030222076657273696f6e3d22312e322220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207374796c653d226261636b67726f756e642d636f6c6f723a20234142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef3c7376672077696474683d223130302522206865696768743d22313030252220a264697066735822122020ca10d25cc2579867a12aa3307559f37a93dd8bba2ce9793f5ce20ade52099564736f6c63430008110033

Deployed Bytecode Sourcemap

1711:28903:21:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5655:607:16;;;;;;;;;;-1:-1:-1;5655:607:16;;;;;:::i;:::-;;:::i;:::-;;;565:14:22;;558:22;540:41;;528:2;513:18;5655:607:16;;;;;;;;11163:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;13050:200::-;;;;;;;;;;-1:-1:-1;13050:200:16;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:22;;;1679:51;;1667:2;1652:18;13050:200:16;1533:203:22;12613:376:16;;;;;;;;;;-1:-1:-1;12613:376:16;;;;;:::i;:::-;;:::i;:::-;;27917:690:21;;;;;;;;;;-1:-1:-1;27917:690:21;;;;;:::i;:::-;;:::i;27224:144::-;;;;;;;;;;-1:-1:-1;27224:144:21;;;;;:::i;:::-;;:::i;6909:429::-;;;;;;;;;;-1:-1:-1;6909:429:21;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;7129:33:22;;;7111:52;;7099:2;7084:18;6909:429:21;6967:202:22;4738:309:16;;;;;;;;;;-1:-1:-1;5000:12:16;;4791:7;4984:13;:28;-1:-1:-1;;4984:46:16;4738:309;;;7320:25:22;;;7308:2;7293:18;4738:309:16;7174:177:22;29430:212:21;;;;;;;;;;-1:-1:-1;29430:212:21;;;;;:::i;:::-;;:::i;22057:2739:16:-;;;;;;;;;;-1:-1:-1;22057:2739:16;;;;;:::i;:::-;;:::i;29141:283:21:-;;;;;;;;;;-1:-1:-1;29141:283:21;;;;;:::i;:::-;;:::i;4607:38::-;;;;;;;;;;-1:-1:-1;4607:38:21;;;;;;;;7344:1036;;;;;;:::i;:::-;;:::i;4652:752::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;27500:168::-;;;;;;;;;;;;;:::i;26991:104::-;;;;;;;;;;;;;:::i;13914:179:16:-;;;;;;;;;;-1:-1:-1;13914:179:16;;;;;:::i;:::-;;:::i;27120:98:21:-;;;;;;;;;;-1:-1:-1;27120:98:21;;;;;:::i;:::-;;:::i;9213:219::-;;;;;;;;;;-1:-1:-1;9213:219:21;;;;;:::i;:::-;;:::i;26862:123::-;;;;;;;;;;;;;:::i;11245:6456::-;;;;;;;;;;-1:-1:-1;11245:6456:21;;;;;:::i;:::-;;:::i;10959:142:16:-;;;;;;;;;;-1:-1:-1;10959:142:16;;;;;:::i;:::-;;:::i;20073:2027:21:-;;;;;;;;;;-1:-1:-1;20073:2027:21;;;;;:::i;:::-;;:::i;4456:37::-;;;;;;;;;;;;;;;;4542:59;;;;;;;;;;;;;:::i;6321:221:16:-;;;;;;;;;;-1:-1:-1;6321:221:16;;;;;:::i;:::-;;:::i;1831:101:0:-;;;;;;;;;;;;;:::i;29661:570:21:-;;;;;;;;;;-1:-1:-1;29661:570:21;;;;;:::i;:::-;;:::i;27702:209::-;;;;;;;;;;-1:-1:-1;27702:209:21;;;;;:::i;:::-;;:::i;8386:821::-;;;;;;;;;;-1:-1:-1;8386:821:21;;;;;:::i;:::-;;:::i;1201:85:0:-;;;;;;;;;;;;;:::i;11325:102:16:-;;;;;;;;;;;;;:::i;30369:243:21:-;;;;;;;;;;-1:-1:-1;30369:243:21;;;;;:::i;:::-;;:::i;13317:303:16:-;;;;;;;;;;-1:-1:-1;13317:303:16;;;;;:::i;:::-;;:::i;4499:37:21:-;;;;;;;;;;;;;;;;407:308:9;;;;;;;;;;-1:-1:-1;407:308:9;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;17707:2360:21:-;;;;;;;;;;-1:-1:-1;17707:2360:21;;;;;:::i;:::-;;:::i;14159:388:16:-;;;;;;;;;;-1:-1:-1;14159:388:16;;;;;:::i;:::-;;:::i;4257:70:21:-;;;;;;;;;;-1:-1:-1;4257:70:21;;;;-1:-1:-1;;;;;4257:70:21;;;22106:3362;;;;;;;;;;-1:-1:-1;22106:3362:21;;;;;:::i;:::-;;:::i;4410:40::-;;;;;;;;;;;;4446:4;4410:40;;26569:204;;;;;;;;;;-1:-1:-1;26569:204:21;;;;;:::i;:::-;;:::i;28613:522::-;;;;;;;;;;-1:-1:-1;28613:522:21;;;;;:::i;:::-;;:::i;25474:1089::-;;;;;;;;;;;;;:::i;13686:162:16:-;;;;;;;;;;-1:-1:-1;13686:162:16;;;;;:::i;:::-;-1:-1:-1;;;;;13806:25:16;;;13783:4;13806:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;13686:162;4333:71:21;;;;;;;;;;-1:-1:-1;4333:71:21;;;;-1:-1:-1;;;;;4333:71:21;;;9438:109;;;;;;;;;;-1:-1:-1;9438:109:21;;;;;:::i;:::-;-1:-1:-1;;;;;9523:17:21;9497:7;9523:17;;;:7;:17;;;;;;;9438:109;2081:198:0;;;;;;;;;;-1:-1:-1;2081:198:0;;;;;:::i;:::-;;:::i;30237:126:21:-;;;;;;;;;;-1:-1:-1;30237:126:21;;;;;:::i;:::-;;:::i;10606:391::-;;;;;;;;;;-1:-1:-1;10606:391:21;;;;;:::i;:::-;;:::i;5655:607:16:-;5740:4;-1:-1:-1;;;;;;;;;6035:25:16;;;;:101;;-1:-1:-1;;;;;;;;;;6111:25:16;;;6035:101;:177;;;-1:-1:-1;;;;;;;;;;6187:25:16;;;6035:177;6016:196;5655:607;-1:-1:-1;;5655:607:16:o;11163:98::-;11217:13;11249:5;11242:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11163:98;:::o;13050:200::-;13118:7;13142:16;13150:7;13142;:16::i;:::-;13137:64;;13167:34;;-1:-1:-1;;;13167:34:16;;;;;;;;;;;13137:64;-1:-1:-1;13219:24:16;;;;:15;:24;;;;;;-1:-1:-1;;;;;13219:24:16;;13050:200::o;12613:376::-;12685:13;12701:16;12709:7;12701;:16::i;:::-;12685:32;-1:-1:-1;32962:10:16;-1:-1:-1;;;;;12732:28:16;;;12728:172;;12779:44;12796:5;32962:10;13686:162;:::i;12779:44::-;12774:126;;12850:35;;-1:-1:-1;;;12850:35:16;;;;;;;;;;;12774:126;12910:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;12910:29:16;-1:-1:-1;;;;;12910:29:16;;;;;;;;;12954:28;;12910:24;;12954:28;;;;;;;12675:314;12613:376;;:::o;27917:690:21:-;28111:10;28090:17;28098:8;28090:7;:17::i;:::-;-1:-1:-1;;;;;28090:31:21;;28082:40;;;;;;28133:18;;;;:8;:18;;;;;:52;28176:9;28133:18;:52;:::i;:::-;-1:-1:-1;28195:18:21;;;;:8;:18;;;;;:38;;:48;28236:7;28195:38;:48;:::i;:::-;-1:-1:-1;28253:18:21;;;;:8;:18;;;;;:39;;:50;28295:8;28253:39;:50;:::i;:::-;;28314:17;28358:9;28372:19;28382:8;28372:9;:19::i;:::-;28341:51;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;28341:51:21;;;;;;;;;28403:18;;;;:8;28341:51;28403:18;;28341:51;;-1:-1:-1;28403:43:21;;:49;28341:51;28403:43;:49;:::i;:::-;;28468:132;28499:8;28521:9;28544:7;28565:8;28587:3;28468:132;;;;;;;;;;:::i;:::-;;;;;;;;28072:535;27917:690;;;;:::o;27224:144::-;1094:13:0;:11;:13::i;:::-;27333:28:21;;27348:13;;27333:12:::1;::::0;;;:28:::1;::::0;:12;:28:::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;27333:28:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;;;;27224:144:21:o;6909:429::-;7121:10;;7068:6;;-1:-1:-1;;;;;7121:10:21;7107;:24;;:141;;-1:-1:-1;7158:10:21;;7151:73;;-1:-1:-1;;;7151:73:21;;;;;7320:25:22;;;-1:-1:-1;;;;;7151:97:21;;;;7158:10;;7151:26;;7293:18:22;;7151:73:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;7151:97:21;;7107:141;7086:172;;;;;;-1:-1:-1;;;;;7269:13:21;;;;;;:7;:13;;;;;:15;;;;;;:::i;:::-;;;;-1:-1:-1;;;;7301:30:21;6909:429;-1:-1:-1;;;;;;;6909:429:21:o;29430:212::-;29526:17;29534:8;29526:7;:17::i;:::-;-1:-1:-1;;;;;29512:31:21;:10;-1:-1:-1;;;;;29512:31:21;;29504:40;;;;;;29554:21;;;;:11;:21;;;;;;;;;:32;;-1:-1:-1;;29554:32:21;;;;;;;;;;29602:33;;22559:25:22;;;22600:18;;;22593:50;29602:33:21;;22532:18:22;29602:33:21;;;;;;;;29430:212;;:::o;22057:2739:16:-;22186:27;22216;22235:7;22216:18;:27::i;:::-;22186:57;;22299:4;-1:-1:-1;;;;;22258:45:16;22274:19;-1:-1:-1;;;;;22258:45:16;;22254:86;;22312:28;;-1:-1:-1;;;22312:28:16;;;;;;;;;;;22254:86;22352:27;20823:21;;;20654:15;20864:4;20857:36;20945:4;20929:21;;21033:26;;32962:10;21768:30;;;-1:-1:-1;;;;;21470:26:16;;21747:19;;;21744:55;22528:173;;22614:43;22631:4;32962:10;13686:162;:::i;22614:43::-;22609:92;;22666:35;;-1:-1:-1;;;22666:35:16;;;;;;;;;;;22609:92;-1:-1:-1;;;;;22716:16:16;;22712:52;;22741:23;;-1:-1:-1;;;22741:23:16;;;;;;;;;;;22712:52;22907:15;22904:157;;;23045:1;23024:19;23017:30;22904:157;-1:-1:-1;;;;;23431:24:16;;;;;;;:18;:24;;;;;;23429:26;;-1:-1:-1;;23429:26:16;;;23499:22;;;;;;23497:24;;23429:26;23497:24;;;23814:142;23518:2;23897:45;23450:4;23518:2;23922:19;23897:14;:45::i;:::-;-1:-1:-1;;;23870:72:16;23814:18;:142::i;:::-;23785:26;;;;:17;:26;;;;;:171;;;;-1:-1:-1;;;24073:46:16;;:51;;24069:616;;24176:1;24166:11;;24144:19;24297:30;;;:17;:30;;;;;;:35;;24293:378;;24433:13;;24418:11;:28;24414:239;;24578:30;;;;:17;:30;;;;;:52;;;24414:239;24126:559;24069:616;24729:7;24725:2;-1:-1:-1;;;;;24710:27:16;24719:4;-1:-1:-1;;;;;24710:27:16;-1:-1:-1;;;;;;;;;;;24710:27:16;;;;;;;;;24747:42;22176:2620;;;22057:2739;;;:::o;29141:283:21:-;29242:17;29250:8;29242:7;:17::i;:::-;-1:-1:-1;;;;;29228:31:21;:10;-1:-1:-1;;;;;29228:31:21;;29220:40;;;;;;29275:9;29270:101;3768:2;29290:1;:14;29270:101;;;29351:6;29358:1;29351:9;;;;;;;;:::i;:::-;;;;;;;;;;;;29325:20;;;;:10;:20;;;;;;:23;;;;;;;;;;:35;;-1:-1:-1;;29325:35:21;;;;;;;;;;:23;29306:3;29325:23;29306:3;:::i;:::-;;;;29270:101;;;;29386:31;29400:8;29410:6;29386:31;;;;;;;:::i;7344:1036::-;7434:7;2261:21:1;:19;:21::i;:::-;26823:14:21::1;:12;:14::i;:::-;26815:23;;;::::0;::::1;;7453:19:::2;7475:14;:12;:14::i;:::-;7513:10;7507:17;::::0;;;:5:::2;:17;::::0;;;;;7453:36;;-1:-1:-1;7537:3:21::2;::::0;7507:26:::2;::::0;7527:6;;7507:26:::2;:::i;:::-;:33;;7499:42;;;::::0;::::2;;3818:2;7559:6;:24;;:38;;;;;7596:1;7587:6;:10;7559:38;7551:47;;;::::0;::::2;;4446:4;7616:20;7630:6:::0;7616:11;:20:::2;:::i;:::-;:33;;7608:42;;;::::0;::::2;;7668:10;7682:9;7668:23;7660:32;;;::::0;::::2;;7755:10;7703:16;7747:19:::0;;;:7:::2;:19;::::0;;;;;7780:11;;7776:496:::2;;7822:6;7811:7;:17;7807:384;;7871:7;7859:9;;:19;;;;:::i;:::-;7848:30;;7940:8;7927:9;;7918:6;:18;;;;:::i;:::-;7917:31;;;;:::i;:::-;7904:9;:44;;7896:53;;;::::0;::::2;;7975:10;7989:1;7967:19:::0;;;:7:::2;:19;::::0;;;;:23;7776:496:::2;;7807:384;8052:6;8040:9;;:18;;;;:::i;:::-;8029:29;;8120:8;8107:9;;8098:6;:18;;;;:::i;:::-;8097:31;;;;:::i;:::-;8084:9;:44;;8076:53;;;::::0;::::2;;8155:10;8147:19;::::0;;;:7:::2;:19;::::0;;;;:29;;8170:6;;8147:19;:29:::2;::::0;8170:6;;8147:29:::2;:::i;:::-;::::0;;;-1:-1:-1;7776:496:21::2;::::0;-1:-1:-1;7776:496:21::2;;8251:9;::::0;8242:18:::2;::::0;:6;:18:::2;:::i;:::-;8229:9;:31;;8221:40;;;::::0;::::2;;8288:10;8282:17;::::0;;;:5:::2;:17;::::0;;;;:27;;8303:6;;8282:17;:27:::2;::::0;8303:6;;8282:27:::2;:::i;:::-;::::0;;;-1:-1:-1;8319:25:21::2;::::0;-1:-1:-1;8325:10:21::2;8337:6:::0;8319:5:::2;:25::i;:::-;-1:-1:-1::0;;1716:1:1;2809:7;:22;8362:11:21;7344:1036;-1:-1:-1;;7344:1036:21:o;2303:20:1:-;7344:1036:21;;;:::o;4652:752::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;27500:168::-;27557:21;27596:11;27588:20;;;;;;27644:6;;27618:43;;-1:-1:-1;;;;;27644:6:21;27653:7;27618:17;:43::i;:::-;27529:139;27500:168::o;26991:104::-;1094:13:0;:11;:13::i;:::-;27070:18:21::1;::::0;;-1:-1:-1;;27048:40:21;::::1;27070:18;::::0;;::::1;27069:19;27048:40;::::0;;26991:104::o;13914:179:16:-;14047:39;14064:4;14070:2;14074:7;14047:39;;;;;;;;;;;;:16;:39::i;:::-;13914:179;;;:::o;27120:98:21:-;1094:13:0;:11;:13::i;:::-;27193:7:21::1;:18;27203:8:::0;27193:7;:18:::1;:::i;:::-;;27120:98:::0;:::o;9213:219::-;9290:4;9308:11;9305:121;;;-1:-1:-1;9341:19:21;;;;:9;:19;;;;;;;;9334:26;;9305:121;-1:-1:-1;;9398:17:21;;;;:7;:17;;;;;;;;;9213:219::o;26862:123::-;26907:4;4446;26930:14;:12;:14::i;:::-;:26;:48;;;;-1:-1:-1;26960:18:21;;;;26930:48;26923:55;;26862:123;:::o;11245:6456::-;11331:13;11368:17;11376:8;11368:7;:17::i;:::-;11360:26;;;;;;11461:22;11486:38;11509:14;3768:2;11522:1;11509:14;:::i;:::-;11486:22;:38::i;:::-;11559:25;;;3768:2;11559:25;;;;;;;;;11461:63;;-1:-1:-1;11535:21:21;;11559:25;;;;;;;;;;;-1:-1:-1;11559:25:21;11535:49;;11600:9;11595:5651;3768:2;11615:1;:14;11595:5651;;;11650:18;11671:4;11676:1;11671:7;;;;;;;;:::i;:::-;;;;;;;11650:28;;11703:1;11699;11695;:5;;;;:::i;:::-;:9;:47;;;;-1:-1:-1;11708:22:21;;;;:12;:22;;;;;;;;:25;;;;;;;;;;;:34;11695:47;11692:5544;;;11789:1;11771:5;11777:1;11771:8;;;;;;;:::i;:::-;;:15;:19;;;;:::i;:::-;11761:4;11766:1;11761:7;;;;;;;;:::i;:::-;;;;;;:29;;;;;11692:5544;;;11829:22;11861;11874:8;11861:12;:22::i;:::-;:32;;;11829:65;;;-1:-1:-1;11912:18:21;4446:4;11829:65;12087:8;12125:12;12136:1;12087:8;12125:12;:::i;:::-;11997:166;;;;;;24374:19:22;;;;24409:12;;24402:28;;;;24446:12;;;24439:28;24483:12;;11997:166:21;;;;;;;;;;;;11962:223;;;;;;11933:270;;:282;;;;:::i;:::-;11912:303;;12247:24;12257:10;12269:1;12247:9;:24::i;:::-;12234:37;;12299:10;12289:4;12294:1;12289:7;;;;;;;;:::i;:::-;;;;;;:20;;;;;12327:10;12358:1;12340:5;12346:1;12340:8;;;;;;;:::i;:::-;;:15;:19;;;;:::i;:::-;12382:20;;;;:10;:20;;;;;;;;:23;;;;;;;;;12327:32;;-1:-1:-1;12382:23:21;;:31;;:23;:31;12378:4844;;12440:1;12445:2;12440:7;:24;;;;;12451:4;12456:1;12451:7;;;;;;;;:::i;:::-;;;;;;;12462:2;12451:13;12440:24;12436:2580;;;12501:5;12491:4;12496:1;12491:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;12535:20;;;;:10;:20;;;;;;12556:1;12535:23;;;;;;;;;;;:32;;;;12532:51;;12579:2;12569:4;12574:1;12569:7;;;;;;;;:::i;:::-;;;;;;:12;;;;;12532:51;12378:4844;;12436:2580;12616:1;12621:2;12616:7;:23;;;;;12627:4;12632:1;12627:7;;;;;;;;:::i;:::-;;;;;;;12638:1;12627:12;12616:23;12612:2404;;;12677:5;12667:4;12672:1;12667:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;12711:20;;;;:10;:20;;;;;;12732:1;12711:23;;;;;;;;;;;:32;;;;12708:50;;12755:1;12745:4;12750:1;12745:7;;;;;;;;:::i;12612:2404::-;12815:1;12820:2;12815:7;:23;;;;;12826:4;12831:1;12826:7;;;;;;;;:::i;:::-;;;;;;;12837:1;12826:12;12815:23;12811:2205;;;12876:5;12866:4;12871:1;12866:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;12910:20;;;;:10;:20;;;;;;12931:2;12910:24;;;;;;;;;;;:33;;;;12907:52;;12956:1;12945:4;12950:2;12945:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;12907:52;12987:20;;;;:10;:20;;;;;;;;13008:1;12987:23;;;;;;;;;;:32;;;;12984:50;;13031:1;13021:4;13026:1;13021:7;;;;;;;;:::i;:::-;;;;;;:11;;;;;12984:50;13062:20;;;;:10;:20;;;;;;;;13083:1;13062:23;;;;;;;;;;:32;;;;13059:50;;13106:1;13096:4;13101:1;13096:7;;;;;;;;:::i;12811:2205::-;13166:1;13171:2;13166:7;:23;;;;;13177:4;13182:1;13177:7;;;;;;;;:::i;:::-;;;;;;;13188:1;13177:12;13166:23;13162:1854;;;13227:5;13217:4;13222:1;13217:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;13261:20;;;;:10;:20;;;;;;13282:2;13261:24;;;;;;;;;;;:33;;;;13258:52;;13307:1;13296:4;13301:2;13296:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;13258:52;13338:20;;;;:10;:20;;;;;;;;13359:1;13338:23;;;;;;;;;;:32;;;;13335:50;;13382:1;13372:4;13377:1;13372:7;;;;;;;;:::i;13162:1854::-;13418:1;13423:2;13418:7;:23;;;;;13429:4;13434:1;13429:7;;;;;;;;:::i;:::-;;;;;;;13440:1;13429:12;13418:23;13414:1602;;;13479:5;13469:4;13474:1;13469:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;13513:20;;;;:10;:20;;;;;;13534:2;13513:24;;;;;;;;;;;:33;;;;13510:52;;13559:1;13548:4;13553:2;13548:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;13510:52;13590:20;;;;:10;:20;;;;;;;;13611:1;13590:23;;;;;;;;;;:32;;;;13587:50;;13634:1;13624:4;13629:1;13624:7;;;;;;;;:::i;13414:1602::-;13670:1;13675:2;13670:7;:23;;;;;13681:4;13686:1;13681:7;;;;;;;;:::i;:::-;;;;;;;13692:1;13681:12;13670:23;13666:1350;;;13731:5;13721:4;13726:1;13721:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;13765:20;;;;:10;:20;;;;;;13786:2;13765:24;;;;;;;;;;;:33;;;;13762:52;;13811:1;13800:4;13805:2;13800:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;13762:52;13842:20;;;;:10;:20;;;;;;;;13863:1;13842:23;;;;;;;;;;:32;;;;13839:50;;13886:1;13876:4;13881:1;13876:7;;;;;;;;:::i;13666:1350::-;13946:1;13951:2;13946:7;:23;;;;;13957:4;13962:1;13957:7;;;;;;;;:::i;:::-;;;;;;;13968:1;13957:12;13946:23;13942:1074;;;14007:5;13997:4;14002:1;13997:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;14041:20;;;;:10;:20;;;;;;14062:2;14041:24;;;;;;;;;;;:33;;;;14038:52;;14087:1;14076:4;14081:2;14076:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;14038:52;14118:20;;;;:10;:20;;;;;;;;14139:1;14118:23;;;;;;;;;;:32;;;;14115:50;;14162:1;14152:4;14157:1;14152:7;;;;;;;;:::i;13942:1074::-;14198:1;14203:2;14198:7;:23;;;;;14209:4;14214:1;14209:7;;;;;;;;:::i;:::-;;;;;;;14220:1;14209:12;14198:23;14194:822;;;14259:5;14249:4;14254:1;14249:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;14293:20;;;;:10;:20;;;;;;14314:2;14293:24;;;;;;;;;;;:33;;;;14290:52;;14339:1;14328:4;14333:2;14328:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;14290:52;14370:20;;;;:10;:20;;;;;;;;14391:1;14370:23;;;;;;;;;;:32;;;;14367:50;;14414:1;14404:4;14409:1;14404:7;;;;;;;;:::i;14194:822::-;14450:1;14455:2;14450:7;:24;;;;;14461:4;14466:1;14461:7;;;;;;;;:::i;:::-;;;;;;;14472:2;14461:13;14450:24;14446:570;;;14512:5;14502:4;14507:1;14502:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;14546:20;;;;:10;:20;;;;;;14567:2;14546:24;;;;;;;;;;;:33;;;;14543:52;;14592:1;14581:4;14586:2;14581:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;14543:52;14623:20;;;;:10;:20;;;;;;;;14644:1;14623:23;;;;;;;;;;:32;;;;14620:50;;14667:1;14657:4;14662:1;14657:7;;;;;;;;:::i;14446:570::-;14703:1;14708:2;14703:7;:24;;;;;14714:4;14719:1;14714:7;;;;;;;;:::i;:::-;;;;;;;14725:2;14714:13;14703:24;14699:317;;;14765:5;14755:4;14760:1;14755:7;;;;;;;;:::i;:::-;;;;;;;;;;;:15;;;;14799:20;;;;:10;:20;;;;;;14820:2;14799:24;;;;;;;;;;;:33;;;;14796:52;;14845:1;14834:4;14839:2;14834:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;14796:52;14876:20;;;;:10;:20;;;;;;;;14897:1;14876:23;;;;;;;;;;:32;;;;14873:50;;14920:1;14910:4;14915:1;14910:7;;;;;;;;:::i;14699:317::-;14988:5;14978:4;14983:1;14978:7;;;;;;;;:::i;12378:4844::-;15088:1;15093:2;15088:7;:25;;;;;15099:4;15104:2;15099:8;;;;;;;;:::i;:::-;;;;;;;15111:2;15099:14;15088:25;15084:129;;;15143:20;;;;:10;:20;;;;;;;;15164:1;15143:23;;;;;;;;;;:32;;;;15140:51;;15187:2;15177:4;15182:1;15177:7;;;;;;;;:::i;:::-;;;;;;:12;;;;;15140:51;15238:1;15243:2;15238:7;15234:1970;;15276:4;15281:2;15276:8;;;;;;;;:::i;:::-;;;;;;;15288:1;15276:13;15272:1910;;15324:20;;;;:10;:20;;;;;;;;15345:1;15324:23;;;;;;;;;;:32;;;;15321:50;;15368:1;15358:4;15363:1;15358:7;;;;;;;;:::i;15272:1910::-;15407:4;15412:2;15407:8;;;;;;;;:::i;:::-;;;;;;;15419:1;15407:13;15403:1779;;15455:20;;;;:10;:20;;;;;;;;15476:2;15455:24;;;;;;;;;;:33;;;;15452:52;;15501:1;15490:4;15495:2;15490:8;;;;;;;;:::i;15403:1779::-;15699:4;15704:2;15699:8;;;;;;;;:::i;:::-;;;;;;;15711:1;15699:13;15695:1487;;15747:20;;;;:10;:20;;;;;;;;15768:2;15747:24;;;;;;;;;;:33;;;;15744:52;;15793:1;15782:4;15787:2;15782:8;;;;;;;;:::i;15695:1487::-;15912:4;15917:2;15912:8;;;;;;;;:::i;:::-;;;;;;;15924:1;15912:13;15908:1274;;15960:20;;;;:10;:20;;;;;;;;15981:2;15960:24;;;;;;;;;;:33;;;;15957:52;;16006:1;15995:4;16000:2;15995:8;;;;;;;;:::i;15908:1274::-;16125:4;16130:2;16125:8;;;;;;;;:::i;:::-;;;;;;;16137:1;16125:13;16121:1061;;16173:20;;;;:10;:20;;;;;;;;16194:2;16173:24;;;;;;;;;;:33;;;;16170:52;;16219:1;16208:4;16213:2;16208:8;;;;;;;;:::i;16121:1061::-;16338:4;16343:2;16338:8;;;;;;;;:::i;:::-;;;;;;;16350:1;16338:13;16334:848;;16386:20;;;;:10;:20;;;;;;;;16407:2;16386:24;;;;;;;;;;:33;;;;16383:52;;16432:1;16421:4;16426:2;16421:8;;;;;;;;:::i;16334:848::-;16551:4;16556:2;16551:8;;;;;;;;:::i;:::-;;;;;;;16563:1;16551:13;16547:635;;16599:20;;;;:10;:20;;;;;;;;16620:2;16599:24;;;;;;;;;;:33;;;;16596:52;;16645:1;16634:4;16639:2;16634:8;;;;;;;;:::i;16547:635::-;16764:4;16769:2;16764:8;;;;;;;;:::i;:::-;;;;;;;16776:2;16764:14;16760:422;;16813:20;;;;:10;:20;;;;;;;;16834:2;16813:24;;;;;;;;;;:33;;;;16810:52;;16859:1;16848:4;16853:2;16848:8;;;;;;;;:::i;16760:422::-;16978:4;16983:2;16978:8;;;;;;;;:::i;:::-;;;;;;;16990:2;16978:14;16974:208;;17027:20;;;;:10;:20;;;;;;;;17048:2;17027:24;;;;;;;;;;:33;;;;17024:52;;17073:1;17062:4;17067:2;17062:8;;;;;;;;:::i;:::-;;;;;;:12;;;;;17024:52;17108:20;;;;:10;:20;;;;;;;;17129:1;17108:23;;;;;;;;;;:32;;;;17105:50;;17152:1;17142:4;17147:1;17142:7;;;;;;;;:::i;:::-;;;;;;:11;;;;;17105:50;11811:5425;;;11692:5544;-1:-1:-1;11631:3:21;;;;:::i;:::-;;;;11595:5651;;;;17261:9;17256:404;17280:4;:11;17276:1;:15;17256:404;;;17326:2;17316:4;17321:1;17316:7;;;;;;;;:::i;:::-;;;;;;;:12;17312:160;;;17348:26;;;;;;;;;;;;-1:-1:-1;;;17348:26:21;;;;;;:9;;:20;:26::i;:::-;17312:160;;;17409:3;17399:4;17404:1;17399:7;;;;;;;;:::i;:::-;;;;;;;:13;17395:77;;;17432:25;;;;;;;;;;;;-1:-1:-1;;;17432:25:21;;;;;;:9;;:20;:25::i;:::-;17499:3;17489:4;17494:1;17489:7;;;;;;;;:::i;:::-;;;;;;;:13;17485:165;;;17522:27;;;;;;;;;;;;-1:-1:-1;;;17522:27:21;;;;;;:9;;:20;:27::i;:::-;17485:165;;;17588:47;17615:18;17625:4;17630:1;17625:7;;;;;;;;:::i;:::-;;;;;;;17615:9;:18::i;:::-;17588:9;;:20;:47::i;:::-;17293:3;;;;:::i;:::-;;;;17256:404;;;-1:-1:-1;17684:9:21;;11245:6456;-1:-1:-1;;;11245:6456:21:o;10959:142:16:-;11023:7;11065:27;11084:7;11065:18;:27::i;20073:2027:21:-;20163:13;20192:26;20221:34;20244:10;20221:22;:34::i;:::-;20192:63;;20265:29;;;;;;;;;;;;;;-1:-1:-1;;;20265:29:21;;;:13;:24;;:29;;;;:::i;:::-;20326:13;20305:12;20326:17;;;;;;;;20416:1;20326:17;20305:12;20344:55;20363:35;20384:5;20391:2;20395;20363:20;:35::i;:::-;20344:18;:55::i;:::-;20326:74;;;;;;;;;;;;;:79;;20320:93;;;;;:::i;:::-;20462:2;20427:12;20448:17;;;:13;:17;;20320:97;-1:-1:-1;20320:97:21;-1:-1:-1;20538:1:21;;-1:-1:-1;20448:17:21;20427:12;20466:55;20485:35;20506:5;20513:2;20517;20485:20;:35::i;20466:55::-;20448:74;;;;;;;;;;;;;:79;;20442:93;;;;;:::i;:::-;20584:2;20549:12;20570:17;;;:13;:17;;20442:97;-1:-1:-1;20442:97:21;-1:-1:-1;20660:1:21;;-1:-1:-1;20570:17:21;20549:12;20588:55;20607:35;20628:5;20635:2;20639;20607:20;:35::i;20588:55::-;20570:74;;;;;;;;;;;;;:79;;20564:93;;;;;:::i;:::-;20706:2;20671:12;20692:17;;;:13;:17;;20564:97;-1:-1:-1;20564:97:21;-1:-1:-1;20782:1:21;;-1:-1:-1;20692:17:21;20671:12;20710:55;20729:35;20750:5;20757:2;20761;20729:20;:35::i;20710:55::-;20692:74;;;;;;;;;;;;;:79;;20686:93;;;;;:::i;:::-;;;:97;20671:112;;20799:9;20794:1261;3768:2;20814:1;:14;20794:1261;;;20849:22;20874:99;20910:49;20931:5;20939;:1;20943;20939:5;:::i;:::-;20948;:1;20952;20948:5;:::i;:::-;20947:11;;20957:1;20947:11;:::i;:::-;20910:20;:49::i;20874:99::-;20997:16;;;;:13;:16;;;;;;;;20849:124;;;;;20997:32;;;;;;;;;20991:51;;20849:124;;-1:-1:-1;21045:1:21;;20991:51;;;:::i;:::-;;;:55;20987:1057;;;21067:317;21198:11;21210:1;21198:14;;;;;;;;:::i;:::-;;;;;;;;;21277:16;;;:13;:16;;;;;;:32;;;;;;;;;21113:253;;;;21198:14;;;;;21277:32;21113:253;;:::i;:::-;;;;-1:-1:-1;;21113:253:21;;;;;;;;;21067:13;;:24;:317::i;:::-;21407:1;21412:2;21407:7;:53;;;;;21419:7;:18;;;;;21430:7;21419:18;:29;;;;;21441:7;21419:29;:40;;;;;21452:7;21419:40;21403:627;;;21483:29;;;;;;;;;;;;-1:-1:-1;;;21483:29:21;;;;;;:13;;:24;:29::i;:::-;21403:627;;;21541:1;21546:2;21541:7;:42;;;;;21553:7;:18;;;;;21564:7;21553:18;:29;;;;;21575:7;21553:29;21537:493;;;21606:29;;;;;;;;;;;;-1:-1:-1;;;21606:29:21;;;;;;:13;;:24;:29::i;21537:493::-;21664:1;21669:2;21664:7;:31;;;;;21676:7;:18;;;;;21687:7;21676:18;21660:370;;;21718:29;;;;;;;;;;;;-1:-1:-1;;;21718:29:21;;;;;;:13;;:24;:29::i;21660:370::-;21776:1;21781:2;21776:7;:18;;;;;21787:7;21776:18;21772:258;;;21817:29;;;;;;;;;;;;-1:-1:-1;;;21817:29:21;;;;;;:13;;:24;:29::i;21772:258::-;21875:1;21880:2;21875:7;21871:159;;21906:29;;;;;;;;;;;;-1:-1:-1;;;21906:29:21;;;;;;:13;;:24;:29::i;21871:159::-;21982:29;;;;;;;;;;;;-1:-1:-1;;;21982:29:21;;;;;;:13;;:24;:29::i;:::-;-1:-1:-1;20830:3:21;;;;:::i;:::-;;;;20794:1261;;;-1:-1:-1;22079:13:21;;20073:2027;-1:-1:-1;;;;;;20073:2027:21:o;4542:59::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;6321:221:16:-;6385:7;-1:-1:-1;;;;;6408:19:16;;6404:60;;6436:28;;-1:-1:-1;;;6436:28:16;;;;;;;;;;;6404:60;-1:-1:-1;;;;;;6481:25:16;;;;;:18;:25;;;;;;-1:-1:-1;;;;;6481:54:16;;6321:221::o;1831:101:0:-;1094:13;:11;:13::i;:::-;1895:30:::1;1922:1;1895:18;:30::i;:::-;1831:101::o:0;29661:570:21:-;1094:13:0;:11;:13::i;:::-;29810:6:21::1;:13;29781:5;29787:11;29781:18;;;;;;;:::i;:::-;;:25:::0;:42:::1;29773:51;;;::::0;::::1;;29834:29;29880:6;:13;-1:-1:-1::0;;;;;29866:28:21::1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;29866:28:21::1;;29834:60;;29909:9;29904:249;29928:6;:13;29924:1;:17;29904:249;;;29980:29;29994:6;30001:1;29994:9;;;;;;;;:::i;:::-;;;;;;;:14;;;29980:13;:29::i;:::-;29962:12;29975:1;29962:15;;;;;;;;:::i;:::-;;;;;;:47;-1:-1:-1::0;;;;;29962:47:21::1;;;-1:-1:-1::0;;;;;29962:47:21::1;;;::::0;::::1;30055:87;;;;;;;;30078:6;30085:1;30078:9;;;;;;;;:::i;:::-;;;;;;;:14;;;30055:87;;;;30110:6;30117:1;30110:9;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;:18;::::1;::::0;30055:87;;;30023:26:::1;::::0;;;:13:::1;:26:::0;;;;;;:29;;;;;;;:119;;:29;;:119:::1;::::0;:29;:119:::1;:::i;:::-;-1:-1:-1::0;30023:119:21::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;;;;;29943:3;;;;;:::i;:::-;;;;29904:249;;;-1:-1:-1::0;30162:31:21::1;::::0;;;:18:::1;:31;::::0;;;;;;;:46;;::::1;::::0;;::::1;::::0;::::1;:::i;27702:209::-:0;27810:10;27789:17;27797:8;27789:7;:17::i;:::-;-1:-1:-1;;;;;27789:31:21;;27781:40;;;;;;27831:17;;;;:7;:17;;;;;:28;27851:8;27831:17;:28;:::i;:::-;;27875:29;27885:8;27895;27875:29;;;;;;;:::i;8386:821::-;8487:7;2261:21:1;:19;:21::i;:::-;26823:14:21::1;:12;:14::i;:::-;26815:23;;;::::0;::::1;;8506:19:::2;8528:14;:12;:14::i;:::-;8506:36;;8555:11;8552:286;;;8589:19;::::0;;;:9:::2;:19;::::0;;;;;::::2;;:28;8581:37;;;::::0;::::2;;8661:11;::::0;8654:37:::2;::::0;-1:-1:-1;;;8654:37:21;;::::2;::::0;::::2;7320:25:22::0;;;-1:-1:-1;;;;;8661:11:21;;::::2;::::0;8654:27:::2;::::0;7293:18:22;;8654:37:21::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8640:51:21::2;:10;-1:-1:-1::0;;;;;8640:51:21::2;;8632:60;;;::::0;::::2;;4446:4;8714:15;:11:::0;8728:1:::2;8714:15;:::i;:::-;:28;;8706:37;;;::::0;::::2;;8758:19;::::0;;;:9:::2;:19;::::0;;;;:26;;-1:-1:-1;;8758:26:21::2;8780:4;8758:26:::0;;::::2;::::0;;;8798:20:::2;::::0;8804:10:::2;::::0;8798:5:::2;:20::i;:::-;8852:11;8848:325;;8898:4;8886:8;:16;;8878:25;;;::::0;::::2;;8925:17;::::0;;;:7:::2;:17;::::0;;;;;::::2;;:26;8917:35;;;::::0;::::2;;8995:10;::::0;8988:36:::2;::::0;-1:-1:-1;;;8988:36:21;;::::2;::::0;::::2;7320:25:22::0;;;-1:-1:-1;;;;;8995:10:21;;::::2;::::0;8988:26:::2;::::0;7293:18:22;;8988:36:21::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8974:50:21::2;:10;-1:-1:-1::0;;;;;8974:50:21::2;;8966:59;;;::::0;::::2;;4446:4;9047:15;:11:::0;9061:1:::2;9047:15;:::i;:::-;:28;;9039:37;;;::::0;::::2;;9091:17;::::0;;;:7:::2;:17;::::0;;;;:24;;-1:-1:-1;;9091:24:21::2;9111:4;9091:24:::0;;::::2;::::0;;;9129:20:::2;::::0;9135:10:::2;::::0;9129:5:::2;:20::i;:::-;9189:11:::0;-1:-1:-1;2303:20:1;1716:1;2809:7;:22;2629:209;1201:85:0;1273:6;;-1:-1:-1;;;;;1273:6:0;;1201:85::o;11325:102:16:-;11381:13;11413:7;11406:14;;;;;:::i;30369:243:21:-;30456:2;30447:6;:11;30439:20;;;;;;30491:17;30499:8;30491:7;:17::i;:::-;-1:-1:-1;;;;;30477:31:21;:10;-1:-1:-1;;;;;30477:31:21;;30469:40;;;;;;30520:22;;;;:12;:22;;;;;;;;:30;;;;;;;;;:37;;-1:-1:-1;;30520:37:21;30553:4;30520:37;;;30573:32;;26510:25:22;;;26551:18;;;26544:34;;;30573:32:21;;26483:18:22;30573:32:21;26336:248:22;13317:303:16;32962:10;-1:-1:-1;;;;;13415:31:16;;;13411:61;;13455:17;;-1:-1:-1;;;13455:17:16;;;;;;;;;;;13411:61;32962:10;13483:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;13483:49:16;;;;;;;;;;;;:60;;-1:-1:-1;;13483:60:16;;;;;;;;;;13558:55;;540:41:22;;;13483:49:16;;32962:10;13558:55;;513:18:22;13558:55:16;;;;;;;13317:303;;:::o;407:308:9:-;475:22;531:4;-1:-1:-1;;;;;519:24:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;509:34;;558:9;553:132;573:15;;;553:132;;;622:52;659:4;666;;671:1;666:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;622:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;622:28:9;;-1:-1:-1;;;622:52:9:i;:::-;609:7;617:1;609:10;;;;;;;;:::i;:::-;;;;;;:65;;;;590:3;;;;;:::i;:::-;;;;553:132;;;;407:308;;;;:::o;17707:2360:21:-;17810:13;17839:22;17871;:33;;;;;;;;;;;;;-1:-1:-1;;;17871:33:21;;;;;17953:1;17925:7;:17;17933:8;17925:17;;;;;;;;;;;17919:31;;;;;:::i;:::-;;;:35;17915:94;;;17981:17;;;;:7;:17;;;;;17970:28;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17915:94;18019:21;18043:34;18066:10;18043:22;:34::i;:::-;18019:58;;18087:176;;;;;;;;;;;;;;;;;;:8;;:19;:176::i;:::-;18273:95;18323:8;18306:52;;;;;;;;:::i;:::-;;;;-1:-1:-1;;18306:52:21;;;;;;;;;18273:8;;:19;:95::i;:::-;18383:9;18378:711;18402:14;18415:1;3768:2;18402:14;:::i;:::-;18398:1;:18;18378:711;;;18450:1;18442:5;18446:1;18442;:5;:::i;:::-;:9;:47;;;;-1:-1:-1;18455:22:21;;;;:12;:22;;;;;;;;:25;;;;;;;;;;;:34;18442:47;18437:642;;18526:107;18566:49;18587:5;18595;:1;18599;18595:5;:::i;:::-;18604;:1;18608;18604:5;:::i;18526:107::-;18509:124;;;;18651:413;18767:13;:16;18781:1;18767:16;;;;;;;;;;;:32;18784:14;18767:32;;;;;;;;;;;:41;;18870:120;18913:51;18926:18;:21;18945:1;18926:21;;;;;;;;;;;18948:14;18926:37;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;18926:37:21;18913:12;:51::i;:::-;18870:13;:120::i;:::-;18692:354;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;18692:354:21;;;;;;;;;18651:8;;:19;:413::i;:::-;18418:3;;;;:::i;:::-;;;;18378:711;;;-1:-1:-1;19116:107:21;19148:65;19169:5;19195:1;19177:14;3768:2;19195:1;19177:14;:::i;:::-;19176:20;;;;:::i;:::-;19198:14;3768:2;19211:1;19198:14;:::i;19116:107::-;19099:124;;;-1:-1:-1;19234:629:21;19326:13;:29;19340:14;19353:1;3768:2;19340:14;:::i;:::-;19326:29;;;;;;;;;;;:45;19356:14;19326:45;;;;;;;;;;;:54;;19426:163;19461:110;19499:18;:34;19531:1;3768:2;19518:14;;;;:::i;:::-;19499:34;;;;;;;;;;;19534:14;19499:50;;;;;;;;:::i;19426:163::-;19267:586;;;;;;;;;:::i;19234:629::-;20005:23;20019:8;20005:13;:23::i;:::-;19917:129;;;;;;;;:::i;:::-;;;;;;;;;;;;;19874:186;;;;;17707:2360;;;;:::o;14159:388:16:-;14320:31;14333:4;14339:2;14343:7;14320:12;:31::i;:::-;-1:-1:-1;;;;;14365:14:16;;;:19;14361:180;;14403:56;14434:4;14440:2;14444:7;14453:5;14403:30;:56::i;:::-;14398:143;;14486:40;;-1:-1:-1;;;14486:40:16;;;;;;;;;;;22106:3362:21;22204:13;22241:17;22249:8;22241:7;:17::i;:::-;22233:26;;;;;;22308:1;22277:21;;:18;:21;;;:28;22269:41;;;;;;22321:23;22347;22361:8;22347:13;:23::i;:::-;22321:49;;22381:22;22406:34;22429:10;22406:22;:34::i;:::-;22511:1;22460:18;;;:8;:18;;;;;22454:54;;22381:59;;-1:-1:-1;22511:1:21;;22454:54;;;:::i;:::-;;;:58;22450:360;;;22644:18;;;;:8;:18;;;;;;;;;22566:136;;22528:188;;22566:136;;22644:18;;22566:136;;:::i;22528:188::-;22450:360;;;22747:52;;;;;;;;;;;;-1:-1:-1;;;22747:52:21;;;;;;:9;;:20;:52::i;:::-;22820:233;22909:19;22919:8;22909:9;:19::i;:::-;22854:189;;;;;22983:24;;22854:189;;;:::i;22820:233::-;23092:1;23074:7;23068:21;;;;;:::i;:::-;;;:25;:59;;;;-1:-1:-1;23097:30:21;;;;:20;:30;;;;;;;;23068:59;23064:2077;;;23143:111;23211:7;23220:19;23230:8;23220:9;:19::i;:::-;23181:59;;;;;;;;;:::i;23143:111::-;23064:2077;;;23285:26;;;;;;;;;:21;:26;;;23329:21;;;:11;:21;;;;;;;;;;23325:1690;;;23370:23;23396:30;23406:9;23417:8;23396:9;:30::i;:::-;23370:56;;23578:438;23899:9;23621:369;;;;;;;;:::i;:::-;;;;;;;;;;;;;23578:13;:438::i;:::-;23482:556;;;;;;;;:::i;:::-;;;;;;;;;;;;;23444:612;;24074:115;24155:9;24116:55;;;;;;;;:::i;:::-;;;;-1:-1:-1;;24116:55:21;;;;;;;;;24074:9;;:20;:115::i;:::-;23352:852;23325:1690;;;24228:23;24254:30;24264:9;24275:8;24254:9;:30::i;:::-;24228:56;;24436:391;24710:9;24479:322;;;;;;;;:::i;24436:391::-;24340:509;;;;;;;;:::i;:::-;;;;;;;;;;;;;24302:565;;24885:115;24966:9;24927:55;;;;;;;;:::i;24885:115::-;24210:805;23325:1690;25029:101;25102:7;25067:49;;;;;;;;:::i;25029:101::-;23271:1870;23064:2077;25151:109;25219:25;25234:9;25219:14;:25::i;:::-;25185:65;;;;;;;;:::i;25151:109::-;25405:24;25419:9;25405:13;:24::i;:::-;25314:133;;;;;;;;:::i;:::-;;;;;;;;;;;;;25271:190;;;;22106:3362;;;:::o;26569:204::-;26690:17;26698:8;26690:7;:17::i;:::-;-1:-1:-1;;;;;26676:31:21;:10;-1:-1:-1;;;;;26676:31:21;;26668:40;;;;;;26718:30;;;;:20;:30;;;;;;:48;;-1:-1:-1;;26718:48:21;;;;;;;;;;26569:204::o;28613:522::-;28757:17;28765:8;28757:7;:17::i;:::-;-1:-1:-1;;;;;28743:31:21;:10;-1:-1:-1;;;;;28743:31:21;;28735:40;;;;;;28785:10;28798:18;;;:8;:18;;;;;:29;;;28840:18;;;28837:109;;28904:18;;;;:8;:18;;;;;:29;;:31;;28885:5;;-1:-1:-1;28885:5:21;;28904:31;;;;:::i;:::-;;;;;;28837:109;28956:18;;;;:8;:18;;;;;;;;:36;;;:25;;:36;;;;;:45;28995:6;28956:36;:45;:::i;:::-;-1:-1:-1;29011:18:21;;;;:8;:18;;;;;;;;:36;;;:25;;:36;;;;;:45;29050:6;29011:36;:45;:::i;:::-;;29072:56;29092:8;29102:9;29113:6;29121;29072:56;;;;;;;;;:::i;25474:1089::-;26308:22;;25518:13;;25677:847;;25803:12;;25899:24;;25996:18;;26088:19;;26188:20;;26298:33;;:9;:33::i;:::-;25716:786;;;;;;;;;;26411:31;;25716:786;;;:::i;25677:847::-;25586:956;;;;;;;;:::i;:::-;;;;;;;;;;;;;25543:1013;;25474:1089;:::o;2081:198:0:-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2169:22:0;::::1;2161:73;;;::::0;-1:-1:-1;;;2161:73:0;;39659:2:22;2161:73:0::1;::::0;::::1;39641:21:22::0;39698:2;39678:18;;;39671:30;39737:34;39717:18;;;39710:62;-1:-1:-1;;;39788:18:22;;;39781:36;39834:19;;2161:73:0::1;;;;;;;;;2244:28;2263:8;2244:18;:28::i;30237:126:21:-:0;1094:13:0;:11;:13::i;:::-;30350:6:21::1;30325:11;30337:9;30325:22;;;;;;;;:::i;:::-;;;;;;;;:31;;;;;;:::i;10606:391::-:0;1094:13:0;:11;:13::i;:::-;10706:21:21::1;10741:8;10730;:19;:41;;10763:8;10730:41;;;10752:8;10730:41;10706:65;;10782:37;10805:13;10782:22;:37::i;:::-;10833:26;10841:17;:13:::0;10857:1:::1;10841:17;:::i;:::-;10833:7;:26::i;:::-;10829:98;;;10875:41;10898:17;:13:::0;10914:1:::1;10898:17;:::i;:::-;10875:22;:41::i;:::-;10937:53;10953:13;10968:21;:19;:21::i;:::-;10937:15;:53::i;14793:268:16:-:0;14850:4;14904:7;4358:3;14885:26;;:65;;;;;14937:13;;14927:7;:23;14885:65;:150;;;;-1:-1:-1;;14987:26:16;;;;:17;:26;;;;;;-1:-1:-1;;;14987:43:16;:48;;14793:268::o;33080:1920::-;33543:4;33537:11;;33550:3;33533:21;;33626:17;;;;34309:11;;;34190:5;34439:2;34453;34443:13;;34435:22;34309:11;34422:36;34493:2;34483:13;;34084:682;34511:4;34084:682;;;34697:1;34692:3;34688:11;34681:18;;34747:2;34741:4;34737:13;34733:2;34729:22;34724:3;34716:36;34604:2;34594:13;;34084:682;;;-1:-1:-1;34794:13:16;;;-1:-1:-1;;34907:12:16;;;34965:19;;;34907:12;33080:1920;-1:-1:-1;33080:1920:16:o;1359:130:0:-;32962:10:16;1422:7:0;:5;:7::i;:::-;-1:-1:-1;;;;;1422:23:0;;1414:68;;;;-1:-1:-1;;;1414:68:0;;40066:2:22;1414:68:0;;;40048:21:22;;;40085:18;;;40078:30;40144:34;40124:18;;;40117:62;40196:18;;1414:68:0;39864:356:22;7951:1105:16;8018:7;8052;;4358:3;8098:23;8094:898;;8150:13;;8143:4;:20;8139:853;;;8187:14;8204:23;;;:17;:23;;;;;;;-1:-1:-1;;;8291:23:16;;:28;;8287:687;;8802:111;8809:6;8819:1;8809:11;8802:111;;-1:-1:-1;;;8879:6:16;8861:25;;;;:17;:25;;;;;;8802:111;;;8945:6;7951:1105;-1:-1:-1;;;7951:1105:16:o;8287:687::-;8165:827;8139:853;9018:31;;-1:-1:-1;;;9018:31:16;;;;;;;;;;;30101:302;30232:7;2166:3;30277:40;;;;30343:31;30354:4;30360:2;30277:40;30343:10;:31::i;:::-;30335:40;;:61;;;30101:302;-1:-1:-1;;;;;30101:302:16:o;10462:440::-;10865:11;10841:22;10837:40;10834:51;-1:-1:-1;;;;;10696:27:16;;;;10824:62;;10462:440::o;2336:287:1:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:1;;40427:2:22;2460:63:1;;;40409:21:22;40466:2;40446:18;;;40439:30;40505:33;40485:18;;;40478:61;40556:18;;2460:63:1;40225:355:22;2460:63:1;1759:1;2598:7;:18;2336:287::o;5140:279:16:-;5187:7;5371:13;-1:-1:-1;;5371:31:16;;5140:279::o;16565:1492::-;16629:20;16652:13;-1:-1:-1;;;;;16679:16:16;;16675:48;;16704:19;;-1:-1:-1;;;16704:19:16;;;;;;;;;;;16675:48;16737:8;16749:1;16737:13;16733:44;;16759:18;;-1:-1:-1;;;16759:18:16;;;;;;;;;;;16733:44;-1:-1:-1;;;;;17252:22:16;;;;;;:18;:22;;1156:2;17252:22;;:70;;-1:-1:-1;;;;;17278:44:16;;17252:70;;;17592:136;;17271:2;;17681:33;;17271:2;17252:22;17681:14;:33::i;:::-;12537:1;12524:15;;12499:23;12495:45;17648:66;17592:18;:136::i;:::-;17558:31;;;;:17;:31;;;;;:170;17576:12;17801:23;;;17838:99;17864:35;;17889:9;;;;;-1:-1:-1;;;;;17864:35:16;;;17881:1;;-1:-1:-1;;;;;;;;;;;17864:35:16;17881:1;;17864:35;17932:3;17922:7;:13;17838:99;;17951:13;:19;-1:-1:-1;13914:179:16;;;:::o;2412:312:6:-;2526:6;2501:21;:31;;2493:73;;;;-1:-1:-1;;;2493:73:6;;40787:2:22;2493:73:6;;;40769:21:22;40826:2;40806:18;;;40799:30;40865:31;40845:18;;;40838:59;40914:18;;2493:73:6;40585:353:22;2493:73:6;2578:12;2596:9;-1:-1:-1;;;;;2596:14:6;2618:6;2596:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2577:52;;;2647:7;2639:78;;;;-1:-1:-1;;;2639:78:6;;41355:2:22;2639:78:6;;;41337:21:22;41394:2;41374:18;;;41367:30;41433:34;41413:18;;;41406:62;-1:-1:-1;;;41484:18:22;;;41477:56;41550:19;;2639:78:6;41153:422:22;1035:989:15;1243:4;1237:11;;1549:20;;;1118:19;1549:20;1586:25;;1719:19;;1755:25;;-1:-1:-1;1906:4:15;1891:20;;;1967:17;;;1891:20;1035:989::o;10228:156:16:-;10290:21;;:::i;:::-;10330:47;10349:27;10368:7;10349:18;:27::i;:::-;10330:18;:47::i;9553:573:21:-;9660:7;;;9722:351;9746:5;9752:11;9746:18;;;;;;;:::i;:::-;;:25;9742:29;;9722:351;;;9792:22;9817:5;9823:11;9817:18;;;;;;;:::i;:::-;;9836:1;9817:21;;;;;;;;:::i;:::-;;;;;;;;;9792:46;;9887:17;9873:10;:31;;:98;;;;-1:-1:-1;9937:34:21;9957:14;9937:17;:34;:::i;:::-;9924:10;:47;9873:98;9852:142;;;-1:-1:-1;9993:1:21;-1:-1:-1;9986:8:21;;-1:-1:-1;9986:8:21;9852:142;10028:34;10048:14;10028:17;:34;:::i;:::-;10008:54;;9778:295;9773:3;;;;;:::i;:::-;;;;9722:351;;;;10118:1;10090:5;10096:11;10090:18;;;;;;;:::i;:::-;;:25;:29;;;;:::i;:::-;10083:36;9553:573;-1:-1:-1;;;;9553:573:21:o;3501:424:15:-;-1:-1:-1;;3680:17:15;;3674:24;3728:13;;3791:11;;-1:-1:-1;;3670:35:15;;;;;;3782:20;;3728:13;3782:20;:::i;:::-;:32;;3761:118;;;;-1:-1:-1;;;3761:118:15;;41782:2:22;3761:118:15;;;41764:21:22;41821:2;41801:18;;;41794:30;41860:34;41840:18;;;41833:62;-1:-1:-1;;;41911:18:22;;;41904:37;41958:19;;3761:118:15;41580:403:22;3761:118:15;3889:29;3905:6;3913:4;3889:15;:29::i;574:409:17:-;704:13;759:3;729:21;805;816:10;805:8;:21;:::i;:::-;-1:-1:-1;;;;;795:32:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;795:32:17;-1:-1:-1;773:54:17;-1:-1:-1;854:10:17;837:109;870:8;866:1;:12;837:109;;;924:8;933:1;924:11;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;924:11:17;899:6;906:14;910:10;906:1;:14;:::i;:::-;899:22;;;;;;;;:::i;:::-;;;;:36;-1:-1:-1;;;;;899:36:17;;;;;;;;-1:-1:-1;880:3:17;;;;:::i;:::-;;;;837:109;;;-1:-1:-1;969:6:17;574:409;-1:-1:-1;;;;;574:409:17:o;82:486::-;165:16;226:2;165:16;;263:278;285:7;:14;281:1;:18;;;263:278;;;370:2;354:7;362:1;354:10;;;;;;;;;;:::i;:::-;;;;;;;342:30;;;;341:84;;;422:2;406:7;414:1;406:10;;;;;;;;;;:::i;:::-;;;;;;;394:30;;341:84;320:211;;;458:10;466:2;458:10;;:::i;:::-;;;514:2;500:7;508:1;500:10;;;;;;;;;;:::i;:::-;;;;;494:22;;;500:10;;494:22;:::i;:::-;486:30;;;;:::i;:::-;;;320:211;301:3;;;;:::i;:::-;;;;263:278;;;-1:-1:-1;557:4:17;82:486;-1:-1:-1;;;82:486:17:o;2433:187:0:-;2525:6;;;-1:-1:-1;;;;;2541:17:0;;;-1:-1:-1;;;;;;2541:17:0;;;;;;;2573:40;;2525:6;;;2541:17;2525:6;;2573:40;;2506:16;;2573:40;2496:124;2433:187;:::o;586:460:19:-;639:15;739:17;759:94;834:5;791:56;;;;;;;;:::i;:::-;;;;;;;;;;;;;759:24;:94::i;:::-;739:114;;949:4;943:11;938:2;932:4;928:13;925:1;918:37;907:48;-1:-1:-1;;;;;;999:21:19;;995:46;;1029:12;;-1:-1:-1;;;1029:12:19;;;;;;;;;;;995:46;656:390;586:460;;;:::o;6469:198:6:-;6552:12;6583:77;6604:6;6612:4;6583:77;;;;;;;;;;;;;;;;;:20;:77::i;1300:134:19:-;1355:12;1382:47;1398:8;1408:1;-1:-1:-1;;1382:15:19;:47::i;505:3026:7:-;563:13;795:4;:11;810:1;795:16;791:31;;-1:-1:-1;;813:9:7;;;;;;;;;-1:-1:-1;813:9:7;;;505:3026::o;791:31::-;872:19;894:6;;;;;;;;;;;;;;;;;872:28;;1303:20;1362:1;1343:4;:11;1357:1;1343:15;;;;:::i;:::-;1342:21;;;;:::i;:::-;1337:27;;:1;:27;:::i;:::-;-1:-1:-1;;;;;1326:39:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1326:39:7;;1303:62;;1540:1;1533:5;1529:13;1641:2;1633:6;1629:15;1748:4;1799;1793:11;1787:4;1783:22;1711:1403;1832:6;1823:7;1820:19;1711:1403;;;1934:1;1925:7;1921:15;1910:26;;1972:7;1966:14;2615:4;2607:5;2603:2;2599:14;2595:25;2585:8;2581:40;2575:47;2564:9;2556:67;2668:1;2657:9;2653:17;2640:30;;2758:4;2750:5;2746:2;2742:14;2738:25;2728:8;2724:40;2718:47;2707:9;2699:67;2811:1;2800:9;2796:17;2783:30;;2900:4;2892:5;2889:1;2885:13;2881:24;2871:8;2867:39;2861:46;2850:9;2842:66;2953:1;2942:9;2938:17;2925:30;;3034:4;3027:5;3023:16;3013:8;3009:31;3003:38;2992:9;2984:58;;3087:1;3076:9;3072:17;3059:30;;1711:1403;;;1715:104;;3272:1;3265:4;3259:11;3255:19;3292:1;3287:120;;;;3425:1;3420:71;;;;3248:243;;3287:120;3339:4;3335:1;3324:9;3320:17;3312:32;3388:4;3384:1;3373:9;3369:17;3361:32;3287:120;;3420:71;3472:4;3468:1;3457:9;3453:17;3445:32;3248:243;-1:-1:-1;3518:6:7;;505:3026;-1:-1:-1;;;;;505:3026:7:o;28651:697:16:-;28829:88;;-1:-1:-1;;;28829:88:16;;28809:4;;-1:-1:-1;;;;;28829:45:16;;;;;:88;;32962:10;;28896:4;;28902:7;;28911:5;;28829:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28829:88:16;;;;;;;;-1:-1:-1;;28829:88:16;;;;;;;;;;;;:::i;:::-;;;28825:517;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29107:6;:13;29124:1;29107:18;29103:229;;29152:40;;-1:-1:-1;;;29152:40:16;;;;;;;;;;;29103:229;29292:6;29286:13;29277:6;29273:2;29269:15;29262:38;28825:517;-1:-1:-1;;;;;;28985:64:16;-1:-1:-1;;;28985:64:16;;-1:-1:-1;28651:697:16;;;;;;:::o;9848:184::-;9918:24;;;;:17;:24;;;;;;:29;;9914:112;;9990:25;10009:5;9990:18;:25::i;:::-;9963:24;;;;:17;:24;;;;;:52;9848:184;:::o;10132:468:21:-;10186:6;;10313:11;10346:12;10380:15;10417:16;10465;10480:1;10346:12;10465:16;:::i;:::-;10275:257;;;;;;44281:19:22;;;;44316:12;;44309:28;;;;44353:12;;;;44346:28;;;;44390:12;;;44383:28;10455:27:21;;44427:13:22;;;44420:29;10504:10:21;44484:15:22;;-1:-1:-1;;;;;;44480:45:22;44465:13;;;44458:68;44542:13;;10275:257:21;;;-1:-1:-1;;10275:257:21;;;;;;;;;10248:298;;10275:257;10248:298;;;;;10132:468;-1:-1:-1;;10132:468:21:o;29443:512:16:-;29520:14;29537:24;;;:17;:24;;;;;;;29575:11;;;29571:61;;29595:37;;-1:-1:-1;;;29595:37:16;;;;;;;;;;;29571:61;29642:23;29915:24;;;:17;:24;;;;;;-1:-1:-1;;;;;29825:38:16;;;;2166:3;29868:36;;;;29824:81;29915:33;;29443:512::o;11003:236:21:-;11145:6;-1:-1:-1;;;;;11170:18:21;;;:62;;11215:17;11170:62;;;11191:21;:19;:21::i;9145:358:16:-;9211:31;;:::i;:::-;-1:-1:-1;;;;;9254:41:16;;;;-1:-1:-1;;;;;1661:3:16;9339:32;;;9305:67;:24;;;:67;-1:-1:-1;;;9401:23:16;;:28;;9382:16;;;:47;2166:3;9468:27;;;;9439:19;;;:57;9254:9;9145:358::o;2289:976:15:-;2441:4;2435:11;2499:4;2493;2489:15;2481:23;;2546:6;2540:4;2536:17;2615:4;2606:6;2600:13;2596:24;2588:6;2584:37;2459:698;2645:7;2639:4;2636:17;2459:698;;;3131:11;;3116:27;;2690:4;2680:15;;;;2722:17;2459:698;;;-1:-1:-1;;3226:13:15;;3222:26;3207:42;;;-1:-1:-1;2289:976:15:o;378:700:14:-;446:12;1002:5;:12;1062:5;956:117;;;;;;;;;:::i;:::-;;;;;;;;;;;;;949:124;;378:700;;;:::o;6853:325:6:-;6994:12;7019;7033:23;7060:6;-1:-1:-1;;;;;7060:19:6;7080:4;7060:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7018:67;;;;7102:69;7129:6;7137:7;7146:10;7158:12;7102:26;:69::i;:::-;7095:76;6853:325;-1:-1:-1;;;;;;6853:325:6:o;1793:946:14:-;1877:18;1356;;1903:13;1944:10;;;1940:32;;-1:-1:-1;;1963:9:14;;;;;;;;;-1:-1:-1;1963:9:14;;1956:16;;1940:32;1992:5;1983:6;:14;1979:36;;;-1:-1:-1;;2006:9:14;;;;;;;;;-1:-1:-1;2006:9:14;;1999:16;;1979:36;2032:6;2025:4;:13;2021:65;;;2047:39;;-1:-1:-1;;;2047:39:14;;;;;45756:25:22;;;45797:18;;;45790:34;;;45840:18;;;45833:34;;;45729:18;;2047:39:14;45554:319:22;2021:65:14;2130:13;;;2169:14;;;2112:15;2207:17;;;:37;;2237:7;2207:37;;;2227:7;2207:37;2413:4;2407:11;;2501:26;;;-1:-1:-1;;2497:42:14;2486:54;;2473:68;;;2584:19;;;2407:11;-1:-1:-1;2192:52:14;-1:-1:-1;2192:52:14;2708:6;2515:4;2690:16;;2683:5;2671:50;2262:467;;;1897:842;1793:946;;;;;:::o;7466:628:6:-;7646:12;7674:7;7670:418;;;7701:10;:17;7722:1;7701:22;7697:286;;-1:-1:-1;;;;;1465:19:6;;;7908:60;;;;-1:-1:-1;;;7908:60:6;;46080:2:22;7908:60:6;;;46062:21:22;46119:2;46099:18;;;46092:30;46158:31;46138:18;;;46131:59;46207:18;;7908:60:6;45878:353:22;7908:60:6;-1:-1:-1;8003:10:6;7996:17;;7670:418;8044:33;8052:10;8064:12;8775:17;;:21;8771:379;;9003:10;8997:17;9059:15;9046:10;9042:2;9038:19;9031:44;8771:379;9126:12;9119:20;;-1:-1:-1;;;9119:20:6;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;14:131:22;-1:-1:-1;;;;;;88:32:22;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:22;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:22;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:22:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:22;;1348:180;-1:-1:-1;1348:180:22:o;1741:131::-;-1:-1:-1;;;;;1816:31:22;;1806:42;;1796:70;;1862:1;1859;1852:12;1877:315;1945:6;1953;2006:2;1994:9;1985:7;1981:23;1977:32;1974:52;;;2022:1;2019;2012:12;1974:52;2061:9;2048:23;2080:31;2105:5;2080:31;:::i;:::-;2130:5;2182:2;2167:18;;;;2154:32;;-1:-1:-1;;;1877:315:22:o;2197:127::-;2258:10;2253:3;2249:20;2246:1;2239:31;2289:4;2286:1;2279:15;2313:4;2310:1;2303:15;2329:253;2401:2;2395:9;2443:4;2431:17;;-1:-1:-1;;;;;2463:34:22;;2499:22;;;2460:62;2457:88;;;2525:18;;:::i;:::-;2561:2;2554:22;2329:253;:::o;2587:::-;2659:2;2653:9;2701:4;2689:17;;-1:-1:-1;;;;;2721:34:22;;2757:22;;;2718:62;2715:88;;;2783:18;;:::i;2845:275::-;2916:2;2910:9;2981:2;2962:13;;-1:-1:-1;;2958:27:22;2946:40;;-1:-1:-1;;;;;3001:34:22;;3037:22;;;2998:62;2995:88;;;3063:18;;:::i;:::-;3099:2;3092:22;2845:275;;-1:-1:-1;2845:275:22:o;3125:531::-;3168:5;3221:3;3214:4;3206:6;3202:17;3198:27;3188:55;;3239:1;3236;3229:12;3188:55;3262:20;;-1:-1:-1;;;;;3294:26:22;;3291:52;;;3323:18;;:::i;:::-;3367:55;3410:2;3391:13;;-1:-1:-1;;3387:27:22;3416:4;3383:38;3367:55;:::i;:::-;3447:2;3438:7;3431:19;3493:3;3486:4;3481:2;3473:6;3469:15;3465:26;3462:35;3459:55;;;3510:1;3507;3500:12;3459:55;3575:2;3568:4;3560:6;3556:17;3549:4;3540:7;3536:18;3523:55;3623:1;3598:16;;;3616:4;3594:27;3587:38;;;;3602:7;3125:531;-1:-1:-1;;;3125:531:22:o;3661:812::-;3777:6;3785;3793;3801;3854:3;3842:9;3833:7;3829:23;3825:33;3822:53;;;3871:1;3868;3861:12;3822:53;3894:23;;;-1:-1:-1;3968:2:22;3953:18;;3940:32;-1:-1:-1;;;;;4021:14:22;;;4018:34;;;4048:1;4045;4038:12;4018:34;4071:50;4113:7;4104:6;4093:9;4089:22;4071:50;:::i;:::-;4061:60;;4174:2;4163:9;4159:18;4146:32;4130:48;;4203:2;4193:8;4190:16;4187:36;;;4219:1;4216;4209:12;4187:36;4242:52;4286:7;4275:8;4264:9;4260:24;4242:52;:::i;:::-;4232:62;;4347:2;4336:9;4332:18;4319:32;4303:48;;4376:2;4366:8;4363:16;4360:36;;;4392:1;4389;4382:12;4360:36;;4415:52;4459:7;4448:8;4437:9;4433:24;4415:52;:::i;:::-;4405:62;;;3661:812;;;;;;;:::o;4478:1543::-;4567:6;4620:2;4608:9;4599:7;4595:23;4591:32;4588:52;;;4636:1;4633;4626:12;4588:52;4663:23;;-1:-1:-1;;;;;4735:14:22;;;4732:34;;;4762:1;4759;4752:12;4732:34;4785:22;;;;4841:4;4823:16;;;4819:27;4816:47;;;4859:1;4856;4849:12;4816:47;4885:22;;:::i;:::-;4945:2;4932:16;4973:2;4963:8;4960:16;4957:36;;;4989:1;4986;4979:12;4957:36;5016:45;5053:7;5042:8;5038:2;5034:17;5016:45;:::i;:::-;5009:5;5002:60;;5108:2;5104;5100:11;5087:25;5137:2;5127:8;5124:16;5121:36;;;5153:1;5150;5143:12;5121:36;5189:45;5226:7;5215:8;5211:2;5207:17;5189:45;:::i;:::-;5184:2;5177:5;5173:14;5166:69;;5281:2;5277;5273:11;5260:25;5310:2;5300:8;5297:16;5294:36;;;5326:1;5323;5316:12;5294:36;5362:45;5399:7;5388:8;5384:2;5380:17;5362:45;:::i;:::-;5357:2;5350:5;5346:14;5339:69;;5454:2;5450;5446:11;5433:25;5483:2;5473:8;5470:16;5467:36;;;5499:1;5496;5489:12;5467:36;5535:45;5572:7;5561:8;5557:2;5553:17;5535:45;:::i;:::-;5530:2;5523:5;5519:14;5512:69;;5627:3;5623:2;5619:12;5606:26;5657:2;5647:8;5644:16;5641:36;;;5673:1;5670;5663:12;5641:36;5710:45;5747:7;5736:8;5732:2;5728:17;5710:45;:::i;:::-;5704:3;5697:5;5693:15;5686:70;;5810:3;5806:2;5802:12;5789:26;5783:3;5776:5;5772:15;5765:51;5862:3;5858:2;5854:12;5841:26;5892:2;5882:8;5879:16;5876:36;;;5908:1;5905;5898:12;5876:36;5945:45;5982:7;5971:8;5967:2;5963:17;5945:45;:::i;:::-;5939:3;5928:15;;5921:70;-1:-1:-1;5932:5:22;4478:1543;-1:-1:-1;;;;;4478:1543:22:o;6026:936::-;6123:6;6131;6139;6147;6155;6208:3;6196:9;6187:7;6183:23;6179:33;6176:53;;;6225:1;6222;6215:12;6176:53;6264:9;6251:23;6283:31;6308:5;6283:31;:::i;:::-;6333:5;-1:-1:-1;6390:2:22;6375:18;;6362:32;6403:33;6362:32;6403:33;:::i;:::-;6455:7;-1:-1:-1;6509:2:22;6494:18;;6481:32;;-1:-1:-1;6564:2:22;6549:18;;6536:32;-1:-1:-1;;;;;6617:14:22;;;6614:34;;;6644:1;6641;6634:12;6614:34;6682:6;6671:9;6667:22;6657:32;;6727:7;6720:4;6716:2;6712:13;6708:27;6698:55;;6749:1;6746;6739:12;6698:55;6789:2;6776:16;6815:2;6807:6;6804:14;6801:34;;;6831:1;6828;6821:12;6801:34;6876:7;6871:2;6862:6;6858:2;6854:15;6850:24;6847:37;6844:57;;;6897:1;6894;6887:12;6844:57;6026:936;;;;-1:-1:-1;6026:936:22;;-1:-1:-1;6928:2:22;6920:11;;6950:6;6026:936;-1:-1:-1;;;6026:936:22:o;7356:160::-;7421:20;;7477:13;;7470:21;7460:32;;7450:60;;7506:1;7503;7496:12;7521:248;7586:6;7594;7647:2;7635:9;7626:7;7622:23;7618:32;7615:52;;;7663:1;7660;7653:12;7615:52;7699:9;7686:23;7676:33;;7728:35;7759:2;7748:9;7744:18;7728:35;:::i;:::-;7718:45;;7521:248;;;;;:::o;7774:456::-;7851:6;7859;7867;7920:2;7908:9;7899:7;7895:23;7891:32;7888:52;;;7936:1;7933;7926:12;7888:52;7975:9;7962:23;7994:31;8019:5;7994:31;:::i;:::-;8044:5;-1:-1:-1;8101:2:22;8086:18;;8073:32;8114:33;8073:32;8114:33;:::i;:::-;7774:456;;8166:7;;-1:-1:-1;;;8220:2:22;8205:18;;;;8192:32;;7774:456::o;8235:180::-;8292:4;-1:-1:-1;;;;;8314:30:22;;8311:56;;;8347:18;;:::i;:::-;-1:-1:-1;8392:1:22;8388:14;8404:4;8384:25;;8235:180::o;8420:956::-;8510:6;8518;8571:2;8559:9;8550:7;8546:23;8542:32;8539:52;;;8587:1;8584;8577:12;8539:52;8610:23;;;-1:-1:-1;8652:2:22;8690:18;;;8677:32;-1:-1:-1;;;;;8721:30:22;;8718:50;;;8764:1;8761;8754:12;8718:50;8787:22;;8840:4;8832:13;;8828:27;-1:-1:-1;8818:55:22;;8869:1;8866;8859:12;8818:55;8905:2;8892:16;8928:57;8944:40;8981:2;8944:40;:::i;:::-;8928:57;:::i;:::-;9019:15;;;9101:1;9097:10;;;;9089:19;;9085:28;;;9050:12;;;;9125:19;;;9122:39;;;9157:1;9154;9147:12;9122:39;9181:11;;;;9201:145;9217:6;9212:3;9209:15;9201:145;;;9283:20;9299:3;9283:20;:::i;:::-;9271:33;;9234:12;;;;9324;;;;9201:145;;;9365:5;9355:15;;;;;;;8420:956;;;;;:::o;9381:1111::-;9798:3;9787:9;9780:22;9761:4;9825:46;9866:3;9855:9;9851:19;9843:6;9825:46;:::i;:::-;9919:9;9911:6;9907:22;9902:2;9891:9;9887:18;9880:50;9953:33;9979:6;9971;9953:33;:::i;:::-;9939:47;;10034:9;10026:6;10022:22;10017:2;10006:9;10002:18;9995:50;10068:33;10094:6;10086;10068:33;:::i;:::-;10054:47;;10149:9;10141:6;10137:22;10132:2;10121:9;10117:18;10110:50;10183:33;10209:6;10201;10183:33;:::i;:::-;10169:47;;10265:9;10257:6;10253:22;10247:3;10236:9;10232:19;10225:51;10299:33;10325:6;10317;10299:33;:::i;:::-;10285:47;;10369:6;10363:3;10352:9;10348:19;10341:35;10425:9;10417:6;10413:22;10407:3;10396:9;10392:19;10385:51;10453:33;10479:6;10471;10453:33;:::i;:::-;10445:41;9381:1111;-1:-1:-1;;;;;;;;;;9381:1111:22:o;10497:322::-;10566:6;10619:2;10607:9;10598:7;10594:23;10590:32;10587:52;;;10635:1;10632;10625:12;10587:52;10662:23;;-1:-1:-1;;;;;10697:30:22;;10694:50;;;10740:1;10737;10730:12;10694:50;10763;10805:7;10796:6;10785:9;10781:22;10763:50;:::i;10824:247::-;10883:6;10936:2;10924:9;10915:7;10911:23;10907:32;10904:52;;;10952:1;10949;10942:12;10904:52;10991:9;10978:23;11010:31;11035:5;11010:31;:::i;11076:2211::-;11195:6;11203;11256:2;11244:9;11235:7;11231:23;11227:32;11224:52;;;11272:1;11269;11262:12;11224:52;11295:23;;;-1:-1:-1;11337:2:22;11375:18;;;11362:32;-1:-1:-1;;;;;11443:14:22;;;11440:34;;;11470:1;11467;11460:12;11440:34;11508:6;11497:9;11493:22;11483:32;;11553:7;11546:4;11542:2;11538:13;11534:27;11524:55;;11575:1;11572;11565:12;11524:55;11611:2;11598:16;11634:57;11650:40;11687:2;11650:40;:::i;11634:57::-;11725:15;;;11807:1;11803:10;;;;11795:19;;11791:28;;;11756:12;;;;11831:19;;;11828:39;;;11863:1;11860;11853:12;11828:39;11895:2;11891;11887:11;11907:1350;11923:6;11918:3;11915:15;11907:1350;;;12009:3;11996:17;12045:2;12032:11;12029:19;12026:109;;;12089:1;12118:2;12114;12107:14;12026:109;12158:20;;12201:4;12229:16;;;-1:-1:-1;;12225:30:22;12221:39;-1:-1:-1;12218:129:22;;;12301:1;12330:2;12326;12319:14;12218:129;12373:22;;:::i;:::-;12445:2;12441;12437:11;12424:25;12478:2;12468:8;12465:16;12462:106;;;12522:1;12551:2;12547;12540:14;12462:106;12595:54;12641:7;12636:2;12625:8;12621:2;12617:17;12613:26;12595:54;:::i;:::-;12588:5;12581:69;;12700:2;12696;12692:11;12679:25;12733:2;12723:8;12720:16;12717:109;;;12778:1;12808:3;12803;12796:16;12717:109;12862:54;12908:7;12903:2;12892:8;12888:2;12884:17;12880:26;12862:54;:::i;:::-;12846:14;;;12839:78;-1:-1:-1;12959:11:22;;;12946:25;;12987:16;;;12984:109;;;13045:1;13075:3;13070;13063:16;12984:109;13129:54;13175:7;13170:2;13159:8;13155:2;13151:17;13147:26;13129:54;:::i;:::-;13124:2;13113:14;;13106:78;13197:18;;-1:-1:-1;;13235:12:22;;;;11940;;11907:1350;;;11911:3;13276:5;13266:15;;;;;;;;11076:2211;;;;;:::o;13292:390::-;13370:6;13378;13431:2;13419:9;13410:7;13406:23;13402:32;13399:52;;;13447:1;13444;13437:12;13399:52;13470:23;;;-1:-1:-1;13544:2:22;13529:18;;13516:32;-1:-1:-1;;;;;13560:30:22;;13557:50;;;13603:1;13600;13593:12;13557:50;13626;13668:7;13659:6;13648:9;13644:22;13626:50;:::i;:::-;13616:60;;;13292:390;;;;;:::o;13687:248::-;13755:6;13763;13816:2;13804:9;13795:7;13791:23;13787:32;13784:52;;;13832:1;13829;13822:12;13784:52;-1:-1:-1;;13855:23:22;;;13925:2;13910:18;;;13897:32;;-1:-1:-1;13687:248:22:o;13940:315::-;14005:6;14013;14066:2;14054:9;14045:7;14041:23;14037:32;14034:52;;;14082:1;14079;14072:12;14034:52;14121:9;14108:23;14140:31;14165:5;14140:31;:::i;:::-;14190:5;-1:-1:-1;14214:35:22;14245:2;14230:18;;14214:35;:::i;14260:626::-;14357:6;14365;14418:2;14406:9;14397:7;14393:23;14389:32;14386:52;;;14434:1;14431;14424:12;14386:52;14461:23;;-1:-1:-1;;;;;14533:14:22;;;14530:34;;;14560:1;14557;14550:12;14530:34;14598:6;14587:9;14583:22;14573:32;;14643:7;14636:4;14632:2;14628:13;14624:27;14614:55;;14665:1;14662;14655:12;14614:55;14705:2;14692:16;14731:2;14723:6;14720:14;14717:34;;;14747:1;14744;14737:12;14717:34;14800:7;14795:2;14785:6;14782:1;14778:14;14774:2;14770:23;14766:32;14763:45;14760:65;;;14821:1;14818;14811:12;14760:65;14852:2;14844:11;;;;;14874:6;;-1:-1:-1;14260:626:22;;-1:-1:-1;;;;14260:626:22:o;14891:801::-;15051:4;15080:2;15120;15109:9;15105:18;15150:2;15139:9;15132:21;15173:6;15208;15202:13;15239:6;15231;15224:22;15277:2;15266:9;15262:18;15255:25;;15339:2;15329:6;15326:1;15322:14;15311:9;15307:30;15303:39;15289:53;;15377:2;15369:6;15365:15;15398:1;15408:255;15422:6;15419:1;15416:13;15408:255;;;15515:2;15511:7;15499:9;15491:6;15487:22;15483:36;15478:3;15471:49;15543:40;15576:6;15567;15561:13;15543:40;:::i;:::-;15533:50;-1:-1:-1;15641:12:22;;;;15606:15;;;;15444:1;15437:9;15408:255;;;-1:-1:-1;15680:6:22;;14891:801;-1:-1:-1;;;;;;;14891:801:22:o;15697:390::-;15775:6;15783;15836:2;15824:9;15815:7;15811:23;15807:32;15804:52;;;15852:1;15849;15842:12;15804:52;15879:23;;-1:-1:-1;;;;;15914:30:22;;15911:50;;;15957:1;15954;15947:12;15911:50;15980;16022:7;16013:6;16002:9;15998:22;15980:50;:::i;:::-;15970:60;16077:2;16062:18;;;;16049:32;;-1:-1:-1;;;;15697:390:22:o;16092:666::-;16187:6;16195;16203;16211;16264:3;16252:9;16243:7;16239:23;16235:33;16232:53;;;16281:1;16278;16271:12;16232:53;16320:9;16307:23;16339:31;16364:5;16339:31;:::i;:::-;16389:5;-1:-1:-1;16446:2:22;16431:18;;16418:32;16459:33;16418:32;16459:33;:::i;:::-;16511:7;-1:-1:-1;16565:2:22;16550:18;;16537:32;;-1:-1:-1;16620:2:22;16605:18;;16592:32;-1:-1:-1;;;;;16636:30:22;;16633:50;;;16679:1;16676;16669:12;16633:50;16702;16744:7;16735:6;16724:9;16720:22;16702:50;:::i;16763:680::-;16869:6;16877;16885;16893;16946:3;16934:9;16925:7;16921:23;16917:33;16914:53;;;16963:1;16960;16953:12;16914:53;16986:23;;;-1:-1:-1;17056:2:22;17041:18;;17028:32;;-1:-1:-1;17111:2:22;17096:18;;17083:32;-1:-1:-1;;;;;17164:14:22;;;17161:34;;;17191:1;17188;17181:12;17448:388;17516:6;17524;17577:2;17565:9;17556:7;17552:23;17548:32;17545:52;;;17593:1;17590;17583:12;17545:52;17632:9;17619:23;17651:31;17676:5;17651:31;:::i;:::-;17701:5;-1:-1:-1;17758:2:22;17743:18;;17730:32;17771:33;17730:32;17771:33;:::i;:::-;17823:7;17813:17;;;17448:388;;;;;:::o;17841:380::-;17920:1;17916:12;;;;17963;;;17984:61;;18038:4;18030:6;18026:17;18016:27;;17984:61;18091:2;18083:6;18080:14;18060:18;18057:38;18054:161;;18137:10;18132:3;18128:20;18125:1;18118:31;18172:4;18169:1;18162:15;18200:4;18197:1;18190:15;18352:545;18454:2;18449:3;18446:11;18443:448;;;18490:1;18515:5;18511:2;18504:17;18560:4;18556:2;18546:19;18630:2;18618:10;18614:19;18611:1;18607:27;18601:4;18597:38;18666:4;18654:10;18651:20;18648:47;;;-1:-1:-1;18689:4:22;18648:47;18744:2;18739:3;18735:12;18732:1;18728:20;18722:4;18718:31;18708:41;;18799:82;18817:2;18810:5;18807:13;18799:82;;;18862:17;;;18843:1;18832:13;18799:82;;19073:1352;19193:10;;-1:-1:-1;;;;;19215:30:22;;19212:56;;;19248:18;;:::i;:::-;19277:97;19367:6;19327:38;19359:4;19353:11;19327:38;:::i;:::-;19321:4;19277:97;:::i;:::-;19429:4;;19493:2;19482:14;;19510:1;19505:663;;;;20212:1;20229:6;20226:89;;;-1:-1:-1;20281:19:22;;;20275:26;20226:89;-1:-1:-1;;19030:1:22;19026:11;;;19022:24;19018:29;19008:40;19054:1;19050:11;;;19005:57;20328:81;;19475:944;;19505:663;18299:1;18292:14;;;18336:4;18323:18;;-1:-1:-1;;19541:20:22;;;19659:236;19673:7;19670:1;19667:14;19659:236;;;19762:19;;;19756:26;19741:42;;19854:27;;;;19822:1;19810:14;;;;19689:19;;19659:236;;;19663:3;19923:6;19914:7;19911:19;19908:201;;;19984:19;;;19978:26;-1:-1:-1;;20067:1:22;20063:14;;;20079:3;20059:24;20055:37;20051:42;20036:58;20021:74;;19908:201;-1:-1:-1;;;;;20155:1:22;20139:14;;;20135:22;20122:36;;-1:-1:-1;19073:1352:22:o;20430:640::-;20710:3;20748:6;20742:13;20764:66;20823:6;20818:3;20811:4;20803:6;20799:17;20764:66;:::i;:::-;-1:-1:-1;;;20852:16:22;;;20877:18;;;20920:13;;20942:78;20920:13;21007:1;20996:13;;20989:4;20977:17;;20942:78;:::i;:::-;21040:20;21062:1;21036:28;;20430:640;-1:-1:-1;;;;20430:640:22:o;21075:783::-;21396:6;21385:9;21378:25;21439:3;21434:2;21423:9;21419:18;21412:31;21359:4;21466:46;21507:3;21496:9;21492:19;21484:6;21466:46;:::i;:::-;21560:9;21552:6;21548:22;21543:2;21532:9;21528:18;21521:50;21594:33;21620:6;21612;21594:33;:::i;:::-;21580:47;;21675:9;21667:6;21663:22;21658:2;21647:9;21643:18;21636:50;21709:33;21735:6;21727;21709:33;:::i;:::-;21695:47;;21791:9;21783:6;21779:22;21773:3;21762:9;21758:19;21751:51;21819:33;21845:6;21837;21819:33;:::i;:::-;21811:41;21075:783;-1:-1:-1;;;;;;;;21075:783:22:o;21863:251::-;21933:6;21986:2;21974:9;21965:7;21961:23;21957:32;21954:52;;;22002:1;21999;21992:12;21954:52;22034:9;22028:16;22053:31;22078:5;22053:31;:::i;22119:127::-;22180:10;22175:3;22171:20;22168:1;22161:31;22211:4;22208:1;22201:15;22235:4;22232:1;22225:15;22251:135;22290:3;22311:17;;;22308:43;;22331:18;;:::i;:::-;-1:-1:-1;22378:1:22;22367:13;;22251:135::o;22654:127::-;22715:10;22710:3;22706:20;22703:1;22696:31;22746:4;22743:1;22736:15;22770:4;22767:1;22760:15;22786:713;22950:4;22998:2;22987:9;22983:18;23028:6;23017:9;23010:25;23054:2;23092;23087;23076:9;23072:18;23065:30;23115:6;23150;23144:13;23181:6;23173;23166:22;23219:2;23208:9;23204:18;23197:25;;23257:2;23249:6;23245:15;23231:29;;23278:1;23288:185;23302:6;23299:1;23296:13;23288:185;;;23377:13;;23370:21;23363:29;23351:42;;23448:15;;;;23413:12;;;;23324:1;23317:9;23288:185;;;-1:-1:-1;23490:3:22;;22786:713;-1:-1:-1;;;;;;;22786:713:22:o;23504:125::-;23569:9;;;23590:10;;;23587:36;;;23603:18;;:::i;23634:168::-;23707:9;;;23738;;23755:15;;;23749:22;;23735:37;23725:71;;23776:18;;:::i;23807:128::-;23874:9;;;23895:11;;;23892:37;;;23909:18;;:::i;23940:127::-;24001:10;23996:3;23992:20;23989:1;23982:31;24032:4;24029:1;24022:15;24056:4;24053:1;24046:15;24072:112;24104:1;24130;24120:35;;24135:18;;:::i;:::-;-1:-1:-1;24169:9:22;;24072:112::o;24506:722::-;24556:3;24597:5;24591:12;24626:36;24652:9;24626:36;:::i;:::-;24681:1;24698:18;;;24725:133;;;;24872:1;24867:355;;;;24691:531;;24725:133;-1:-1:-1;;24758:24:22;;24746:37;;24831:14;;24824:22;24812:35;;24803:45;;;-1:-1:-1;24725:133:22;;24867:355;24898:5;24895:1;24888:16;24927:4;24972:2;24969:1;24959:16;24997:1;25011:165;25025:6;25022:1;25019:13;25011:165;;;25103:14;;25090:11;;;25083:35;25146:16;;;;25040:10;;25011:165;;;25015:3;;;25205:6;25200:3;25196:16;25189:23;;24691:531;;;;;24506:722;;;;:::o;25233:802::-;-1:-1:-1;;;25727:55:22;;25709:3;25801:47;25844:2;25835:12;;25827:6;25801:47;:::i;:::-;-1:-1:-1;;;25857:46:22;;25922;25964:2;25956:11;;25948:6;25922:46;:::i;:::-;-1:-1:-1;;;25977:26:22;;26027:1;26019:10;;25233:802;-1:-1:-1;;;;;25233:802:22:o;26040:291::-;26217:6;26206:9;26199:25;26260:2;26255;26244:9;26240:18;26233:30;26180:4;26280:45;26321:2;26310:9;26306:18;26298:6;26280:45;:::i;26589:521::-;26666:4;26672:6;26732:11;26719:25;26826:2;26822:7;26811:8;26795:14;26791:29;26787:43;26767:18;26763:68;26753:96;;26845:1;26842;26835:12;26753:96;26872:33;;26924:20;;;-1:-1:-1;;;;;;26956:30:22;;26953:50;;;26999:1;26996;26989:12;26953:50;27032:4;27020:17;;-1:-1:-1;27063:14:22;27059:27;;;27049:38;;27046:58;;;27100:1;27097;27090:12;27046:58;26589:521;;;;;:::o;27115:474::-;27347:3;27385:6;27379:13;27401:66;27460:6;27455:3;27448:4;27440:6;27436:17;27401:66;:::i;:::-;-1:-1:-1;;;27489:16:22;;27514:39;;;-1:-1:-1;27580:2:22;27569:14;;27115:474;-1:-1:-1;27115:474:22:o;27594:835::-;-1:-1:-1;;;28098:3:22;28091:20;28073:3;28130:46;28173:1;28168:3;28164:11;28156:6;28130:46;:::i;:::-;-1:-1:-1;;;28192:2:22;28185:22;28236:6;28230:13;28252:73;28318:6;28314:1;28310:2;28306:10;28299:4;28291:6;28287:17;28252:73;:::i;:::-;-1:-1:-1;;;28383:1:22;28344:15;;;;28375:10;;;28368:28;28420:2;28412:11;;27594:835;-1:-1:-1;;;;27594:835:22:o;28434:1321::-;-1:-1:-1;;;28938:3:22;28931:20;28913:3;28970:46;29013:1;29008:3;29004:11;28996:6;28970:46;:::i;:::-;-1:-1:-1;;;29032:2:22;29025:22;29076:6;29070:13;29092:73;29158:6;29154:1;29150:2;29146:10;29139:4;29131:6;29127:17;29092:73;:::i;:::-;29227:34;29223:1;29184:15;;;;29215:10;;;29208:54;29291:34;29286:2;29278:11;;29271:55;29355:34;29350:2;29342:11;;29335:55;29420:34;29414:3;29406:12;;29399:56;29485:34;29479:3;29471:12;;29464:56;29550:34;29544:3;29536:12;;29529:56;29615:66;29609:3;29601:12;;29594:88;-1:-1:-1;;;29706:3:22;29698:12;;29691:30;29745:3;29737:12;;28434:1321;-1:-1:-1;;;;28434:1321:22:o;29760:458::-;-1:-1:-1;;;30017:3:22;30010:41;29992:3;30080:6;30074:13;30096:75;30164:6;30159:2;30154:3;30150:12;30143:4;30135:6;30131:17;30096:75;:::i;:::-;30191:16;;;;30209:2;30187:25;;29760:458;-1:-1:-1;;29760:458:22:o;30223:358::-;-1:-1:-1;;;30470:43:22;;30452:3;30529:46;30572:1;30563:11;;30555:6;30529:46;:::i;30586:874::-;-1:-1:-1;;;31090:3:22;31083:16;31065:3;31128:6;31122:13;31144:74;31211:6;31207:1;31202:3;31198:11;31191:4;31183:6;31179:17;31144:74;:::i;:::-;-1:-1:-1;;;31277:1:22;31237:16;;;31269:10;;;31262:66;31347:46;31389:2;31381:11;;31373:6;31347:46;:::i;:::-;-1:-1:-1;;;31402:26:22;;31452:1;31444:10;;30586:874;-1:-1:-1;;;;;30586:874:22:o;31465:550::-;-1:-1:-1;;;31760:43:22;;31742:3;31822:46;31865:1;31856:11;;31848:6;31822:46;:::i;:::-;31897:6;31891:13;31913:65;31971:6;31967:2;31960:4;31952:6;31948:17;31913:65;:::i;:::-;31994:15;;31465:550;-1:-1:-1;;;;31465:550:22:o;32020:1148::-;-1:-1:-1;;;;;;;;;;;32378:3:22;32371:79;32480:66;32475:2;32470:3;32466:12;32459:88;32577:34;32572:2;32567:3;32563:12;32556:56;32642:66;32637:2;32632:3;32628:12;32621:88;32740:66;32734:3;32729;32725:13;32718:89;32838:66;32832:3;32827;32823:13;32816:89;32353:3;32934:6;32928:13;32950:74;33017:6;33011:3;33006;33002:13;32997:2;32989:6;32985:15;32950:74;:::i;:::-;-1:-1:-1;;;33083:3:22;33043:16;;;;33075:12;;;33068:66;-1:-1:-1;33158:3:22;33150:12;;32020:1148;-1:-1:-1;32020:1148:22:o;33173:644::-;-1:-1:-1;;;33524:61:22;;33608:13;;33506:3;;33630:75;33608:13;33693:2;33684:12;;33677:4;33665:17;;33630:75;:::i;:::-;-1:-1:-1;;;33764:2:22;33724:16;;;;33756:11;;;33749:35;-1:-1:-1;33808:2:22;33800:11;;33173:644;-1:-1:-1;33173:644:22:o;33822:1062::-;-1:-1:-1;;;;;;;;;;;34180:3:22;34173:79;34282:66;34277:2;34272:3;34268:12;34261:88;34379:66;34374:2;34369:3;34365:12;34358:88;34476:66;34471:2;34466:3;34462:12;34455:88;34583:36;34578:3;34574:46;34568:3;34563;34559:13;34552:69;34155:3;34650:6;34644:13;34666:74;34733:6;34727:3;34722;34718:13;34713:2;34705:6;34701:15;34666:74;:::i;:::-;-1:-1:-1;;;34799:3:22;34759:16;;;;34791:12;;;34784:66;-1:-1:-1;34874:3:22;34866:12;;33822:1062;-1:-1:-1;33822:1062:22:o;34889:636::-;-1:-1:-1;;;35240:53:22;;35316:13;;35222:3;;35338:75;35316:13;35401:2;35392:12;;35385:4;35373:17;;35338:75;:::i;:::-;-1:-1:-1;;;35472:2:22;35432:16;;;;35464:11;;;35457:35;-1:-1:-1;35516:2:22;35508:11;;34889:636;-1:-1:-1;34889:636:22:o;35530:623::-;-1:-1:-1;;;35881:51:22;;35955:13;;35863:3;;35977:75;35955:13;36040:2;36031:12;;36024:4;36012:17;;35977:75;:::i;:::-;-1:-1:-1;;;36111:2:22;36071:16;;;;36103:11;;;36096:24;-1:-1:-1;36144:2:22;36136:11;;35530:623;-1:-1:-1;35530:623:22:o;36158:461::-;36420:31;36415:3;36408:44;36390:3;36481:6;36475:13;36497:75;36565:6;36560:2;36555:3;36551:12;36544:4;36536:6;36532:17;36497:75;:::i;:::-;36592:16;;;;36610:2;36588:25;;36158:461;-1:-1:-1;;36158:461:22:o;36624:527::-;36877:6;36866:9;36859:25;36920:6;36915:2;36904:9;36900:18;36893:34;36963:3;36958:2;36947:9;36943:18;36936:31;36840:4;36990:46;37031:3;37020:9;37016:19;37008:6;36990:46;:::i;:::-;37084:9;37076:6;37072:22;37067:2;37056:9;37052:18;37045:50;37112:33;37138:6;37130;37112:33;:::i;:::-;37104:41;36624:527;-1:-1:-1;;;;;;;36624:527:22:o;37156:2296::-;-1:-1:-1;;;38383:43:22;;38365:3;38445:46;38488:1;38479:11;;38471:6;38445:46;:::i;:::-;-1:-1:-1;;;38500:58:22;;38577:46;38619:2;38611:11;;38603:6;38577:46;:::i;:::-;-1:-1:-1;;;38632:46:22;;38567:56;-1:-1:-1;38697:46:22;38739:2;38731:11;;38723:6;38697:46;:::i;:::-;-1:-1:-1;;;38752:48:22;;38687:56;-1:-1:-1;38819:46:22;38861:2;38853:11;;38845:6;38819:46;:::i;:::-;-1:-1:-1;;;38874:62:22;;38809:56;-1:-1:-1;38955:46:22;38997:2;38989:11;;38981:6;38955:46;:::i;:::-;-1:-1:-1;;;39010:79:22;;39112:13;;38945:56;;-1:-1:-1;39134:74:22;39112:13;39196:2;39188:11;;39181:4;39169:17;;39134:74;:::i;:::-;-1:-1:-1;;;39266:2:22;39227:15;;;;39258:11;;;39251:69;39339:46;39381:2;39373:11;;39365:6;39339:46;:::i;:::-;-1:-1:-1;;;39394:26:22;;39444:1;39436:10;;37156:2296;-1:-1:-1;;;;;;;;;;37156:2296:22:o;41988:225::-;42092:4;42071:12;;;42085;;;42067:31;42118:22;;;;42159:24;;;42149:58;;42187:18;;:::i;42218:151::-;42308:4;42301:12;;;42287;;;42283:31;;42326:14;;42323:40;;;42343:18;;:::i;42374:148::-;42462:4;42441:12;;;42455;;;42437:31;;42480:13;;42477:39;;;42496:18;;:::i;42527:175::-;42564:3;42608:4;42601:5;42597:16;42637:4;42628:7;42625:17;42622:43;;42645:18;;:::i;:::-;42694:1;42681:15;;42527:175;-1:-1:-1;;42527:175:22:o;42707:427::-;42967:1;42962:3;42955:14;42937:3;42998:6;42992:13;43014:74;43081:6;43077:1;43072:3;43068:11;43061:4;43053:6;43049:17;43014:74;:::i;:::-;43108:16;;;;43126:1;43104:24;;42707:427;-1:-1:-1;;42707:427:22:o;43139:120::-;43179:1;43205;43195:35;;43210:18;;:::i;:::-;-1:-1:-1;43244:9:22;;43139:120::o;43264:489::-;-1:-1:-1;;;;;43533:15:22;;;43515:34;;43585:15;;43580:2;43565:18;;43558:43;43632:2;43617:18;;43610:34;;;43680:3;43675:2;43660:18;;43653:31;;;43458:4;;43701:46;;43727:19;;43719:6;43701:46;:::i;43758:249::-;43827:6;43880:2;43868:9;43859:7;43855:23;43851:32;43848:52;;;43896:1;43893;43886:12;43848:52;43928:9;43922:16;43947:30;43971:5;43947:30;:::i;44566:691::-;-1:-1:-1;;;44941:16:22;;45012:3;44990:16;;;-1:-1:-1;;;;;;44986:43:22;44982:1;44973:11;;44966:64;-1:-1:-1;;;45055:1:22;45046:11;;45039:51;45113:13;;-1:-1:-1;;45135:75:22;45113:13;45198:2;45189:12;;45182:4;45170:17;;45135:75;:::i;:::-;45230:16;;;;45248:2;45226:25;;44566:691;-1:-1:-1;;;44566:691:22:o;45262:287::-;45391:3;45429:6;45423:13;45445:66;45504:6;45499:3;45492:4;45484:6;45480:17;45445:66;:::i;:::-;45527:16;;;;;45262:287;-1:-1:-1;;45262:287:22:o

Swarm Source

ipfs://20ca10d25cc2579867a12aa3307559f37a93dd8bba2ce9793f5ce20ade520995
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.