// Contract: TheContract
// Target function: function supportsInterface(bytes4 interfaceId) public view returns (bool)
27%2520calcMode%253D%2527spline%2527%2520keySplines%253D%25270.4%25200%25200.2%25201%253B%25200.4%25200%25200.2%25201%2527%2520dur%253D%252730s%2527%2520repeatCount%253D%2527indefinite%2527%2520%252F>%253C%252FfeColorMatrix>%253C%252Ffilter>";
        _svgParts[9]="<linearGradient id='TheContractGradient' x1='0' x2='0' y1='0' y2='1'><stop offset='0%' stop-color='#";
        _svgParts[10]="%3ClinearGradient%20id%3D%27TheContractGradient%27%20x1%3D%270%27%20x2%3D%270%27%20y1%3D%270%27%20y2%3D%271%27>%3Cstop%20offset%3D%270%25%27%20stop-color%3D%27%23";
        _svgParts[11]="%253ClinearGradient%2520id%253D%2527TheContractGradient%2527%2520x1%253D%25270%2527%2520x2%253D%25270%2527%2520y1%253D%25270%2527%2520y2%253D%25271%2527>%253Cstop%2520offset%253D%25270%2525%2527%2520stop-color%253D%2527%2523";
        _svgParts[12]="'/><stop offset='50%' stop-color='#";
        _svgParts[13]="%27%2F>%3Cstop%20offset%3D%2750%25%27%20stop-color%3D%27%23";
        _svgParts[14]="%2527%252F>%253Cstop%2520offset%253D%252750%2525%2527%2520stop-color%253D%2527%2523";
        _svgParts[15]="'/><stop offset='100%' stop-color='#";
        _svgParts[16]="%27%2F>%3Cstop%20offset%3D%27100%25%27%20stop-color%3D%27%23";
        _svgParts[17]="%2527%252F>%253Cstop%2520offset%253D%2527100%2525%2527%2520stop-color%253D%2527%2523";
        _svgParts[18]="'/></linearGradient>";
        _svgParts[19]="%27%2F>%3C%2FlinearGradient>";
        _svgParts[20]="%2527%252F>%253C%252FlinearGradient>";
        _svgParts[21]="</defs><g filter='url(#TheContractFilter)' clip-path='url(#TheContractClipPath)'><circle cx='50' cy='50' r='71' fill='url(#TheContractGradient)' fill-opacity='20%'><animateTransform attributeName='transform' type='rotate' from='0 50 50' to='360 50 50' dur='60s' repeatCount='indefinite' /></circle>";
        _svgParts[22]="%3C%2Fdefs>%3Cg%20filter%3D%27url%28%23TheContractFilter%29%27%20clip-path%3D%27url%28%23TheContractClipPath%29%27>%3Ccircle%20cx%3D%2750%27%20cy%3D%2750%27%20r%3D%2771%27%20fill%3D%27url%28%23TheContractGradient%29%27%20fill-opacity%3D%2720%25%27>%3CanimateTransform%20attributeName%3D%27transform%27%20type%3D%27rotate%27%20from%3D%270%2050%2050%27%20to%3D%27360%2050%2050%27%20dur%3D%2760s%27%20repeatCount%3D%27indefinite%27%20%2F>%3C%2Fcircle>";
        _svgParts[23]="%253C%252Fdefs>%253Cg%2520filter%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)
        }
    }