示例#1
0
        public void StorageSesameDeleteTriples1()
        {
            Graph g = new Graph();

            FileLoader.Load(g, "InferenceTest.ttl");
            g.BaseUri = new Uri("http://example.org/SesameTest");

            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();

            sesame.SaveGraph(g);

            Console.WriteLine("Graph before deletion");
            TestTools.ShowGraph(g);

            //Delete all Triples about the Ford Fiesta
            sesame.UpdateGraph(g.BaseUri, null, g.GetTriplesWithSubject(new Uri("http://example.org/vehicles/FordFiesta")));

            Object results = sesame.Query("ASK WHERE { GRAPH <http://example.org/SesameTest> { <http://example.org/vehicles/FordFiesta> ?p ?o } }");

            if (results is SparqlResultSet)
            {
                Assert.IsFalse(((SparqlResultSet)results).Result, "There should no longer be any triples about the Ford Fiesta present");
            }

            Graph h = new Graph();

            sesame.LoadGraph(h, g.BaseUri);

            Console.WriteLine("Graph after deletion");
            TestTools.ShowGraph(h);

            Assert.IsFalse(h.IsEmpty, "Graph should not be completely empty");
            Assert.IsTrue(g.HasSubGraph(h), "Graph retrieved with missing Triples should be a sub-graph of the original Graph");
            Assert.IsFalse(g.Equals(h), "Graph retrieved should not be equal to original Graph");
        }
示例#2
0
        public void StorageSesameSaveLoad()
        {
            try
            {
                Graph g = new Graph();
                FileLoader.Load(g, "InferenceTest.ttl");
                g.BaseUri = new Uri("http://example.org/SesameTest");

                SesameHttpProtocolConnector sesame = new SesameHttpProtocolConnector("http://nottm-virtual.ecs.soton.ac.uk:8080/openrdf-sesame/", "unit-test");
                sesame.SaveGraph(g);

                //Options.HttpDebugging = true;
                //Options.HttpFullDebugging = true;

                Graph h = new Graph();
                sesame.LoadGraph(h, "http://example.org/SesameTest");
                Assert.IsFalse(h.IsEmpty, "Graph should not be empty after loading");

                Assert.AreEqual(g, h, "Graphs should have been equal");
            }
            catch (Exception ex)
            {
                TestTools.ReportError("Error", ex, true);
            }
            finally
            {
                //Options.HttpFullDebugging = false;
                //Options.HttpDebugging = true;
            }
        }
        public void StorageSesameDeleteGraph2()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
            Uri graphUri = null;

            sesame.DeleteGraph(graphUri);

            Graph g = new Graph();

            FileLoader.Load(g, "resources\\InferenceTest.ttl");
            g.BaseUri = graphUri;

            sesame.SaveGraph(g);

            Graph h = new Graph();

            sesame.LoadGraph(h, graphUri);
            Assert.False(h.IsEmpty, "Graph should not be empty after loading");

            Assert.Equal(g, h);

            sesame.DeleteGraph(graphUri);
            h = new Graph();
            sesame.LoadGraph(h, graphUri);
            Assert.True(h.IsEmpty, "Graph should be equal after deletion");
            Assert.NotEqual(g, h);
        }
示例#4
0
        public void StorageSesameSaveLoad()
        {
            try
            {
                Graph g = new Graph();
                FileLoader.Load(g, "InferenceTest.ttl");
                g.BaseUri = new Uri("http://example.org/SesameTest");

                SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
                sesame.SaveGraph(g);

                //Options.HttpDebugging = true;
                //Options.HttpFullDebugging = true;

                Graph h = new Graph();
                sesame.LoadGraph(h, "http://example.org/SesameTest");
                Assert.IsFalse(h.IsEmpty, "Graph should not be empty after loading");

                Assert.AreEqual(g, h, "Graphs should have been equal");
            }
            finally
            {
                //Options.HttpFullDebugging = false;
                //Options.HttpDebugging = true;
            }
        }
示例#5
0
        public void StorageSesameDeleteTriples2()
        {
            Graph g = new Graph();

            g.BaseUri = new Uri("http://example.org/SesameTest/Delete2");
            g.NamespaceMap.AddNamespace("ex", new Uri("http://example.org/ns#"));
            g.Assert(g.CreateUriNode("ex:subj"), g.CreateUriNode("ex:pred"), g.CreateUriNode("ex:obj"));

            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();

            sesame.SaveGraph(g);

            Console.WriteLine("Graph before deletion");
            TestTools.ShowGraph(g);

            //Delete the single triple
            sesame.UpdateGraph(g.BaseUri, null, g.Triples);

            Object results = sesame.Query("ASK WHERE { GRAPH <http://example.org/SesameTest/Delete2> { <http://example.org/ns#subj> ?p ?o } }");

            if (results is SparqlResultSet)
            {
                Assert.IsFalse(((SparqlResultSet)results).Result, "There should no longer be any triples present in the graph");
            }

            Graph h = new Graph();

            sesame.LoadGraph(h, g.BaseUri);

            Console.WriteLine("Graph after deletion");
            TestTools.ShowGraph(h);

            Assert.IsTrue(h.IsEmpty, "Graph should not be completely empty");
            Assert.IsFalse(g.Equals(h), "Graph retrieved should not be equal to original Graph");
        }
示例#6
0
        public void StorageSesameDeleteGraph1()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
            Uri graphUri = new Uri("http://example.org/Sesame/delete");

            Graph g = new Graph();

            FileLoader.Load(g, "resources\\InferenceTest.ttl");
            g.BaseUri = graphUri;

            sesame.SaveGraph(g);

            Graph h = new Graph();

            sesame.LoadGraph(h, graphUri);
            Assert.IsFalse(h.IsEmpty, "Graph should not be empty after loading");

            Assert.AreEqual(g, h, "Graphs should have been equal");

            sesame.DeleteGraph(graphUri);
            h = new Graph();
            sesame.LoadGraph(h, graphUri);
            Assert.IsTrue(h.IsEmpty, "Graph should be equal after deletion");
            Assert.AreNotEqual(g, h, "Graphs should not be equal after deletion");
        }
        public void StorageSesameDeleteTriples3()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
            Graph g = new Graph();

            g.BaseUri = new Uri("http://example.org/sesame/chinese");
            FileLoader.Load(g, @"..\\resources\chinese.ttl");
            sesame.SaveGraph(g);

            String ask = "ASK WHERE { GRAPH <http://example.org/sesame/chinese> { ?s ?p '例子' } }";

            Object results = sesame.Query(ask);

            Assert.IsAssignableFrom <SparqlResultSet>(results);
            if (results is SparqlResultSet)
            {
                TestTools.ShowResults(results);
                Assert.True(((SparqlResultSet)results).Result);
            }

            // Now delete the triple in question
            sesame.UpdateGraph(g.BaseUri, null, g.Triples);

            // Re-issue ASK to check deletion
            results = sesame.Query(ask);
            Assert.IsAssignableFrom <SparqlResultSet>(results);
            if (results is SparqlResultSet)
            {
                TestTools.ShowResults(results);
                Assert.False(((SparqlResultSet)results).Result);
            }
        }
        public void StorageSesameSaveEmptyGraph2()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
            Uri graphUri = new Uri("http://example.org/Sesame/empty2");

            Console.WriteLine("Deleting any existing graph");
            sesame.DeleteGraph(graphUri);
            Console.WriteLine("Existing graph deleted");

            // First create a non-empty graph
            Graph g = new Graph();

            g.BaseUri = graphUri;
            g.Assert(g.CreateBlankNode(), g.CreateUriNode("rdf:type"), g.CreateUriNode(new Uri("http://example.org/BNode")));
            Console.WriteLine("Saving non-empty graph");
            sesame.SaveGraph(g);
            Console.WriteLine("Non-empty graph saved");

            Graph h = new Graph();

            sesame.LoadGraph(h, graphUri);
            Assert.False(h.IsEmpty, "Graph should not be empty after loading");

            Assert.Equal(g, h);

            // Now attempt to save an empty graph as well
            g         = new Graph();
            g.BaseUri = graphUri;
            Console.WriteLine("Attempting to save empty graph with same name");
            sesame.SaveGraph(g);
            Console.WriteLine("Empty graph saved");

            h = new Graph();
            sesame.LoadGraph(h, graphUri);
            Assert.True(h.IsEmpty, "Graph should be empty after loading");

            Assert.Equal(g, h);
        }
        public void StorageSesameSaveEmptyGraph3()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
            Uri graphUri = null;

            Console.WriteLine("Deleting any existing graph");
            sesame.DeleteGraph(graphUri);
            Console.WriteLine("Existing graph deleted");

            // First create a non-empty graph
            Graph g = new Graph();

            g.BaseUri = graphUri;
            g.Assert(g.CreateBlankNode(), g.CreateUriNode("rdf:type"), g.CreateUriNode(new Uri("http://example.org/BNode")));
            Console.WriteLine("Saving non-empty graph");
            sesame.SaveGraph(g);
            Console.WriteLine("Non-empty graph saved");

            Graph h = new Graph();

            sesame.LoadGraph(h, graphUri);
            Assert.False(h.IsEmpty, "Graph should not be empty after loading");

            Assert.Equal(g, h);

            // Now attempt to overwrite with an empty graph
            g         = new Graph();
            g.BaseUri = graphUri;
            Console.WriteLine("Attempting to save empty graph with same name");
            sesame.SaveGraph(g);
            Console.WriteLine("Empty graph saved");

            h = new Graph();
            sesame.LoadGraph(h, graphUri);

            // Since saving to default graph does not overwrite the graph we've just retrieved must contain the empty graph as a sub-graph
            Assert.True(h.HasSubGraph(g));
        }
        public void StorageSesameSaveEmptyGraph1()
        {
            Graph g = new Graph();

            g.BaseUri = new Uri("http://example.org/Sesame/empty");

            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();

            sesame.SaveGraph(g);

            Graph h = new Graph();

            sesame.LoadGraph(h, "http://example.org/Sesame/empty");
            Assert.True(h.IsEmpty, "Graph should be empty after loading");

            Assert.Equal(g, h);
        }
        public void StorageSesameSparqlUpdate2()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
            Graph g = new Graph();

            g.LoadFromEmbeddedResource("VDS.RDF.Configuration.configuration.ttl");
            g.BaseUri = new Uri("http://example.org/sparqlUpdateDeleteWhere");
            sesame.SaveGraph(g);

            sesame.Update("WITH <http://example.org/sparqlUpdateDeleteWhere> DELETE { ?s a ?type } WHERE { ?s a ?type }");

            Graph h = new Graph();

            sesame.LoadGraph(h, "http://example.org/sparqlUpdateDeleteWhere");
            INode rdfType = h.CreateUriNode("rdf:type");

            Assert.False(h.GetTriplesWithPredicate(rdfType).Any(), "Should not be any rdf:type triples after SPARQL Update operation");
        }
示例#12
0
        public void StorageSesameSparqlUpdate3()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();

            // Ensure required graph is present
            Graph g = new Graph();

            g.BaseUri = new Uri("http://example.org/sesame/chinese");
            FileLoader.Load(g, @"resources\chinese.ttl");
            sesame.SaveGraph(g);

            String ask = "ASK WHERE { GRAPH <http://example.org/sesame/chinese> { ?s ?p '例子' } }";

            // Issue query to validate data was added
            Object results = sesame.Query(ask);

            if (results is SparqlResultSet)
            {
                TestTools.ShowResults(results);
                Assert.IsTrue(((SparqlResultSet)results).Result);
            }
            else
            {
                Assert.Fail("Failed to get a Result Set as expected");
            }

            // Issue a DELETE for the Chinese literal
            String update = "DELETE WHERE { GRAPH <http://example.org/sesame/chinese> { ?s ?p '例子' } }";

            sesame.Update(update);

            // Re-issue query to validate triple was deleted
            results = sesame.Query(ask);
            if (results is SparqlResultSet)
            {
                TestTools.ShowResults(results);
                Assert.IsFalse(((SparqlResultSet)results).Result);
            }
            else
            {
                Assert.Fail("Failed to get a Result Set as expected");
            }
        }
        public void StorageSesameChinese()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
            Graph g = new Graph();

            g.BaseUri = new Uri("http://example.org/sesame/chinese");
            FileLoader.Load(g, @"..\\resources\chinese.ttl");
            sesame.SaveGraph(g);

            String ask = "ASK WHERE { GRAPH <http://example.org/sesame/chinese> { ?s ?p '例子' } }";

            Object results = sesame.Query(ask);

            Assert.IsAssignableFrom <SparqlResultSet>(results);
            if (results is SparqlResultSet)
            {
                TestTools.ShowResults(results);
                Assert.True(((SparqlResultSet)results).Result);
            }
        }
示例#14
0
        public void StorageSesameCyrillic()
        {
            SesameHttpProtocolConnector sesame = SesameTests.GetConnection();
            Graph g = new Graph();

            g.BaseUri = new Uri("http://example.org/sesame/cyrillic");
            FileLoader.Load(g, "cyrillic.rdf");
            sesame.SaveGraph(g);

            String ask = "ASK WHERE {?s ?p 'литерал'}";

            Object results = sesame.Query(ask);

            if (results is SparqlResultSet)
            {
                TestTools.ShowResults(results);
            }
            else
            {
                Assert.Fail("Failed to get a Result Set as expected");
            }
        }
示例#15
0
        public void StorageSesameDeleteTriples()
        {
            try
            {
                Graph g = new Graph();
                FileLoader.Load(g, "InferenceTest.ttl");
                g.BaseUri = new Uri("http://example.org/SesameTest");

                SesameHttpProtocolConnector sesame = new SesameHttpProtocolConnector("http://nottm-virtual.ecs.soton.ac.uk:8080/openrdf-sesame/", "unit-test");
                sesame.SaveGraph(g);

                Console.WriteLine("Graph before deletion");
                TestTools.ShowGraph(g);

                //Delete all Triples about the Ford Fiesta
                sesame.UpdateGraph(g.BaseUri, null, g.GetTriplesWithSubject(new Uri("http://example.org/vehicles/FordFiesta")));

                Object results = sesame.Query("ASK WHERE { <http://example.org/vehicles/FordFiesta> ?p ?o }");
                if (results is SparqlResultSet)
                {
                    Assert.IsFalse(((SparqlResultSet)results).Result, "There should no longer be any triples about the Ford Fiesta present");
                }

                Graph h = new Graph();
                sesame.LoadGraph(h, g.BaseUri);

                Console.WriteLine("Graph after deletion");
                TestTools.ShowGraph(h);

                Assert.IsFalse(h.IsEmpty, "Graph should not be completely empty");
                Assert.IsTrue(g.HasSubGraph(h), "Graph retrieved with missing Triples should be a sub-graph of the original Graph");
                Assert.IsFalse(g.Equals(h), "Graph retrieved should not be equal to original Graph");
            }
            catch (Exception ex)
            {
                TestTools.ReportError("Error", ex, true);
            }
        }
示例#16
0
        public void StorageSesameCyrillic()
        {
            try
            {
                SesameHttpProtocolConnector sesame = new SesameHttpProtocolConnector("http://nottm-virtual.ecs.soton.ac.uk:8080/openrdf-sesame/", "unit-test");
                Graph g = new Graph();
                g.BaseUri = new Uri("http://example.org/sesame/cyrillic");
                FileLoader.Load(g, "cyrillic.rdf");
                sesame.SaveGraph(g);

                String ask = "ASK WHERE {?s ?p 'литерал'}";

                Object results = sesame.Query(ask);
                if (results is SparqlResultSet)
                {
                    TestTools.ShowResults(results);
                }
                else
                {
                    Assert.Fail("Failed to get a Result Set as expected");
                }
            }
            catch (Exception ex)
            {
                TestTools.ReportError("Error", ex, true);
            
            }
        }
        /// <summary>
        /// Initialize repository
        /// Save site triples, role triples, new schema definition
        /// </summary>
        public void Initialize()
        {
            using (SesameHttpProtocolConnector connector = new SesameHttpProtocolConnector(RtvSloConfig.RepositoryUrl, RtvSloConfig.RepositoryName))
            {
                if (connector.IsReady)
                {
                    /// SELECT *
                    /// WHERE {
                    ///     ?s ?p sioc:Site
                    /// }
                    SparqlResultSet queryResult = connector.QueryFormat("SELECT * WHERE {{ ?s ?p {0} }}", Predicate.SiocSite); //TODO optimize query syntax
                    if (queryResult == null)
                    {
                        return;
                    }
                    else if (!queryResult.Results.IsEmpty())
                    {
                        /// sioc:Site is already in repository
                        /// we assumed that repository is initialized
                        return;
                    }

                    /// clear repository
                    this.ClearRepository();

                    /// initialize repository
                    using (Graph g = new Graph())
                    {
                        g.BaseUri = RepositoryHelper.BaseUrl.ToUri();

                        /// Namespaces
                        //foreach (Namespace value in RepositoryHelper.NamespaceDictionary.Values
                        //    .Where(x => x.Status == NamespaceStatusEnum.Internal))
                        //{
                        //    Uri uri = UriFactory.Create(string.Format("{0}", value.FullPath));
                        //    g.NamespaceMap.AddNamespace(value.Prefix, UriFactory.Create(value.FullPath));
                        //}

                        /// Site
                        g.Assert(RepositoryHelper.SiteUrl.ToUriNode(g), Predicate.RdfType.ToUriNode(g), Predicate.SiocSite.ToUriNode(g));
                        g.Assert(RepositoryHelper.SiteUrl.ToUriNode(g), Predicate.RdfsLabel.ToUriNode(g), RtvSloConfig.RtvSloName.ToLiteralNode(g));

                        /// Role
                        g.Assert(RepositoryHelper.JournalistRoleUrl.ToUriNode(g), Predicate.RdfType.ToUriNode(g), Predicate.SiocRole.ToUriNode(g));
                        g.Assert(RepositoryHelper.JournalistRoleUrl.ToUriNode(g), Predicate.NewsHasScope.ToUriNode(g), RepositoryHelper.SiteUrl.ToUriNode(g));

                        g.Assert(RepositoryHelper.ReaderRoleUrl.ToUriNode(g), Predicate.RdfType.ToUriNode(g), Predicate.SiocRole.ToUriNode(g));
                        g.Assert(RepositoryHelper.ReaderRoleUrl.ToUriNode(g), Predicate.NewsHasScope.ToUriNode(g), RepositoryHelper.SiteUrl.ToUriNode(g));

                        /// Gender
                        g.Assert(RepositoryHelper.CreateTypeTriple(g, Predicate.MmcGender, Predicate.RdfsClass));
                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.NewsHasScope, Predicate.MmcGender));

                        g.Assert(RepositoryHelper.CreateTypeTriple(g, RepositoryHelper.GenderMaleUrl, Predicate.MmcGender));
                        g.Assert(RepositoryHelper.GenderMaleUrl.ToUriNode(g), Predicate.NewsHasScope.ToUriNode(g), RepositoryHelper.SiteUrl.ToUriNode(g));

                        g.Assert(RepositoryHelper.CreateTypeTriple(g, RepositoryHelper.GenderFemaleUrl, Predicate.MmcGender));
                        g.Assert(RepositoryHelper.GenderFemaleUrl.ToUriNode(g), Predicate.NewsHasScope.ToUriNode(g), RepositoryHelper.SiteUrl.ToUriNode(g));

                        /// Category
                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.RdfsSeeAlso, Predicate.SiocCategory));

                        /// Post
                        g.Assert(RepositoryHelper.CreateTypeDomainTriples(g, Predicate.MmcSubtitle, Predicate.OwlDatatypeProperty, Predicate.SiocPost));
                        g.Assert(Predicate.MmcSubtitle.ToUriNode(g), Predicate.RdfsSubPropertyOf.ToUriNode(g), Predicate.DctTitle.ToUriNode(g));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcLastUpdated, Predicate.OwlDatatypeProperty, Predicate.SiocPost, Predicate.XsdDateTime));

                        /// Comment
                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcRating, Predicate.OwlDatatypeProperty, Predicate.NewsComment, Predicate.XsdInteger));

                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.NewsId, Predicate.NewsComment));
                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.RdfsSeeAlso, Predicate.NewsComment));
                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.NewsAccessed, Predicate.NewsComment));

                        /// User
                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.NewsId, Predicate.SiocUserAccount));
                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.RdfsSeeAlso, Predicate.SiocUserAccount));
                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.NewsAccessed, Predicate.SiocUserAccount));

                        g.Assert(RepositoryHelper.CreateTypeDomainTriples(g, Predicate.MmcEmail, Predicate.OwlDatatypeProperty, Predicate.SiocUserAccount));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcBirthDate, Predicate.OwlDatatypeProperty, Predicate.SiocUserAccount, Predicate.XsdDate));

                        g.Assert(RepositoryHelper.CreateTypeDomainTriples(g, Predicate.MmcAbout, Predicate.OwlDatatypeProperty, Predicate.SiocUserAccount));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcUserStatistics, Predicate.OwlObjectProperty, Predicate.SiocUserAccount, Predicate.MmcStatistics));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcHasGender, Predicate.OwlObjectProperty, Predicate.SiocUserAccount, Predicate.MmcGender));

                        /// Mmc Statistics
                        g.Assert(RepositoryHelper.CreateTypeTriple(g, Predicate.MmcStatistics, Predicate.RdfsClass));

                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.NewsAvgRating, Predicate.MmcStatistics));
                        g.Assert(RepositoryHelper.CreateDomainTriple(g, Predicate.NewsNRatings, Predicate.MmcStatistics));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcNumOfForumPosts, Predicate.OwlDatatypeProperty, Predicate.MmcStatistics, Predicate.XsdInteger));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcNumOfBlogPosts, Predicate.OwlDatatypeProperty, Predicate.MmcStatistics, Predicate.XsdInteger));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcNumOfPublishedPictures, Predicate.OwlDatatypeProperty, Predicate.MmcStatistics, Predicate.XsdInteger));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcNumOfPublishedComments, Predicate.OwlDatatypeProperty, Predicate.MmcStatistics, Predicate.XsdInteger));

                        g.Assert(RepositoryHelper.CreateTypeDomainRangeTriples(g, Predicate.MmcNumOfPublishedVideos, Predicate.OwlDatatypeProperty, Predicate.MmcStatistics, Predicate.XsdInteger));

                        /// Save graph
                        connector.SaveGraph(g);
                    }
                }
                else
                {
                    this._logger.FatalFormat("RepositoryService, Initialize, SesameHttpProtocolConnector is not ready");
                }
            }
        }