Groups
Groups

"allValuesfrom" Function Missing in SHACL file

91 views
Skip to first unread message

Emily Zhang

unread,
Jun 29, 2020, 6:47:30 PM6/29/20
to TopBraid Suite Users
Hi Irene,
Just wondering if I can use SHACL and the OWL function "allvaluesfrom" or "somevaluesfrom" together? I do see there is "hasvalue" function embedded in the SHACL file, however, I didn't find the other two functions.
Thanks,
Emily

Holger Knublauch

unread,
Jun 29, 2020, 7:56:23 PM6/29/20
to topbrai...@googlegroups.com

OWL and SHACL are different languages with different semantics. You can use OWL and SHACL separately, but their terms don't mean anything to one another. If you want to use something similar to owl:allValuesFrom in SHACL, look at sh:datatype and sh:class.

Holger

--
You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/89d3bec0-016d-4696-80a0-73fa467cdf98o%40googlegroups.com.

Irene Polikoff

unread,
Jun 29, 2020, 8:04:49 PM6/29/20
to topbrai...@googlegroups.com
Hi Emily,

I am not sure I understand the question. OWL is OWL and SHACL is SHACL.  They are different languages with different semantics. OWL is based on the Open World Assumption and SHACL is not.

You can combine OWL axioms and SHACL constraints and rules in the same RDF graph if this is what you mean by “using together”.

There are similarities between SHACL and OWL and you can find constraint components in SHACL that are similar to certain OWL restrictions. If your question is “what in SHACL would be similar to the OWL allValueFrom and someValuesFrom restrictions", then:

For allValuesFrom, if values are resources, use sh:class - this means that all values must be members of the specified class. If values are literals, use sh:datatype.

OWL someValuesFrom is simply a short hand for a qualified cardinality restriction with min = 1. In other words, at least one value must satisfy the restriction, others could be different. In SHACL, you could use qualified value shapes for something similar to the qualified cardinality restrictions. See https://www.w3.org/TR/shacl/#QualifiedValueShapeConstraintComponent.

There is no short hand for someValuesFrom in the spec, we we have defined dash:hasValueWithClass in the dash (http://datashapes.org/dash) namespace. You can find it at http://datashapes.org/dash.ttl and some documentation at http://datashapes.org/dash

You can also take a look at the mapping from OWL to SHACL that is used by TopBraid to auto-generate SHACL from RDFS/OWL. It is described in https://www.topquadrant.com/from-owl-to-shacl-in-an-automated-way/. For the most up to date version of the rules, see the file in the workspace.

Regards,

Irene


Emily Zhang

unread,
Jun 29, 2020, 11:14:43 PM6/29/20
to TopBraid Suite Users
Thanks so much for the detailed reply! I actually found out that sh:in might be a better choice for me. 
To give a summary of my question: 
It's a inference question that all the instances of "Patient" who has the property of "3point_dermfeatures" that satisfy the constrain: (a): their features are within the range of "Atypical, Asymmetry, blue_white_structure"; (b): the number of all the features are in the range [2,3]; should be inferred to as having the disease of "Melanoma".
However, when I tried to "Run Inferences" for the instance of "Patient", nothing returned. Do you think it has something to do with my source code?
Here is the source code I've edited according to to tutorial. 

p3point_validation:Melanoma

  rdf:type owl:Class ;

  rdf:type sh:NodeShape ;

  rdfs:subClassOf owl:Thing ;

  sh:values [

      sh:filterShape [

          sh:property [

              sh:path p3point_validation:point_dermfeatures ;

              sh:in (

                  p3point_validation:Atypical

                  p3point_validation:Asymmetry

                  p3point_validation:Blue_white_structure

                ) ;

              sh:maxCount 3 ;

              sh:minCount 2 ;

            ] ;

        ] ;

      sh:nodes [

          sh:path p3point_validation:Patient ;

        ] ;

    ] ;

.


在 2020年6月29日星期一 UTC-5下午7:04:49,Irene Polikoff写道:
To unsubscribe from this group and stop receiving emails from it, send an email to topbrai...@googlegroups.com.

Holger Knublauch

unread,
Jun 29, 2020, 11:30:58 PM6/29/20
to topbrai...@googlegroups.com

Hi Emily,

the definition below doesn't look correct: you can only use sh:values rules in a property shape, not in a class or node shape. Also, any such rule would need to be attached to the class Patient because you want to apply it to all instances of that class to infer an additional triple. It may work better if you have something like

:Patient
    sh:rule [
        a sh:TripleRule ;
        sh:subject sh:this;
        sh:predicate rdf:type ;
        sh:object p3point_validation:Patient ;
        sh:condition [
            # your sh:filterShape, i.e. start with sh:property
          sh:property [

              sh:path p3point_validation:point_dermfeatures ;

              sh:in (

                  p3point_validation:Atypical

                  p3point_validation:Asymmetry

                  p3point_validation:Blue_white_structure

                ) ;

              sh:maxCount 3 ;    # Are those constraints really needed?

              sh:minCount 2 ;

            ] ;
        ]
    ]

HTH
Holger
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/300044d2-bec1-49a5-85d2-c2de44bfd74fo%40googlegroups.com.

Emily Zhang

unread,
Jun 29, 2020, 11:53:02 PM6/29/20
to TopBraid Suite Users
Thank for the quick reply, Holger! It make sense that I should define the rule under Patient class. However, how can I link the rule to "Melanoma" since its the the instance of patient should be inferred as? Should I define the "melanoma" as the sh:node under sh:filtershape?
Thanks again,
Emily

在 2020年6月29日星期一 UTC-5下午10:30:58,Holger Knublauch写道:

Holger Knublauch

unread,
Jun 29, 2020, 11:54:59 PM6/29/20
to topbrai...@googlegroups.com

Oh I guess I made a copy and paste mistake. Change the line to sh:object p3point_validation:Melanoma because that's the rdf:type you want to infer?

Holger

To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/d5d89d89-0fb2-4af6-883d-a453c5f6257do%40googlegroups.com.

Irene Polikoff

unread,
Jun 30, 2020, 12:26:35 AM6/30/20
to topbrai...@googlegroups.com
These slides may be useful.

Rules and Inferencing with SHAC.pdf

Emily Zhang

unread,
Jun 30, 2020, 12:40:35 PM6/30/20
to TopBraid Suite Users
Thanks, Hogler! I've revised the code accordingly, however, when I "Run Inference" against the instance of "Patient", still nothing returned. I am wondering whether that's because I should write a GraphQL/SPARQL query for inference? I've read the slides provided by Irene, very helpful, thank you! But it only provided examples for the EDG version. It did provide example for GraphQL query, but I am using SHACL file right now, and I think it only contains the SPARQL query function. 

在 2020年6月29日星期一 UTC-5下午10:54:59,Holger Knublauch写道:

Irene Polikoff

unread,
Jun 30, 2020, 2:10:42 PM6/30/20
to topbrai...@googlegroups.com
Emily,

If you have a shape like this

p3point_validation:Patient a owl:Class, sh:NodeShape


    sh:rule [
        a sh:TripleRule ;
        sh:subject sh:this;
        sh:predicate rdf:type ;

        sh:objectp3point_validation:Melanoma;

        sh:condition [
          sh:property [

              sh:path p3point_validation:point_dermfeatures ;

              sh:in (

                  p3point_validation:Atypical

                  p3point_validation:Asymmetry

                  p3point_validation:Blue_white_structure

                ) ;

              sh:minCount 2 ;

            ] ;
        ]
    ]



And you have an instance of p3point_validation:Patient with some of the listed values for the p3point_validation:point_dermfeatures property, you will get this inference - provided that the patient has at least 2 values for the property.

I do not understand what you meant by "it only provided examples for the EDG version”. EDG version of what? 

EDG performs these inferences so yes, everything you see is for EDG.

How are you running the inferences? You need to go to the Transform tab in EDG to execute.

If you wanting to invoke inference execution programmatically, then, as explained in the slides, you need to script it. You will need to write a script that will call the SPARQLMotion module - again, explained in the slides. This would be either SWP or SPARQLMotion script, but to do so, you will need to get familiar with these scripting technologies and it will take you some time
. I doubt that we will be able to get you successfully through this learning curve just by using this mailing list. It will need you to take some training/mentoring.

GraphQL example in the slides was to show that if you are using sh:values to infer property values, a dynamically inferred value of a property will be available to the GraphQL query. Sh:values inferences get computed on the fly and they do not need any triggering. For your example, however, we are not using sh:values. So, this is irrelevant to your particular example. 

Inferred values will be available to SPARQL queries as well. But again, this is unconnected to what you are currently trying to accomplish.

One reason we are not using sh:values for your example is that you are trying to infer the type of a resource. A property backed by sh:values rule is protected from edits. It is always system generated on a fly. We would not want this for rdf:type since when you create a new resource, you specify its type. 

Another approach is not to infer rdf:type Melanoma for the patient. Instead, create a new property e.g., :diagnosis and infer :diagnosis :Melanoma. After all, a patient is not melanoma, he has melanoma, but he is not a disease, he is a person.

If you do this, then you will be able to use sh:values. And then, the inference will happen on the fly. You will be able to get the inferred value in a GraphQL query as explained in the slides. To get it in a SPARQL query, you need to use tosh:values. See https://www.topquadrant.com/graphql/values.html for an example of a SPARQL query to retrieve dynamically inferred values.




To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/49c2c4eb-85dc-4009-b52d-a4c73a3e2e74o%40googlegroups.com.

Emily Zhang

unread,
Jun 30, 2020, 5:47:25 PM6/30/20
to TopBraid Suite Users
Thanks, Irene! It's a great suggestion to create a new property for diagnosis:Melanoma. I will try to add sh:values for the new property. Just to clarify, I was using TopBraid Composer instead of EDG, and according to the tutorial, I should "press the Run Inferences button to materialize the inferences." 
For the materials you've provided so far, I've only seen the example GraphQL query to fetch the results. But I guess that's okay since I found another type of file in composer that I can create which is "GraphQL/SHACL" file. I could try to move my source code, write a GraphQL to query the results and press the Run Inferences button. Hopefully I can get the returned label "Melanoma" for that "patient".


在 2020年6月30日星期二 UTC-5下午1:10:42,Irene Polikoff写道:
To unsubscribe from this group and stop receiving emails from it, send an email to topbrai...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/49c2c4eb-85dc-4009-b52d-a4c73a3e2e74o%40googlegroups.com.

Irene Polikoff

unread,
Jun 30, 2020, 6:34:47 PM6/30/20
to topbrai...@googlegroups.com
Yes, if you are in Composer, then clicking on Run Inferencing would normally run SHACL rules. You will need to run it on a graph that has data and it must include your model and rules.

I do not know if Composer will run Property Value rules when Run Inferencing is pressed. Holger will know.

The whole point with Property Value rules is that values are calculated dynamically at query time, they are not stored any where. When you press Run Inferencing, however, inferred triples actually get materialized in a graph.

The page I sent you has a section entitled Use of Inferred Values using SPARQLThis is for dynamic inferencing.

If you Run Inferencing and get triples persisted/materialized, then you can query for them as you would for any other triple - nothing special is required.

To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/475dcb32-2794-4c11-8955-cbd64bb1a9c7o%40googlegroups.com.

Emily Zhang

unread,
Jul 8, 2020, 12:04:02 AM7/8/20
to TopBraid Suite Users
Hi Irene,
Great suggestions on creating a property for "Diagnosis". I've done that but I am not exactly sure: 1) If I want to infer a patient has Melanoma, should Melanoma be an instance under the property "Diagnosis"? 2) You mentioned "I need to run it on a graph that has data and it must include your model and rules.", I am not really familiar with the concept "graph" in the Top Braid Composer. 3) For the inferred results, since you mentioned I don't have to use tosh:value for sparql in this case, I was expecting to "run inference" against the instance of "Patient" and got a returned label for " Melanoma"? But there was still nothing returned. The inference run successfully, 4) I even tried to add sparql query attached below, the "execute SPARQL" button was grey somehow. 
Here is the source code I used: 

p3point_validation:Patient

  rdf:type owl:Class ;

  rdf:type sh:NodeShape ;

  rdfs:subClassOf rdfs:Resource ;

  sh:rule [

      rdf:type sh:TripleRule ;

      sh:condition [

          sh:property [

              sh:path <http://example.org/3point_validation#Diagnosis:Melanoma> ;

              sh:in (

                  p3point_validation:Atypical

                  p3point_validation:Asymmetry

                  p3point_validation:Blue_white_structure

                ) ;

              sh:maxCount 3 ;

              sh:minCount 2 ;

            ] ;

        ] ;

      sh:object p3point_validation:Melanoma ;

      sh:predicate rdf:type ;

      sh:subject sh:this ;

    ] ;

.

Here is the SPARQL query:

SELECT *

WHERE {

?Patient a schema: Patient .

    (?Patient schema: Diagnosis) tosh:values ?Diagnosis .

}


Appreciate a lot!

Best,

Emily

在 2020年6月30日星期二 UTC-5下午5:34:47,Irene Polikoff写道:
To unsubscribe from this group and stop receiving emails from it, send an email to topbrai...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/475dcb32-2794-4c11-8955-cbd64bb1a9c7o%40googlegroups.com.

Irene Polikoff

unread,
Jul 8, 2020, 12:29:14 AM7/8/20
to topbrai...@googlegroups.com
On Jul 8, 2020, at 12:04 AM, Emily Zhang <zxy10...@gmail.com> wrote:

Hi Irene,
Great suggestions on creating a property for "Diagnosis". I've done that but I am not exactly sure: 1) If I want to infer a patient has Melanoma, should Melanoma be an instance under the property "Diagnosis”?

What do you mean by “under”. How can an instance be under a property?

2) You mentioned "I need to run it on a graph that has data and it must include your model and rules.", I am not really familiar with the concept "graph" in the Top Braid Composer.


3) For the inferred results, since you mentioned I don't have to use tosh:value for sparql in this case, I was expecting to "run inference" against the instance of "Patient" and got a returned label for " Melanoma"? But there was still nothing returned. The inference run successfully,

Not sure what is going wrong for you.

4) I even tried to add sparql query attached below, the "execute SPARQL" button was grey somehow. 
Here is the source code I used: 

p3point_validation:Patient

  rdf:type owl:Class ;

  rdf:type sh:NodeShape ;

  rdfs:subClassOf rdfs:Resource ;

  sh:rule [

      rdf:type sh:TripleRule ;

      sh:condition [

          sh:property [

              sh:path <http://example.org/3point_validation#Diagnosis:Melanoma> ;

              sh:in (

                  p3point_validation:Atypical

                  p3point_validation:Asymmetry

                  p3point_validation:Blue_white_structure

                ) ;

              sh:maxCount 3 ;

              sh:minCount 2 ;

            ] ;

        ] ;

      sh:object p3point_validation:Melanoma ;

      sh:predicate rdf:type ;

      sh:subject sh:this ;

    ] ;

.



How do your data triples look like?

Is your data graph separate from the graph containing your model and the rule or are they together? If they are separate, does your data graph owl:imports your shapes graph?


To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/74a5ec44-6f12-4c0d-a591-2d2d0c343e44o%40googlegroups.com.

Emily Zhang

unread,
Jul 9, 2020, 12:55:32 AM7/9/20
to TopBraid Suite Users
Hi Irene,
Thanks for the reply! The documents were really helpful! I think I understand the concept "graph" now. I've attached my answers to some of your questions below.

1. What do you mean by “under”. How can an instance be under a property?
 So clearly, property shouldn't have instance. I wasn't sure what is the relationship between "diagnosis" and "melanoma" when you give this comment: "create a new property e.g., :diagnosis and infer :diagnosis :Melanoma". Is "melanoma" a label of the property "diagnosis"?
            

2. How do your data triples look like?

Is your data graph separate from the graph containing your model and the rule or are they together? If they are separate, does your data graph owl:imports your shapes graph?


By "data triples", my understanding is the classes, properties I defined in a graph, which in my case in "shacl.ttl". I've attached a screenshot of all the classes, properties I've created so far.
And they are all in the same graph. My rule was defined in the "source code" of "patient" class. 

Screenshot 2020-07-08 23.47.20.png

Appreciate a lot!
Best,
Emily

在 2020年7月7日星期二 UTC-5下午11:29:14,Irene Polikoff写道:
To unsubscribe from this group and stop receiving emails from it, send an email to topbrai...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/74a5ec44-6f12-4c0d-a591-2d2d0c343e44o%40googlegroups.com.

Irene Polikoff

unread,
Jul 9, 2020, 9:44:21 AM7/9/20
to topbrai...@googlegroups.com
Hi Emily,

There are too many misunderstandings and things to correct. We will not be able to help you through this on the mailing list. The learning gap is too large.

My recommendation, if you want to continue with this, is to go back to basics and do this step by step - learn RDF, including key concepts and terminology, learn how to work in TopBraid Composer, including managing graphs, understand modeling, etc. For example, you should never modify shacl.ttl. All the documentation I have been pointing you to is readily available - both on the web and in TBC itself under Help. You need to take some time to study these topics, go through tutorials, etc. If you are at a university, get help from your professors. If you are doing this from work, try to find a training class.

Then, may be you can try to progress to more technically advanced topics like SHACL rules.

Regards,

Irene

On Jul 9, 2020, at 12:55 AM, Emily Zhang <zxy10...@gmail.com> wrote:

Hi Irene,
Thanks for the reply! The documents were really helpful! I think I understand the concept "graph" now. I've attached my answers to some of your questions below.

1. What do you mean by “under”. How can an instance be under a property?
 So clearly, property shouldn't have instance. I wasn't sure what is the relationship between "diagnosis" and "melanoma" when you give this comment: "create a new property e.g., :diagnosis and infer :diagnosis :Melanoma". Is "melanoma" a label of the property "diagnosis"?
            

2. How do your data triples look like?

Is your data graph separate from the graph containing your model and the rule or are they together? If they are separate, does your data graph owl:imports your shapes graph?


By "data triples", my understanding is the classes, properties I defined in a graph, which in my case in "shacl.ttl". I've attached a screenshot of all the classes, properties I've created so far.
And they are all in the same graph. My rule was defined in the "source code" of "patient" class. 

<Screenshot 2020-07-08 23.47.20.png>

To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/78ca7f0c-baeb-4391-b7af-dc529fde5c72o%40googlegroups.com.
<Screenshot 2020-07-08 23.47.20.png>

Emily Zhang

unread,
Jul 12, 2020, 10:42:26 PM7/12/20
to TopBraid Suite Users
Hi Irene,
I was trying to learn the key concepts while managing to finish this task. I've read all the tutorials I could find before I start posting on this forum. I wish there are documents that explain how TopBraid Composer works in a more general way. For example, you said "I should never modify shacl.ttl", I guess I won't learn that from any tutorials or classes. Even if I am familiar with all the RDF concepts, I still wouldn't know that. And I don't know anyone else who has experience with TopBraid Composer. If you think I need other training, please point me to. 
Many thanks,
Emily

在 2020年7月9日星期四 UTC-5上午8:44:21,Irene Polikoff写道:
Irene

To unsubscribe from this group and stop receiving emails from it, send an email to topbrai...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/78ca7f0c-baeb-4391-b7af-dc529fde5c72o%40googlegroups.com.
<Screenshot 2020-07-08 23.47.20.png>

Irene Polikoff

unread,
Jul 12, 2020, 11:24:10 PM7/12/20
to topbrai...@googlegroups.com

Please see below

On Jul 12, 2020, at 10:42 PM, Emily Zhang <zxy10...@gmail.com> wrote:

Hi Irene,
I was trying to learn the key concepts while managing to finish this task. I've read all the tutorials I could find before I start posting on this forum. I wish there are documents that explain how TopBraid Composer works in a more general way. For example, you said "I should never modify shacl.ttl", I guess I won't learn that from any tutorials or classes. Even if I am familiar with all the RDF concepts, I still wouldn't know that.

Yes, I believe you would. A general best practice and convention with RDF is that you do not modify other people’s namespaces and files. You create your own.

In case of SHACL.ttl, if you looked at its description, you would see "This vocabulary defines terms used in SHACL, the W3C Shapes Constraint Language."

This is a standard ontology of SHACL language elements. It would be quite peculiar to think that one should or even could put their own domain specific shapes into it.

Further, certain files in the TBC namespace are locked - because they are system files. This includes shacl.ttl and a number of others. Users should not be unlocking locked files and changing them.

And when you create new files you should not put them into projects that are pre-built - those that are in the workspace after install. You should create your own project and use it for your artifacts. 
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/64aeb414-0b53-40af-9528-1fba08d35ad0o%40googlegroups.com.

Emily Zhang

unread,
Jul 12, 2020, 11:28:32 PM7/12/20
to TopBraid Suite Users
Thanks for the quick reply. I feel like there is a misunderstanding here. I didn't modify the system file, I created my own shacl file and built my own namespace. I only modified the source code for one property which is a function I believe. 

在 2020年7月12日星期日 UTC-5下午10:24:10,Irene Polikoff写道:
To unsubscribe from this group and stop receiving emails from it, send an email to topbrai...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/64aeb414-0b53-40af-9528-1fba08d35ad0o%40googlegroups.com.

Irene Polikoff

unread,
Jul 12, 2020, 11:52:31 PM7/12/20
to topbrai...@googlegroups.com
Emily,

I was going by your response where you answered my question as follows:

"By "data triples", my understanding is the classes, properties I defined in a graph, which in my case in "shacl.ttl”.”

In any case, I did not mean your classes and properties when I said “data triples”. By data triples I meant data that you are trying to process by rules i.e., add new inferred triples to.

I believe we have a disconnect even at the level of basic terminology, making it difficult and time consuming for me to help you.

If you send your file(s) and provide the exact triples you want to be produced as a result of rule execution, I may be able to look at this.

To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/d3ebf7e8-8e53-4bb3-9274-0fecf08c205bo%40googlegroups.com.

Emily Zhang

unread,
Jul 12, 2020, 11:55:05 PM7/12/20
to TopBraid Suite Users
Thank you so much! I really appreciate that! How would you like me to send my files? 

在 2020年7月12日星期日 UTC-5下午10:52:31,Irene Polikoff写道:
Emily,

To unsubscribe from this group and stop receiving emails from it, send an email to topbrai...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/d3ebf7e8-8e53-4bb3-9274-0fecf08c205bo%40googlegroups.com.

Irene Polikoff

unread,
Jul 13, 2020, 11:46:28 AM7/13/20
to topbrai...@googlegroups.com, Composer Support
To keep it off the list, send it to composer support - copied here.

To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/d4f13872-c673-42c2-b8d5-9783651dcf35o%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages
Search
Clear search
Close search
Google apps
Main menu