abstract contract GeneticChainMetadata is GeneticChain721
{

    //-------------------------------------------------------------------------
    // constants
    //-------------------------------------------------------------------------

    uint256 constant private kActiveIdx      = 0;
    uint256 constant private kDeactivatedIdx = 1;

    uint256 constant public projectId  = 8;
    string constant public artist      = "Alejandro Mirabal";
    string constant public description = "The Rainbow7 Pass provides holders with membership to the Genetic Chain Platform.  Passes will unlock access to pre-sales, free mints, future GC programs, as well as access to live events at the GC gallery.";

    //-------------------------------------------------------------------------
    // fields
    //-------------------------------------------------------------------------

    string[2] private _tokenIpfsHashes;
    string private _baseUri;

    //-------------------------------------------------------------------------
    // ctor
    //-------------------------------------------------------------------------

    constructor(
        address spirals,
        string[2] memory tokenIpfsHashes_,
        string memory baseUri_,
        uint256 seed,
        address proxyRegistryAddress)
        GeneticChain721(
          spirals,
          seed,
          proxyRegistryAddress)
    {
        _tokenIpfsHashes = tokenIpfsHashes_;
        _baseUri         = baseUri_;
    }

    //-------------------------------------------------------------------------
    // functions
    //-------------------------------------------------------------------------

    /**
     * Each pass is associated with the spiral it was mint to.
     */
    function isActive(uint256 tokenId)
        public
        view
        validTokenId(tokenId)
        returns (bool)
    {
        return ownerOf(tokenId) == IERC721(_spirals).ownerOf(_spiralIds[tokenId]);
    }

    //-------------------------------------------------------------------------
    // accessors
    //-------------------------------------------------------------------------

    function tokenIpfsHash(uint256 tokenId)
        public
        view
        returns (string memory)
    {
        return isActive(tokenId)
            ? _tokenIpfsHashes[kActiveIdx]
            : _tokenIpfsHashes[kDeactivatedIdx];
    }

    //-------------------------------------------------------------------------

    function baseTokenURI()
        override public view returns (string memory)
    {
        return string(abi.encodePacked(_baseUri, "/api/project/", Strings.toString(projectId), "/token"));
    }

    //-------------------------------------------------------------------------

    function contractURI()
        public view returns (string memory)
    {
        return string(abi.encodePacked(_baseUri, "/api/project/", Strings.toString(projectId), "/contract"));
    }

}
/**
 * @title GeneticChainMetadata
 * Holds all required metadata for Genetic Chain projects.
 */
function isActive(uint256 tokenId)
        public
        view
        validTokenId(tokenId)
        returns (bool)
    {
        return ownerOf(tokenId) == IERC721(_spirals).ownerOf(_spiralIds[tokenId]);
    }
/**
 * Each pass is associated with the spiral it was mint to.
 */