Baetle draft

0 views
Skip to first unread message

Erling Wegger Linde

unread,
May 16, 2008, 8:09:00 AM5/16/08
to bae...@googlegroups.com
Hi everyone,

I've written out a new draft for Baetle now. I've tried to implement
various ideas we have discussed on the mailing list. The ontology
validates on http://rdfabout.com/demo/validator/ apart from nagging
about the need for a baseUri.

Please say what you think:

Btw. I've made some comments using #.. . You should also see the
skos:editorialNotes.

#Need to find a permanent namespace / home!
@prefix : <http://xmlns.com/baetle/#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix wf: <http://www.w3.org/2005/01/wf/flow#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .

#Need a baseUri for the validators to be satisfied?
<> a owl:Ontology;
dc:creator <http://bblfish.net/people/henry/card#me>;
dc:creator [ foaf:nick "fraktaltek" ];
dc:contributor <http://www.erlingwl.com/foaf.n3#me> .

:Comitting a owl:Class;
rdfs:subClassOf owl:Thing,
wf:Action .


#Is this correct?
:DocumentVersion a owl:Class ;
rdfs:subClassOf :Version, foaf:Document.

# Issue and subclasses :

:Issue a owl:Class;
rdfs:subClassOf owl:Thing,
wf:Task,
[ a owl:Restriction;
owl:allValuesFrom :Priority;
owl:onProperty :priority ];
rdfs:comment "An issue in a bug database."@en;
skos:editorialNote "Every bug tracking system creates subclasses of
Issues, usually classes such as Bug, Enhancement, NewFeature, etc.. We
define a few here as examples but it is not clear that this should be
the role of this ontology."@en;
skos:editorialNote "Good practice is to arrange it so that the url of
the issue should be related to the url of a page that described the
issue. A good way to distinguish the page from the issue, is to append
some anchor such as #issue to the url of the page."@en;
.


:Enhancement a owl:Class;
rdfs:subClassOf :Issue ;
.

:Defect a owl:Class;
rdfs:subClassOf :Issue ;
.

#Duplicate of Defect
#:Bug a owl:Class;
# rdfs:subClassOf :Issue ;
# skos:editorialNote "It is not clear whether we should be
specifying subclasses in this ontology, as there may be many ways of
doing this, and each project may have its preferred way. It may be on
the #other hand that an analysis of most bug tracking systems shows
them to use similar concepts."@en;
#.

:Task a owl:Class;
rdfs:subClassOf :Issue ;
skos:editorialNote "It is unclear whether this class should be a sub
or superclass of Issue."@en;
.


# Subclasses of wf:State :
# Use multiple inheritance to specify status + resolution of an issue
e.g. Resolved, Later or Closed, Fixed
# E.g. Fixed can both be combined with Resolved and Closed, hence it
must be a subclass of wf:State but not wf:NonTerminalState or
wf:TerminalState agree?

:Open a owl:Class ;
rdfs:subClassOf wf:NonTerminalState .

:New a owl:Class ;
rdfs:subClassOf :Open .

:Unconfirmed a owl:Class ;
rdfs:subClassOf :Open .

:Reopened a owl:Class ;
rdfs:subClassOf :Open .

:Started a owl:Class ;
rdfs:subClassOf wf:NonTerminalState ;
skos:editorialNote "Is this really a subclass of Open?."@en;
.

:Verified a owl:Class ;
rdfs:subClassOf wf:NonTerminalState ;
skos:editorialNote "Is this really a subclass of Open? Is it relevant
at all?."@en;
.

:Resolved a owl:Class ;
rdfs:subClassOf wf:NonTerminalState .

:NotReproducible a owl:Class;
rdfs:subClassOf wf:State;
skos:editorialNote "Specify that this is disjoint with Open etc.?."@en;
.

:WorksForMe a owl:Class;
rdfs:subClassOf wf:State ;
skos:editorialNote "Specify that this is disjoint with Open etc.?."@en;
.

:WontFix a owl:Class;
rdfs:subClassOf wf:State ;
skos:editorialNote "Specify that this is disjoint with Open etc.?."@en;
.

:Incomplete a owl:Class;
rdfs:subClassOf wf:State ;
skos:editorialNote "Specify that this is disjoint with Open etc.?."@en;
.

:Later a owl:Class;
rdfs:subClassOf wf:State ;
skos:editorialNote "Specify that this is disjoint with Open etc.?."@en;
.

:Remind a owl:Class;
rdfs:subClassOf wf:State ;
skos:editorialNote "Specify that this is disjoint with Open etc.?."@en;
.

:Duplicate a owl:Class;
rdfs:subClassOf wf:State ;
skos:editorialNote "Specify that this is disjoint with Open etc.?."@en;
.

:Fixed a owl:Class;
rdfs:subClassOf wf:State ;
skos:editorialNote "Specify that this is disjoint with Open etc.?."@en;
.

:Closed a owl:Class;
rdfs:subClassOf wf:TerminalState ;
.


# What's intended with this class?
#:Patch a owl:Class;
# rdfs:subClassOf :Fix .

# This could be a Restriction or a subclass of the combination of
Fixed and Closed for instance?
#:Solution a owl:Class;
# rdfs:subClassOf owl:Thing,
# wf:TerminalState .

# Priorities :

:Priority a owl:Class;
rdfs:label "Priority";
rdfs:comment "Priority values.";
.

:Blocker a owl:Class;
rdfs:subClassOf :Priority .

:Critical a owl:Class;
rdfs:subClassOf :Priority .

:Major a owl:Class;
rdfs:subClassOf :Priority .

:Trivial a owl:Class;
rdfs:subClassOf :Priority .

:Minor a owl:Class;
rdfs:subClassOf :Priority .

:SoftwarePackage a owl:Class;
rdfs:subClassOf :DocumentVersion;
#rdfs:sublClassOf foaf:Document . - inherits this from DocumentVersion..
.


:Version a owl:Class .

#Properties of Version
:id a owl:DatatypeProperty ;
rdfs:domain :Version;
skos:editorialNote "Should the domain really be specified?"@en;
.


# Issuekeys

:IssueKey a owl:Class ;
skos:editorialNote "Use this class or it subclasses to indicate a key
used for this issue in a tool. But be aware that this key is not
necessarily unique!"@en;
.

:IssueTrackerKey a owl:Class;
rdfs:subClassOf :IssueKey .

:JiraKey a owl:Class;
rdfs:subClassOf :IssueTrackerKey .

:TracKey a owl:Class;
rdfs:subClassOf :IssueTrackerKey .

:RepositoryKey a owl:Class;
rdfs:subClassOf :IssueKey .

:SVNKey a owl:Class;
rdfs:subClassOf :RepositoryKey;
skos:editorialNote "This is used to state that an issue can be
referred to in a Subversion commit log etc."@en;
.

#S hould probably add subclasses for BugZilla, CVS +++

# Properties of IssueKey

:key a owl:DatatypeProperty ;
rdfs:domain :IssueKey .

# Properties of Issue

:issueKey a owl:ObjectProperty ;
rdfs:domain :Issue ;
rdfs:ragne :IssueKey .

:project a owl:ObjectProperty;
rdfs:domain :Issue;
rdfs:range doap:Project;
rdfs:comment "the project this issue concerns"@en;
.

:reporter a owl:ObjectProperty;
rdfs:domain :Issue;
rdfs:range sioc:User;
rdfs:comment "the reporter of the bug"@en;
.

:assigned_to a owl:ObjectProperty ;
rdfs:domain :Issue;
rdfs:range sioc:User ;
rdfs:comment "the person the bug is assigned to"@en;
.

:interested a owl:ObjectProperty ;
rdfs:domain :Issue;
rdfs:range sioc:User ;
rdfs:comment "A user interested in changes to this issue"@en;
.

:qa_contact a owl:ObjectProperty ;
rdfs:domain :Issue;
rdfs:range sioc:User ;
rdfs:comment "A contact point"@en;
skos:editorialNote "This was available on NetBeans issuezilla. Perhaps
it would be better placed somewhere else."@en;
.

# See editorialnote
:about a owl:ObjectProperty;
skos:editorialNote "Range: SoftwarePackage"@en;
.

# what about :attachment(s) ? or is this a subproperty of :comment? or what?

:comment a owl:ObjectProperty ;
rdfs:label "comment"@en;
rdfs:domain :Issue;
rdfs:range sioc:Post ;
rdfs:comment "A comment on an Issue"@en;
.

:contains a owl:ObjectProperty ;
skos:editorialNote "Range: DocumentVersion, Domain: SoftwarePackage"@en;
.

:blocks a owl:ObjectProperty ;
rdfs:label "blocks";
rdfs:comment "this issue is blocking the other"@en;
rdfs:domain :Issue;
rdfs:range :Issue;
skos:editorialNote "the range should perhaps be an wf:Task"@en;
skos:editorialNote "Is this the inverse of depends_on?"@en;
.

:subtask a owl:DatatypeProperty ;
rdfs:label "subtask";
rdfs:comment "a subtask of this issue"@en;
rdfs:domain :Issue;
rdfs:range :Issue;
skos:editorialNote "the range should perhaps be an wf:Task"@en;
.

:depends_on a owl:ObjectProperty ;
rdfs:label "depends_on";
rdfs:comment "a task that depends on this one being completed"@en;
rdfs:domain :Issue;
rdfs:range :Issue;
skos:editorialNote "the range and domain should perhaps be an wf:Task"@en;
.

:causes a owl:ObjectProperty ;
rdfs:label "causes";
rdfs:comment "this Issue causes the other one"@en;
rdfs:domain :Issue;
rdfs:range :Issue;
.

:duplicate a owl:ObjectProperty ;
rdfs:label "duplicate";
rdfs:comment "this Issue is a duplicate of the other."@en;
rdfs:domain :Issue;
rdfs:range :Issue;
skos:editorialNote "should this be a symmetric and transitive
property? Without symmetry we can have the direction have some
implication as to the which one was the last one being worked on"@en;
.


:name a owl:ObjectProperty ;
skos:editorialNote "Used as an attribute on SoftwarePackage"@en;
.


# Deprecated
#:operating_system a owl:ObjectProperty .

# Deprecated
#:platform a owl:ObjectProperty .

:environment a owl:DatatypeProperty ;
rdfs:label "environment";
rdfs:domain :Issue;
rdfs:comment "description of the environment where the issue was noticed";
skos:editorialNote "this was found in Jira on Sesame. The OS and other
relations were not clearly distinguished";
.

:priority a owl:ObjectProperty ;
rdfs:domain :Issue;
rdfs:range :Priority;
rdfs:label "priority";
rdfs:comment "the priority value recognised by those responsible for the issue";
.


:relates_to a owl:ObjectProperty ;
skos:editorialNote "Domain: Committing, Range: :Issue";
.


# do we need this? Use wf:state
#:resolution a owl:ObjectProperty .

:resolvedWith a owl:ObjectProperty ;
skos:editorialNote "Domain: :Issue, Range: Committting, InverseOf relates_to?";
.

#Use wf:state
#:status a owl:ObjectProperty .

:summary a owl:DatatypeProperty ;
rdfs:domain :Issue;
rdfs:comment "summary of Issue"@en;
rdfs:label "summary"@en;
.


:description a owl:DatatypeProperty ;
rdfs:domain :Issue;
rdfs:comment "longer description of the Issue"@en;
rdfs:label "description"@en;
.

# Add more info on this one?
:target_milestone a owl:ObjectProperty .

:created a owl:DatatypeProperty ;
rdfs:labed "created";
rdfs:range xsd:dateTime;
rdfs:domain :Issue;
rdfs:subPropertyOf dct:created;
rdfs:comment "Creation date of Issue";
skos:editorialNote "Should probably just use Dublin Core here";
.

:updated a owl:DatatypeProperty ;
rdfs:labed "updated";
rdfs:range xsd:dateTime;
rdfs:domain :Issue;
rdfs:comment "date Issue was updated";
skos:editorialNote "Should probably just use Dublin Core here";
.

:due_date a owl:DatatypeProperty ;
rdfs:labed "updated";
rdfs:range xsd:dateTime;
rdfs:domain :Issue;
rdfs:comment "date the task is due by";
skos:editorialNote "Should probably have this be on the milestone relations";
.

# Specify this one? see editorial note
:version a owl:ObjectProperty ;
skos:editorialNote "Domain :Issue, Range :Version?";
.

:votes a owl:DatatypeProperty;
rdfs:label "votes";
rdfs:range xsd:integer;
rdfs:comment "number of votes for the issue";
skos:editorialNote "Should probably use some voting ontology";
.

Henry Story

unread,
May 25, 2008, 9:42:52 PM5/25/08
to bae...@googlegroups.com, Wegger Linde Erling
Sorry to have taken so long to reply. I have been very busy in
conferences in California.

http://blogs.sun.com/bblfish/entry/3_weeks_of_conferences_and

-----

Concerning the code. We need to find a way to make it a little easier
to view the diffs. Perhaps if you attach the code in emails that would
reduce the breakages due to spaces, tabs and newlines getting munged.

-----

In order to distinguish comments made by different people I suggest
everyone editing the file creates a special relation that is a
subrelation of skos:editorialNote such as

:ewlNote rdfs:subPropertyOf skos:editorialNote;
rdfs:comment "a note by Erling Wegger Linde" .

then I can add the same, and we can work out who is saying what.

-----

we should add a base with the line such as
@base <http://baetle.googlecode.com/ns> .

----

:DocumentVersion a owl:Class ;
rdfs:subClassOf :Version, foaf:Document.

thanks for adding the second line

----

#Duplicate of Defect
#:Bug a owl:Class;

I think the word Bug is much better understood than defect. To have a
bug ontology without a bug class would be a little odd. It does not
really matter how one names things, but working with general
intuitions would be good.

----

:Task a owl:Class;
rdfs:subClassOf :Issue ;

we have defined further up that

[[
:Issue rdfs:subClassOf wf:Task .
]]

we need to understand what the difference between wf:Task and :Task
is. That should be added to your comments.

-----

[[[


# Subclasses of wf:State :
# Use multiple inheritance to specify status + resolution of an issue

# e.g. Resolved, Later or Closed, Fixed


# E.g. Fixed can both be combined with Resolved and Closed, hence it

# must be a subclass of wf:State but not wf:NonTerminalState or
# wf:TerminalState agree?
]]

Can you give more careful examples of this on a seperate thread to
this list?

-----

The whole section on subclasses of wf:State can be improoved. But I
would be interested to know why you moved here from the UML diagram on
http://code.google.com/p/baetle/

You made some states subclasses of wf:NonTerminalState, others
directly of wf:State.
Why? (Seperate thread please)

[[

]]]

-----

[[


# What's intended with this class?
#:Patch a owl:Class;
# rdfs:subClassOf :Fix .

# This could be a Restriction or a subclass of the combination of

# Fixed and Closed for instance?


#:Solution a owl:Class;
# rdfs:subClassOf owl:Thing,
# wf:TerminalState .

]]


Not sure right now. Probably worth leaving it in there for a while.
Perhaps it will come back to me.

------

[[


:Blocker a owl:Class;
rdfs:subClassOf :Priority .

]]

Not sure I like the name Blocker, as a priority.
Should the priority perhaps better be expressed as a relation to a
project? So one could specify that a bug is a minor for one project,
but a blocker for another?

So we could have something like

:bug1 beatle:blockerFor <http://apache.org/bugdatbaseProj>;
baetle:minorFor <http://netbeans.org/#proj> .

Mhh, that would be cool. :-)

------

[[


#Properties of Version
:id a owl:DatatypeProperty ;
rdfs:domain :Version;
skos:editorialNote "Should the domain really be specified?"@en;
.

]]

something like this would be more complete

[[
:id a owl:DatatypeProperty;
rdfs:label "id"@en;
rdfs:comment "See §4.2.6 rfc 4287 spec. All Versions with the
same id can be considered to be versions of the resource identified by
the id. The id mentions the resource of which it is a representat
ion. "@en;
rdfs:domain :Version;
rdfs:range xsd:anyURI .
]]

But I am thinking it should just be an owl:ObjectProperty. One could
think of the inverse of id as being the part of relation. It should
also be a functional Property.

------

I think making whole classes out of issue keys seems a bit heavy.
Would a relation to a string not be good enough? A note to the effect
that each repository should create its own subrealtion of this
relation would be valuable.

[[
# Issuekeys

# Properties of IssueKey

# Properties of Issue

]]

----

You added
[[


# what about :attachment(s) ? or is this a subproperty of :comment? or
what?

]]

I think we pointed to this in a previous thread, and I think I gave
some example in one of my serialisation. It would be good to put one
or two of these examples up on the wiki.

btw. for those of you interested in doing ontology unit tests, I would
really suggest looking at the cwm source code repository. There are a
lot of interesting things in there.

----

[[


# Deprecated
#:operating_system a owl:ObjectProperty .

# Deprecated
#:platform a owl:ObjectProperty .

]]

There is a deprecated relationship you can add on relations. You will
find something like
that in foaf, and skos I think.

Why are these deprecated? Did we find a better known name for that
relationship? If so it would be good to add a comment on that.

-----

[[


# Specify this one? see editorial note
:version a owl:ObjectProperty ;
skos:editorialNote "Domain :Issue, Range :Version?";
.

]]

can't quite remember. I don't think this is applicatble to an issue,
but perhaps more to document versions. Document versions are needed to
be able to tell which piece of source code is the next version of the
some other piece of source code....

------

Do these notes help?

Henry

Erling Wegger Linde

unread,
May 26, 2008, 5:48:17 AM5/26/08
to Henry Story, bae...@googlegroups.com
Hi!

On Mon, May 26, 2008 at 3:42 AM, Henry Story <henry...@gmail.com> wrote:
> Sorry to have taken so long to reply. I have been very busy in conferences
> in California.
>
> http://blogs.sun.com/bblfish/entry/3_weeks_of_conferences_and

Yes, I saw that blog post earlier so I understood you were busy.
Sounds like you've had three very interesting weeks =)

>
> -----
>
> Concerning the code. We need to find a way to make it a little easier to
> view the diffs. Perhaps if you attach the code in emails that would reduce
> the breakages due to spaces, tabs and newlines getting munged.
>
> -----
>

Good idea!

> In order to distinguish comments made by different people I suggest everyone
> editing the file creates a special relation that is a subrelation of
> skos:editorialNote such as
>
> :ewlNote rdfs:subPropertyOf skos:editorialNote;
> rdfs:comment "a note by Erling Wegger Linde" .
>
> then I can add the same, and we can work out who is saying what.

I've done that - see the attachment =)

>
> -----
>
> we should add a base with the line such as
> @base <http://baetle.googlecode.com/ns> .
>
> ----

I've added this line. I also added ""Does this mean we should change
the namespace too? i.e. we should probably settle on a permanent
namespace soon, agree?"" to the attached Baetle.n3

>
> :DocumentVersion a owl:Class ;
> rdfs:subClassOf :Version, foaf:Document.
>
> thanks for adding the second line
>
> ----
>
> #Duplicate of Defect
> #:Bug a owl:Class;
>
> I think the word Bug is much better understood than defect. To have a bug
> ontology without a bug class would be a little odd. It does not really
> matter how one names things, but working with general intuitions would be
> good.
>
> ----

Agree, see the attachment.

>
> :Task a owl:Class;
> rdfs:subClassOf :Issue ;
>
> we have defined further up that
>
> [[
> :Issue rdfs:subClassOf wf:Task .
> ]]
>
> we need to understand what the difference between wf:Task and :Task is. That
> should be added to your comments.
>
> -----
>
> [[[
> # Subclasses of wf:State :
> # Use multiple inheritance to specify status + resolution of an issue
> # e.g. Resolved, Later or Closed, Fixed
> # E.g. Fixed can both be combined with Resolved and Closed, hence it
> # must be a subclass of wf:State but not wf:NonTerminalState or
> # wf:TerminalState agree?
> ]]
>
> Can you give more careful examples of this on a seperate thread to this
> list?
>

I'll do that, and if we reach an agreement it should probably be added
to the wiki too.

> -----
>
> The whole section on subclasses of wf:State can be improoved. But I would be
> interested to know why you moved here from the UML diagram on
> http://code.google.com/p/baetle/
>
> You made some states subclasses of wf:NonTerminalState, others directly of
> wf:State.
> Why? (Seperate thread please)

I'll answer this in the new thread as you suggest.

I just left them like that - see the attachment.

>
> ------
>
> [[
> :Blocker a owl:Class;
> rdfs:subClassOf :Priority .
> ]]
>
> Not sure I like the name Blocker, as a priority.
> Should the priority perhaps better be expressed as a relation to a project?
> So one could specify that a bug is a minor for one project, but a blocker
> for another?
>
> So we could have something like
>
> :bug1 beatle:blockerFor <http://apache.org/bugdatbaseProj>;
> baetle:minorFor <http://netbeans.org/#proj> .
>
> Mhh, that would be cool. :-)
>

Very good idea! Would this make the :project property superfluous then?

> ------
>
> [[
> #Properties of Version
> :id a owl:DatatypeProperty ;
> rdfs:domain :Version;
> skos:editorialNote "Should the domain really be specified?"@en;
> .
> ]]
>
> something like this would be more complete
>
> [[
> :id a owl:DatatypeProperty;
> rdfs:label "id"@en;
> rdfs:comment "See §4.2.6 rfc 4287 spec. All Versions with the same id
> can be considered to be versions of the resource identified by the id. The
> id mentions the resource of which it is a representat
> ion. "@en;
> rdfs:domain :Version;
> rdfs:range xsd:anyURI .
> ]]
>
> But I am thinking it should just be an owl:ObjectProperty. One could think
> of the inverse of id as being the part of relation. It should also be a
> functional Property.
>

I've added this, see the attachment.

> ------
>
> I think making whole classes out of issue keys seems a bit heavy. Would a
> relation to a string not be good enough? A note to the effect that each
> repository should create its own subrealtion of this relation would be
> valuable.
>

Maybe a string would be sufficient, I might have gotten a little
carried away here. Should we change to:

:issueKey a owl:DatatypeProperty ;
rdfs:domain :Issue ;
rdfs:range xsd:String ;
.

?

I'll try to put up some examples on the wiki.

>
> btw. for those of you interested in doing ontology unit tests, I would
> really suggest looking at the cwm source code repository. There are a lot of
> interesting things in there.
>
> ----
>
> [[
> # Deprecated
> #:operating_system a owl:ObjectProperty .
>
> # Deprecated
> #:platform a owl:ObjectProperty .
> ]]
>
> There is a deprecated relationship you can add on relations. You will find
> something like
> that in foaf, and skos I think.
>
> Why are these deprecated? Did we find a better known name for that
> relationship? If so it would be good to add a comment on that.
>

We used :environment instead. See the attachment.

> -----
>
> [[
> # Specify this one? see editorial note
> :version a owl:ObjectProperty ;
> skos:editorialNote "Domain :Issue, Range :Version?";
> .
> ]]
>
> can't quite remember. I don't think this is applicatble to an issue, but
> perhaps more to document versions. Document versions are needed to be able
> to tell which piece of source code is the next version of the some other
> piece of source code....

I think I'll start a new thread for this one too.


>
> ----
>
> Do these notes help?

Yes, they were very helpful!

Thanks,
-Erling

>
> Henry
>
>
> On 16 May 2008, at 05:09, Erling Wegger Linde wrote:
>
>> Hi everyone,
>>
>> I've written out a new draft for Baetle now. I've tried to implement
>> various ideas we have discussed on the mailing list. The ontology
>> validates on http://rdfabout.com/demo/validator/ apart from nagging
>> about the need for a baseUri.
>>
>> Please say what you think:
>>
>> Btw. I've made some comments using #.. . You should also see the
>> skos:editorialNotes.
>
>

--
Med vennlig hilsen
Erling Wegger Linde

Baetle.n3

Erling Wegger Linde

unread,
May 30, 2008, 7:23:35 AM5/30/08
to bae...@googlegroups.com
New draft!

Have changed priorities to properties (not Classes) as you suggested
Henry. I think that is a great idea, I'm not even sure if the old
approach would be correct at all if you linked an issue to more than
one project.

I've also just used a property to indicated the key an issue might
have on an issue tracker or a repository ++

- Erling

Btw. It now validates perfectly.

Baetle.n3
Reply all
Reply to author
Forward
0 new messages