diff --git a/Antlr4.Runtime/ANTLRErrorListener.cs b/Antlr4.Runtime/ANTLRErrorListener.cs
new file mode 100644
index 000000000..c73bf3bbb
--- /dev/null
+++ b/Antlr4.Runtime/ANTLRErrorListener.cs
@@ -0,0 +1,78 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2013 Terence Parr
+ * Copyright (c) 2013 Sam Harwell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Antlr4.Runtime;
+using Sharpen;
+
+namespace Antlr4.Runtime
+{
+ /// How to emit recognition errors
+ public interface ANTLRErrorListener
+ {
+ /// Upon syntax error, notify any interested parties.
+ ///
+ /// Upon syntax error, notify any interested parties. This is not
+ /// how to recover from errors or compute error messages. The
+ /// parser ANTLRErrorStrategy specifies how to recover from syntax
+ /// errors and how to compute error messages. This listener's job
+ /// is simply to emit a computed message, though it has enough
+ /// information to create its own message in many cases.
+ /// The RecognitionException is non-null for all syntax errors
+ /// except when we discover mismatched token errors that we can
+ /// recover from in-line, without returning from the surrounding
+ /// rule (via the single token insertion and deletion mechanism).
+ ///
+ ///
+ /// What parser got the error. From this
+ /// object, you can access the context as well
+ /// as the input stream.
+ ///
+ ///
+ /// The offending token in the input token
+ /// stream, unless recognizer is a lexer (then it's null) If
+ /// no viable alternative error, e has token at which we
+ /// started production for the decision.
+ ///
+ ///
+ /// At what line in input to the error occur? This always refers to
+ /// stopTokenIndex
+ ///
+ /// At what character position within that line did the error occur.
+ ///
+ /// The message to emit
+ ///
+ /// The exception generated by the parser that led to
+ /// the reporting of an error. It is null in the case where
+ /// the parser was able to recover in line without exiting the
+ /// surrounding rule.
+ ///
+ void SyntaxError(Recognizer recognizer, T offendingSymbol, int line
+ , int charPositionInLine, string msg, RecognitionException e) where T:Symbol;
+ }
+}
diff --git a/Antlr4.Runtime/ANTLRErrorStrategy.cs b/Antlr4.Runtime/ANTLRErrorStrategy.cs
new file mode 100644
index 000000000..669a0030d
--- /dev/null
+++ b/Antlr4.Runtime/ANTLRErrorStrategy.cs
@@ -0,0 +1,157 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2013 Terence Parr
+ * Copyright (c) 2013 Sam Harwell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Antlr4.Runtime;
+using Sharpen;
+
+namespace Antlr4.Runtime
+{
+ ///
+ /// The interface for defining strategies to deal with syntax errors
+ /// encountered during a parse by ANTLR-generated parsers and tree parsers.
+ ///
+ ///
+ /// The interface for defining strategies to deal with syntax errors
+ /// encountered during a parse by ANTLR-generated parsers and tree parsers.
+ /// We distinguish between three different kinds of errors:
+ /// o The parser could not figure out which path to take in the ATN
+ /// (none of the available alternatives could possibly match)
+ /// o The current input does not match what we were looking for.
+ /// o A predicate evaluated to false.
+ /// The default implementation of this interface reports errors to any
+ /// error listeners of the parser. It also handles single token insertion
+ /// and deletion for mismatched elements.
+ /// We pass in the parser to each function so that the same strategy
+ /// can be shared between multiple parsers running at the same time.
+ /// This is just for flexibility, not that we need it for the default system.
+ /// TODO: To bail out upon first error, simply rethrow e?
+ /// TODO: what to do about lexers
+ ///
+ public interface ANTLRErrorStrategy
+ {
+ ///
+ /// When matching elements within alternative, use this method
+ /// to recover.
+ ///
+ ///
+ /// When matching elements within alternative, use this method
+ /// to recover. The default implementation uses single token
+ /// insertion and deletion. If you want to change the way ANTLR
+ /// response to mismatched element errors within an alternative,
+ /// implement this method.
+ /// From the recognizer, we can get the input stream to get
+ /// the current input symbol and we can get the current context.
+ /// That context gives us the current state within the ATN.
+ /// From that state, we can look at its transition to figure out
+ /// what was expected.
+ /// Because we can recover from a single token deletions by
+ /// "inserting" tokens, we need to specify what that implicitly created
+ /// token is. We use object, because it could be a tree node.
+ ///
+ ///
+ Token RecoverInline(Parser recognizer);
+
+ ///
+ /// Resynchronize the parser by consuming tokens until we find one
+ /// in the resynchronization set--loosely the set of tokens that can follow
+ /// the current rule.
+ ///
+ ///
+ /// Resynchronize the parser by consuming tokens until we find one
+ /// in the resynchronization set--loosely the set of tokens that can follow
+ /// the current rule. The exception contains info you might want to
+ /// use to recover better.
+ ///
+ void Recover(Parser recognizer, RecognitionException e);
+
+ ///
+ /// Make sure that the current lookahead symbol is consistent with
+ /// what were expecting at this point in the ATN.
+ ///
+ ///
+ /// Make sure that the current lookahead symbol is consistent with
+ /// what were expecting at this point in the ATN. You can call this
+ /// anytime but ANTLR only generates code to check before subrules/loops
+ /// and each iteration.
+ /// Implements Jim Idle's magic sync mechanism in closures and optional
+ /// subrules. E.g.,
+ /// a : sync ( stuff sync )* ;
+ /// sync : {consume to what can follow sync} ;
+ /// Previous versions of ANTLR did a poor job of their recovery within
+ /// loops. A single mismatch token or missing token would force the parser
+ /// to bail out of the entire rules surrounding the loop. So, for rule
+ /// classDef : 'class' ID '{' member* '}'
+ /// input with an extra token between members would force the parser to
+ /// consume until it found the next class definition rather than the
+ /// next member definition of the current class.
+ /// This functionality cost a little bit of effort because the parser
+ /// has to compare token set at the start of the loop and at each
+ /// iteration. If for some reason speed is suffering for you, you can
+ /// turn off this functionality by simply overriding this method as
+ /// a blank { }.
+ ///
+ void Sync(Parser recognizer);
+
+ /// Notify handler that parser has entered an error state.
+ ///
+ /// Notify handler that parser has entered an error state. The
+ /// parser currently doesn't call this--the handler itself calls this
+ /// in report error methods. But, for symmetry with endErrorCondition,
+ /// this method is in the interface.
+ ///
+ void BeginErrorCondition(Parser recognizer);
+
+ ///
+ /// Is the parser in the process of recovering from an error? Upon
+ /// a syntax error, the parser enters recovery mode and stays there until
+ /// the next successful match of a token.
+ ///
+ ///
+ /// Is the parser in the process of recovering from an error? Upon
+ /// a syntax error, the parser enters recovery mode and stays there until
+ /// the next successful match of a token. In this way, we can
+ /// avoid sending out spurious error messages. We only want one error
+ /// message per syntax error
+ ///
+ bool InErrorRecoveryMode(Parser recognizer);
+
+ /// Reset the error handler.
+ ///
+ /// Reset the error handler. Call this when the parser
+ /// matches a valid token (indicating no longer in recovery mode)
+ /// and from its own reset method.
+ ///
+ void EndErrorCondition(Parser recognizer);
+
+ /// Report any kind of RecognitionException.
+ /// Report any kind of RecognitionException.
+ ///
+ void ReportError(Parser recognizer, RecognitionException e);
+ }
+}
diff --git a/Antlr4.Runtime/ANTLRFileStream.cs b/Antlr4.Runtime/ANTLRFileStream.cs
new file mode 100644
index 000000000..1fab3edaa
--- /dev/null
+++ b/Antlr4.Runtime/ANTLRFileStream.cs
@@ -0,0 +1,97 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2013 Terence Parr
+ * Copyright (c) 2013 Sam Harwell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System.IO;
+using Antlr4.Runtime;
+using Sharpen;
+
+namespace Antlr4.Runtime
+{
+ ///
+ /// This is an ANTLRInputStream that is loaded from a file
+ /// all at once when you construct the object.
+ ///
+ ///
+ /// This is an ANTLRInputStream that is loaded from a file
+ /// all at once when you construct the object. This is a special case
+ /// since we know the exact size of the object to load. We can avoid lots
+ /// of data copying.
+ ///
+ public class ANTLRFileStream : ANTLRInputStream
+ {
+ protected internal string fileName;
+
+ ///
+ public ANTLRFileStream(string fileName) : this(fileName, null)
+ {
+ }
+
+ ///
+ public ANTLRFileStream(string fileName, string encoding)
+ {
+ this.fileName = fileName;
+ Load(fileName, encoding);
+ }
+
+ ///
+ public virtual void Load(string fileName, string encoding)
+ {
+ if (fileName == null)
+ {
+ return;
+ }
+ FilePath f = new FilePath(fileName);
+ int size = (int)f.Length();
+ InputStreamReader isr;
+ FileInputStream fis = new FileInputStream(fileName);
+ if (encoding != null)
+ {
+ isr = new InputStreamReader(fis, encoding);
+ }
+ else
+ {
+ isr = new InputStreamReader(fis);
+ }
+ try
+ {
+ data = new char[size];
+ base.n = isr.Read(data);
+ }
+ finally
+ {
+ isr.Close();
+ }
+ }
+
+ public override string GetSourceName()
+ {
+ return fileName;
+ }
+ }
+}
diff --git a/Antlr4.Runtime/ANTLRInputStream.cs b/Antlr4.Runtime/ANTLRInputStream.cs
new file mode 100644
index 000000000..4f614b9af
--- /dev/null
+++ b/Antlr4.Runtime/ANTLRInputStream.cs
@@ -0,0 +1,308 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2013 Terence Parr
+ * Copyright (c) 2013 Sam Harwell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+using Antlr4.Runtime;
+using Antlr4.Runtime.Misc;
+using Sharpen;
+
+namespace Antlr4.Runtime
+{
+ /// Vacuum all input from a Reader/InputStream and then treat it like a char[] buffer.
+ ///
+ ///
+ /// Vacuum all input from a Reader/InputStream and then treat it like a char[] buffer.
+ /// Can also pass in a string or char[] to use.
+ /// If you need encoding, pass in stream/reader with correct encoding.
+ ///
+ public class ANTLRInputStream : CharStream
+ {
+ public const int ReadBufferSize = 1024;
+
+ public const int InitialBufferSize = 1024;
+
+ /// The data being scanned
+ protected internal char[] data;
+
+ /// How many characters are actually in the buffer
+ protected internal int n;
+
+ /// 0..n-1 index into string of next char
+ protected internal int p = 0;
+
+ /// What is name or source of this char stream?
+ public string name;
+
+ public ANTLRInputStream()
+ {
+ }
+
+ /// Copy data in string to a local char array
+ public ANTLRInputStream(string input)
+ {
+ this.data = input.ToCharArray();
+ this.n = input.Length;
+ }
+
+ /// This is the preferred constructor for strings as no data is copied
+ public ANTLRInputStream(char[] data, int numberOfActualCharsInArray)
+ {
+ this.data = data;
+ this.n = numberOfActualCharsInArray;
+ }
+
+ ///
+ public ANTLRInputStream(StreamReader r) : this(r, InitialBufferSize, ReadBufferSize
+ )
+ {
+ }
+
+ ///
+ public ANTLRInputStream(StreamReader r, int initialSize) : this(r, initialSize, ReadBufferSize
+ )
+ {
+ }
+
+ ///
+ public ANTLRInputStream(StreamReader r, int initialSize, int readChunkSize)
+ {
+ Load(r, initialSize, readChunkSize);
+ }
+
+ ///
+ public ANTLRInputStream(InputStream input) : this(new InputStreamReader(input), InitialBufferSize
+ )
+ {
+ }
+
+ ///
+ public ANTLRInputStream(InputStream input, int initialSize) : this(new InputStreamReader
+ (input), initialSize)
+ {
+ }
+
+ ///
+ public ANTLRInputStream(InputStream input, int initialSize, int readChunkSize) :
+ this(new InputStreamReader(input), initialSize, readChunkSize)
+ {
+ }
+
+ ///
+ public virtual void Load(StreamReader r, int size, int readChunkSize)
+ {
+ if (r == null)
+ {
+ return;
+ }
+ if (size <= 0)
+ {
+ size = InitialBufferSize;
+ }
+ if (readChunkSize <= 0)
+ {
+ readChunkSize = ReadBufferSize;
+ }
+ // System.out.println("load "+size+" in chunks of "+readChunkSize);
+ try
+ {
+ // alloc initial buffer size.
+ data = new char[size];
+ // read all the data in chunks of readChunkSize
+ int numRead = 0;
+ int p = 0;
+ do
+ {
+ if (p + readChunkSize > data.Length)
+ {
+ // overflow?
+ // System.out.println("### overflow p="+p+", data.length="+data.length);
+ data = Arrays.CopyOf(data, data.Length * 2);
+ }
+ numRead = r.Read(data, p, readChunkSize);
+ // System.out.println("read "+numRead+" chars; p was "+p+" is now "+(p+numRead));
+ p += numRead;
+ }
+ while (numRead != -1);
+ // while not EOF
+ // set the actual size of the data available;
+ // EOF subtracted one above in p+=numRead; add one back
+ n = p + 1;
+ }
+ finally
+ {
+ //System.out.println("n="+n);
+ r.Close();
+ }
+ }
+
+ ///
+ /// Reset the stream so that it's in the same state it was
+ /// when the object was created *except* the data array is not
+ /// touched.
+ ///
+ ///
+ /// Reset the stream so that it's in the same state it was
+ /// when the object was created *except* the data array is not
+ /// touched.
+ ///
+ public virtual void Reset()
+ {
+ p = 0;
+ }
+
+ public virtual void Consume()
+ {
+ if (p >= n)
+ {
+ System.Diagnostics.Debug.Assert(La(1) == IntStream.Eof);
+ throw new InvalidOperationException("cannot consume EOF");
+ }
+ //System.out.println("prev p="+p+", c="+(char)data[p]);
+ if (p < n)
+ {
+ p++;
+ }
+ }
+
+ //System.out.println("p moves to "+p+" (c='"+(char)data[p]+"')");
+ public virtual int La(int i)
+ {
+ if (i == 0)
+ {
+ return 0;
+ }
+ // undefined
+ if (i < 0)
+ {
+ i++;
+ // e.g., translate LA(-1) to use offset i=0; then data[p+0-1]
+ if ((p + i - 1) < 0)
+ {
+ return IntStream.Eof;
+ }
+ }
+ // invalid; no char before first char
+ if ((p + i - 1) >= n)
+ {
+ //System.out.println("char LA("+i+")=EOF; p="+p);
+ return IntStream.Eof;
+ }
+ //System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p);
+ //System.out.println("LA("+i+"); p="+p+" n="+n+" data.length="+data.length);
+ return data[p + i - 1];
+ }
+
+ public virtual int Lt(int i)
+ {
+ return La(i);
+ }
+
+ ///
+ /// Return the current input symbol index 0..n where n indicates the
+ /// last symbol has been read.
+ ///
+ ///
+ /// Return the current input symbol index 0..n where n indicates the
+ /// last symbol has been read. The index is the index of char to
+ /// be returned from LA(1).
+ ///
+ public virtual int Index()
+ {
+ return p;
+ }
+
+ public virtual int Size()
+ {
+ return n;
+ }
+
+ /// mark/release do nothing; we have entire buffer
+ public virtual int Mark()
+ {
+ return -1;
+ }
+
+ public virtual void Release(int marker)
+ {
+ }
+
+ ///
+ /// consume() ahead until p==index; can't just set p=index as we must
+ /// update line and charPositionInLine.
+ ///
+ ///
+ /// consume() ahead until p==index; can't just set p=index as we must
+ /// update line and charPositionInLine. If we seek backwards, just set p
+ ///
+ public virtual void Seek(int index)
+ {
+ if (index <= p)
+ {
+ p = index;
+ // just jump; don't update stream state (line, ...)
+ return;
+ }
+ // seek forward, consume until p hits index
+ while (p < index && index < n)
+ {
+ Consume();
+ }
+ }
+
+ public override string GetText(Interval interval)
+ {
+ int start = interval.a;
+ int stop = interval.b;
+ if (stop >= n)
+ {
+ stop = n - 1;
+ }
+ int count = stop - start + 1;
+ if (start >= n)
+ {
+ return string.Empty;
+ }
+ // System.err.println("data: "+Arrays.toString(data)+", n="+n+
+ // ", start="+start+
+ // ", stop="+stop);
+ return new string(data, start, count);
+ }
+
+ public virtual string GetSourceName()
+ {
+ return name;
+ }
+
+ public override string ToString()
+ {
+ return new string(data);
+ }
+ }
+}
diff --git a/Antlr4.Runtime/Antlr4.Runtime.csproj b/Antlr4.Runtime/Antlr4.Runtime.csproj
index da813927f..b66dd38c9 100644
--- a/Antlr4.Runtime/Antlr4.Runtime.csproj
+++ b/Antlr4.Runtime/Antlr4.Runtime.csproj
@@ -39,7 +39,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+