This is an automated email from the ASF dual-hosted git repository.

sergeykamov pushed a commit to branch NLPCRAFT-491
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit 5d37fdb2582af5b2e2c78d53714f0c860796d86c
Author: Sergey Kamov <[email protected]>
AuthorDate: Fri Apr 1 16:42:13 2022 +0300

    WIP.
---
 nlpcraft-examples/order/README.md                  |  46 +++++++
 nlpcraft-examples/order/pom.xml                    |  62 +++++++++
 .../org/apache/nlpcraft/examples/order/Order.scala |  82 ++++++++++++
 .../nlpcraft/examples/order/OrderModel.scala       | 144 +++++++++++++++++++++
 .../order/src/main/resources/order_model.yaml      |  60 +++++++++
 .../examples/order/NCModelValidationSpec.scala     |  30 +++++
 .../nlpcraft/examples/order/OrderModelSpec.scala   |  54 ++++++++
 pom.xml                                            |   1 +
 8 files changed, 479 insertions(+)

diff --git a/nlpcraft-examples/order/README.md 
b/nlpcraft-examples/order/README.md
new file mode 100644
index 0000000..cf21b29
--- /dev/null
+++ b/nlpcraft-examples/order/README.md
@@ -0,0 +1,46 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<img alt="" src="https://nlpcraft.apache.org/images/nlpcraft_logo_black.gif"; 
height="80px">
+<br>
+
+[![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://raw.githubusercontent.com/apache/opennlp/master/LICENSE)
+[![Build](https://github.com/apache/incubator-nlpcraft/workflows/build/badge.svg)](https://github.com/apache/incubator-nlpcraft/actions)
+[![Documentation 
Status](https://img.shields.io/:docs-latest-green.svg)](https://nlpcraft.apache.org/docs.html)
+[![Gitter](https://badges.gitter.im/apache-nlpcraft/community.svg)](https://gitter.im/apache-nlpcraft/community)
+
+### Light Switch Example
+TODO:
+### Documentation
+TODO:
+
+For any questions, feedback or suggestions:
+
+ * View & run other 
[examples](https://github.com/apache/incubator-nlpcraft/tree/master/nlpcraft-examples)
+ * Read [documentation](https://nlpcraft.apache.org/docs.html), latest 
[Javadoc](https://nlpcraft.apache.org/apis/latest/index.html) and [REST 
APIs](https://nlpcraft.apache.org/using-rest.html)
+ * Download & Maven/Grape/Gradle/SBT 
[instructions](https://nlpcraft.apache.org/download.html)
+ * File a bug or improvement in 
[JIRA](https://issues.apache.org/jira/projects/NLPCRAFT)
+ * Post a question at [Stack 
Overflow](https://stackoverflow.com/questions/ask) using <code>nlpcraft</code> 
tag
+ * Access [GitHub](https://github.com/apache/incubator-nlpcraft) mirror 
repository.
+ * Join project developers on 
[[email protected]](mailto:[email protected])
+
+### Copyright
+Copyright (C) 2021 Apache Software Foundation
+
+<img src="https://www.apache.org/img/ASF20thAnniversary.jpg"; height="64px" 
alt="ASF Logo">
+
+
diff --git a/nlpcraft-examples/order/pom.xml b/nlpcraft-examples/order/pom.xml
new file mode 100644
index 0000000..41a4266
--- /dev/null
+++ b/nlpcraft-examples/order/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://maven.apache.org/POM/4.0.0";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <name>NLPCraft Example Order</name>
+    <artifactId>nlpcraft-example-order</artifactId>
+
+    <parent>
+        <artifactId>nlpcraft-parent</artifactId>
+        <groupId>org.apache.nlpcraft</groupId>
+        <version>1.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>nlpcraft</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Test dependencies. -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven.compiler.plugin.ver}</version>
+                <configuration>
+                    <source>${java.ver}</source>
+                    <target>${java.ver}</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/Order.scala
 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/Order.scala
new file mode 100644
index 0000000..769e8ab
--- /dev/null
+++ 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/Order.scala
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.examples.order
+
+import scala.collection.mutable
+
+private enum PizzaSize:
+    case SMALL, MEDIUM, LARGE
+
+private class Pizza(name: String, var sizeOpt: Option[PizzaSize]):
+    override def toString: String =
+        val sz = 
Option.when(sizeOpt.nonEmpty)(sizeOpt.toString.toLowerCase).getOrElse("unknown")
+        s"$name $sz size"
+
+object Order:
+    def getPizzaSizeKinds: String = 
PizzaSize.values.map(_.toString.toLowerCase).mkString(", ")
+    def pizza2Str(name: String, size: PizzaSize): String = s"$name 
${size.toString.toLowerCase} size"
+
+import Order.*
+
+/**
+  * Contract.
+  * 1. 'mkSpecifyRequest' scans ordered data, finds first invalid element and 
asks to specify it.
+  * 2. 'specify' methods (specifyPizzaSize) should specify elements in the 
same order.
+  * So, we don't need to save which concrete element we treying to specify.
+  */
+class Order:
+    private val pizza = mutable.LinkedHashMap.empty[String, PizzaSize]
+    private val drinks = mutable.LinkedHashSet.empty[String]
+
+    def addDrink(drink: String): Unit = drinks += drink
+    def addPizza(name: String, size: PizzaSize): Unit = pizza += name -> size
+    def addPizza(name: String): Unit = pizza += name -> null
+
+    def inProgress(): Boolean = pizza.nonEmpty || drinks.nonEmpty
+
+    def isValid(): Boolean =
+        (pizza.nonEmpty || drinks.nonEmpty) &&
+        (pizza.isEmpty || pizza.forall{ (_, size) => size != null } )
+
+    def specifyPizzaSize(sz: PizzaSize): Boolean = pizza.find { (_, size) => 
size == null } match
+        case Some((name, _)) => pizza += name -> sz; true
+        case None => false
+
+    def ask2Specify(): String =
+        require(!isValid())
+
+        if pizza.isEmpty && drinks.isEmpty then
+            "Order is empty. Please order some pizza or drinks."
+        else
+            pizza.find { (_, size) => size == null } match
+                case Some((name, _)) => s"Please specify $name size? It can be 
$getPizzaSizeKinds"
+                case None => throw new AssertionError("Invalid state")
+
+    def ask2Confirm(): String =
+        require(isValid())
+        s"Let me specify your order.\n${this.toString()}\nIs it correct?"
+
+    override def toString(): String =
+        val ps = if pizza.nonEmpty then s"Pizza: ${pizza.map { (name, sz) => 
pizza2Str(name, sz) }.mkString(", ")}. " else ""
+        val ds = if drinks.nonEmpty then s"Drinks: ${drinks.mkString(", ")}. " 
else ""
+
+        s"$ps$ds"
+
+    def clear(): Unit =
+        pizza.clear()
+        drinks.clear()
\ No newline at end of file
diff --git 
a/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
new file mode 100644
index 0000000..7f0bc74
--- /dev/null
+++ 
b/nlpcraft-examples/order/src/main/java/org/apache/nlpcraft/examples/order/OrderModel.scala
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.examples.order
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.internal.util.NCResourceReader
+import org.apache.nlpcraft.nlp.*
+import org.apache.nlpcraft.nlp.entity.parser.semantic.NCSemanticEntityParser
+import org.apache.nlpcraft.nlp.entity.parser.*
+import org.apache.nlpcraft.nlp.token.enricher.NCEnStopWordsTokenEnricher
+import org.apache.nlpcraft.nlp.token.parser.NCOpenNLPTokenParser
+import scala.collection.mutable
+import org.apache.nlpcraft.NCResultType.*
+import scala.jdk.CollectionConverters.*
+
+/**
+  * This example provides very simple implementation for NLI-powered light 
switch.
+  * You can say something like this:
+  * <ul>
+  *     <li>"Turn the lights off in the entire house."</li>
+  *     <li>"Switch on the illumination in the master bedroom closet."</li>
+  * </ul>
+  * You can easily modify intent callbacks to perform the actual light 
switching using
+  * HomeKit or Arduino-based controllers.
+  * <p>
+  * See 'README.md' file in the same folder for running and testing 
instructions.
+  */
+
+class OrderModel extends NCModelAdapter(
+    new NCModelConfig("nlpcraft.order.ex", "Order Example Model", "1.0"),
+    new NCPipelineBuilder().withSemantic("en", "order_model.yaml").build()
+):
+    private val orders = mutable.HashMap.empty[String, Order]
+
+    private def getOrder(im: NCIntentMatch): Order = 
orders.getOrElseUpdate(im.getContext.getRequest.getUserId, new Order)
+    private def extractPizza(e: NCEntity): String = 
e.get[String]("ord:pizza:kind:value")
+    private def extractPizzaSize(e: NCEntity): String = 
e.get[String]("ord:pizza:size:value")
+    private def extractDrink(e: NCEntity): String = 
e.get[String]("ord:drink:value")
+
+    private def confirmOrSpecify(ord: Order): NCResult =
+        if ord.isValid() then
+            NCResult(ord.ask2Confirm(), ASK_DIALOG)
+        else
+            NCResult(ord.ask2Specify(), ASK_DIALOG)
+
+    private def getAvgPosition(e: NCEntity): Double =
+        val toks = e.getTokens.asScala
+
+        (toks.head.getIndex + toks.last.getIndex) / 2.0
+
+    @NCIntent("intent=confirm term(confirm)={has(ent_groups, 'confirm')}")
+    def onConfirm(im: NCIntentMatch, @NCIntentTerm("confirm") confirm: 
NCEntity): NCResult =
+        val ord = getOrder(im)
+
+        if !ord.inProgress() then throw new NCRejection("No orders in 
progress")
+
+        if confirm.getId == "ord:confirm:yes" then
+            if ord.isValid() then
+                println("Congratulations. Order executed!")
+                ord.clear()
+                NCResult("Order executed.", ASK_RESULT)
+            else
+                NCResult(ord.ask2Specify(), ASK_DIALOG)
+        else
+            ord.clear()
+            NCResult("Order cleared. We are ready for new orders.", ASK_RESULT)
+
+    @NCIntent(
+        "intent=order " +
+        "  term(common)={# == 'ord:common'}* " +
+        "  term(pizzaList)={# == 'ord:pizza:kind'}*" +
+        "  term(pizzaSizesList)={# == 'ord:pizza:size'}* " +
+        "  term(drinkList)={# == 'ord:drink'}*"
+    )
+    @NCIntentSample(Array(
+        "I want to order margherita, marinara and tea"
+    ))
+    def onCommonOrder(
+        im: NCIntentMatch,
+        @NCIntentTerm("common") common: List[NCEntity],
+        @NCIntentTerm("pizzaList") pizzas: List[NCEntity],
+        @NCIntentTerm("pizzaSizesList") pizzaSizes: List[NCEntity],
+        @NCIntentTerm("drinkList") drinks: List[NCEntity]
+    ): NCResult =
+        if pizzas.isEmpty && drinks.isEmpty then throw new NCRejection("Please 
order some pizza or drinks")
+        if pizzaSizes.size > pizzas.size then throw new NCRejection("Pizza and 
their sizes cannot be recognized")
+
+        val ord = getOrder(im)
+
+        case class Size(entity: NCEntity, position: Double)
+
+        val sizes = mutable.ArrayBuffer.empty ++ pizzaSizes.map(p => Size( 
p,getAvgPosition(p)))
+
+        pizzas.foreach(p => {
+            sizes.size match
+                case 0 => ord.addPizza(extractPizza(p))
+                case _ =>
+                    val avgPos = getAvgPosition(p)
+                    val nextNeighbour = sizes.minBy(p => Math.abs(avgPos - 
p.position))
+                    ord.addPizza(extractPizza(p), 
PizzaSize.valueOf(extractPizzaSize(nextNeighbour.entity).toUpperCase))
+                    sizes -= nextNeighbour
+        })
+
+        for (p <- drinks.map(extractDrink)) ord.addDrink(p)
+
+        confirmOrSpecify(ord)
+
+    @NCIntent(
+        "intent=specifyPizzaSize " +
+        "  term(common)={# == 'ord:common'}* " +
+        "  term(size)={# == 'ord:pizza:size'} " +
+        "  term(pizza)={# == 'ord:pizza:kind'}?"
+    )
+    def onSpecifyPizzaSize(
+        im: NCIntentMatch,
+        @NCIntentTerm("common") common: List[NCEntity],
+        @NCIntentTerm("size") size: NCEntity,
+        @NCIntentTerm("pizza") pizzaOpt: Option[NCEntity]
+    ): NCResult =
+        val ord = getOrder(im)
+        require(!ord.isValid())
+
+        val sz = PizzaSize.valueOf(extractPizzaSize(size).toUpperCase)
+
+        pizzaOpt match
+            case Some(pizza) => ord.addPizza(extractPizza(pizza), sz)
+            case None => if !ord.specifyPizzaSize(sz) then throw new 
NCRejection("What specified?")
+
+        confirmOrSpecify(ord)
\ No newline at end of file
diff --git a/nlpcraft-examples/order/src/main/resources/order_model.yaml 
b/nlpcraft-examples/order/src/main/resources/order_model.yaml
new file mode 100644
index 0000000..728f875
--- /dev/null
+++ b/nlpcraft-examples/order/src/main/resources/order_model.yaml
@@ -0,0 +1,60 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+elements:
+  - id: "ord:common"
+    description: "Common words for order."
+    synonyms:
+      - "{pizza|food}"
+      - "{drink|lemonade}"
+      - "{buy|order|bring|delivery}"
+
+  - id: "ord:pizza:kind"
+    description: "Kinds of pizza."
+    values:
+      "margherita": [ ]
+      "marbonara": [ ]
+      "marinara": [ ]
+
+  - id: "ord:pizza:size"
+    description: "Size of pizza."
+    values:
+      "small": [ "{small|smallest|min|minimal} {size|*}" ]
+      "medium": [ "{medium|intermediate} {size|*}" ]
+      "large": [ "{big|large|max|maximum} {size|*}" ]
+
+  - id: "ord:drink"
+    description: "Kinds of drinks."
+    values:
+      "tea": [ ]
+      "green tea": [ ]
+      "coffee": [ ]
+      "cola": [ "{coca|cola|coca cola|cocacola|coca-cola}" ]
+
+  - id: "ord:confirm:yes"
+    description: "Conformation (yes)."
+    groups: ["confirm"]
+    synonyms:
+      - "{yes|yeah|right|fine|nice|excellent|good}"
+      - "{you are|*} {correct|right}"
+
+  - id: "ord:confirm:no"
+    description: "Conformation (no)."
+    groups: ["confirm"]
+    synonyms:
+      - "{no|nope|incorrect|wrong}"
+      - "{you are|*} {not|are not|aren't } {correct|right}"
diff --git 
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/NCModelValidationSpec.scala
 
b/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/NCModelValidationSpec.scala
new file mode 100644
index 0000000..5210050
--- /dev/null
+++ 
b/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/NCModelValidationSpec.scala
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.examples.order
+
+import org.apache.nlpcraft.*
+import org.junit.jupiter.api.*
+
+import scala.util.Using
+
+/**
+  * JUnit models validation.
+  */
+class NCModelValidationSpec:
+    @Test
+    def test(): Unit = Using.resource(new NCModelClient(new OrderModel())) { 
_.validateSamples() }
\ No newline at end of file
diff --git 
a/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/OrderModelSpec.scala
 
b/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/OrderModelSpec.scala
new file mode 100644
index 0000000..bb324c7
--- /dev/null
+++ 
b/nlpcraft-examples/order/src/test/java/org/apache/nlpcraft/examples/order/OrderModelSpec.scala
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.examples.order
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.NCResultType.*
+import org.junit.jupiter.api.Test
+
+import scala.util.Using
+import scala.collection.mutable
+/**
+  *
+  */
+class OrderModelSpec:
+    @Test
+    def test(): Unit =
+        val buf = mutable.ArrayBuffer.empty[String]
+
+        def printDialog(): Unit = for (line <- buf) println(line)
+
+        Using.resource(new NCModelClient(new OrderModel)) { client =>
+            def ask(txt: String, expType: NCResultType): Unit =
+                val resp = client.ask(txt, null, "userId")
+
+                buf += s">> $txt"
+                buf += s">> ${resp.getBody} (${resp.getType})"
+                buf += ""
+
+                if expType != resp.getType then
+                    printDialog()
+                    require(false, s"Unexpected type: ${resp.getType}, 
expected: ${expType}.")
+
+            ask("I want to order margherita medium size, marbonara, marinara 
and tea", ASK_DIALOG)
+            ask("large size please", ASK_DIALOG)
+            ask("smallest", ASK_DIALOG)
+            ask("you are right", ASK_RESULT)
+
+            printDialog()
+        }
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 669f422..3659f9c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -393,6 +393,7 @@
                 <module>nlpcraft-examples/lightswitch</module>
                 <module>nlpcraft-examples/lightswitch-ru</module>
                 <module>nlpcraft-examples/lightswitch-fr</module>
+                <module>nlpcraft-examples/order</module>
             </modules>
         </profile>
     </profiles>

Reply via email to