You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ge...@apache.org on 2010/09/22 17:17:05 UTC

svn commit: r1000036 - in /geronimo/server/trunk/plugins/console/console-portal-driver/src: main/java/org/apache/geronimo/console/navigation/ main/webapp/ main/webapp/WEB-INF/themes/ test/java/org/apache/geronimo/console/navigation/

Author: genspring
Date: Wed Sep 22 15:17:04 2010
New Revision: 1000036

URL: http://svn.apache.org/viewvc?rev=1000036&view=rev
Log:
GERONIMO-5516 Display basic set of navigation items in a list instead of a tree

Modified:
    geronimo/server/trunk/plugins/console/console-portal-driver/src/main/java/org/apache/geronimo/console/navigation/NavigationJsonGenerator.java
    geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/WEB-INF/themes/navigation.jsp
    geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/main.css
    geronimo/server/trunk/plugins/console/console-portal-driver/src/test/java/org/apache/geronimo/console/navigation/NavigationJsonGeneratorTest.java

Modified: geronimo/server/trunk/plugins/console/console-portal-driver/src/main/java/org/apache/geronimo/console/navigation/NavigationJsonGenerator.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/console/console-portal-driver/src/main/java/org/apache/geronimo/console/navigation/NavigationJsonGenerator.java?rev=1000036&r1=1000035&r2=1000036&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/console/console-portal-driver/src/main/java/org/apache/geronimo/console/navigation/NavigationJsonGenerator.java (original)
+++ geronimo/server/trunk/plugins/console/console-portal-driver/src/main/java/org/apache/geronimo/console/navigation/NavigationJsonGenerator.java Wed Sep 22 15:17:04 2010
@@ -16,6 +16,7 @@
  */
 package org.apache.geronimo.console.navigation;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -47,6 +48,10 @@ import org.slf4j.LoggerFactory;
  */
 
 public class NavigationJsonGenerator {
+    
+    private static  Map<String, Map<String, TreeNode>> navigationTrees=new HashMap<String, Map<String, TreeNode>>();
+    
+    public static final String ALL = "all";
       
     private ResourceBundle navigationResourcebundle;
          
@@ -61,75 +66,92 @@ public class NavigationJsonGenerator {
         }
     }
     
-    public String generateTreeJSON(List<PageConfig> pageConfigList, String contextPath, String DefaultIcon) {
-       
-        Map<String, TreeNode> navigationTree = new TreeMap<String, TreeNode>();
-        
-        for (PageConfig pc : pageConfigList) {
-            try {
-                new TreeNode(pc).populateTree(navigationTree);
-            } catch (Exception e) {
-                log.error(e.getMessage(),e);
-                continue;
-            }
-        }
-
-        StringBuffer sb = new StringBuffer(10);
-        sb.append("[");
+    
+    private Map<String, TreeNode> getNavigationTree(List<PageConfig> pageConfigList, String mode){
         
+        Map<String, TreeNode> navigationTree;
         
-        for (TreeNode node : navigationTree.values()) {
+        if (navigationTrees.get(mode) != null) {
+            navigationTree = navigationTrees.get(mode);
+        } else {
 
-            if (node.isTopNode()) {
-                sb.append("\n");
-                appendNodeToTreeJSON(sb, node, contextPath, DefaultIcon);
+            navigationTree = new TreeMap<String, TreeNode>();
+
+            for (PageConfig pc : pageConfigList) {
+                if (mode.equals(ALL) || (pc.getMode() != null && mode.equals(pc.getMode()))) {
+                    try {
+                        new TreeNode(pc).populateTree(navigationTree);
+                    } catch (Exception e) {
+                        log.error(e.getMessage(), e);
+                        continue;
+                    }
+                }
             }
 
-        }
-        
-        //remove the extra ','
-        if(navigationTree.values().size()>0){
-            sb.deleteCharAt(sb.length()-1);
+            navigationTrees.put(mode, navigationTree);
+
         }
 
-        sb.append("\n]");
-        return sb.toString();
+        return navigationTree;
     }
-    public String generateTreeJSON(List<PageConfig> pageConfigList, String contextPath, String DefaultIcon, String mode) {
-        
-        Map<String, TreeNode> navigationTree = new TreeMap<String, TreeNode>();
+       
+    
+    public String generateTreeJSON(List<PageConfig> pageConfigList, String contextPath, String DefaultIcon, String mode, int threshold) {
         
-        for (PageConfig pc : pageConfigList) {
-            if(pc.getMode()!=null&&mode.equals(pc.getMode())){
-                try {
-                    new TreeNode(pc).populateTree(navigationTree);
-                } catch (Exception e) {
-                    log.error(e.getMessage(),e);
-                    continue;
-                }
-            }
-        }
+        Map<String, TreeNode> navigationTree=this.getNavigationTree(pageConfigList, mode);
 
+       
+        boolean isTreeAList=this.isTreeAList(pageConfigList, mode, threshold);
+        
+        
         StringBuffer sb = new StringBuffer(10);
         sb.append("[");
         
         
-        for (TreeNode node : navigationTree.values()) {
+        if(!isTreeAList){
+            
+            for (TreeNode node : navigationTree.values()) {
+
+                // when menu items number is less than 6, let's only display the basic menu to the user.
+                // because the user won't need a t to organize the.
+
+                    if (node.isTopNode()) {
+                        sb.append("\n");
+                        appendNodeToTreeJSON(sb, node, contextPath, DefaultIcon);
+                    }
+
 
-            if (node.isTopNode()) {
-                sb.append("\n");
-                appendNodeToTreeJSON(sb, node, contextPath, DefaultIcon);
             }
+            
+            //remove the extra ','
+            sb.deleteCharAt(sb.length()-1);
 
-        }
-        //remove the extra ','
-        if(navigationTree.values().size()>0){
+            sb.append("\n]");
+            
+        } else {
+            
+            for (TreeNode node : navigationTree.values()) {
+                if (node.isLeafNode()) {
+    
+                    sb.append("\n");
+    
+                    appendBasicListJSON(sb, node, contextPath, DefaultIcon);
+                } 
+            }
+            //remove the extra ','
             sb.deleteCharAt(sb.length()-1);
+            
+            sb.append("\n]");
+            
         }
+ 
+        
+        
 
-        sb.append("\n]");
         return sb.toString();
     }
+    
+    
     private void appendNodeToTreeJSON(StringBuffer sb, TreeNode node, String contextPath, String DefaultIcon) {
 
         sb.append("{");
@@ -165,50 +187,32 @@ public class NavigationJsonGenerator {
 
     }
     
-    public String generateQuickLauncherJSON(List<PageConfig> pageConfigList, String contextPath, String DefaultIcon) {
-        
-        Map<String, TreeNode> navigationTree = new TreeMap<String, TreeNode>();
-        
-        for (PageConfig pc : pageConfigList) {
-            try {
-                new TreeNode(pc).populateTree(navigationTree);
-            } catch (Exception e) {
-                log.error(e.getMessage(),e);
-                continue;
-            }
-        }
+    
+    private void appendBasicListJSON(StringBuffer sb, TreeNode node, String contextPath, String DefaultIcon) {
 
-        StringBuffer sb = new StringBuffer(10);
-        sb.append("[\n");
-        
-        for (TreeNode node : navigationTree.values()) {
+        sb.append("{");
 
-            if (node.isTopNode()) {
-                appendNodeToQuickLauncherJSON(sb, node, contextPath, DefaultIcon);
-            }
+        
 
+        if (node.isLeafNode()) {
+            sb.append("label: \'<img src=\"" + contextPath + node.getIcon() + "\" alt=\"\" border=\"0\">&nbsp;");
+            sb.append("<a href=\"" + contextPath + "/portal/" + node.getId() + "/" + node.getPath() + "\">"
+                    + getLocalizedString(node.getLabel()) + "</a>\'");
         }
-        //remove the extra ','
-        sb.deleteCharAt(sb.length()-1);
 
-        sb.append("\n]");
-        return sb.toString();
+        sb.append(",");
+        sb.append("id: \'" + node.getId() + "\'");
+
+        sb.append("},");
+
     }
+    
+   
 
-    public String generateQuickLauncherJSON(List<PageConfig> pageConfigList, String contextPath, String DefaultIcon,String mode) {
+    public String generateQuickLauncherJSON(List<PageConfig> pageConfigList, String contextPath, String DefaultIcon, String mode) {
         
-        Map<String, TreeNode> navigationTree = new TreeMap<String, TreeNode>();
         
-        for (PageConfig pc : pageConfigList) {
-            if(pc.getMode()!=null&&mode.equals(pc.getMode())){
-                try {
-                    new TreeNode(pc).populateTree(navigationTree);
-                } catch (Exception e) {
-                    log.error(e.getMessage(),e);
-                    continue;
-                }
-            }
-        }
+        Map<String, TreeNode> navigationTree=this.getNavigationTree(pageConfigList, mode);
 
         StringBuffer sb = new StringBuffer(10);
         sb.append("[\n");
@@ -226,6 +230,8 @@ public class NavigationJsonGenerator {
         sb.append("\n]");
         return sb.toString();
     }
+    
+    
     private void appendNodeToQuickLauncherJSON(StringBuffer sb, TreeNode node, String contextPath, String DefaultIcon) {
 
         if (node.isLeafNode()) {
@@ -271,5 +277,40 @@ public class NavigationJsonGenerator {
         return key;
 
     }
+    
+    public boolean isTreeHasValidItem(List<PageConfig> pageConfigList, String mode){
+        
+        Map<String, TreeNode> navigationTree=this.getNavigationTree(pageConfigList, mode);
+        
+        
+        for (TreeNode node:navigationTree.values()){
+            
+            if(node.isLeafNode()){
+                return true;
+            }
+            
+        }
+        
+        return false;
+    }
+    
+    
+    private boolean isTreeAList(List<PageConfig> pageConfigList, String mode, int threshold ){
+        
+        Map<String, TreeNode> navigationTree=this.getNavigationTree(pageConfigList, mode);
+        
+        
+        int leafNodeCount=0;
+        
+        for (TreeNode node:navigationTree.values()){
+            
+            if(node.isLeafNode()){
+                leafNodeCount=leafNodeCount+1;
+            }
+            
+        }
+        
+        return leafNodeCount< threshold;
+    }
 
 }

Modified: geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/WEB-INF/themes/navigation.jsp
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/WEB-INF/themes/navigation.jsp?rev=1000036&r1=1000035&r2=1000036&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/WEB-INF/themes/navigation.jsp (original)
+++ geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/WEB-INF/themes/navigation.jsp Wed Sep 22 15:17:04 2010
@@ -39,10 +39,12 @@ limitations under the License.
 
 <%
     NavigationJsonGenerator generator = new NavigationJsonGenerator(request.getLocale());
-    String treeJson = generator.generateTreeJSON(pageConfigList, request.getContextPath(), "/images/ico_doc_16x16.gif");
-    String treeJsonBasic = generator.generateTreeJSON(pageConfigList, request.getContextPath(), "/images/ico_doc_16x16.gif","basic");
-    String listJson = generator.generateQuickLauncherJSON(pageConfigList, request.getContextPath(), "/images/ico_doc_16x16.gif");
+    String treeJson = generator.generateTreeJSON(pageConfigList, request.getContextPath(), "/images/ico_doc_16x16.gif", "all", 8);
+    String treeJsonBasic = generator.generateTreeJSON(pageConfigList, request.getContextPath(), "/images/ico_doc_16x16.gif","basic", 8);
+    String listJson = generator.generateQuickLauncherJSON(pageConfigList, request.getContextPath(), "/images/ico_doc_16x16.gif", "all");
     String listJsonBasic = generator.generateQuickLauncherJSON(pageConfigList, request.getContextPath(), "/images/ico_doc_16x16.gif","basic");
+    boolean isBasicTreeHasValidItem=generator.isTreeHasValidItem(pageConfigList,"basic");
+
 %>
 
 <table class="tundra" width="200px" border="0" cellpadding="0" cellspacing="0">
@@ -50,8 +52,11 @@ limitations under the License.
         <td CLASS="ReallyDarkBackground"><strong>&nbsp;<fmt:message    key="Console Navigation"/></strong></td>
     </tr>
     <tr>
-        <td>&nbsp;<input type="radio" name="mode" id ="mode" checked="checked" onclick="changeMode()"/><fmt:bundle basename="portaldriver"><fmt:message key="console.mode.basic"/></fmt:bundle>
+        <td>
+		<div id="modeSwitcher" class="<%=isBasicTreeHasValidItem?"modeSwitcher":"hidden"%>">
+		&nbsp;<input type="radio" name="mode" id ="mode" checked="checked" onclick="changeMode()"/><fmt:bundle basename="portaldriver"><fmt:message key="console.mode.basic"/></fmt:bundle>
                   <input type="radio"  name="mode" id ="mode" onclick="changeMode()"/><fmt:bundle basename="portaldriver"><fmt:message key="console.mode.advanced"/></fmt:bundle>
+				  </div>
         </td>
     </tr>
     <tr><td>&nbsp;&nbsp;</td></tr>
@@ -59,7 +64,12 @@ limitations under the License.
         <td>&nbsp;&nbsp;<input id="quickLauncher"></td>
     </tr>
     <tr>
-        <td>&nbsp;&nbsp;<div id="navigationTreeBasic"></div><div id="navigationTreeAdvanced"></div>
+        <td>&nbsp;&nbsp;
+			<div id="navigationTreeBasic">
+			
+			
+			</div>
+			<div id="navigationTreeAdvanced"></div>
         </td>
     </tr>
 </table>
@@ -107,5 +117,14 @@ limitations under the License.
             items: listDataBasic
             }
      });
-    dojo.addOnLoad(function() { createNavigationTree(treeStoreBasic,listStoreBasic,"basic"); });
+     
+     <% if(isBasicTreeHasValidItem) {%>
+   
+		dojo.addOnLoad(function() { createNavigationTree(treeStoreBasic,listStoreBasic,"basic"); });
+    
+	<%} else {%>
+    
+		dojo.addOnLoad(function() { createNavigationTree(treeStore,listStore,"advanced"); });
+   
+   <% }%>
 </script>

Modified: geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/main.css
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/main.css?rev=1000036&r1=1000035&r2=1000036&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/main.css (original)
+++ geronimo/server/trunk/plugins/console/console-portal-driver/src/main/webapp/main.css Wed Sep 22 15:17:04 2010
@@ -137,28 +137,52 @@ a:hover 
 
 
 .tundra .dijitLeaf {
-    width: 0px;
-    height: 0px; 
+    display: none;
+}
+
+.tundra .dijitTreeIcon {
+    display: none;
 }
 
 .tundra .dijitFolderOpened {
-    background: url('images/folderOpened_new.gif') no-repeat;
     display: none;
 }
+
 .tundra .dijitFolderClosed {
-    background: url('images/folderClosed_new.gif') no-repeat;
     display: none;
 }
 
-.tundra .dijitTreeRow {	
-    padding-bottom: 3px;
+.tundra .dijitTreeRow {
+    padding-bottom: 4px;
 }
 
-.tundra .dijitTreeIcon {
-    display: none;
-    height: 16px;
-    width: 16px;
+.tundra .dijitTreeExpandoLeaf #navigationTreeBasic {
+    background-image: url("images/transparent.gif");
 }
+
+.tundra .dijitTreeNodeSelected {
+    font-size: 1.2em;
+}
+
+.modeSwitcher {
+    margin-bottom: 2px;
+    margin-left: 12px;
+    margin-right: 5px;
+    margin-top: 6px;
+    padding-bottom: 2px;
+    padding-left: 2px;
+    padding-right: 2px;
+    padding-top: 2px;
+}
+
+#navigationTreeAdvanced {
+    padding-left: 4px;
+}
+
+#navigationTreeBasic {
+    padding-left: 4px;
+}
+
  
 .Content .TopLeft
 {

Modified: geronimo/server/trunk/plugins/console/console-portal-driver/src/test/java/org/apache/geronimo/console/navigation/NavigationJsonGeneratorTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/console/console-portal-driver/src/test/java/org/apache/geronimo/console/navigation/NavigationJsonGeneratorTest.java?rev=1000036&r1=1000035&r2=1000036&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/console/console-portal-driver/src/test/java/org/apache/geronimo/console/navigation/NavigationJsonGeneratorTest.java (original)
+++ geronimo/server/trunk/plugins/console/console-portal-driver/src/test/java/org/apache/geronimo/console/navigation/NavigationJsonGeneratorTest.java Wed Sep 22 15:17:04 2010
@@ -25,18 +25,18 @@ import junit.framework.TestCase;
 import org.apache.geronimo.pluto.impl.PageConfig;
 
 /*
-* @version $Rev$ $Date$
-*/
+ * @version $Rev$ $Date$
+ */
 public class NavigationJsonGeneratorTest extends TestCase {
 
     NavigationJsonGenerator navigationJsonGenerator;
     List<PageConfig> pageList;
-    
+
     protected void setUp() throws Exception {
         super.setUp();
-        
-        navigationJsonGenerator=new NavigationJsonGenerator(null);
-        
+
+        navigationJsonGenerator = new NavigationJsonGenerator(null);
+
         pageList = new ArrayList<PageConfig>();
         PageConfig pc = new PageConfig();
 
@@ -52,7 +52,6 @@ public class NavigationJsonGeneratorTest
         pc.setUri("/server/serverlog");
         pageList.add(pc);
 
-        
         pc = new PageConfig();
         pc.setIcon("/images/ico_deploy_16x16.gif");
         pc.setName("2-2-1/cat2/cat2-1/item2-2-1");
@@ -65,28 +64,35 @@ public class NavigationJsonGeneratorTest
         pc.setName("1-2/cat1/item1-2");
         pc.setUri("/server/serverlog");
         pageList.add(pc);
-    
 
-        
     }
 
     public void testGenerateTreeJSON() {
         System.out.println("testGenerateTreeJSON() ------ ");
-        String json=navigationJsonGenerator.generateTreeJSON(pageList, "console", "/images/ico_deploy_16x16.gif");
-        
-        String expected="[\n{label: \'cat1\',id: \'1\',children: [{label: \'cat1-1\',id: \'1-1\',children: [{label: \'cat1-1-1\',id: \'1-1-1\',children: [{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/1-1-1-1/cat1/cat1-1/cat1-1-1/item1-1-1-1\">item1-1-1-1</a>\',id: \'1-1-1-1\'}]\n}]\n},{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/1-2/cat1/item1-2\">item1-2</a>\',id: \'1-2\'}]\n},\n{label: \'cat2\',id: \'2\',children: [{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/2-2/cat2/item2-2\">item2-2</a>\',id: \'2-2\'}]\n}\n]";
-       
+        String json = navigationJsonGenerator.generateTreeJSON(pageList, "console", "/images/ico_deploy_16x16.gif",
+                "all", 3);
+
+        String expected = "[\n{label: \'cat1\',id: \'1\',children: [{label: \'cat1-1\',id: \'1-1\',children: [{label: \'cat1-1-1\',id: \'1-1-1\',children: [{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/1-1-1-1/cat1/cat1-1/cat1-1-1/item1-1-1-1\">item1-1-1-1</a>\',id: \'1-1-1-1\'}]\n}]\n},{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/1-2/cat1/item1-2\">item1-2</a>\',id: \'1-2\'}]\n},\n{label: \'cat2\',id: \'2\',children: [{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/2-2/cat2/item2-2\">item2-2</a>\',id: \'2-2\'}]\n}\n]";
+
         System.out.println(json);
-        Assert.assertEquals(expected,json);
+        Assert.assertEquals(expected, json);
+
+        json = navigationJsonGenerator.generateTreeJSON(pageList, "console", "/images/ico_deploy_16x16.gif", "all", 5);
+
+        expected = "[\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/1-1-1-1/cat1/cat1-1/cat1-1-1/item1-1-1-1\">item1-1-1-1</a>\',id: \'1-1-1-1\'},\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/1-2/cat1/item1-2\">item1-2</a>\',id: \'1-2\'},\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/2-2/cat2/item2-2\">item2-2</a>\',id: \'2-2\'},\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\" alt=\"\" border=\"0\">&nbsp;<a href=\"console/portal/2-2-1/cat2/cat2-1/item2-2-1\">item2-2-1</a>\',id: \'2-2-1\'}\n]";
+        System.out.println(json);
+        Assert.assertEquals(expected, json);
+
     }
-    
+
     public void testGenerateQuickLauncherJSON() {
         System.out.println("testGenerateQuickLauncherJSON() ------ ");
-        String json=navigationJsonGenerator.generateQuickLauncherJSON(pageList, "console", "/images/ico_deploy_16x16.gif");
-        String expected="[\n\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\">&nbsp;<span>item1-1-1-1</span>\',name: \'item1-1-1-1\',href:\'console/portal/1-1-1-1/cat1/cat1-1/cat1-1-1/item1-1-1-1'},\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\">&nbsp;<span>item1-2</span>\',name: \'item1-2\',href:\'console/portal/1-2/cat1/item1-2\'},\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\">&nbsp;<span>item2-2</span>\',name: \'item2-2\',href:\'console/portal/2-2/cat2/item2-2\'}\n]";
-       
+        String json = navigationJsonGenerator.generateQuickLauncherJSON(pageList, "console",
+                "/images/ico_deploy_16x16.gif", "all");
+        String expected = "[\n\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\">&nbsp;<span>item1-1-1-1</span>\',name: \'item1-1-1-1\',href:\'console/portal/1-1-1-1/cat1/cat1-1/cat1-1-1/item1-1-1-1'},\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\">&nbsp;<span>item1-2</span>\',name: \'item1-2\',href:\'console/portal/1-2/cat1/item1-2\'},\n{label: \'<img src=\"console/images/ico_deploy_16x16.gif\">&nbsp;<span>item2-2</span>\',name: \'item2-2\',href:\'console/portal/2-2/cat2/item2-2\'}\n]";
+
         System.out.println(json);
-        Assert.assertEquals(expected,json);
+        Assert.assertEquals(expected, json);
 
     }
 }