library BlueprintV2 {
    // {token_id}:{name,issueNumber}
    function deserialize(bytes calldata blob)
        internal
        pure
        returns (
            uint256,
            bytes memory,
            bytes memory,
            uint256
        )
    {
        int256 blobIndex = ByteUtils.indexOf(blob, ":", 0);
        require(blobIndex >= 0, "Blob separator must exist");
        // Trim the { and } from the parameters
        uint256 tokenID = ByteUtils.toUint(blob[1:uint256(blobIndex) - 1]);
        uint256 blueprintLength = blob.length - uint256(blobIndex) - 3;
        require(blueprintLength > 0, "Invalid blueprint");
        bytes calldata blueprint = blob[uint256(blobIndex) + 2:blob.length - 1];

        int256 blueprintIndex = ByteUtils.indexOf(blueprint, ",", 0);
        require(blueprintIndex >= 0, "Blueprint separator must exist");
        bytes calldata name = blueprint[0:uint256(blueprintIndex)];
        uint256 issueNumber = ByteUtils.toUint(
            blueprint[uint256(blueprintIndex) + 1:blueprint.length]
        );
        require(issueNumber > 0, "Invalid issue number");
        return (tokenID, blueprint, name, issueNumber);
    }

    function serialize(string memory name, uint256 issueNumber)
        internal
        pure
        returns (bytes memory)
    {
        return
            bytes(
                abi.encodePacked(
                    name,
                    ",",
                    StringsUpgradeable.toString(issueNumber)
                )
            );
    }
}
function deserialize(bytes calldata blob)
    internal
    pure
    returns (
        uint256,
        bytes memory,
        bytes memory,
        uint256
    )
{
    int256 blobIndex = ByteUtils.indexOf(blob, ":", 0);
    require(blobIndex >= 0, "Blob separator must exist");
    // Trim the { and } from the parameters
    uint256 tokenID = ByteUtils.toUint(blob[1:uint256(blobIndex) - 1]);
    uint256 blueprintLength = blob.length - uint256(blobIndex) - 3;
    require(blueprintLength > 0, "Invalid blueprint");
    bytes calldata blueprint = blob[uint256(blobIndex) + 2:blob.length - 1];

    int256 blueprintIndex = ByteUtils.indexOf(blueprint, ",", 0);
    require(blueprintIndex >= 0, "Blueprint separator must exist");
    bytes calldata name = blueprint[0:uint256(blueprintIndex)];
    uint256 issueNumber = ByteUtils.toUint(
        blueprint[uint256(blueprintIndex) + 1:blueprint.length]
    );
    require(issueNumber > 0, "Invalid issue number");
    return (tokenID, blueprint, name, issueNumber);
}

// {token_id}:{name,issueNumber}