Modified: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTreeConstants.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTreeConstants.java?rev=731779&r1=731778&r2=731779&view=diff
==============================================================================
--- 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTreeConstants.java
 (original)
+++ 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTreeConstants.java
 Mon Jan  5 16:10:57 2009
@@ -1,5 +1,4 @@
-/* Generated By:JJTree: Do not edit this line. ParserTreeConstants.java */
-
+/* Generated By:JavaCC: Do not edit this line. ParserTreeConstants.java 
Version 4.1 */
 package org.apache.velocity.runtime.parser;
 
 public interface ParserTreeConstants
@@ -9,43 +8,44 @@
   public int JJTESCAPEDDIRECTIVE = 2;
   public int JJTESCAPE = 3;
   public int JJTCOMMENT = 4;
-  public int JJTFLOATINGPOINTLITERAL = 5;
-  public int JJTINTEGERLITERAL = 6;
-  public int JJTSTRINGLITERAL = 7;
-  public int JJTIDENTIFIER = 8;
-  public int JJTWORD = 9;
-  public int JJTDIRECTIVE = 10;
-  public int JJTBLOCK = 11;
-  public int JJTMAP = 12;
-  public int JJTOBJECTARRAY = 13;
-  public int JJTINTEGERRANGE = 14;
-  public int JJTMETHOD = 15;
-  public int JJTINDEX = 16;
-  public int JJTREFERENCE = 17;
-  public int JJTTRUE = 18;
-  public int JJTFALSE = 19;
-  public int JJTTEXT = 20;
-  public int JJTIFSTATEMENT = 21;
-  public int JJTELSESTATEMENT = 22;
-  public int JJTELSEIFSTATEMENT = 23;
-  public int JJTSETDIRECTIVE = 24;
-  public int JJTSTOP = 25;
-  public int JJTEXPRESSION = 26;
-  public int JJTASSIGNMENT = 27;
-  public int JJTORNODE = 28;
-  public int JJTANDNODE = 29;
-  public int JJTEQNODE = 30;
-  public int JJTNENODE = 31;
-  public int JJTLTNODE = 32;
-  public int JJTGTNODE = 33;
-  public int JJTLENODE = 34;
-  public int JJTGENODE = 35;
-  public int JJTADDNODE = 36;
-  public int JJTSUBTRACTNODE = 37;
-  public int JJTMULNODE = 38;
-  public int JJTDIVNODE = 39;
-  public int JJTMODNODE = 40;
-  public int JJTNOTNODE = 41;
+  public int JJTTEXTBLOCK = 5;
+  public int JJTFLOATINGPOINTLITERAL = 6;
+  public int JJTINTEGERLITERAL = 7;
+  public int JJTSTRINGLITERAL = 8;
+  public int JJTIDENTIFIER = 9;
+  public int JJTWORD = 10;
+  public int JJTDIRECTIVE = 11;
+  public int JJTBLOCK = 12;
+  public int JJTMAP = 13;
+  public int JJTOBJECTARRAY = 14;
+  public int JJTINTEGERRANGE = 15;
+  public int JJTMETHOD = 16;
+  public int JJTINDEX = 17;
+  public int JJTREFERENCE = 18;
+  public int JJTTRUE = 19;
+  public int JJTFALSE = 20;
+  public int JJTTEXT = 21;
+  public int JJTIFSTATEMENT = 22;
+  public int JJTELSESTATEMENT = 23;
+  public int JJTELSEIFSTATEMENT = 24;
+  public int JJTSETDIRECTIVE = 25;
+  public int JJTSTOP = 26;
+  public int JJTEXPRESSION = 27;
+  public int JJTASSIGNMENT = 28;
+  public int JJTORNODE = 29;
+  public int JJTANDNODE = 30;
+  public int JJTEQNODE = 31;
+  public int JJTNENODE = 32;
+  public int JJTLTNODE = 33;
+  public int JJTGTNODE = 34;
+  public int JJTLENODE = 35;
+  public int JJTGENODE = 36;
+  public int JJTADDNODE = 37;
+  public int JJTSUBTRACTNODE = 38;
+  public int JJTMULNODE = 39;
+  public int JJTDIVNODE = 40;
+  public int JJTMODNODE = 41;
+  public int JJTNOTNODE = 42;
 
 
   public String[] jjtNodeName = {
@@ -54,6 +54,7 @@
     "EscapedDirective",
     "Escape",
     "Comment",
+    "Textblock",
     "FloatingPointLiteral",
     "IntegerLiteral",
     "StringLiteral",
@@ -93,3 +94,4 @@
     "NotNode",
   };
 }
+/* JavaCC - OriginalChecksum=6486d1e0227c52f059ed205018b7b6fa (do not edit 
this line) */

Added: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java?rev=731779&view=auto
==============================================================================
--- 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
 (added)
+++ 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
 Mon Jan  5 16:10:57 2009
@@ -0,0 +1,94 @@
+package org.apache.velocity.runtime.parser.node;
+
+/*
+ * 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.    
+ */
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.velocity.context.InternalContextAdapter;
+import org.apache.velocity.exception.TemplateInitException;
+import org.apache.velocity.runtime.parser.Parser;
+import org.apache.velocity.runtime.parser.Token;
+
+/**
+ * This node holds the "Textblock" data which should not be interpreted by 
Velocity.
+ *
+ * Textblocks are marked in Velocity with #[[content here]]# notation. Velocity
+ * will output everything between the markers and does not attempt to parse it 
in any way.
+ */
+public class ASTTextblock extends SimpleNode
+{
+    public static final String START = "#[[";
+    public static final String END = "]]#";
+    private char[] ctext;
+
+    /**
+     * @param id
+     */
+    public ASTTextblock(int id)
+    {
+        super(id);
+    }
+
+    /**
+     * @param p
+     * @param id
+     */
+    public ASTTextblock(Parser p, int id)
+    {
+        super(p, id);
+    }
+
+    /**
+     * @see 
org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor,
 java.lang.Object)
+     */
+    public Object jjtAccept(ParserVisitor visitor, Object data)
+    {
+        return visitor.visit(this, data);
+    }
+
+    /**
+     * @see 
org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter,
 java.lang.Object)
+     */
+    public Object init( InternalContextAdapter context, Object data)
+    throws TemplateInitException
+    {
+        Token t = getFirstToken();
+        
+        String text = t.image;
+        
+        // t.image is in format: #% <string> %#
+        // we must strip away the hash tags
+        text = text.substring(START.length(), text.length() - END.length());
+
+        ctext = text.toCharArray();
+        return data;
+    }
+
+    /**
+     * @see 
org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter,
 java.io.Writer)
+     */
+    public boolean render( InternalContextAdapter context, Writer writer)
+        throws IOException
+    {
+        writer.write(ctext);
+        return true;
+    }
+}

Propchange: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
------------------------------------------------------------------------------
    svn:keywords = Revision

Propchange: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: velocity/engine/trunk/src/parser/Parser.jjt
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/parser/Parser.jjt?rev=731779&r1=731778&r2=731779&view=diff
==============================================================================
--- velocity/engine/trunk/src/parser/Parser.jjt (original)
+++ velocity/engine/trunk/src/parser/Parser.jjt Mon Jan  5 16:10:57 2009
@@ -86,6 +86,7 @@
 import org.apache.velocity.runtime.directive.Macro;
 import org.apache.velocity.runtime.directive.MacroParseException;
 import org.apache.velocity.util.StringUtils;
+import org.apache.commons.lang.text.StrBuilder;
 
 /**
  * This class is responsible for parsing a Velocity
@@ -104,9 +105,9 @@
 public class Parser
 {
     /**
-     *  This Hashtable contains a list of all of the dynamic directives.
+     *  This Map contains a list of all of the dynamic directives.
      */
-    private Hashtable directives = new Hashtable(0);
+    private Map directives = new HashMap();
 
     /**
      *  Name of current template we are parsing.  Passed to us in parse()
@@ -217,7 +218,7 @@
      */
     public void setDirectives(Hashtable directives)
     {
-        this.directives = directives;
+        this.directives = new HashMap(directives);
     }
 
     /**
@@ -350,7 +351,8 @@
     private int lparen = 0;
     private int rparen = 0;
 
-    Stack stateStack = new Stack();
+    List stateStack = new ArrayList(50);
+    
     public boolean debugPrint = false;
 
     private boolean inReference;
@@ -368,14 +370,14 @@
      */
     public boolean stateStackPop()
     {
-        Hashtable h;
-
+        ParserState s;
         try
         {
-            h = (Hashtable) stateStack.pop();
+            s = (ParserState) stateStack.remove(stateStack.size() - 1); // 
stack.pop
         }
-        catch( EmptyStackException e)
+        catch(IndexOutOfBoundsException e)
         {
+            // empty stack
             lparen=0;
             SwitchTo(DEFAULT);
             return false;
@@ -384,13 +386,13 @@
         if( debugPrint )
             System.out.println(
                 " stack pop (" + stateStack.size() + ") : lparen=" +
-                    ( (Integer) h.get("lparen")).intValue() +
-                        " newstate=" + ( (Integer) 
h.get("lexstate")).intValue() );
+                    s.lparen +
+                        " newstate=" + s.lexstate );
 
-        lparen = ( (Integer) h.get("lparen")).intValue();
-        rparen = ( (Integer) h.get("rparen")).intValue();
+        lparen = s.lparen;
+        rparen = s.rparen;
 
-        SwitchTo( ( (Integer) h.get("lexstate")).intValue() );
+        SwitchTo(s.lexstate);
 
         return true;
     }
@@ -405,16 +407,14 @@
         if( debugPrint )
             System.out.println(" (" + stateStack.size() + ") pushing cur state 
: " +
                 curLexState );
-
-        Hashtable h = new Hashtable();
-
-        h.put("lexstate", new Integer( curLexState ) );
-        h.put("lparen", new Integer( lparen ));
-        h.put("rparen", new Integer( rparen ));
+        
+        ParserState s = new ParserState();
+        s.lparen = lparen;
+        s.rparen = rparen;
+        s.lexstate = curLexState;
 
         lparen = 0;
-
-        stateStack.push( h );
+        stateStack.add(s); // stack.push
 
         return true;
     }
@@ -423,7 +423,6 @@
      *  Clears all state variables, resets to
      *  start values, clears stateStack.  Call
      *  before parsing.
-     *  @return void
      */
     public void clearStateVars()
     {
@@ -440,6 +439,16 @@
     }
 
     /**
+     * Holds the state of the parsing process.
+     */
+    private class ParserState
+    {
+        int lparen;
+        int rparen;
+        int lexstate;
+    }
+    
+    /**
      *  handles the dropdown logic when encountering a RPAREN
      */
     private void RPARENHandler()
@@ -739,6 +748,16 @@
         }
     }
 
+|   "#[["
+    {
+       if (!inComment)
+       {
+           inComment = true;
+           stateStackPush();
+           SwitchTo( IN_TEXTBLOCK );
+       }
+    }
+    
 |   <"#**" ~["#"]>
     {
        if (!inComment)
@@ -759,7 +778,7 @@
                SwitchTo( IN_MULTI_LINE_COMMENT );
        }
     }
-
+    
 |   <HASH : "#" >
     {
         if (! inComment)
@@ -855,12 +874,28 @@
   }
 }
 
+<IN_TEXTBLOCK>
+TOKEN :
+{
+  <TEXTBLOCK: "]]#" >
+  {
+    inComment = false;
+    stateStackPop();
+  }
+}
+
 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
 SKIP :
 {
   < ~[] >
 }
 
+<IN_TEXTBLOCK>
+MORE :
+{
+  < ~[] >
+}
+
 /* -----------------------------------------------------------------------
  *
  *  DIRECTIVE Lexical State (some of it, anyway)
@@ -1188,6 +1223,7 @@
 |   StopStatement()
 |   LOOKAHEAD(2) Reference()
 |   Comment()
+|   Textblock()
 |   SetDirective()
 |   EscapedDirective()
 |   Escape()
@@ -1276,6 +1312,11 @@
 |   <FORMAL_COMMENT>
 }
 
+void Textblock() : {}
+{
+   <TEXTBLOCK>
+}
+
 void FloatingPointLiteral() : {}
 {
     <FLOATING_POINT_LITERAL>

Added: 
velocity/engine/trunk/src/test/org/apache/velocity/test/TextblockTestCase.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/TextblockTestCase.java?rev=731779&view=auto
==============================================================================
--- 
velocity/engine/trunk/src/test/org/apache/velocity/test/TextblockTestCase.java 
(added)
+++ 
velocity/engine/trunk/src/test/org/apache/velocity/test/TextblockTestCase.java 
Mon Jan  5 16:10:57 2009
@@ -0,0 +1,145 @@
+package org.apache.velocity.test;
+
+/*
+ * 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.    
+ */
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.parser.node.ASTTextblock;
+import org.apache.velocity.test.misc.TestLogChute;
+import org.apache.velocity.test.provider.ForeachMethodCallHelper;
+
+/**
+ * This class tests the Textblock directive.
+ */
+public class TextblockTestCase extends BaseEvalTestCase
+{
+    // these are all here so that the test case adapts instantly
+    // to changes in the textblock start/end sequences
+    private static final String START = ASTTextblock.START;
+    private static final String END = ASTTextblock.END;
+    private static final String PARTIAL_START = START.substring(0, 
START.length() - 1);
+    private static final String PARTIAL_END = END.substring(1, END.length());
+    private static final String END_OF_START = START.substring(START.length() 
- 1, START.length());
+    private static final String START_OF_END = END.substring(0, 1);
+
+    public TextblockTestCase(String name)
+    {
+        super(name);
+        //DEBUG = true;
+    }
+
+    public String textblock(String s)
+    {
+        return START + s + END;
+    }
+
+    public void assertTextblockEvalEquals(String s) throws Exception
+    {
+        assertEvalEquals(s, textblock(s));
+    }
+
+    /**
+     * https://issues.apache.org/jira/browse/VELOCITY-661
+     */
+    public void testTextblockAjaxcode() throws Exception
+    {
+        String s = "var myId = 'someID';$('#test).append($.template('<div 
id=\"${myId}\"></div>').apply({myId: myId}));";
+        assertEvalEquals(s + " 123", textblock(s)+" #foreach($i in 
[1..3])$i#end");
+    }
+
+    public void testLooseTextblockEnd() throws Exception
+    {
+        // just like a multi-line comment end (*#), this must be
+        // followed by a character.  by itself, it bombs for some reason.
+        assertEvalEquals(END+" ", END+" ");
+    }
+
+    public void testTextblockStartInTextblock() throws Exception
+    {
+        assertTextblockEvalEquals(START);
+    }
+
+    public void testTextblockEndBetweenTwoTextblockHalves() throws Exception
+    {
+        // just like a multi-line comment end (*#), the end token
+        // in the middle must be followed by some character.
+        // by itself, it bombs.  not sure why that is, but the
+        // same has been true of multi-line comments without complaints,
+        // so i'm not going to worry about it just yet.
+        assertEvalEquals(" "+END+"  ", textblock(" ")+END+" "+textblock(" "));
+    }
+
+    public void testZerolengthTextblock() throws Exception
+    {
+        assertTextblockEvalEquals("");
+    }
+
+    public void testTextblockInsideForeachLoop() throws Exception
+    {
+        String s = "var myId = 'someID';$('#test).append($.template('<div 
id=\"${myId}\"></div>').apply({myId: myId}));";
+        assertEvalEquals("1 "+s+"2 "+s+"3 "+s, "#foreach($i in [1..3])$i "+ 
textblock(s) + "#end");
+    }
+
+    public void testSingleHashInsideTextblock() throws Exception
+    {
+        assertTextblockEvalEquals(" # ");
+    }
+
+    public void testDollarInsideTextblock() throws Exception
+    {
+        assertTextblockEvalEquals("$");
+    }
+
+    public void testTextblockInsideComment() throws Exception
+    {
+        String s = "FOOBAR";
+        assertEvalEquals("", "#* comment "+textblock(s) + " *#");
+    }
+
+    public void testPartialStartEndTokensInsideTextblock() throws Exception
+    {
+        assertTextblockEvalEquals(PARTIAL_START+"foo"+PARTIAL_END);
+    }
+
+    public void testDupeTokenChars() throws Exception
+    {
+        assertTextblockEvalEquals(END_OF_START+START_OF_END);
+        
assertTextblockEvalEquals(END_OF_START+END_OF_START+START_OF_END+START_OF_END);
+        
assertTextblockEvalEquals(END_OF_START+END_OF_START+"#"+START_OF_END+START_OF_END);
+    }
+
+    /**
+     * https://issues.apache.org/jira/browse/VELOCITY-584
+     */
+    public void testServerSideIncludeEscaping() throws Exception
+    {
+        assertTextblockEvalEquals("<!--#include file=\"wisdom.inc\"--> ");
+    }
+
+    
+}

Propchange: 
velocity/engine/trunk/src/test/org/apache/velocity/test/TextblockTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
velocity/engine/trunk/src/test/org/apache/velocity/test/TextblockTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Revision

Propchange: 
velocity/engine/trunk/src/test/org/apache/velocity/test/TextblockTestCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: velocity/engine/trunk/xdocs/docs/translations/user-guide_fr.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/xdocs/docs/translations/user-guide_fr.xml?rev=731779&r1=731778&r2=731779&view=diff
==============================================================================
--- velocity/engine/trunk/xdocs/docs/translations/user-guide_fr.xml (original)
+++ velocity/engine/trunk/xdocs/docs/translations/user-guide_fr.xml Mon Jan  5 
16:10:57 2009
@@ -724,14 +724,14 @@
     de Velocity. Ce comportement peut être changé en éditant le fichier 
<code>velocity.properties</code> et en y écrivant
     l'entrée: <code>stringliterals.interpolate=false</code>.
   </p>
-<p>Également, la directive <em>#litteral</em> permet au concepteur de 
gabarits de facilement utiliser de gros morceaux de contenu
+<p>Également, la directive <em>#[[ ]]#</em> permet au concepteur de gabarits 
de facilement utiliser de gros morceaux de contenu
 non interprété de code VTL. Ceci peut être particulièrement utile en 
remplacement de multiples <a href="#EchappementdesdirectivesVTL">échappements 
de directives</a>.</p>
 <source><![CDATA[
-#literal()
+#[[
 #foreach ($woogie in $boogie)
   nothing will happen to $woogie
 #end
-#end 
+]]# 
 ]]></source>
 <p>Sera rendu comme :</p>
 <source><![CDATA[

Modified: velocity/engine/trunk/xdocs/docs/user-guide.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/xdocs/docs/user-guide.xml?rev=731779&r1=731778&r2=731779&view=diff
==============================================================================
--- velocity/engine/trunk/xdocs/docs/user-guide.xml (original)
+++ velocity/engine/trunk/xdocs/docs/user-guide.xml Mon Jan  5 16:10:57 2009
@@ -1100,18 +1100,20 @@
  </p>
 
  <p>
-    Alternately, the <em>#literal</em> script element allows the
+    Alternately, the <em>#[[</em>don't parse me!<em>]]#</em> syntax allows the
     template designer to easily use large chunks of uninterpreted
-    content in VTL code.  This can be especially useful in place of <a
-    href="#EscapingVTLDirectives">escaping</a> multiple directives.
+    and unparsed content in VTL code.  This can be especially useful in place 
of <a
+    href="#EscapingVTLDirectives">escaping</a> multiple directives or escaping
+    sections which have content that would otherwise be invalid (and thus 
unparseable)
+    VTL.
  </p>
 
 <source><![CDATA[
-#literal()
+#[[
 #foreach ($woogie in $boogie)
   nothing will happen to $woogie
 #end
-#end
+]]#
 ]]></source>
 
     <p>

Modified: velocity/engine/trunk/xdocs/docs/vtl-reference-guide.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/xdocs/docs/vtl-reference-guide.xml?rev=731779&r1=731778&r2=731779&view=diff
==============================================================================
--- velocity/engine/trunk/xdocs/docs/vtl-reference-guide.xml (original)
+++ velocity/engine/trunk/xdocs/docs/vtl-reference-guide.xml Mon Jan  5 
16:10:57 2009
@@ -570,6 +570,28 @@
     </subsection>
 </section>
 
+<section name="Unparsed Content" href="Unparsed">
+    <p>
+    Unparsed content is rendered at runtime, but is not parsed or interpreted.
+    </p>
+    <p>
+    Example:
+    </p>
+
+    <p>
+    <strong>
+    #[[<br/>
+    This has invalid syntax that would normally need 
+    "poor man's escaping" like:
+    <ul>
+     <li>#define()</li>
+     <li>${blah</li>
+    </ul>
+    ]]#
+    </strong>
+    </p>
+</section>
+
 </body>
 </document>
 


Reply via email to