]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Comparison of dependencies and expression texts
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 20 Jan 2010 15:54:43 +0000 (15:54 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 20 Jan 2010 15:54:43 +0000 (15:54 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@13570 ac1ea38d-2e2b-0410-8846-a27921b304fc

13 files changed:
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ExpressionComposite.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/AuxiliaryExpressionViewFactor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ConstantExpressionViewFactor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/DelayExpressionViewFactor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ExpressionFieldKeyListener.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/IExpressionViewFactor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupExpressionViewFactor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ParameterExpressionViewFactor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/StockExpressionViewFactor.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java
org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.jj
org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/TestExpressionParser.java

index 1819e6ffb115e5aebe4c6456785a639d80aeeb0c..742ae5a350b6eb54e7e21ffb53f10bd0b3425bb4 100644 (file)
@@ -1,6 +1,10 @@
 package org.simantics.sysdyn.ui.equation;\r
 \r
 \r
+import java.io.StringReader;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
 import org.eclipse.jface.layout.GridDataFactory;\r
 import org.eclipse.jface.layout.GridLayoutFactory;\r
 import org.eclipse.jface.viewers.ISelection;\r
@@ -8,10 +12,13 @@ import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.SWT;\r
 import org.eclipse.swt.events.FocusEvent;\r
 import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
 import org.eclipse.swt.events.MouseEvent;\r
 import org.eclipse.swt.events.MouseListener;\r
 import org.eclipse.swt.events.SelectionEvent;\r
 import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Color;\r
 import org.eclipse.swt.graphics.Font;\r
 import org.eclipse.swt.graphics.Point;\r
 import org.eclipse.swt.layout.RowLayout;\r
@@ -30,6 +37,8 @@ import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.procedure.Listener;\r
 import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
+import org.simantics.sysdyn.expressionParser.ParseException;\r
 import org.simantics.ui.SimanticsUI;\r
 \r
 public class EquationView extends ViewPart implements ISelectionListener {\r
@@ -54,7 +63,6 @@ public class EquationView extends ViewPart implements ISelectionListener {
     Composite unitsAndRange;  \r
     Composite emptyComposite;\r
     \r
-    \r
     @Override    \r
     public void createPartControl(Composite parent) {\r
         // Listeners\r
@@ -202,15 +210,15 @@ public class EquationView extends ViewPart implements ISelectionListener {
                                                 unitSelector.updateUnits(variable);\r
                                             }\r
                                             \r
+                                            if(shortcutTabs != null) shortcutTabs.updateTables(variable);\r
+                                            \r
                                             String expressionType = expressionComposite.resetExpressionView(variable);\r
+                                            addExpressionFieldListeners();\r
+                                            validateExpressionFields();\r
                                             expressionController.setExpressionTypes(expressionComposite.getExpressionTypes());  \r
                                             expressionController.select(expressionType);\r
                                             \r
                                             nameText.setText(result.name);\r
-                                            \r
-                                            if(shortcutTabs != null) {\r
-                                                shortcutTabs.updateTables(variable);\r
-                                            }\r
                                         }\r
                                     });      \r
 \r
@@ -247,6 +255,8 @@ public class EquationView extends ViewPart implements ISelectionListener {
             @Override\r
             public void widgetSelected(SelectionEvent e) {\r
                 expressionComposite.displayExpressionView(expressionController.getSelecetedType());\r
+                addExpressionFieldListeners();\r
+                validateExpressionFields();\r
             }\r
 \r
             @Override\r
@@ -300,7 +310,46 @@ public class EquationView extends ViewPart implements ISelectionListener {
         });\r
     }\r
     \r
-\r
-\r
+    private void addExpressionFieldListeners() {\r
+    if(expressionComposite.getExpressionViewFactor() != null)\r
+        for(Text text : expressionComposite.getExpressionViewFactor().getExpressionFields()) {\r
+            text.addModifyListener(new ModifyListener() {\r
+\r
+                @Override\r
+                public void modifyText(ModifyEvent e) {\r
+                    validateExpressionFields();\r
+                }\r
+            });\r
+        }\r
+    }\r
+    \r
+    private void validateExpressionFields() {\r
+        ExpressionParser parser = new ExpressionParser(new StringReader(""));\r
+        Set<String> variables = new HashSet<String>();\r
+        \r
+        if(expressionComposite.getExpressionViewFactor() != null)\r
+            for(Text text : expressionComposite.getExpressionViewFactor().getExpressionFields()) {\r
+                String textString = text.getText();\r
+                parser.ReInit(new StringReader(textString));\r
+                try {\r
+                    parser.expr();\r
+                    variables.addAll(parser.getReferences());\r
+                    text.setBackground(new Color(text.getDisplay(), 255, 255, 255));\r
+                } catch (ParseException e1) {\r
+                    text.setBackground(new Color(text.getDisplay(), 255, 230, 230));\r
+                    return;\r
+                }\r
+            }\r
+        \r
+        for(TableItem ti : this.shortcutTabs.getVariableTable().getItems()) {\r
+            if(!variables.contains(ti.getText())) {\r
+                for(Text text : expressionComposite.getExpressionViewFactor().getExpressionFields())\r
+                    text.setBackground(new Color(text.getDisplay(), 255, 230, 230)); \r
+                ti.setBackground(new Color(ti.getDisplay(), 255, 230, 230));\r
+            } else {\r
+                ti.setBackground(new Color(ti.getDisplay(), 255, 255, 255));\r
+            }\r
+        }\r
+    }\r
 \r
 }
\ No newline at end of file
index bb5bc09e5d09ad49cfe51355de96294006f86b1a..339bd000a6ec046c52deedf94aab4ebe67e15a7f 100644 (file)
@@ -69,8 +69,8 @@ public class ExpressionComposite extends Composite {
     }\r
 \r
     public String resetExpressionView(Resource variable) {\r
-        data.clear();\r
-        origData.clear();\r
+        this.data.clear();\r
+        this.origData.clear();\r
         this.variable = variable;\r
         this.expressionViewFactor = null;\r
         String origExpressionType = getOriginalExpressionType().toString();\r
@@ -166,6 +166,10 @@ public class ExpressionComposite extends Composite {
         this.expressionViewFactor.replaceSelection(var);\r
     }\r
     \r
+    public IExpressionViewFactor getExpressionViewFactor() {\r
+        return this.expressionViewFactor;\r
+    }\r
+    \r
     private ExpressionType getOriginalExpressionType() {\r
 \r
         ExpressionType et = null;\r
index 4d523cd1b43fc05aa630f71232d26d160fef5933..0a6810a57da22bc500eb27911ca96250e8a7d1c7 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.sysdyn.ui.equation.expressions;\r
 \r
+import java.util.Arrays;\r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.eclipse.jface.layout.GridDataFactory;\r
@@ -47,13 +49,17 @@ public class AuxiliaryExpressionViewFactor implements IExpressionViewFactor {
 \r
         expression.addFocusListener(new FocusAdapter() {\r
 \r
+            @Override\r
+            public void focusGained(FocusEvent e){\r
+                \r
+            }\r
+\r
             @Override\r
             public void focusLost(FocusEvent e) {\r
                 lastSelection = expression.getSelection();      \r
             }\r
         });\r
         \r
-        expression.addKeyListener(new ExpressionFieldKeyListener(equation));\r
     }\r
 \r
     @Override\r
@@ -129,4 +135,9 @@ public class AuxiliaryExpressionViewFactor implements IExpressionViewFactor {
         if(this.expression != null && this.expression.getText() != null)\r
             data.put("equation", this.expression.getText());\r
     }\r
+\r
+    @Override\r
+    public List<Text> getExpressionFields() {\r
+        return Arrays.asList(this.expression);\r
+    }\r
 }\r
index a3c24fec7540b4589c377afe72af5a2d849224f4..def62261fed08adc62e8701da456291890fb893c 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.sysdyn.ui.equation.expressions;\r
 \r
+import java.util.Arrays;\r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.eclipse.jface.layout.GridDataFactory;\r
@@ -32,7 +34,6 @@ public class ConstantExpressionViewFactor implements IExpressionViewFactor {
 \r
         final String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
 \r
-\r
         GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);\r
         GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(parent);\r
         equationLabel = new Label(parent, SWT.NONE);\r
@@ -54,9 +55,6 @@ public class ConstantExpressionViewFactor implements IExpressionViewFactor {
             }\r
         });\r
 \r
-        expression.addKeyListener(new ExpressionFieldKeyListener(equation));\r
-\r
-\r
     }\r
 \r
     @Override\r
@@ -133,4 +131,9 @@ public class ConstantExpressionViewFactor implements IExpressionViewFactor {
             data.put("equation", this.expression.getText());        \r
     }\r
 \r
+    @Override\r
+    public List<Text> getExpressionFields() {\r
+        return Arrays.asList(this.expression);\r
+    }\r
+\r
 }\r
index fbb6392df4d526207231dffe6a6f9af3d0503301..75abce6548760f8c1465f86c1f316f9c556463b6 100644 (file)
@@ -1,8 +1,10 @@
 package org.simantics.sysdyn.ui.equation.expressions;\r
 \r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Text;\r
 import org.simantics.db.Resource;\r
 \r
 public class DelayExpressionViewFactor implements IExpressionViewFactor {\r
@@ -43,4 +45,10 @@ public class DelayExpressionViewFactor implements IExpressionViewFactor {
         \r
     }\r
 \r
+    @Override\r
+    public List<Text> getExpressionFields() {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+\r
 }\r
index a199f75b6b93e565f2558a6cc7439d059cb656ee..e9452789d328988fb8d259bf6675751b0a17942b 100644 (file)
@@ -12,10 +12,13 @@ import org.simantics.sysdyn.expressionParser.ParseException;
 \r
 public class ExpressionFieldKeyListener implements KeyListener {\r
 \r
-    String originalText; \r
+    private String originalText; \r
+    private ExpressionParser parser;\r
     \r
-    public ExpressionFieldKeyListener(String originalText) {\r
-        this.originalText = originalText;        \r
+    public ExpressionFieldKeyListener(ExpressionParser parser, Text text) {\r
+        this.originalText = text.getText();        \r
+        this.parser = parser;\r
+        this.handleKeyReleased(text);        \r
     }\r
     @Override\r
     public void keyPressed(KeyEvent e) {   \r
@@ -29,17 +32,19 @@ public class ExpressionFieldKeyListener implements KeyListener {
     public void keyReleased(KeyEvent e) {     \r
         if(e.widget instanceof Text) {\r
             Text text = (Text)e.widget;\r
-            \r
-            ExpressionParser parser = new ExpressionParser(\r
-                    new StringReader(text.getText())\r
-            );\r
-            try {\r
-                parser.expr();\r
-                text.setBackground(new Color(text.getDisplay(), 255, 255, 255));\r
-            } catch (ParseException e1) {\r
-                text.setBackground(new Color(text.getDisplay(), 255, 230, 230));\r
-            }\r
+            this.handleKeyReleased(text);\r
+        }\r
+    }\r
+    \r
+    private void handleKeyReleased(Text text) {\r
+        String textString = text.getText();\r
+        this.parser.ReInit(new StringReader(textString));\r
+        \r
+        try {\r
+            parser.expr();\r
+            text.setBackground(new Color(text.getDisplay(), 255, 255, 255));\r
+        } catch (ParseException e1) {\r
+            text.setBackground(new Color(text.getDisplay(), 255, 230, 230));\r
         }\r
     }\r
-\r
 }\r
index 76ca71707634bbc72067342a0074112c2f4fd8fb..e7d37515ef5a8cabbe269e7f0ff3e4b3e56de9d3 100644 (file)
@@ -1,10 +1,12 @@
 package org.simantics.sysdyn.ui.equation.expressions;\r
 \r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.eclipse.swt.SWT;\r
 import org.eclipse.swt.graphics.Font;\r
 import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Text;\r
 import org.simantics.db.Resource;\r
 \r
 public interface IExpressionViewFactor {\r
@@ -49,4 +51,10 @@ public interface IExpressionViewFactor {
      * @param data\r
      */\r
     void updateData(Map<String, Object> data);\r
+    \r
+    /**\r
+     * @return all individual expression fields for modelica validation\r
+     */\r
+    List<Text> getExpressionFields();\r
+   \r
 }\r
index 98571aa96ce71e6d18f4db8e8f6973b99862dade..df077d606e0cb812a2c413cafda2ebee4194d55c 100644 (file)
@@ -1,8 +1,10 @@
 package org.simantics.sysdyn.ui.equation.expressions;\r
 \r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Text;\r
 import org.simantics.db.Resource;\r
 \r
 public class LookupExpressionViewFactor implements IExpressionViewFactor {\r
@@ -43,4 +45,10 @@ public class LookupExpressionViewFactor implements IExpressionViewFactor {
         \r
     }\r
 \r
+    @Override\r
+    public List<Text> getExpressionFields() {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+\r
 }\r
index aee644370be6426d67a0554e9705507013dcfdce..66a00b3a418bf22f052d29fe31cb200c31836ab5 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.sysdyn.ui.equation.expressions;\r
 \r
+import java.util.Arrays;\r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.eclipse.jface.layout.GridDataFactory;\r
@@ -54,9 +56,6 @@ public class ParameterExpressionViewFactor implements IExpressionViewFactor {
             }\r
         });\r
 \r
-        expression.addKeyListener(new ExpressionFieldKeyListener(equation));\r
-\r
-        \r
     }\r
 \r
     @Override\r
@@ -133,5 +132,10 @@ public class ParameterExpressionViewFactor implements IExpressionViewFactor {
             data.put("equation", this.expression.getText());        \r
     }\r
 \r
+    @Override\r
+    public List<Text> getExpressionFields() {\r
+        return Arrays.asList(this.expression);\r
+    }\r
+\r
 }\r
 \r
index 3b2e036fbbe035d7cb6da8d9a26f455a7414cbfa..4070348b86f766b2b9f0d708c76076900f5e6773 100644 (file)
@@ -1,6 +1,8 @@
 package org.simantics.sysdyn.ui.equation.expressions;\r
 \r
+import java.util.Arrays;\r
 import java.util.Collection;\r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.eclipse.jface.layout.GridDataFactory;\r
@@ -24,18 +26,18 @@ import org.simantics.ui.SimanticsUI;
 \r
 public class StockExpressionViewFactor implements IExpressionViewFactor {\r
 \r
-    Label integralLabel;\r
-    Text integral;\r
-    Label equationLabel;\r
-    Text expression;\r
-    Point lastSelection = new Point(0,0);\r
+    private Label integralLabel;\r
+    private Text integral;\r
+    private Label equationLabel;\r
+    private Text expression;\r
+    private Point lastSelection = new Point(0,0);\r
 \r
     @Override\r
     public void createView(Composite parent, Map<String, Object> data) {\r
 \r
         final String initialEquation = data.get("initialEquation") != null ? (String)data.get("initialEquation") : "";\r
         final String integralEquation = data.get("integral") != null ? (String)data.get("integral") : "";\r
-\r
+        \r
         GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);\r
         GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(parent);\r
 \r
@@ -69,8 +71,6 @@ public class StockExpressionViewFactor implements IExpressionViewFactor {
             }\r
         });\r
 \r
-        expression.addKeyListener(new ExpressionFieldKeyListener(initialEquation));\r
-\r
     }\r
 \r
     @Override\r
@@ -198,4 +198,9 @@ public class StockExpressionViewFactor implements IExpressionViewFactor {
         if(this.integral != null && this.integral.getText() != null)\r
             data.put("integral", this.integral.getText());\r
     }\r
+\r
+    @Override\r
+    public List<Text> getExpressionFields() {\r
+        return Arrays.asList(this.expression);\r
+    }\r
 }\r
index e0c6212a2d1fac7d767af861ea90917f21f29c20..e9b9e0aec2be2c2085607a0fd3e55efec4140576 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.sysdyn.ui.equation.expressions;\r
 \r
+import java.util.Arrays;\r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.eclipse.jface.layout.GridDataFactory;\r
@@ -24,11 +26,10 @@ import org.simantics.ui.SimanticsUI;
 public class WithLookupExpressionViewFactor implements IExpressionViewFactor {\r
 \r
     \r
-    Label expressionLabel;\r
-    Text expression;\r
-    Label lookupLabel;\r
-    Text lookup;\r
-    \r
+    private Label expressionLabel;\r
+    private Text expression;\r
+    private Label lookupLabel;\r
+    private Text lookup;\r
     private Point lastSelection = new Point(0,0);\r
     private Text lastSelectedText = expression;\r
     \r
@@ -61,8 +62,6 @@ public class WithLookupExpressionViewFactor implements IExpressionViewFactor {
             }\r
         });\r
 \r
-        expression.addKeyListener(new ExpressionFieldKeyListener(equation));\r
-\r
         lookupLabel = new Label(parent, SWT.NONE);\r
         lookupLabel.setFont(FONT);\r
         lookupLabel.setText("Lookup\ntable");\r
@@ -83,8 +82,6 @@ public class WithLookupExpressionViewFactor implements IExpressionViewFactor {
             }\r
         });\r
 \r
-        lookup.addKeyListener(new ExpressionFieldKeyListener(lookupTable));\r
-        \r
     }\r
 \r
     @Override\r
@@ -171,4 +168,9 @@ public class WithLookupExpressionViewFactor implements IExpressionViewFactor {
         if(this.lookup != null && this.lookup.getText() != null)\r
             data.put("lookup", this.lookup.getText());        \r
     }\r
+\r
+    @Override\r
+    public List<Text> getExpressionFields() {\r
+        return Arrays.asList(this.expression, this.lookup);\r
+    }\r
 }
\ No newline at end of file
index 285bfafba72322a71b35ed868f39abe0f67a34d3..b9fd2b45fb0f98c8b9205a5eaf9a6545da69cfcb 100644 (file)
@@ -6,13 +6,13 @@ options {
 PARSER_BEGIN(ExpressionParser)\r
 package org.simantics.sysdyn.expressionParser;\r
 \r
-import java.util.List;\r
-import java.util.ArrayList;\r
+import java.util.Set;\r
+import java.util.HashSet;\r
 \r
 public class ExpressionParser {\r
-    List<List<String>> references = new ArrayList<List<String>>();\r
+    Set<String> references = new HashSet<String>();\r
     \r
-    public List<List<String>> getReferences() {\r
+    public Set<String> getReferences() {\r
         return references;\r
     }\r
 }\r
@@ -56,6 +56,7 @@ TOKEN:
 // { add_op term } -> ( add_op() term() )*\r
 \r
 void expr() : {\r
+       references = new HashSet<String>();\r
 } {\r
        simple_expression() <EOF> \r
        | "if" expression() "then" expression() ( "elseif" expression() "then" expression() )*\r
@@ -132,9 +133,7 @@ void primary() : {
   | "false"\r
   | "true"\r
   |   LOOKAHEAD( name() "(" ) name() function_call_args()\r
-  | { List<String> reference = new ArrayList<String>(); } \r
-    component_reference(reference)\r
-    { references.add(reference); }\r
+  | component_reference()\r
   // | "(" output_expression_list() ")"\r
   // | "[" expression_list() { ";" expression_list() } "]"\r
   //| "{" function_arguments() "}"\r
@@ -146,11 +145,11 @@ void name() : {
        <IDENT> ( "." name() )?\r
 }\r
 \r
-void component_reference(List<String> reference) : {\r
+void component_reference() : {\r
 } {\r
        //IDENT [ array_subscripts ] [ "." component_reference ]\r
-       <IDENT> { reference.add(token.image); } \r
-       ( "." component_reference(reference) )?\r
+       <IDENT> { references.add(token.image); } \r
+       ( "." component_reference() )?\r
 }\r
 \r
 \r
index 91a3d2472fcc30b320a7d280829d2ef1c194949f..bed43adb1ae49c64fd68e51488fb16a85c2eba81 100644 (file)
@@ -1,17 +1,16 @@
 package org.simantics.sysdyn.expressionParser;\r
 \r
 import java.io.StringReader;\r
-import java.util.List;\r
 \r
 public class TestExpressionParser {\r
     \r
+    static private ExpressionParser parser;\r
+    \r
     public static void parse(String string) {\r
-        ExpressionParser parser = new ExpressionParser(\r
-                new StringReader(string)\r
-        );\r
+        parser.ReInit(new StringReader(string));\r
         try {\r
             parser.expr();\r
-            for(List<String> ref : parser.getReferences()) {\r
+            for(String ref : parser.getReferences()) {\r
                 System.out.println(ref);\r
             }\r
         } catch (ParseException e) {\r
@@ -22,8 +21,13 @@ public class TestExpressionParser {
     }\r
     \r
     public static void main(String[] args) {\r
-        parse("1 + m2ma +");\r
+        parser = new ExpressionParser(\r
+                new StringReader("")\r
+        );\r
+        parse("1 + m2ma");\r
+        System.out.println("##");\r
         parse("ter2e + moro");\r
-        parse("moro * sqr(4.0) + min(3, 2)");\r
+        System.out.println("##");\r
+        parse("moro * sqr(4.0) + min(m2ma, moi)");\r
     }\r
 }\r