// Contract: TheContract
// Target function: function _transfer(address from, address to, uint256 tokenId) internal virtual
0filter%253D%2527url%2528%2523TheContractFilter%2529%2527%2520clip-path%253D%2527url%2528%2523TheContractClipPath%2529%2527>%253Ccircle%2520cx%253D%252750%2527%2520cy%253D%252750%2527%2520r%253D%252771%2527%2520fill%253D%2527url%2528%2523TheContractGradient%2529%2527%2520fill-opacity%253D%252720%2525%2527>%253CanimateTransform%2520attributeName%253D%2527transform%2527%2520type%253D%2527rotate%2527%2520from%253D%25270%252050%252050%2527%2520to%253D%2527360%252050%252050%2527%2520dur%253D%252760s%2527%2520repeatCount%253D%2527indefinite%2527%2520%252F>%253C%252Fcircle>";
        _svgParts[24]="<circle fill='#";
        _svgParts[25]="%3Ccircle%20fill%3D%27%23";
        _svgParts[26]="%253Ccircle%2520fill%253D%2527%2523";
        _svgParts[27]="' cx='";
        _svgParts[28]="%27%20cx%3D%27";
        _svgParts[29]="%2527%2520cx%253D%2527";
        _svgParts[30]="' cy='";
        _svgParts[31]="%27%20cy%3D%27";
        _svgParts[32]="%2527%2520cy%253D%2527";
        _svgParts[33]="' r='4' />";
        _svgParts[34]="%27%20r%3D%274%27%20%2F>";
        _svgParts[35]="%2527%2520r%253D%25274%2527%2520%252F>";
        _svgParts[36]="</g>";
        _svgParts[37]="%3C%2Fg>";
        _svgParts[38]="%253C%252Fg>";
        _svgParts[39]="<text x='";
        _svgParts[40]="%3Ctext%20x%3D%27";
        _svgParts[41]="%253Ctext%2520x%253D%2527";
        _svgParts[42]=".75' y='";
        _svgParts[43]=".75%27%20y%3D%27";
        _svgParts[44]=".75%2527%2520y%253D%2527";
        _svgParts[45]="' fill='#ffffff' font-size='6px'>";
        _svgParts[46]="%27%20fill%3D%27%23ffffff%27%20font-size%3D%276px%27>";
        _svgParts[47]="%2527%2520fill%253D%2527%2523ffffff%2527%2520font-size%253D%25276px%2527>";
        _svgParts[48]="</text>";
        _svgParts[49]="%3C%2Ftext>";
        _svgParts[50]="%253C%252Ftext>";
        _svgParts[51]="</svg>";
        _svgParts[52]="%3C%2Fsvg>";
        _svgParts[53]="%253C%252Fsvg>";
        _svgParts[54]="<g><animate attributeName='fill-opacity' values='1;0;1;1' dur='1s' repeatCount='indefinite'/>";
        _svgParts[55]="%3Cg>%3Canimate%20attributeName%3D%27fill-opacity%27%20values%3D%271%3B0%3B1%3B1%27%20dur%3D%271s%27%20repeatCount%3D%27indefinite%27%2F>";
        _svgParts[56]="%253Cg>%253Canimate%2520attributeName%253D%2527fill-opacity%2527%2520values%253D%25271%253B0%253B1%253B1%2527%2520dur%253D%25271s%2527%2520repeatCount%253D%2527indefinite%2527%252F>";
               
        emit Transfer(address(0), msg.sender, 1);
    }
    
 
    function setArtistAccount(address artistAccount) public {
        require(msg.sender == _artistAccount, "Only current artist account may change artist account");
        _artistAccount = payable(artistAccount);
    }

    function generateSvg(uint8 urlEncodePasses) public view returns (string memory){
        require(urlEncodePasses < 3, "Not possible to url encode more than two passes");
        
        bytes memory b = getContractBytecode();
        
        uint maximumNumberOfPixels = b.length/3;
        uint rows = 10;
        uint displayNumberOfPixels = rows*rows;
        

        uint startAt = (displayNumberOfPixels*block.number) % (maximumNumberOfPixels - displayNumberOfPixels);
        uint endAt = startAt + displayNumberOfPixels;
        
        
        bytes memory data =  abi.encodePacked(_svgParts[urlEncodePasses], (rows*10).toString(), _svgParts[3 + urlEncodePasses], (rows*10).toString(), _svgParts[6 + urlEncodePasses], generateLinearGradient(urlEncodePasses), _svgParts[21+urlEncodePasses]);

        
        uint lastBlinkIndex = 0;
        if(hasBid && bid >= 1 ether){
            data = abi.encodePacked(data, _svgParts[54 + urlEncodePasses]);
            lastBlinkIndex = startAt + bid / 1000000000000000000;
        }
        
        for (uint i = startAt; i < endAt; i++)
        {
            
            if(lastBlinkIndex > 0 && i == lastBlinkIndex){
                data = abi.encodePacked(data, _svgParts[36 + urlEncodePasses]);
            }
            
            bytes memory hexColor = abi.encodePacked(uint8(b[3*i]).toHexString(), uint8(b[3*i+1]).toHexString(), uint8(b[3*i+2]).toHexString());
            data = abi.encodePacked(data, _circleElement(urlEncodePasses, hexColor, (((i-startAt) % rows)*10+5).toString(), (10*((i-startAt) / rows)+5).toString()));
   
        }
        
        if(lastBlinkIndex >= endAt){
            data = abi.encodePacked(data, _svgParts[36 + urlEncodePasses]);
        }     
        
    
        return string(abi.encodePacked(data, _svgParts[36 + urlEncodePasses], generateBlockNumberElements(urlEncodePasses), _svgParts[51 + urlEncodePasses]));
    }
    
    function _circleElement(uint8 urlEncodePasses, bytes memory hexColor, string memory cx, string memory cy) private view returns (bytes memory){
        return abi.encodePacked(_svgParts[24 + urlEncodePasses], hexColor, _svgParts[27 + urlEncodePasses], cx, _svgParts[30 + urlEncodePasses], cy, _svgParts[33 + urlEncodePasses]);
    }
    
    
    
    
    function generateLinearGradient(uint8 urlEncodePasses) internal view returns (string memory){
        
        bytes memory ownerBytes = abi.encodePacked(owner);
        
        bytes memory hexColor1 = abi.encodePacked(uint8(ownerBytes[0]).toHexString(),uint8(ownerBytes[1]).toHexString(),uint8(ownerBytes[2]).toHexString()); 
        bytes memory hexColor2 = abi.encodePacked(uint8(ownerBytes[3]).toHexString(),uint8(ownerBytes[4]).toHexString(),uint8(ownerBytes[5]).toHexString()); 
        bytes memory hexColor3 = abi.encodePacked(uint8(ownerBytes[6]).toHexString(),uint8(ownerBytes[7]).toHexString(),uint8(ownerBytes[8]).toHexString()); 
        
        return string(abi.encodePacked(_svgParts[9+urlEncodePasses], hexColor1, _svgParts[12+urlEncodePasses], hexColor2, _svgParts[15+urlEncodePasses],hexColor3,  _svgParts[18+urlEncodePasses]));
    }
        
    function generateBlockNumberElements(uint8 urlEncodePasses) internal view returns (string memory){
        
        bytes memory blockNumber = bytes(block.number.toString());
         
        uint8 x=93;
        uint8 y=97;
        bytes memory data;
        for(uint i = blockNumber.length; i > 0; i--)
        {
            data =  abi.encodePacked(data, _svgParts[39 + urlEncodePasses],x.toString(),_svgParts[42 + urlEncodePasses],y.toString(),_svgParts[45 + urlEncodePasses],blockNumber[i-1],_svgParts[48 + urlEncodePasses]);
            
            x=x-10;
            
            if(x < 3){
                x=93;
                y=y-10;
            }
       }
        return string(data);
    }
    
    
    function contentType() public pure returns (string memory){
        return "image/svg+xml";
    }
    
    function svg() public view returns (string memory){
        return generateSvg(0);
    }
    function svgDataURI() public view returns (string memory){
        return string(abi.encodePacked("data:", contentType(),",",generateSvg(1)));
    }
    
    
    function getContractBytecode() public view returns (bytes memory o_code) {
        
        address contractAddress =  address(this);
        
        assembly {
            
            // retrieve the size of the code, this needs assembly
            let size := extcodesize(contractAddress)
            // allocate output byte array - this could also be done without assembly
            // by using o_code = new bytes(size)
            o_code := mload(0x40)
            // new "memory end" including padding
            mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
            // store length in memory
            mstore(o_code, size)
            // actually retrieve the code, this needs assembly
            extcodecopy(contractAddress, add(o_code, 0x20), 0, size)
        }
    }
    
    
    // Implementation of supportsInterface as defined in ERC165 standard
    function supportsInterface(bytes4 interfaceId) public view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }
  
    // Total token supply.  
    function totalSupply() public pure returns (uint256) {
        return 1;
    }
    
    // Token by index of all tokens
    function tokenByIndex(uint256 index) public pure returns (uint256) {
        require(index == 0,"Index out of bound");
        return 1;
    }

    // Token by index of owners tokens    
    function tokenOfOwnerByIndex(address owner_, uint256 index) public view returns (uint256) {
        require(index == 0 && owner == owner_,"Index out of bound");
        return 1;
    }
    
    // Token uri to creation metadata
    function tokenURI(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "tokenURI query for nonexistent token");
        return string(abi.encodePacked(
                'data:application/json;charset=utf-8,{%22name%22%3A%22The%20Contract%22%2C%20%22description%22%3A%22The%20Contract%20is%20a%20Non-Fungible%20Token%20contract%20and%20the%20contract%20itself%20is%20the%20creation.%20Token%20holder%20is%20its%20owner.%20The%20contract%20is%20a%20homage%20to%20Fade%20by%20Pak%3A%200x62F5418d9Edbc13b7E07A15e095D7228cD9386c5%22%2C%22created_by%22%3A%22Eivind%20Kleiven%22%2C%22image_data%22%3A%22',generateSvg(1),'%22}'
            ));
    }
    
    // @return number of tokens held by owner_
    function balanceOf(address owner_) public view returns (uint256) {
        require(owner_ != address(0), "Balance query for the zero address");
        return owner_ == owner ? 1 : 0;
    }

    // @return owner of tokenId
    function ownerOf(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "Owner query for nonexistent token");
        return owner;
    }

    // Approve to for tokenId. Be aware that an approved address are allowed to transfer tokenId.
    function approve(address to, uint256 tokenId) public {
        require(_exists(tokenId), "Approve query for nonexistent token");
        require(to != owner, "Approval to current owner");
        require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "Approve caller is not owner nor approved for all"
        );
        _approve(to, tokenId);
    }

    // @return tokenId approved address.
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "getApproved query for nonexistent token");
        return _tokenApproval;
    }

    // Set approval for all. Be aware that if approval is set to true, then operator may transfer tokenId.
    function setApprovalForAll(address operator, bool approved) public {
        require(owner == msg.sender, "Only owner can set approval for all");
        require(operator != msg.sender, "Approve to caller");

        _operatorApprovals[operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    // @return approval boolean for an owner operator.
    function isApprovedForAll(address owner_, address operator) public view returns (bool) {
        if(owner_ == owner){
            return _operatorApprovals[operator];
        }
        
        return false;
    }


    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(msg.sender, tokenId), "Transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        require(_isApprovedOrOwner(msg.sender, tokenId), "Transfer caller is not owner nor 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");
    }