From d55f9a11a94ecdbf8952822c410fba3caae79563 Mon Sep 17 00:00:00 2001
From: brezza92
Date: Thu, 2 Mar 2017 14:23:42 +0700
Subject: [PATCH] convert brotli java decoder to c# library
---
.gitattributes | 63 ++
csharp/CSharpBrotli/CSharpBrotli.sln | 34 +
.../CSharpBrotli/CSharpBrotli.csproj | 65 ++
.../CSharpBrotli/Decode/BitReader.cs | 212 ++++
.../CSharpBrotli/Decode/BritliInputStream.cs | 199 ++++
.../Decode/BrotliRuntimeExpression.cs | 14 +
.../CSharpBrotli/Decode/Context.cs | 159 +++
.../CSharpBrotli/Decode/Decode.cs | 969 ++++++++++++++++++
.../CSharpBrotli/Decode/Dictionary.cs | 68 ++
.../CSharpBrotli/Decode/Huffman.cs | 147 +++
.../CSharpBrotli/Decode/HuffmanTreeGroup.cs | 54 +
.../CSharpBrotli/Decode/IntBufferReader.cs | 36 +
.../CSharpBrotli/Decode/Prefix.cs | 62 ++
.../CSharpBrotli/Decode/RunningStage.cs | 22 +
.../CSharpBrotli/CSharpBrotli/Decode/State.cs | 122 +++
.../CSharpBrotli/Decode/Transform.cs | 254 +++++
.../CSharpBrotli/CSharpBrotli/Decode/Utils.cs | 48 +
.../CSharpBrotli/Decode/WordTransformType.cs | 52 +
.../CSharpBrotli/Properties/AssemblyInfo.cs | 30 +
19 files changed, 2610 insertions(+)
create mode 100644 .gitattributes
create mode 100644 csharp/CSharpBrotli/CSharpBrotli.sln
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/CSharpBrotli.csproj
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/BitReader.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/BritliInputStream.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/BrotliRuntimeExpression.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/Context.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/Decode.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/Dictionary.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/Huffman.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/HuffmanTreeGroup.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/IntBufferReader.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/Prefix.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/RunningStage.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/State.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/Transform.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/Utils.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Decode/WordTransformType.cs
create mode 100644 csharp/CSharpBrotli/CSharpBrotli/Properties/AssemblyInfo.cs
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/csharp/CSharpBrotli/CSharpBrotli.sln b/csharp/CSharpBrotli/CSharpBrotli.sln
new file mode 100644
index 0000000..01fc779
--- /dev/null
+++ b/csharp/CSharpBrotli/CSharpBrotli.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBrotli", "CSharpBrotli\CSharpBrotli.csproj", "{50443CB1-3712-49A1-BBF8-91A31D0C4BA1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBrotliTest", "CSharpBrotliTest\CSharpBrotliTest.csproj", "{AE8BE423-ACAB-47D7-AD71-771773C47652}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpZLib", "..\..\..\..\Visual Studio 2015\Projects\SrcSamples\src\ICSharpCode.SharpZLib.csproj", "{0E7413FF-EB9E-4714-ACF2-BE3A6A7B2FFD}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {50443CB1-3712-49A1-BBF8-91A31D0C4BA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {50443CB1-3712-49A1-BBF8-91A31D0C4BA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {50443CB1-3712-49A1-BBF8-91A31D0C4BA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {50443CB1-3712-49A1-BBF8-91A31D0C4BA1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AE8BE423-ACAB-47D7-AD71-771773C47652}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AE8BE423-ACAB-47D7-AD71-771773C47652}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE8BE423-ACAB-47D7-AD71-771773C47652}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AE8BE423-ACAB-47D7-AD71-771773C47652}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0E7413FF-EB9E-4714-ACF2-BE3A6A7B2FFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0E7413FF-EB9E-4714-ACF2-BE3A6A7B2FFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0E7413FF-EB9E-4714-ACF2-BE3A6A7B2FFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0E7413FF-EB9E-4714-ACF2-BE3A6A7B2FFD}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/csharp/CSharpBrotli/CSharpBrotli/CSharpBrotli.csproj b/csharp/CSharpBrotli/CSharpBrotli/CSharpBrotli.csproj
new file mode 100644
index 0000000..6b380a0
--- /dev/null
+++ b/csharp/CSharpBrotli/CSharpBrotli/CSharpBrotli.csproj
@@ -0,0 +1,65 @@
+
+
+
+
+ 12.0
+ Debug
+ AnyCPU
+ {50443CB1-3712-49A1-BBF8-91A31D0C4BA1}
+ Library
+ Properties
+ CSharpBrotli
+ CSharpBrotli
+ en-US
+ 512
+ {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Profile44
+ v4.6
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/csharp/CSharpBrotli/CSharpBrotli/Decode/BitReader.cs b/csharp/CSharpBrotli/CSharpBrotli/Decode/BitReader.cs
new file mode 100644
index 0000000..753e58b
--- /dev/null
+++ b/csharp/CSharpBrotli/CSharpBrotli/Decode/BitReader.cs
@@ -0,0 +1,212 @@
+using System;
+using System.IO;
+
+namespace CSharpBrotli.Decode
+{
+ ///
+ /// Bit reading helpers.
+ ///
+ public class BitReader
+ {
+ ///
+ /// Input byte buffer, consist of a ring-buffer and a "slack" region where bytes from the start of
+ /// the ring-buffer are copied.
+ ///
+ private const int READ_SIZE = 4096;
+ private const int BUF_SIZE = READ_SIZE + 64;
+
+ //private const ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUF_SIZE).order(ByteOrder.LITTLE_ENDIAN);
+ //private const IntBuffer intBuffer = byteBuffer.asIntBuffer();
+ private MemoryStream byteBuffer;// = CreatesStream();
+ private IntBufferReader intBuffer;// = new BinaryReader(byteBuffer);
+ private byte[] shadowBuffer = new byte[BUF_SIZE];
+
+ private Stream input;
+
+ ///
+ /// Input stream is finished.
+ ///
+ private bool endOfStreamReached;
+
+ private long acc;
+ ///
+ /// Pre-fetched bits.
+ ///
+ public long accumulator
+ {
+ get
+ {
+ return acc;
+ }
+ set
+ {
+ acc = value;
+ }
+ }
+
+ ///
+ /// Current bit-reading position in accumulator.
+ ///
+ public int bitOffset;
+
+ ///
+ /// Number of 32-bit integers availabale for reading.
+ ///
+ private int available;
+
+ private int tailBytes = 0;
+
+ public BitReader()
+ {
+ byteBuffer = new MemoryStream(BUF_SIZE);
+ intBuffer = new IntBufferReader(byteBuffer);
+ }
+
+ ///
+ /// Fills up the input buffer.
+ /// No-op if there are at least 36 bytes present after current position.
+ /// After encountering the end of the input stream, 64 additional zero bytes are copied
+ /// to the buffer.
+ ///
+ public static void ReadMoreInput(BitReader br)
+ {
+ if (br.available > 9)
+ {
+ return;
+ }
+ if (br.endOfStreamReached)
+ {
+ if (br.available > 4)
+ {
+ return;
+ }
+ throw new BrotliRuntimeException("No more input");
+ }
+ int readOffset = (int)(br.intBuffer.Position << 2);
+ int bytesRead = READ_SIZE - readOffset;
+ Array.Copy(br.shadowBuffer, readOffset, br.shadowBuffer, 0, bytesRead);
+ try
+ {
+ while (bytesRead < READ_SIZE)
+ {
+ int len = br.input.Read(br.shadowBuffer, bytesRead, READ_SIZE - bytesRead);
+ if (len <= 0)
+ {
+ br.endOfStreamReached = true;
+ Utils.FillWithZeroes(br.shadowBuffer, bytesRead, 64);
+ bytesRead += 64;
+ br.tailBytes = bytesRead & 3;
+ break;
+ }
+ bytesRead += len;
+ }
+ }
+ catch (IOException e)
+ {
+ throw new BrotliRuntimeException("Failed to read input", e);
+ }
+ br.byteBuffer.SetLength(0);//clear
+ br.byteBuffer.Write(br.shadowBuffer, 0, bytesRead & 0xFFFC);
+ br.intBuffer.Position = 0;//rewind
+ br.available = bytesRead >> 2;
+ }
+
+ public static void CheckHealth(BitReader br)
+ {
+ if (!br.endOfStreamReached)
+ {
+ return;
+ }
+ /* When end of stream is reached, we "borrow" up to 64 zeroes to bit reader.
+ * If compressed stream is valid, then borrowed zeroes should remain unused.
+ */
+ int valentBytes = (br.available << 2) + ((64 - br.bitOffset) >> 3);
+ int borrowedBytes = 64 - br.tailBytes;
+ if (valentBytes != borrowedBytes)
+ {
+ throw new BrotliRuntimeException("Read after end");
+ }
+ }
+
+ ///
+ /// Advances the Read buffer by 5 bytes to make room for reading next 24 bits.
+ ///
+ public static void FillBitWindow(BitReader br)
+ {
+ if (br.bitOffset >= 32)
+ {
+ int temp = br.intBuffer.ReadInt32();
+ br.accumulator = ((long)temp << 32) | (long)((ulong)br.accumulator >> 32);
+ br.bitOffset -= 32;
+ br.available--;
+ }
+ }
+
+ ///
+ /// Reads the specified number of bits from Read Buffer.
+ ///
+ public static int ReadBits(BitReader br, int n)
+ {
+ FillBitWindow(br);
+ int val = (int)((ulong)br.accumulator >> br.bitOffset) & ((1 << n) - 1);
+ br.bitOffset += n;
+ return val;
+ }
+
+ ///
+ /// Initialize bit reader.
+ /// Initialisation turns bit reader to a ready state. Also a number of bytes is prefetched to
+ /// accumulator. Because of that this method may block until enough data could be read from input.
+ ///
+ /// BitReader POJO
+ /// data source
+ public static void Init(BitReader br, Stream input)
+ {
+ if (br.input != null)
+ {
+ throw new InvalidOperationException("Bit reader already has associated input stream");
+ }
+ br.input = input;
+ br.accumulator = 0;
+ br.intBuffer.Position = (READ_SIZE >> 2);
+ br.bitOffset = 64;
+ br.available = 0;
+ br.endOfStreamReached = false;
+ ReadMoreInput(br);
+ /* This situation is impossible in current implementation. */
+ if (br.available == 0)
+ {
+ throw new BrotliRuntimeException("Can't initialize reader");
+ }
+ FillBitWindow(br);
+ FillBitWindow(br);
+ }
+
+ public static void Close(BitReader br)
+ {
+ try
+ {
+ Stream input = br.input;
+ br.input = null;
+ input = null;
+ }
+ catch (IOException ex)
+ {
+ throw ex;
+ }
+ }
+
+ public static void JumpToByteBoundry(BitReader br)
+ {
+ int padding = (64 - br.bitOffset) & 7;
+ if (padding != 0)
+ {
+ int paddingBits = BitReader.ReadBits(br, padding);
+ if (paddingBits != 0)
+ {
+ throw new BrotliRuntimeException("Corrupted padding bits ");
+ }
+ }
+ }
+ }
+}
diff --git a/csharp/CSharpBrotli/CSharpBrotli/Decode/BritliInputStream.cs b/csharp/CSharpBrotli/CSharpBrotli/Decode/BritliInputStream.cs
new file mode 100644
index 0000000..bdb304d
--- /dev/null
+++ b/csharp/CSharpBrotli/CSharpBrotli/Decode/BritliInputStream.cs
@@ -0,0 +1,199 @@
+using System;
+using System.IO;
+
+namespace CSharpBrotli.Decode
+{
+ ///
+ /// {@link InputStream} decorator that decompresses brotli data.
+ /// Not thread-safe.
+ ///
+ public class BrotliInputStream
+ {
+ public const int DEFAULT_INTERNAL_BUFFER_SIZE = 16384;
+
+ ///
+ /// Internal buffer used for efficient byte-by-byte reading.
+ ///
+ private byte[] buffer;
+
+ ///
+ /// Number of decoded but still unused bytes in internal buffer.
+ ///
+ private int remainingBufferBytes;
+
+ ///
+ /// Next unused byte offset.
+ ///
+ private int bufferOffset;
+
+ ///
+ /// Decoder state.
+ ///
+ private readonly State state = new State();
+
+ ///
+ /// Creates a wrapper that decompresses brotli data.
+ /// For byte-by-byte reading ( ) internal buffer with
+ /// size is allocated and used.
+ ///
+ /// Will block the thread until first kilobyte of data of source is available.
+ ///
+ /// underlying data source
+ public BrotliInputStream(Stream source) : this(source, DEFAULT_INTERNAL_BUFFER_SIZE, null) { }
+
+ ///
+ /// Creates a wrapper that decompresses brotli data.
+ /// For byte-by-byte reading ( ) internal buffer of specified size is
+ /// allocated and used.
+ ///
+ /// Will block the thread until first kilobyte of data of source is available.
+ ///
+ /// compressed data source
+ /// size of internal buffer used in case of byte-by-byte reading
+ public BrotliInputStream(Stream source, int byteReadBufferSize) : this(source, byteReadBufferSize, null) { }
+
+ ///
+ /// Creates a wrapper that decompresses brotli data.
+ /// For byte-by-byte reading ( ) internal buffer of specified size is
+ /// allocated and used.
+ ///
+ /// Will block the thread until first kilobyte of data of source is available.
+ ///
+ /// compressed data source
+ /// size of internal buffer used in case of byte-by-byte reading
+ /// custom dictionary data; null if not used
+ public BrotliInputStream(Stream source, int byteReadBufferSize, byte[] customDictionary)
+ {
+ try
+ {
+ if (byteReadBufferSize <= 0)
+ {
+ throw new InvalidOperationException("Bad buffer size:" + byteReadBufferSize);
+ }
+ else if (source == null)
+ {
+ throw new InvalidOperationException("source is null");
+ }
+ this.buffer = new byte[byteReadBufferSize];
+ this.remainingBufferBytes = 0;
+ this.bufferOffset = 0;
+ try
+ {
+ State.SetInput(state, source);
+ }
+ catch (BrotliRuntimeException ex)
+ {
+ throw new IOException(ex.Message, ex.InnerException);
+ }
+ if (customDictionary != null)
+ {
+ Decode.SetCustomDictionary(state, customDictionary);
+ }
+ }
+ catch(IOException ex)
+ {
+ throw ex;
+ }
+ }
+
+ public void Close()
+ {
+ try
+ {
+ State.Close(state);
+ }
+ catch (IOException ex)
+ {
+ throw ex;
+ }
+ }
+
+ public int Read()
+ {
+ try
+ {
+ if (bufferOffset >= remainingBufferBytes)
+ {
+ remainingBufferBytes = Read(buffer, 0, buffer.Length);
+ bufferOffset = 0;
+ if (remainingBufferBytes == -1)
+ {
+ return -1;
+ }
+ }
+ return buffer[bufferOffset++] & 0xFF;
+ }
+ catch(IOException ex)
+ {
+ throw ex;
+ }
+ catch(BrotliRuntimeException ex)
+ {
+ throw new IOException(ex.Message, ex.InnerException);
+ }
+ }
+
+ public int Read(byte[] destBuffer)
+ {
+ return Read(destBuffer, 0, destBuffer.Length);
+ }
+
+ public int Read(byte[] destBuffer, int destOffset, int destLen)
+ {
+ try
+ {
+ if (destOffset < 0)
+ {
+ throw new InvalidOperationException("Bad offset: " + destOffset);
+ }
+ else if (destLen < 0)
+ {
+ throw new InvalidOperationException("Bad length: " + destLen);
+ }
+ else if (destOffset + destLen > destBuffer.Length)
+ {
+ throw new InvalidOperationException(
+ "Buffer overflow: " + (destOffset + destLen) + " > " + destBuffer.Length);
+ }
+ else if (destLen == 0)
+ {
+ return 0;
+ }
+ int copyLen = Math.Max(remainingBufferBytes - bufferOffset, 0);
+ if (copyLen != 0)
+ {
+ copyLen = Math.Min(copyLen, destLen);
+ Array.Copy(buffer, bufferOffset, destBuffer, destOffset, copyLen);
+ bufferOffset += copyLen;
+ destOffset += copyLen;
+ destLen -= copyLen;
+ if (destLen == 0)
+ {
+ return copyLen;
+ }
+ }
+ try
+ {
+ state.output = destBuffer;
+ state.outputOffset = destOffset;
+ state.outputLength = destLen;
+ state.outputUsed = 0;
+ Decode.Decompress(state);
+ if (state.outputUsed == 0)
+ {
+ return -1;
+ }
+ return state.outputUsed + copyLen;
+ }
+ catch (BrotliRuntimeException ex)
+ {
+ throw new IOException(ex.Message, ex.InnerException);
+ }
+ }
+ catch (IOException ex)
+ {
+ throw ex;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/csharp/CSharpBrotli/CSharpBrotli/Decode/BrotliRuntimeExpression.cs b/csharp/CSharpBrotli/CSharpBrotli/Decode/BrotliRuntimeExpression.cs
new file mode 100644
index 0000000..f0861e8
--- /dev/null
+++ b/csharp/CSharpBrotli/CSharpBrotli/Decode/BrotliRuntimeExpression.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace CSharpBrotli.Decode
+{
+ ///
+ /// Unchecked exception used internally.
+ ///
+ public class BrotliRuntimeException : Exception
+ {
+ public BrotliRuntimeException() : base() { }
+ public BrotliRuntimeException(string message) : base(message) { }
+ public BrotliRuntimeException(string message, Exception innerException) : base(message, innerException) { }
+ }
+}
\ No newline at end of file
diff --git a/csharp/CSharpBrotli/CSharpBrotli/Decode/Context.cs b/csharp/CSharpBrotli/CSharpBrotli/Decode/Context.cs
new file mode 100644
index 0000000..436fa18
--- /dev/null
+++ b/csharp/CSharpBrotli/CSharpBrotli/Decode/Context.cs
@@ -0,0 +1,159 @@
+namespace CSharpBrotli.Decode
+{
+ ///
+ /// Common context lookup table for all context modes.
+ ///
+ public sealed class Context
+ {
+ public static readonly int[] LOOKUP =
+ {
+ // CONTEXT_UTF8, last byte.
+ // ASCII range.
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12,
+ 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48,
+ 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12,
+ 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56,
+ 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0,
+
+ // UTF8 continuation byte range.
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+
+ // UTF8 lead byte range.
+ 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
+ 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
+ 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
+ 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
+
+ // CONTEXT_UTF8 second last byte.
+ // ASCII range.
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,
+
+ // UTF8 continuation byte range.
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ // UTF8 lead byte range.
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+
+ // CONTEXT_SIGNED, second last byte.
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+
+ // CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits.
+ 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56,
+
+ // CONTEXT_LSB6, last byte.
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+
+ // CONTEXT_MSB6, last byte.
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
+ 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
+ 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
+ 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
+ 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27,
+ 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
+ 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,
+ 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
+ 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,
+ 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47,
+ 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51,
+ 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55,
+ 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59,
+ 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63,
+
+ // CONTEXT_{M,L}SB6, second last byte,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ public static readonly int[] LOOKUP_OFFSETS =
+ {
+ // CONTEXT_LSB6
+ 1024, 1536,
+ // CONTEXT_MSB6
+ 1280, 1536,
+ // CONTEXT_UTF8
+ 0, 256,
+ // CONTEXT_SIGNED
+ 768, 512
+ };
+ }
+}
\ No newline at end of file
diff --git a/csharp/CSharpBrotli/CSharpBrotli/Decode/Decode.cs b/csharp/CSharpBrotli/CSharpBrotli/Decode/Decode.cs
new file mode 100644
index 0000000..3287f71
--- /dev/null
+++ b/csharp/CSharpBrotli/CSharpBrotli/Decode/Decode.cs
@@ -0,0 +1,969 @@
+using System;
+
+namespace CSharpBrotli.Decode
+{
+ public sealed class Decode
+ {
+ private const int DEFAULT_CODE_LENGTH = 8;
+ private const int CODE_LENGTH_REPEAT_CODE = 16;
+ private const int NUM_LITERAL_CODES = 256;
+ private const int NUM_INSERT_AND_COPY_CODES = 704;
+ private const int NUM_BLOCK_LENGTH_CODES = 26;
+ private const int LITERAL_CONTEXT_BITS = 6;
+ private const int DISTANCE_CONTEXT_BITS = 2;
+
+ private const int HUFFMAN_TABLE_BITS = 8;
+ private const int HUFFMAN_TABLE_MASK = 0xFF;
+
+ private const int CODE_LENGTH_CODES = 18;
+ private static readonly int[] CODE_LENGTH_CODE_ORDER =
+ {
+ 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ };
+
+ private const int NUM_DISTANCE_SHORT_CODES = 16;
+ private static readonly int[] DISTANCE_SHORT_CODE_INDEX_OFFSET =
+ {
+ 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2
+ };
+
+ private static readonly int[] DISTANCE_SHORT_CODE_VALUE_OFFSET =
+ {
+ 0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3
+ };
+
+ ///
+ /// Static Huffman code for the code length code lengths.
+ ///
+ private static readonly int[] FIXED_TABLE =
+ {
+ 0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040001,
+ 0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040005
+ };
+
+ ///
+ /// Decodes a number in the range [0..255], by reading 1 - 11 bits.
+ ///
+ private static int DecodeVarLenUnsignedByte(BitReader br)
+ {
+ if (BitReader.ReadBits(br, 1) != 0)
+ {
+ int n = BitReader.ReadBits(br, 3);
+ if (n == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return BitReader.ReadBits(br, n) + (1 << n);
+ }
+ }
+ return 0;
+ }
+
+ private static void DecodeMetaBlockLength(BitReader br, State state)
+ {
+ state.inputEnd = BitReader.ReadBits(br, 1) == 1;
+ state.metaBlockLength = 0;
+ state.isUncompressed = false;
+ state.isMetadata = false;
+ if (state.inputEnd && BitReader.ReadBits(br, 1) != 0)
+ {
+ return;
+ }
+ int sizeNibbles = BitReader.ReadBits(br, 2) + 4;
+ if (sizeNibbles == 7)
+ {
+ state.isMetadata = true;
+ if (BitReader.ReadBits(br, 1) != 0)
+ {
+ throw new BrotliRuntimeException("Corrupted reserved bit");
+ }
+ int sizeBytes = BitReader.ReadBits(br, 2);
+ if (sizeBytes == 0)
+ {
+ return;
+ }
+ for (int i = 0; i < sizeBytes; i++)
+ {
+ int bits = BitReader.ReadBits(br, 8);
+ if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1)
+ {
+ throw new BrotliRuntimeException("Exuberant nibble");
+ }
+ state.metaBlockLength |= bits << (i * 8);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < sizeNibbles; i++)
+ {
+ int bits = BitReader.ReadBits(br, 4);
+ if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4)
+ {
+ throw new BrotliRuntimeException("Exuberant nibble");
+ }
+ state.metaBlockLength |= bits << (i * 4);
+ }
+ }
+ state.metaBlockLength++;
+ if (!state.inputEnd)
+ {
+ state.isUncompressed = BitReader.ReadBits(br, 1) == 1;
+ }
+ }
+
+ private static int ReadSymbol(int[] table, int offset, BitReader br)
+ {
+ BitReader.FillBitWindow(br);
+ offset += (int)((ulong)br.accumulator >> br.bitOffset) & HUFFMAN_TABLE_MASK;
+ int n = (table[offset] >> 16) - HUFFMAN_TABLE_BITS;
+ if (n > 0)
+ {
+ br.bitOffset += HUFFMAN_TABLE_BITS;
+ offset += table[offset] & 0xFFFF;
+ offset += (int)((ulong)br.accumulator >> br.bitOffset) & ((1 << n) - 1);
+ }
+ br.bitOffset += table[offset] >> 16;
+ return table[offset] & 0xFFFF;
+ }
+
+ private static int ReadBlockLength(int[] table, int offset, BitReader br)
+ {
+ int code = ReadSymbol(table, offset, br);
+ int n = Prefix.BLOCK_LENGTH_N_BITS[code];
+ return Prefix.BLOCK_LENGTH_OFFSET[code] + BitReader.ReadBits(br, n);
+ }
+
+ private static int TranslateShortCodes(int code, int[] ringBuffer, int index)
+ {
+ if (code < NUM_DISTANCE_SHORT_CODES)
+ {
+ index += DISTANCE_SHORT_CODE_INDEX_OFFSET[code];
+ index &= 3;
+ return ringBuffer[index] + DISTANCE_SHORT_CODE_VALUE_OFFSET[code];
+ }
+ return code - NUM_DISTANCE_SHORT_CODES + 1;
+ }
+
+ private static void MoveToFront(int[] v, int index)
+ {
+ int value = v[index];
+ for (; index > 0; index--)
+ {
+ v[index] = v[index - 1];
+ }
+ v[0] = value;
+ }
+
+ private static void InverseMoveToFrontTransform(byte[] v, int vLen)
+ {
+ int[] mtf = new int[256];
+ for (int i = 0; i < 256; i++)
+ {
+ mtf[i] = i;
+ }
+ for (int i = 0; i < vLen; i++)
+ {
+ int index = v[i] & 0xFF;
+ v[i] = (byte)mtf[index];
+ if (index != 0)
+ {
+ MoveToFront(mtf, index);
+ }
+ }
+ }
+
+ private static void ReadHuffmanCodeLengths(
+ int[] codeLengthCodeLengths, int numSymbols, int[] codeLengths, BitReader br)
+ {
+ int symbol = 0;
+ int prevCodeLen = DEFAULT_CODE_LENGTH;
+ int repeat = 0;
+ int repeatCodeLen = 0;
+ int space = 32768;
+ int[] table = new int[32];
+
+ Huffman.BuildHuffmanTable(table, 0, 5, codeLengthCodeLengths, CODE_LENGTH_CODES);
+
+ while (symbol < numSymbols && space > 0)
+ {
+ BitReader.ReadMoreInput(br);
+ BitReader.FillBitWindow(br);
+ int p = (int)(((ulong)br.accumulator >> br.bitOffset)) & 31;
+ br.bitOffset += table[p] >> 16;
+ int codeLen = table[p] & 0xFFFF;
+ if (codeLen < CODE_LENGTH_REPEAT_CODE)
+ {
+ repeat = 0;
+ codeLengths[symbol++] = codeLen;
+ if (codeLen != 0)
+ {
+ prevCodeLen = codeLen;
+ space -= 32768 >> codeLen;
+ }
+ }
+ else
+ {
+ int extraBits = codeLen - 14;
+ int newLen = 0;
+ if (codeLen == CODE_LENGTH_REPEAT_CODE)
+ {
+ newLen = prevCodeLen;
+ }
+ if (repeatCodeLen != newLen)
+ {
+ repeat = 0;
+ repeatCodeLen = newLen;
+ }
+ int oldRepeat = repeat;
+ if (repeat > 0)
+ {
+ repeat -= 2;
+ repeat <<= extraBits;
+ }
+ repeat += BitReader.ReadBits(br, extraBits) + 3;
+ int repeatDelta = repeat - oldRepeat;
+ if (symbol + repeatDelta > numSymbols)
+ {
+ throw new BrotliRuntimeException("symbol + repeatDelta > numSymbols"); // COV_NF_LINE
+ }
+ for (int i = 0; i < repeatDelta; i++)
+ {
+ codeLengths[symbol++] = repeatCodeLen;
+ }
+ if (repeatCodeLen != 0)
+ {
+ space -= repeatDelta << (15 - repeatCodeLen);
+ }
+ }
+ }
+ if (space != 0)
+ {
+ throw new BrotliRuntimeException("Unused space"); // COV_NF_LINE
+ }
+ // TODO: Pass max_symbol to Huffman table builder instead?
+ Utils.FillWithZeroes(codeLengths, symbol, numSymbols - symbol);
+ }
+
+ public static void ReadHuffmanCode(int alphabetSize, int[] table, int offset, BitReader br)
+ {
+ bool ok = true;
+ int simpleCodeOrSkip;
+ BitReader.ReadMoreInput(br);
+ // TODO: Avoid allocation.
+ int[] codeLengths = new int[alphabetSize];
+ simpleCodeOrSkip = BitReader.ReadBits(br, 2);
+ if (simpleCodeOrSkip == 1)
+ { // Read symbols, codes & code lengths directly.
+ int maxBitsCounter = alphabetSize - 1;
+ int maxBits = 0;
+ int[] symbols = new int[4];
+ int numSymbols = BitReader.ReadBits(br, 2) + 1;
+ while (maxBitsCounter != 0)
+ {
+ maxBitsCounter >>= 1;
+ maxBits++;
+ }
+ Utils.FillWithZeroes(codeLengths, 0, alphabetSize);
+ for (int i = 0; i < numSymbols; i++)
+ {
+ symbols[i] = BitReader.ReadBits(br, maxBits) % alphabetSize;
+ codeLengths[symbols[i]] = 2;
+ }
+ codeLengths[symbols[0]] = 1;
+ switch (numSymbols)
+ {
+ case 1:
+ break;
+ case 2:
+ ok = symbols[0] != symbols[1];
+ codeLengths[symbols[1]] = 1;
+ break;
+ case 3:
+ ok = symbols[0] != symbols[1] && symbols[0] != symbols[2] && symbols[1] != symbols[2];
+ break;
+ case 4:
+ ok = symbols[0] != symbols[1] && symbols[0] != symbols[2] && symbols[0] != symbols[3]
+ && symbols[1] != symbols[2] && symbols[1] != symbols[3] && symbols[2] != symbols[3];
+ if (BitReader.ReadBits(br, 1) == 1)
+ {
+ codeLengths[symbols[2]] = 3;
+ codeLengths[symbols[3]] = 3;
+ }
+ else
+ {
+ codeLengths[symbols[0]] = 2;
+ }
+ break;
+ }
+ }
+ else
+ { // Decode Huffman-coded code lengths.
+ int[] codeLengthCodeLengths = new int[CODE_LENGTH_CODES];
+ int space = 32;
+ int numCodes = 0;
+ for (int i = simpleCodeOrSkip; i < CODE_LENGTH_CODES && space > 0; i++)
+ {
+ int codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
+ BitReader.FillBitWindow(br);
+ int p = (int)((ulong)br.accumulator >> br.bitOffset) & 15;
+ // TODO: Demultiplex FIXED_TABLE.
+ br.bitOffset += FIXED_TABLE[p] >> 16;
+ int v = FIXED_TABLE[p] & 0xFFFF;
+ codeLengthCodeLengths[codeLenIdx] = v;
+ if (v != 0)
+ {
+ space -= (32 >> v);
+ numCodes++;
+ }
+ }
+ ok = (numCodes == 1 || space == 0);
+ ReadHuffmanCodeLengths(codeLengthCodeLengths, alphabetSize, codeLengths, br);
+ }
+ if (!ok)
+ {
+ throw new BrotliRuntimeException("Can't readHuffmanCode"); // COV_NF_LINE
+ }
+ Huffman.BuildHuffmanTable(table, offset, HUFFMAN_TABLE_BITS, codeLengths, alphabetSize);
+ }
+
+ private static int DecodeContextMap(int contextMapSize, byte[] contextMap, BitReader br)
+ {
+ BitReader.ReadMoreInput(br);
+ int numTrees = DecodeVarLenUnsignedByte(br) + 1;
+
+ if (numTrees == 1)
+ {
+ Utils.FillWithZeroes(contextMap, 0, contextMapSize);
+ return numTrees;
+ }
+
+ bool useRleForZeros = BitReader.ReadBits(br, 1) == 1;
+ int maxRunLengthPrefix = 0;
+ if (useRleForZeros)
+ {
+ maxRunLengthPrefix = BitReader.ReadBits(br, 4) + 1;
+ }
+ int[] table = new int[Huffman.HUFFMAN_MAX_TABLE_SIZE];
+ ReadHuffmanCode(numTrees + maxRunLengthPrefix, table, 0, br);
+ for (int i = 0; i < contextMapSize;)
+ {
+ BitReader.ReadMoreInput(br);
+ int code = ReadSymbol(table, 0, br);
+ if (code == 0)
+ {
+ contextMap[i] = 0;
+ i++;
+ }
+ else if (code <= maxRunLengthPrefix)
+ {
+ int reps = (1 << code) + BitReader.ReadBits(br, code);
+ while (reps != 0)
+ {
+ if (i >= contextMapSize)
+ {
+ throw new BrotliRuntimeException("Corrupted context map"); // COV_NF_LINE
+ }
+ contextMap[i] = 0;
+ i++;
+ reps--;
+ }
+ }
+ else
+ {
+ contextMap[i] = (byte)(code - maxRunLengthPrefix);
+ i++;
+ }
+ }
+ if (BitReader.ReadBits(br, 1) == 1)
+ {
+ InverseMoveToFrontTransform(contextMap, contextMapSize);
+ }
+ return numTrees;
+ }
+
+ private static void DecodeBlockTypeAndLength(State state, int treeType)
+ {
+ BitReader br = state.br;
+ int[] ringBuffers = state.blockTypeRb;
+ int offset = treeType * 2;
+ int blockType = ReadSymbol(state.blockTypeTrees, treeType * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
+ state.blockLength[treeType] = ReadBlockLength(state.blockLenTrees,
+ treeType * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
+
+ if (blockType == 1)
+ {
+ blockType = ringBuffers[offset + 1] + 1;
+ }
+ else if (blockType == 0)
+ {
+ blockType = ringBuffers[offset];
+ }
+ else
+ {
+ blockType -= 2;
+ }
+ if (blockType >= state.numBlockTypes[treeType])
+ {
+ blockType -= state.numBlockTypes[treeType];
+ }
+ ringBuffers[offset] = ringBuffers[offset + 1];
+ ringBuffers[offset + 1] = blockType;
+ }
+
+ private static void DecodeLiteralBlockSwitch(State state)
+ {
+ DecodeBlockTypeAndLength(state, 0);
+ int literalBlockType = state.blockTypeRb[1];
+ state.contextMapSlice = literalBlockType << LITERAL_CONTEXT_BITS;
+ state.literalTreeIndex = state.contextMap[state.contextMapSlice] & 0xFF;
+ state.literalTree = state.hGroup0.trees[state.literalTreeIndex];
+ int contextMode = state.contextModes[literalBlockType];
+ state.contextLookupOffset1 = Context.LOOKUP_OFFSETS[contextMode];
+ state.contextLookupOffset2 = Context.LOOKUP_OFFSETS[contextMode + 1];
+ }
+
+ private static void DecodeCommandBlockSwitch(State state)
+ {
+ DecodeBlockTypeAndLength(state, 1);
+ state.treeCommandOffset = state.hGroup1.trees[state.blockTypeRb[3]];
+ }
+
+ private static void DecodeDistanceBlockSwitch(State state)
+ {
+ DecodeBlockTypeAndLength(state, 2);
+ state.distContextMapSlice = state.blockTypeRb[5] << DISTANCE_CONTEXT_BITS;
+ }
+
+ public static void MaybeReallocateRingBuffer(State state)
+ {
+ int newSize = state.maxRingBufferSize;
+ if ((long)newSize > state.expectedTotalSize)
+ {
+ /* TODO: Handle 2GB+ cases more gracefully. */
+ int minimalNewSize = (int)state.expectedTotalSize + state.customDictionary.Length;
+ while ((newSize >> 1) > minimalNewSize)
+ {
+ newSize >>= 1;
+ }
+ if (!state.inputEnd && newSize < 16384 && state.maxRingBufferSize >= 16384)
+ {
+ newSize = 16384;
+ }
+ }
+ if (newSize <= state.ringBufferSize)
+ {
+ return;
+ }
+ int ringBufferSizeWithSlack = newSize + Dictionary.MAX_TRANSFORMED_WORD_LENGTH;
+ byte[] newBuffer = new byte[ringBufferSizeWithSlack];
+ if (state.ringBuffer != null)
+ {
+ Array.Copy(state.ringBuffer, 0, newBuffer, 0, state.ringBufferSize);
+ }
+ else
+ {
+ /* Prepend custom dictionary, if any. */
+ if (state.customDictionary.Length != 0)
+ {
+ int length = state.customDictionary.Length;
+ int offset = 0;
+ if (length > state.maxBackwardDistance)
+ {
+ offset = length - state.maxBackwardDistance;
+ length = state.maxBackwardDistance;
+ }
+ Array.Copy(state.customDictionary, offset, newBuffer, 0, length);
+ state.pos = length;
+ state.bytesToIgnore = length;
+ }
+ }
+ state.ringBuffer = newBuffer;
+ state.ringBufferSize = newSize;
+ }
+
+ ///
+ /// Reads next metablock header.
+ ///
+ /// decoding state
+ public static void ReadMeablockInfo(State state)
+ {
+ BitReader br = state.br;
+
+ if (state.inputEnd)
+ {
+ state.nextRunningState = RunningStage.FINISHED;
+ state.bytesToWrite = state.pos & (state.ringBufferSize - 1);
+ state.bytesWritten = 0;
+ state.runningState = RunningStage.WRITE;
+ return;
+ }
+ // TODO: Reset? Do we need this?
+ state.hGroup0.codes = null;
+ state.hGroup0.trees = null;
+ state.hGroup1.codes = null;
+ state.hGroup1.trees = null;
+ state.hGroup2.codes = null;
+ state.hGroup2.trees = null;
+
+ BitReader.ReadMoreInput(br);
+ DecodeMetaBlockLength(br, state);
+ if (state.metaBlockLength == 0 && !state.isMetadata)
+ {
+ return;
+ }
+ if (state.isUncompressed || state.isMetadata)
+ {
+ BitReader.JumpToByteBoundry(br);
+ state.runningState = state.isMetadata ? RunningStage.READ_METADATA : RunningStage.COPY_UNCOMPRESSED;
+ }
+ else
+ {
+ state.runningState = RunningStage.COMPRESSED_BLOCK_START;
+ }
+
+ if (state.isMetadata)
+ {
+ return;
+ }
+ state.expectedTotalSize += state.metaBlockLength;
+ if (state.ringBufferSize < state.maxRingBufferSize)
+ {
+ MaybeReallocateRingBuffer(state);
+ }
+ }
+
+ public static void ReadMetablockHuffmanCodesAndContextMaps(State state)
+ {
+ BitReader br = state.br;
+
+ for (int i = 0; i < 3; i++)
+ {
+ state.numBlockTypes[i] = DecodeVarLenUnsignedByte(br) + 1;
+ state.blockLength[i] = 1 << 28;
+ if (state.numBlockTypes[i] > 1)
+ {
+ ReadHuffmanCode(state.numBlockTypes[i] + 2, state.blockTypeTrees,
+ i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
+ ReadHuffmanCode(NUM_BLOCK_LENGTH_CODES, state.blockLenTrees,
+ i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
+ state.blockLength[i] = ReadBlockLength(state.blockLenTrees,
+ i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
+ }
+ }
+
+ BitReader.ReadMoreInput(br);
+ state.distancePostfixBits = BitReader.ReadBits(br, 2);
+ state.numDirectDistanceCodes =
+ NUM_DISTANCE_SHORT_CODES + (BitReader.ReadBits(br, 4) << state.distancePostfixBits);
+ state.distancePostfixMask = (1 << state.distancePostfixBits) - 1;
+ int numDistanceCodes = state.numDirectDistanceCodes + (48 << state.distancePostfixBits);
+ // TODO: Reuse?
+ state.contextModes = new byte[state.numBlockTypes[0]];
+ for (int i = 0; i < state.numBlockTypes[0];)
+ {
+ /* Ensure that less than 256 bits read between readMoreInput. */
+ int limit = Math.Min(i + 96, state.numBlockTypes[0]);
+ for (; i < limit; ++i)
+ {
+ state.contextModes[i] = (byte)(BitReader.ReadBits(br, 2) << 1);
+ }
+ BitReader.ReadMoreInput(br);
+ }
+
+ // TODO: Reuse?
+ state.contextMap = new byte[state.numBlockTypes[0] << LITERAL_CONTEXT_BITS];
+ int numLiteralTrees = DecodeContextMap(state.numBlockTypes[0] << LITERAL_CONTEXT_BITS,
+ state.contextMap, br);
+ state.trivialLiteralContext = true;
+ for (int j = 0; j < state.numBlockTypes[0] << LITERAL_CONTEXT_BITS; j++)
+ {
+ if (state.contextMap[j] != j >> LITERAL_CONTEXT_BITS)
+ {
+ state.trivialLiteralContext = false;
+ break;
+ }
+ }
+
+ // TODO: Reuse?
+ state.distContextMap = new byte[state.numBlockTypes[2] << DISTANCE_CONTEXT_BITS];
+ int numDistTrees = DecodeContextMap(state.numBlockTypes[2] << DISTANCE_CONTEXT_BITS,
+ state.distContextMap, br);
+
+ HuffmanTreeGroup.Init(state.hGroup0, NUM_LITERAL_CODES, numLiteralTrees);
+ HuffmanTreeGroup.Init(state.hGroup1, NUM_INSERT_AND_COPY_CODES, state.numBlockTypes[1]);
+ HuffmanTreeGroup.Init(state.hGroup2, numDistanceCodes, numDistTrees);
+
+ HuffmanTreeGroup.Decode(state.hGroup0, br);
+ HuffmanTreeGroup.Decode(state.hGroup1, br);
+ HuffmanTreeGroup.Decode(state.hGroup2, br);
+
+ state.contextMapSlice = 0;
+ state.distContextMapSlice = 0;
+ state.contextLookupOffset1 = Context.LOOKUP_OFFSETS[state.contextModes[0]];
+ state.contextLookupOffset2 = Context.LOOKUP_OFFSETS[state.contextModes[0] + 1];
+ state.literalTreeIndex = 0;
+ state.literalTree = state.hGroup0.trees[0];
+ state.treeCommandOffset = state.hGroup1.trees[0]; // TODO: == 0?
+
+ state.blockTypeRb[0] = state.blockTypeRb[2] = state.blockTypeRb[4] = 1;
+ state.blockTypeRb[1] = state.blockTypeRb[3] = state.blockTypeRb[5] = 0;
+ }
+
+ public static void CopyUncompressedData(State state)
+ {
+ BitReader br = state.br;
+ byte[] ringBuffer = state.ringBuffer;
+ int ringBufferMask = state.ringBufferSize - 1;
+
+ while (state.metaBlockLength > 0)
+ {
+ BitReader.ReadMoreInput(br);
+ // Optimize
+ ringBuffer[state.pos & ringBufferMask] = (byte)(BitReader.ReadBits(br, 8));
+ state.metaBlockLength--;
+ if ((state.pos++ & ringBufferMask) == ringBufferMask)
+ {
+ state.nextRunningState = RunningStage.COPY_UNCOMPRESSED;
+ state.bytesToWrite = state.ringBufferSize;
+ state.bytesWritten = 0;
+ state.runningState = RunningStage.WRITE;
+ return;
+ }
+ }
+ state.runningState = RunningStage.BLOCK_START;
+ }
+
+ public static bool WriteRingBuffer(State state)
+ {
+ /* Ignore custom dictionary bytes. */
+ if (state.bytesToIgnore != 0)
+ {
+ state.bytesWritten += state.bytesToIgnore;
+ state.bytesToIgnore = 0;
+ }
+ int toWrite = Math.Min(state.outputLength - state.outputUsed,
+ state.bytesToWrite - state.bytesWritten);
+ if (toWrite != 0)
+ {
+ Array.Copy(state.ringBuffer, state.bytesWritten, state.output,
+ state.outputOffset + state.outputUsed, toWrite);
+ state.outputUsed += toWrite;
+ state.bytesWritten += toWrite;
+ }
+
+ return state.outputUsed < state.outputLength;
+ }
+
+ public static void SetCustomDictionary(State state, byte[] data)
+ {
+ state.customDictionary = (data == null) ? new byte[0] : data;
+ }
+
+ public static void Decompress(State state)
+ {
+ if (state.runningState == RunningStage.UNINITIALIZED)
+ {
+ throw new InvalidOperationException("Can't decompress until initialized");
+ }
+ if (state.runningState == RunningStage.CLOSED)
+ {
+ throw new InvalidOperationException("Can't decompress after close");
+ }
+ BitReader br = state.br;
+ int ringBufferMask = state.ringBufferSize - 1;
+ byte[] ringBuffer = state.ringBuffer;
+
+ while (state.runningState != RunningStage.FINISHED)
+ {
+ // TODO: extract cases to methods for the better readability.
+ switch (state.runningState)
+ {
+ case RunningStage.BLOCK_START:
+ if (state.metaBlockLength < 0)
+ {
+ throw new BrotliRuntimeException("Invalid metablock length");
+ }
+ ReadMeablockInfo(state);
+ /* Ring-buffer would be reallocated here. */
+ ringBufferMask = state.ringBufferSize - 1;
+ ringBuffer = state.ringBuffer;
+ continue;
+
+ case RunningStage.COMPRESSED_BLOCK_START:
+ ReadMetablockHuffmanCodesAndContextMaps(state);
+ state.runningState = RunningStage.MAIN_LOOP;
+ goto case RunningStage.MAIN_LOOP;
+ // Fall through
+
+ case RunningStage.MAIN_LOOP:
+ if (state.metaBlockLength <= 0)
+ {
+ // Protect pos from overflow, wrap it around at every GB of input data.
+ state.pos &= 0x3fffffff;
+ state.runningState = RunningStage.BLOCK_START;
+ continue;
+ }
+ BitReader.ReadMoreInput(br);
+ if (state.blockLength[1] == 0)
+ {
+ DecodeCommandBlockSwitch(state);
+ }
+ state.blockLength[1]--;
+ int cmdCode = ReadSymbol(state.hGroup1.codes, state.treeCommandOffset, br);
+ int rangeIdx = (int)((uint)cmdCode >> 6);
+ state.distanceCode = 0;
+ if (rangeIdx >= 2)
+ {
+ rangeIdx -= 2;
+ state.distanceCode = -1;
+ }
+ int insertCode = Prefix.INSERT_RANGE_LUT[rangeIdx] + ((int)((uint)cmdCode >> 3) & 7);
+ int copyCode = Prefix.COPY_RANGE_LUT[rangeIdx] + (cmdCode & 7);
+ state.insertLength = Prefix.INSERT_LENGTH_OFFSET[insertCode] + BitReader
+ .ReadBits(br, Prefix.INSERT_LENGTH_N_BITS[insertCode]);
+ state.copyLength = Prefix.COPY_LENGTH_OFFSET[copyCode] + BitReader
+ .ReadBits(br, Prefix.COPY_LENGTH_N_BITS[copyCode]);
+
+ state.j = 0;
+ state.runningState = RunningStage.INSERT_LOOP;
+ goto case RunningStage.INSERT_LOOP;
+ // Fall through
+ case RunningStage.INSERT_LOOP:
+ if (state.trivialLiteralContext)
+ {
+ while (state.j < state.insertLength)
+ {
+ BitReader.ReadMoreInput(br);
+ if (state.blockLength[0] == 0)
+ {
+ DecodeLiteralBlockSwitch(state);
+ }
+ state.blockLength[0]--;
+ ringBuffer[state.pos & ringBufferMask] = (byte)ReadSymbol(
+ state.hGroup0.codes, state.literalTree, br);
+ state.j++;
+ if ((state.pos++ & ringBufferMask) == ringBufferMask)
+ {
+ state.nextRunningState = RunningStage.INSERT_LOOP;
+ state.bytesToWrite = state.ringBufferSize;
+ state.bytesWritten = 0;
+ state.runningState = RunningStage.WRITE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ int prevByte1 = ringBuffer[(state.pos - 1) & ringBufferMask] & 0xFF;
+ int prevByte2 = ringBuffer[(state.pos - 2) & ringBufferMask] & 0xFF;
+ while (state.j < state.insertLength)
+ {
+ BitReader.ReadMoreInput(br);
+ if (state.blockLength[0] == 0)
+ {
+ DecodeLiteralBlockSwitch(state);
+ }
+ int literalTreeIndex = state.contextMap[state.contextMapSlice
+ + (Context.LOOKUP[state.contextLookupOffset1 + prevByte1]
+ | Context.LOOKUP[state.contextLookupOffset2 + prevByte2])] & 0xFF;
+ state.blockLength[0]--;
+ prevByte2 = prevByte1;
+ prevByte1 = ReadSymbol(
+ state.hGroup0.codes, state.hGroup0.trees[literalTreeIndex], br);
+ ringBuffer[state.pos & ringBufferMask] = (byte)prevByte1;
+ state.j++;
+ if ((state.pos++ & ringBufferMask) == ringBufferMask)
+ {
+ state.nextRunningState = RunningStage.INSERT_LOOP;
+ state.bytesToWrite = state.ringBufferSize;
+ state.bytesWritten = 0;
+ state.runningState = RunningStage.WRITE;
+ break;
+ }
+ }
+ }
+ if (state.runningState != RunningStage.INSERT_LOOP)
+ {
+ continue;
+ }
+ state.metaBlockLength -= state.insertLength;
+ if (state.metaBlockLength <= 0)
+ {
+ state.runningState = RunningStage.MAIN_LOOP;
+ continue;
+ }
+ if (state.distanceCode < 0)
+ {
+ BitReader.ReadMoreInput(br);
+ if (state.blockLength[2] == 0)
+ {
+ DecodeDistanceBlockSwitch(state);
+ }
+ state.blockLength[2]--;
+ state.distanceCode = ReadSymbol(state.hGroup2.codes, state.hGroup2.trees[
+ state.distContextMap[state.distContextMapSlice
+ + (state.copyLength > 4 ? 3 : state.copyLength - 2)] & 0xFF], br);
+ if (state.distanceCode >= state.numDirectDistanceCodes)
+ {
+ state.distanceCode -= state.numDirectDistanceCodes;
+ int postfix = state.distanceCode & state.distancePostfixMask;
+ //state.distanceCode >>>= state.distancePostfixBits;
+ state.distanceCode = (int)((uint)state.distanceCode >> state.distancePostfixBits);
+ int n = (int)((uint)state.distanceCode >> 1) + 1;
+ int offset = ((2 + (state.distanceCode & 1)) << n) - 4;
+ state.distanceCode = state.numDirectDistanceCodes + postfix
+ + ((offset + BitReader.ReadBits(br, n)) << state.distancePostfixBits);
+ }
+ }
+
+ // Convert the distance code to the actual distance by possibly looking up past distances
+ // from the ringBuffer.
+ state.distance = TranslateShortCodes(state.distanceCode, state.distRb, state.distRbIdx);
+ if (state.distance < 0)
+ {
+ throw new BrotliRuntimeException("Negative distance"); // COV_NF_LINE
+ }
+
+ if (state.pos < state.maxBackwardDistance
+ && state.maxDistance != state.maxBackwardDistance)
+ {
+ state.maxDistance = state.pos;
+ }
+ else
+ {
+ state.maxDistance = state.maxBackwardDistance;
+ }
+
+ state.copyDst = state.pos & ringBufferMask;
+ if (state.distance > state.maxDistance)
+ {
+ state.runningState = RunningStage.TRANSFORM;
+ continue;
+ }
+
+ if (state.distanceCode > 0)
+ {
+ state.distRb[state.distRbIdx & 3] = state.distance;
+ state.distRbIdx++;
+ }
+
+ if (state.copyLength > state.metaBlockLength)
+ {
+ throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE
+ }
+ state.j = 0;
+ state.runningState = RunningStage.COPY_LOOP;
+ goto case RunningStage.COPY_LOOP;
+ // fall through
+ case RunningStage.COPY_LOOP:
+ for (; state.j < state.copyLength;)
+ {
+ ringBuffer[state.pos & ringBufferMask] =
+ ringBuffer[(state.pos - state.distance) & ringBufferMask];
+ // TODO: condense
+ state.metaBlockLength--;
+ state.j++;
+ if ((state.pos++ & ringBufferMask) == ringBufferMask)
+ {
+ state.nextRunningState = RunningStage.COPY_LOOP;
+ state.bytesToWrite = state.ringBufferSize;
+ state.bytesWritten = 0;
+ state.runningState = RunningStage.WRITE;
+ break;
+ }
+ }
+ if (state.runningState == RunningStage.COPY_LOOP)
+ {
+ state.runningState = RunningStage.MAIN_LOOP;
+ }
+ continue;
+
+ case RunningStage.TRANSFORM:
+ if (state.copyLength >= Dictionary.MIN_WORD_LENGTH
+ && state.copyLength <= Dictionary.MAX_WORD_LENGTH)
+ {
+ int offset = Dictionary.OFFSETS_BY_LENGTH[state.copyLength];
+ int wordId = state.distance - state.maxDistance - 1;
+ int shift = Dictionary.SIZE_BITS_BY_LENGTH[state.copyLength];
+ int mask = (1 << shift) - 1;
+ int wordIdx = wordId & mask;
+ int transformIdx = (int)((uint)wordId >> shift);
+ offset += wordIdx * state.copyLength;
+ if (transformIdx < Transform.TRANSFORMS.Length)
+ {
+ int len = Transform.TransformDictionaryWord(ringBuffer, state.copyDst,
+ Dictionary.GetData(), offset, state.copyLength,
+ Transform.TRANSFORMS[transformIdx]);
+ state.copyDst += len;
+ state.pos += len;
+ state.metaBlockLength -= len;
+ if (state.copyDst >= state.ringBufferSize)
+ {
+ state.nextRunningState = RunningStage.COPY_WRAP_BUFFER;
+ state.bytesToWrite = state.ringBufferSize;
+ state.bytesWritten = 0;
+ state.runningState = RunningStage.WRITE;
+ continue;
+ }
+ }
+ else
+ {
+ throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE
+ }
+ }
+ else
+ {
+ throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE
+ }
+ state.runningState = RunningStage.MAIN_LOOP;
+ continue;
+
+ case RunningStage.COPY_WRAP_BUFFER:
+ Array.Copy(ringBuffer, state.ringBufferSize, ringBuffer, 0,
+ state.copyDst - state.ringBufferSize);
+ state.runningState = RunningStage.MAIN_LOOP;
+ continue;
+
+ case RunningStage.READ_METADATA:
+ while (state.metaBlockLength > 0)
+ {
+ BitReader.ReadMoreInput(br);
+ // Optimize
+ BitReader.ReadBits(br, 8);
+ state.metaBlockLength--;
+ }
+ state.runningState = RunningStage.BLOCK_START;
+ continue;
+
+
+ case RunningStage.COPY_UNCOMPRESSED:
+ CopyUncompressedData(state);
+ continue;
+
+ case RunningStage.WRITE:
+ if (!WriteRingBuffer(state))
+ {
+ // Output buffer is full.
+ return;
+ }
+ state.runningState = state.nextRunningState;
+ continue;
+
+ default:
+ throw new BrotliRuntimeException("Unexpected state " + state.runningState);
+ }
+ }
+ if (state.runningState == RunningStage.FINISHED)
+ {
+ if (state.metaBlockLength < 0)
+ {
+ throw new BrotliRuntimeException("Invalid metablock length");
+ }
+ BitReader.JumpToByteBoundry(br);
+ BitReader.CheckHealth(state.br);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/csharp/CSharpBrotli/CSharpBrotli/Decode/Dictionary.cs b/csharp/CSharpBrotli/CSharpBrotli/Decode/Dictionary.cs
new file mode 100644
index 0000000..f1617a2
--- /dev/null
+++ b/csharp/CSharpBrotli/CSharpBrotli/Decode/Dictionary.cs
@@ -0,0 +1,68 @@
+namespace CSharpBrotli.Decode
+{
+ ///
+ /// Collection of static dictionary words.
+ /// Dictionary content is loaded from binary resource when is executed for the
+ /// first time.Consequently, it saves memory and CPU in case dictionary is not required.
+ /// One possible drawback is that multiple threads that need dictionary data may be blocked (only
+ /// once in each classworld). To avoid this, it is enough to call proactively.
+ ///
+ public sealed class Dictionary
+ {
+ private static class DataHolder
+ {
+ private static byte[] _data = getData();
+ public static byte[] Data { get { return _data; } }
+
+ private static byte[] getData()
+ {
+ byte[] data = new byte[122784];
+ string[] chunks =
+ {
+ "timedownlifeleftbackcodedatashowonlysitecityopenjustlikefreeworktextyearoverbodyloveformbookplaylivelinehelphomesidemorewordlongthemviewfindpagedaysfullheadtermeachareafromtruemarkableuponhighdatelandnewsevennextcasebothpostusedmadehandherewhatnameLinkblogsizebaseheldmakemainuser') +holdendswithNewsreadweresigntakehavegameseencallpathwellplusmenufilmpartjointhislistgoodneedwayswestjobsmindalsologorichuseslastteamarmyfoodkingwilleastwardbestfirePageknowaway.pngmovethanloadgiveselfnotemuchfeedmanyrockicononcelookhidediedHomerulehostajaxinfoclublawslesshalfsomesuchzone100%onescareTimeracebluefourweekfacehopegavehardlostwhenparkkeptpassshiproomHTMLplanTypedonesavekeepflaglinksoldfivetookratetownjumpthusdarkcardfilefearstaykillthatfallautoever.comtalkshopvotedeepmoderestturnbornbandfellroseurl(skinrolecomeactsagesmeetgold.jpgitemvaryfeltthensenddropViewcopy1.0\"stopelseliestourpack.gifpastcss?graymean>rideshotlatesaidroadvar feeljohnrickportfast'UA-deadpoorbilltypeU.S.woodmust2px;Inforankwidewantwalllead[0];paulwavesure$('#waitmassarmsgoesgainlangpaid!-- lockunitrootwalkfirmwifexml\"songtest20pxkindrowstoolfontmailsafestarmapscorerainflowbabyspansays4px;6px;artsfootrealwikiheatsteptriporg/lakeweaktoldFormcastfansbankveryrunsjulytask1px;goalgrewslowedgeid=\"sets5px;.js?40pxif (soonseatnonetubezerosentreedfactintogiftharm18pxcamehillboldzoomvoideasyringfillpeakinitcost3px;jacktagsbitsrolleditknewnearironfreddiskwentsoilputs/js/holyT22:ISBNT20:adamseesjson', 'contT21: RSSloopasiamoon
soulLINEfortcartT14:80px!--<9px;T04:mike:46ZniceinchYorkricezh:\u00E4'));puremageparatonebond:37Z_of_']);000,zh:\u00E7tankyardbowlbush:56ZJava30px\n|}\n%C3%:34ZjeffEXPIcashvisagolfsnowzh:\u00E9quer.csssickmeatmin.binddellhirepicsrent:36ZHTTP-201fotowolfEND xbox:54ZBODYdick;\n}\nexit:35Zvarsbeat'});diet999;anne}}[i].Langkm\u00C2\u00B2wiretoysaddssealalex;\n\t}echonine.org005)tonyjewssandlegsroof000) 200winegeardogsbootgarycutstyletemption.xmlcockgang$('.50pxPh.Dmiscalanloandeskmileryanunixdisc);}\ndustclip).\n\n70px-200DVDs7]>sonyguysfuckpipe|-\n!002)ndow[1];[];\nLog salt\r\n\t\tbangtrimbath){\r\n00px\n});ko:\u00ECfeesad>\rs:// [];tollplug(){\n{\r\n .js'200pdualboat.JPG);\n}quot);\n\n');\n\r\n}\r201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037201320122011201020092008200720062005200420032002200120001999199819971996199519941993199219911990198919881987198619851984198319821981198019791978197719761975197419731972197119701969196819671966196519641963196219611960195919581957195619551954195319521951195010001024139400009999comom\u00C3\u00A1sesteestaperotodohacecadaa\u00C3\u00B1obiend\u00C3\u00ADaas\u00C3\u00ADvidacasootroforosolootracualdijosidograntipotemadebealgoqu\u00C3\u00A9estonadatrespococasabajotodasinoaguapuesunosantediceluisellamayozonaamorpisoobraclicellodioshoracasi\u00D0\u00B7\u00D0\u00B0\u00D0\u00BD\u00D0\u00B0\u00D0\u00BE\u00D0\u00BC\u00D1\u0080\u00D0\u00B0\u00D1\u0080\u00D1\u0083\u00D1\u0082\u00D0\u00B0\u00D0\u00BD\u00D0\u00B5\u00D0\u00BF\u00D0\u00BE\u00D0\u00BE\u00D1\u0082\u00D0\u00B8\u00D0\u00B7\u00D0\u00BD\u00D0\u00BE\u00D0\u00B4\u00D0\u00BE\u00D1\u0082\u00D0\u00BE\u00D0\u00B6\u00D0\u00B5\u00D0\u00BE\u00D0\u00BD\u00D0\u00B8\u00D1\u0085\u00D0\u009D\u00D0\u00B0\u00D0\u00B5\u00D0\u00B5\u00D0\u00B1\u00D1\u008B\u00D0\u00BC\u00D1\u008B\u00D0\u0092\u00D1\u008B\u00D1\u0081\u00D0\u00BE\u00D0\u00B2\u00D1\u008B\u00D0\u00B2\u00D0\u00BE\u00D0\u009D\u00D0\u00BE\u00D0\u00BE\u00D0\u00B1\u00D0\u009F\u00D0\u00BE\u00D0\u00BB\u00D0\u00B8\u00D0\u00BD\u00D0\u00B8\u00D0\u00A0\u00D0\u00A4\u00D0\u009D\u00D0\u00B5\u00D0\u009C\u00D1\u008B\u00D1\u0082\u00D1\u008B\u00D0\u009E\u00D0\u00BD\u00D0\u00B8\u00D0\u00BC\u00D0\u00B4\u00D0\u00B0\u00D0\u0097\u00D0\u00B0\u00D0\u0094\u00D0\u00B0\u00D0\u009D\u00D1\u0083\u00D0\u009E\u00D0\u00B1\u00D1\u0082\u00D0\u00B5\u00D0\u0098\u00D0\u00B7\u00D0\u00B5\u00D0\u00B9\u00D0\u00BD\u00D1\u0083\u00D0\u00BC\u00D0\u00BC\u00D0\u00A2\u00D1\u008B\u00D1\u0083\u00D0\u00B6\u00D9\u0081\u00D9\u008A\u00D8\u00A3\u00D9\u0086\u00D9\u0085\u00D8\u00A7\u00D9\u0085\u00D8\u00B9\u00D9\u0083\u00D9\u0084\u00D8\u00A3\u00D9\u0088\u00D8\u00B1\u00D8\u00AF\u00D9\u008A\u00D8\u00A7\u00D9\u0081\u00D9\u0089\u00D9\u0087\u00D9\u0088\u00D9\u0084\u00D9\u0085\u00D9\u0084\u00D9\u0083\u00D8\u00A7\u00D9\u0088\u00D9\u0084\u00D9\u0087\u00D8\u00A8\u00D8\u00B3\u00D8\u00A7\u00D9\u0084\u00D8\u00A5\u00D9\u0086\u00D9\u0087\u00D9\u008A\u00D8\u00A3\u00D9\u008A\u00D9\u0082\u00D8\u00AF\u00D9\u0087\u00D9\u0084\u00D8\u00AB\u00D9\u0085\u00D8\u00A8\u00D9\u0087\u00D9\u0084\u00D9\u0088\u00D9\u0084\u00D9\u008A\u00D8\u00A8\u00D9\u0084\u00D8\u00A7\u00D9\u008A\u00D8\u00A8\u00D9\u0083\u00D8\u00B4\u00D9\u008A\u00D8\u00A7\u00D9\u0085\u00D8\u00A3\u00D9\u0085\u00D9\u0086\u00D8\u00AA\u00D8\u00A8\u00D9\u008A\u00D9\u0084\u00D9\u0086\u00D8\u00AD\u00D8\u00A8\u00D9\u0087\u00D9\u0085\u00D9\u0085\u00D8\u00B4\u00D9\u0088\u00D8\u00B4firstvideolightworldmediawhitecloseblackrightsmallbooksplacemusicfieldorderpointvalueleveltableboardhousegroupworksyearsstatetodaywaterstartstyledeathpowerphonenighterrorinputabouttermstitletoolseventlocaltimeslargewordsgamesshortspacefocusclearmodelblockguideradiosharewomenagainmoneyimagenamesyounglineslatercolorgreenfront&watchforcepricerulesbeginaftervisitissueareasbelowindextotalhourslabelprintpressbuiltlinksspeedstudytradefoundsenseundershownformsrangeaddedstillmovedtakenaboveflashfixedoftenotherviewschecklegalriveritemsquickshapehumanexistgoingmoviethirdbasicpeacestagewidthloginideaswrotepagesusersdrivestorebreaksouthvoicesitesmonthwherebuildwhichearthforumthreesportpartyClicklowerlivesclasslayerentrystoryusagesoundcourtyour birthpopuptypesapplyImagebeinguppernoteseveryshowsmeansextramatchtrackknownearlybegansuperpapernorthlearngivennamedendedTermspartsGroupbrandusingwomanfalsereadyaudiotakeswhile.com/livedcasesdailychildgreatjudgethoseunitsneverbroadcoastcoverapplefilescyclesceneplansclickwritequeenpieceemailframeolderphotolimitcachecivilscaleenterthemetheretouchboundroyalaskedwholesincestock namefaithheartemptyofferscopeownedmightalbumthinkbloodarraymajortrustcanonunioncountvalidstoneStyleLoginhappyoccurleft:freshquitefilmsgradeneedsurbanfightbasishoverauto;route.htmlmixedfinalYour slidetopicbrownalonedrawnsplitreachRightdatesmarchquotegoodsLinksdoubtasyncthumballowchiefyouthnovel10px;serveuntilhandsCheckSpacequeryjamesequaltwice0,000Startpanelsongsroundeightshiftworthpostsleadsweeksavoidthesemilesplanesmartalphaplantmarksratesplaysclaimsalestextsstarswrongthing.org/multiheardPowerstandtokensolid(thisbringshipsstafftriedcallsfullyfactsagentThis //-->adminegyptEvent15px;Emailtrue\"crossspentblogsbox\">notedleavechinasizesguestrobotheavytrue,sevengrandcrimesignsawaredancephase>\n\n\r\nname=diegopage swiss-->\n\n#fff;\">Log.com\"treatsheet) && 14px;sleepntentfiledja:\u00E3\u0083id=\"cName\"worseshots-box-delta\n<bears:48Z spendbakershops= \"\";php\">ction13px;brianhellosize=o=%2F joinmaybe , fjsimg\" \")[0]MTopBType\"newlyDanskczechtrailknowsfaq\">zh-cn10);\n-1\");type=bluestrulydavis.js';>\r\n\r\nform jesus100% menu.\r\n\t\r\nwalesrisksumentddingb-likteachgif\" vegasdanskeestishqipsuomisobredesdeentretodospuedea\u00C3\u00B1osest\u00C3\u00A1tienehastaotrospartedondenuevohacerformamismomejormundoaqu\u00C3\u00ADd\u00C3\u00ADass\u00C3\u00B3loayudafechatodastantomenosdatosotrassitiomuchoahoralugarmayorestoshorastenerantesfotosestaspa\u00C3\u00ADsnuevasaludforosmedioquienmesespoderchileser\u00C3\u00A1vecesdecirjos\u00C3\u00A9estarventagrupohechoellostengoamigocosasnivelgentemismaairesjuliotemashaciafavorjuniolibrepuntobuenoautorabrilbuenatextomarzosaberlistaluegoc\u00C3\u00B3moenerojuegoper\u00C3\u00BAhaberestoynuncamujervalorfueralibrogustaigualvotoscasosgu\u00C3\u00ADapuedosomosavisousteddebennochebuscafaltaeurosseriedichocursoclavecasasle\u00C3\u00B3nplazolargoobrasvistaapoyojuntotratavistocrearcampohemoscincocargopisosordenhacen\u00C3\u00A1readiscopedrocercapuedapapelmenor\u00C3\u00BAtilclarojorgecalleponertardenadiemarcasigueellassiglocochemotosmadreclaserestoni\u00C3\u00B1oquedapasarbancohijosviajepablo\u00C3\u00A9stevienereinodejarfondocanalnorteletracausatomarmanoslunesautosvillavendopesartipostengamarcollevapadreunidovamoszonasambosbandamariaabusomuchasubirriojavivirgradochicaall\u00C3\u00ADjovendichaestantalessalirsuelopesosfinesllamabusco\u00C3\u00A9stalleganegroplazahumorpagarjuntadobleislasbolsaba\u00C3\u00B1ohablalucha\u00C3\u0081readicenjugarnotasvalleall\u00C3\u00A1cargadolorabajoest\u00C3\u00A9gustomentemariofirmacostofichaplatahogarartesleyesaquelmuseobasespocosmitadcielochicomiedoganarsantoetapadebesplayaredessietecortecoreadudasdeseoviejodeseaaguas"domaincommonstatuseventsmastersystemactionbannerremovescrollupdateglobalmediumfilternumberchangeresultpublicscreenchoosenormaltravelissuessourcetargetspringmodulemobileswitchphotosborderregionitselfsocialactivecolumnrecordfollowtitle>eitherlengthfamilyfriendlayoutauthorcreatereviewsummerserverplayedplayerexpandpolicyformatdoublepointsseriespersonlivingdesignmonthsforcesuniqueweightpeopleenergynaturesearchfigurehavingcustomoffsetletterwindowsubmitrendergroupsuploadhealthmethodvideosschoolfutureshadowdebatevaluesObjectothersrightsleaguechromesimplenoticesharedendingseasonreportonlinesquarebuttonimagesenablemovinglatestwinterFranceperiodstrongrepeatLondondetailformeddemandsecurepassedtoggleplacesdevicestaticcitiesstreamyellowattackstreetflighthiddeninfo\">openedusefulvalleycausesleadersecretseconddamagesportsexceptratingsignedthingseffectfieldsstatesofficevisualeditorvolumeReportmuseummoviesparentaccessmostlymother\" id=\"marketgroundchancesurveybeforesymbolmomentspeechmotioninsidematterCenterobjectexistsmiddleEuropegrowthlegacymannerenoughcareeransweroriginportalclientselectrandomclosedtopicscomingfatheroptionsimplyraisedescapechosenchurchdefinereasoncorneroutputmemoryiframepolicemodelsNumberduringoffersstyleskilledlistedcalledsilvermargindeletebetterbrowselimitsGlobalsinglewidgetcenterbudgetnowrapcreditclaimsenginesafetychoicespirit-stylespreadmakingneededrussiapleaseextentScriptbrokenallowschargedividefactormember-basedtheoryconfigaroundworkedhelpedChurchimpactshouldalwayslogo\" bottomlist\">){var prefixorangeHeader.push(couplegardenbridgelaunchReviewtakingvisionlittledatingButtonbeautythemesforgotSearchanchoralmostloadedChangereturnstringreloadMobileincomesupplySourceordersviewed courseAbout island: The dialoghousesBEGIN MexicostartscentreheightaddingIslandassetsEmpireSchooleffortdirectnearlymanualSelect.\n\nOnejoinedmenu\">PhilipawardshandleimportOfficeregardskillsnationSportsdegreeweekly (e.g.behinddoctorloggedunitedbeyond-scaleacceptservedmarineFootercamera \n_form\"leavesstress\" />\r\n.gif\" onloadloaderOxfordsistersurvivlistenfemaleDesignsize=\"appealtext\">levelsthankshigherforcedanimalanyoneAfricaagreedrecentPeople wonderpricesturned|| {};main\">inlinesundaywrap\">failedcensusminutebeaconquotes150px|estateremoteemail\"linkedright;signalformal1.htmlsignupprincefloat:.png\" forum.AccesspaperssoundsextendHeightsliderUTF-8\"& Before. WithstudioownersmanageprofitjQueryannualparamsboughtfamousgooglelongeri++) {israelsayingdecidehome\">headerensurebranchpiecesblock;statedtop\">boston.test(avatartested_countforumsschemaindex,filledsharesreaderalert(appearSubmitline\">body\">\n* TheThoughseeingjerseyNews\nSystem DavidcancertablesprovedApril reallydriveritem\">more\">boardscolorscampusfirst || [];media.guitarfinishwidth:showedOther .php\" assumelayerswilsonstoresreliefswedenCustomeasily your String\n\nWhiltaylorclear:resortfrenchthough\") + \"buyingbrandsMembername\">oppingsector5px;\">vspacepostermajor coffeemartinmaturehappenkansaslink\">Images=falsewhile hspace0& \n\nIn powerPolski-colorjordanBottomStart -count2.htmlnews\">01.jpgOnline-rightmillerseniorISBN 00,000 guidesvalue)ectionrepair.xml\" rights.html-blockregExp:hoverwithinvirginphones\rusing \n\tvar >');\n\t\n\nbahasabrasilgalegomagyarpolskisrpski\u00D8\u00B1\u00D8\u00AF\u00D9\u0088\u00E4\u00B8\u00AD\u00E6\u0096\u0087\u00E7\u00AE\u0080\u00E4\u00BD\u0093\u00E7\u00B9\u0081\u00E9\u00AB\u0094\u00E4\u00BF\u00A1\u00E6\u0081\u00AF\u00E4\u00B8\u00AD\u00E5\u009B\u00BD\u00E6\u0088\u0091\u00E4\u00BB\u00AC\u00E4\u00B8\u0080\u00E4\u00B8\u00AA\u00E5\u0085\u00AC\u00E5\u008F\u00B8\u00E7\u00AE\u00A1\u00E7\u0090\u0086\u00E8\u00AE\u00BA\u00E5\u009D\u009B\u00E5\u008F\u00AF\u00E4\u00BB\u00A5\u00E6\u009C\u008D\u00E5\u008A\u00A1\u00E6\u0097\u00B6\u00E9\u0097\u00B4\u00E4\u00B8\u00AA\u00E4\u00BA\u00BA\u00E4\u00BA\u00A7\u00E5\u0093\u0081\u00E8\u0087\u00AA\u00E5\u00B7\u00B1\u00E4\u00BC\u0081\u00E4\u00B8\u009A\u00E6\u009F\u00A5\u00E7\u009C\u008B\u00E5\u00B7\u00A5\u00E4\u00BD\u009C\u00E8\u0081\u0094\u00E7\u00B3\u00BB\u00E6\u00B2\u00A1\u00E6\u009C\u0089\u00E7\u00BD\u0091\u00E7\u00AB\u0099\u00E6\u0089\u0080\u00E6\u009C\u0089\u00E8\u00AF\u0084\u00E8\u00AE\u00BA\u00E4\u00B8\u00AD\u00E5\u00BF\u0083\u00E6\u0096\u0087\u00E7\u00AB\u00A0\u00E7\u0094\u00A8\u00E6\u0088\u00B7\u00E9\u00A6\u0096\u00E9\u00A1\u00B5\u00E4\u00BD\u009C\u00E8\u0080\u0085\u00E6\u008A\u0080\u00E6\u009C\u00AF\u00E9\u0097\u00AE\u00E9\u00A2\u0098\u00E7\u009B\u00B8\u00E5\u0085\u00B3\u00E4\u00B8\u008B\u00E8\u00BD\u00BD\u00E6\u0090\u009C\u00E7\u00B4\u00A2\u00E4\u00BD\u00BF\u00E7\u0094\u00A8\u00E8\u00BD\u00AF\u00E4\u00BB\u00B6\u00E5\u009C\u00A8\u00E7\u00BA\u00BF\u00E4\u00B8\u00BB\u00E9\u00A2\u0098\u00E8\u00B5\u0084\u00E6\u0096\u0099\u00E8\u00A7\u0086\u00E9\u00A2\u0091\u00E5\u009B\u009E\u00E5\u00A4\u008D\u00E6\u00B3\u00A8\u00E5\u0086\u008C\u00E7\u00BD\u0091\u00E7\u00BB\u009C\u00E6\u0094\u00B6\u00E8\u0097\u008F\u00E5\u0086\u0085\u00E5\u00AE\u00B9\u00E6\u008E\u00A8\u00E8\u008D\u0090\u00E5\u00B8\u0082\u00E5\u009C\u00BA\u00E6\u00B6\u0088\u00E6\u0081\u00AF\u00E7\u00A9\u00BA\u00E9\u0097\u00B4\u00E5\u008F\u0091\u00E5\u00B8\u0083\u00E4\u00BB\u0080\u00E4\u00B9\u0088\u00E5\u00A5\u00BD\u00E5\u008F\u008B\u00E7\u0094\u009F\u00E6\u00B4\u00BB\u00E5\u009B\u00BE\u00E7\u0089\u0087\u00E5\u008F\u0091\u00E5\u00B1\u0095\u00E5\u00A6\u0082\u00E6\u009E\u009C\u00E6\u0089\u008B\u00E6\u009C\u00BA\u00E6\u0096\u00B0\u00E9\u0097\u00BB\u00E6\u009C\u0080\u00E6\u0096\u00B0\u00E6\u0096\u00B9\u00E5\u00BC\u008F\u00E5\u008C\u0097\u00E4\u00BA\u00AC\u00E6\u008F\u0090\u00E4\u00BE\u009B\u00E5\u0085\u00B3\u00E4\u00BA\u008E\u00E6\u009B\u00B4\u00E5\u00A4\u009A\u00E8\u00BF\u0099\u00E4\u00B8\u00AA\u00E7\u00B3\u00BB\u00E7\u00BB\u009F\u00E7\u009F\u00A5\u00E9\u0081\u0093\u00E6\u00B8\u00B8\u00E6\u0088\u008F\u00E5\u00B9\u00BF\u00E5\u0091\u008A\u00E5\u0085\u00B6\u00E4\u00BB\u0096\u00E5\u008F\u0091\u00E8\u00A1\u00A8\u00E5\u00AE\u0089\u00E5\u0085\u00A8\u00E7\u00AC\u00AC\u00E4\u00B8\u0080\u00E4\u00BC\u009A\u00E5\u0091\u0098\u00E8\u00BF\u009B\u00E8\u00A1\u008C\u00E7\u0082\u00B9\u00E5\u0087\u00BB\u00E7\u0089\u0088\u00E6\u009D\u0083\u00E7\u0094\u00B5\u00E5\u00AD\u0090\u00E4\u00B8\u0096\u00E7\u0095\u008C\u00E8\u00AE\u00BE\u00E8\u00AE\u00A1\u00E5\u0085\u008D\u00E8\u00B4\u00B9\u00E6\u0095\u0099\u00E8\u0082\u00B2\u00E5\u008A\u00A0\u00E5\u0085\u00A5\u00E6\u00B4\u00BB\u00E5\u008A\u00A8\u00E4\u00BB\u0096\u00E4\u00BB\u00AC\u00E5\u0095\u0086\u00E5\u0093\u0081\u00E5\u008D\u009A\u00E5\u00AE\u00A2\u00E7\u008E\u00B0\u00E5\u009C\u00A8\u00E4\u00B8\u008A\u00E6\u00B5\u00B7\u00E5\u00A6\u0082\u00E4\u00BD\u0095\u00E5\u00B7\u00B2\u00E7\u00BB\u008F\u00E7\u0095\u0099\u00E8\u00A8\u0080\u00E8\u00AF\u00A6\u00E7\u00BB\u0086\u00E7\u00A4\u00BE\u00E5\u008C\u00BA\u00E7\u0099\u00BB\u00E5\u00BD\u0095\u00E6\u009C\u00AC\u00E7\u00AB\u0099\u00E9\u009C\u0080\u00E8\u00A6\u0081\u00E4\u00BB\u00B7\u00E6\u00A0\u00BC\u00E6\u0094\u00AF\u00E6\u008C\u0081\u00E5\u009B\u00BD\u00E9\u0099\u0085\u00E9\u0093\u00BE\u00E6\u008E\u00A5\u00E5\u009B\u00BD\u00E5\u00AE\u00B6\u00E5\u00BB\u00BA\u00E8\u00AE\u00BE\u00E6\u009C\u008B\u00E5\u008F\u008B\u00E9\u0098\u0085\u00E8\u00AF\u00BB\u00E6\u00B3\u0095\u00E5\u00BE\u008B\u00E4\u00BD\u008D\u00E7\u00BD\u00AE\u00E7\u00BB\u008F\u00E6\u00B5\u008E\u00E9\u0080\u0089\u00E6\u008B\u00A9\u00E8\u00BF\u0099\u00E6\u00A0\u00B7\u00E5\u00BD\u0093\u00E5\u0089\u008D\u00E5\u0088\u0086\u00E7\u00B1\u00BB\u00E6\u008E\u0092\u00E8\u00A1\u008C\u00E5\u009B\u00A0\u00E4\u00B8\u00BA\u00E4\u00BA\u00A4\u00E6\u0098\u0093\u00E6\u009C\u0080\u00E5\u0090\u008E\u00E9\u009F\u00B3\u00E4\u00B9\u0090\u00E4\u00B8\u008D\u00E8\u0083\u00BD\u00E9\u0080\u009A\u00E8\u00BF\u0087\u00E8\u00A1\u008C\u00E4\u00B8\u009A\u00E7\u00A7\u0091\u00E6\u008A\u0080\u00E5\u008F\u00AF\u00E8\u0083\u00BD\u00E8\u00AE\u00BE\u00E5\u00A4\u0087\u00E5\u0090\u0088\u00E4\u00BD\u009C\u00E5\u00A4\u00A7\u00E5\u00AE\u00B6\u00E7\u00A4\u00BE\u00E4\u00BC\u009A\u00E7\u00A0\u0094\u00E7\u00A9\u00B6\u00E4\u00B8\u0093\u00E4\u00B8\u009A\u00E5\u0085\u00A8\u00E9\u0083\u00A8\u00E9\u00A1\u00B9\u00E7\u009B\u00AE\u00E8\u00BF\u0099\u00E9\u0087\u008C\u00E8\u00BF\u0098\u00E6\u0098\u00AF\u00E5\u00BC\u0080\u00E5\u00A7\u008B\u00E6\u0083\u0085\u00E5\u0086\u00B5\u00E7\u0094\u00B5\u00E8\u0084\u0091\u00E6\u0096\u0087\u00E4\u00BB\u00B6\u00E5\u0093\u0081\u00E7\u0089\u008C\u00E5\u00B8\u00AE\u00E5\u008A\u00A9\u00E6\u0096\u0087\u00E5\u008C\u0096\u00E8\u00B5\u0084\u00E6\u00BA\u0090\u00E5\u00A4\u00A7\u00E5\u00AD\u00A6\u00E5\u00AD\u00A6\u00E4\u00B9\u00A0\u00E5\u009C\u00B0\u00E5\u009D\u0080\u00E6\u00B5\u008F\u00E8\u00A7\u0088\u00E6\u008A\u0095\u00E8\u00B5\u0084\u00E5\u00B7\u00A5\u00E7\u00A8\u008B\u00E8\u00A6\u0081\u00E6\u00B1\u0082\u00E6\u0080\u008E\u00E4\u00B9\u0088\u00E6\u0097\u00B6\u00E5\u0080\u0099\u00E5\u008A\u009F\u00E8\u0083\u00BD\u00E4\u00B8\u00BB\u00E8\u00A6\u0081\u00E7\u009B\u00AE\u00E5\u0089\u008D\u00E8\u00B5\u0084\u00E8\u00AE\u00AF\u00E5\u009F\u008E\u00E5\u00B8\u0082\u00E6\u0096\u00B9\u00E6\u00B3\u0095\u00E7\u0094\u00B5\u00E5\u00BD\u00B1\u00E6\u008B\u009B\u00E8\u0081\u0098\u00E5\u00A3\u00B0\u00E6\u0098\u008E\u00E4\u00BB\u00BB\u00E4\u00BD\u0095\u00E5\u0081\u00A5\u00E5\u00BA\u00B7\u00E6\u0095\u00B0\u00E6\u008D\u00AE\u00E7\u00BE\u008E\u00E5\u009B\u00BD\u00E6\u00B1\u00BD\u00E8\u00BD\u00A6\u00E4\u00BB\u008B\u00E7\u00BB\u008D\u00E4\u00BD\u0086\u00E6\u0098\u00AF\u00E4\u00BA\u00A4\u00E6\u00B5\u0081\u00E7\u0094\u009F\u00E4\u00BA\u00A7\u00E6\u0089\u0080\u00E4\u00BB\u00A5\u00E7\u0094\u00B5\u00E8\u00AF\u009D\u00E6\u0098\u00BE\u00E7\u00A4\u00BA\u00E4\u00B8\u0080\u00E4\u00BA\u009B\u00E5\u008D\u0095\u00E4\u00BD\u008D\u00E4\u00BA\u00BA\u00E5\u0091\u0098\u00E5\u0088\u0086\u00E6\u009E\u0090\u00E5\u009C\u00B0\u00E5\u009B\u00BE\u00E6\u0097\u0085\u00E6\u00B8\u00B8\u00E5\u00B7\u00A5\u00E5\u0085\u00B7\u00E5\u00AD\u00A6\u00E7\u0094\u009F\u00E7\u00B3\u00BB\u00E5\u0088\u0097\u00E7\u00BD\u0091\u00E5\u008F\u008B\u00E5\u00B8\u0096\u00E5\u00AD\u0090\u00E5\u00AF\u0086\u00E7\u00A0\u0081\u00E9\u00A2\u0091\u00E9\u0081\u0093\u00E6\u008E\u00A7\u00E5\u0088\u00B6\u00E5\u009C\u00B0\u00E5\u008C\u00BA\u00E5\u009F\u00BA\u00E6\u009C\u00AC\u00E5\u0085\u00A8\u00E5\u009B\u00BD\u00E7\u00BD\u0091\u00E4\u00B8\u008A\u00E9\u0087\u008D\u00E8\u00A6\u0081\u00E7\u00AC\u00AC\u00E4\u00BA\u008C\u00E5\u0096\u009C\u00E6\u00AC\u00A2\u00E8\u00BF\u009B\u00E5\u0085\u00A5\u00E5\u008F\u008B\u00E6\u0083\u0085\u00E8\u00BF\u0099\u00E4\u00BA\u009B\u00E8\u0080\u0083\u00E8\u00AF\u0095\u00E5\u008F\u0091\u00E7\u008E\u00B0\u00E5\u009F\u00B9\u00E8\u00AE\u00AD\u00E4\u00BB\u00A5\u00E4\u00B8\u008A\u00E6\u0094\u00BF\u00E5\u00BA\u009C\u00E6\u0088\u0090\u00E4\u00B8\u00BA\u00E7\u008E\u00AF\u00E5\u00A2\u0083\u00E9\u00A6\u0099\u00E6\u00B8\u00AF\u00E5\u0090\u008C\u00E6\u0097\u00B6\u00E5\u00A8\u00B1\u00E4\u00B9\u0090\u00E5\u008F\u0091\u00E9\u0080\u0081\u00E4\u00B8\u0080\u00E5\u00AE\u009A\u00E5\u00BC\u0080\u00E5\u008F\u0091\u00E4\u00BD\u009C\u00E5\u0093\u0081\u00E6\u00A0\u0087\u00E5\u0087\u0086\u00E6\u00AC\u00A2\u00E8\u00BF\u008E\u00E8\u00A7\u00A3\u00E5\u0086\u00B3\u00E5\u009C\u00B0\u00E6\u0096\u00B9\u00E4\u00B8\u0080\u00E4\u00B8\u008B\u00E4\u00BB\u00A5\u00E5\u008F\u008A\u00E8\u00B4\u00A3\u00E4\u00BB\u00BB\u00E6\u0088\u0096\u00E8\u0080\u0085\u00E5\u00AE\u00A2\u00E6\u0088\u00B7\u00E4\u00BB\u00A3\u00E8\u00A1\u00A8\u00E7\u00A7\u00AF\u00E5\u0088\u0086\u00E5\u00A5\u00B3\u00E4\u00BA\u00BA\u00E6\u0095\u00B0\u00E7\u00A0\u0081\u00E9\u0094\u0080\u00E5\u0094\u00AE\u00E5\u0087\u00BA\u00E7\u008E\u00B0\u00E7\u00A6\u00BB\u00E7\u00BA\u00BF\u00E5\u00BA\u0094\u00E7\u0094\u00A8\u00E5\u0088\u0097\u00E8\u00A1\u00A8\u00E4\u00B8\u008D\u00E5\u0090\u008C\u00E7\u00BC\u0096\u00E8\u00BE\u0091\u00E7\u00BB\u009F\u00E8\u00AE\u00A1\u00E6\u009F\u00A5\u00E8\u00AF\u00A2\u00E4\u00B8\u008D\u00E8\u00A6\u0081\u00E6\u009C\u0089\u00E5\u0085\u00B3\u00E6\u009C\u00BA\u00E6\u009E\u0084\u00E5\u00BE\u0088\u00E5\u00A4\u009A\u00E6\u0092\u00AD\u00E6\u0094\u00BE\u00E7\u00BB\u0084\u00E7\u00BB\u0087\u00E6\u0094\u00BF\u00E7\u00AD\u0096\u00E7\u009B\u00B4\u00E6\u008E\u00A5\u00E8\u0083\u00BD\u00E5\u008A\u009B\u00E6\u009D\u00A5\u00E6\u00BA\u0090\u00E6\u0099\u0082\u00E9\u0096\u0093\u00E7\u009C\u008B\u00E5\u0088\u00B0\u00E7\u0083\u00AD\u00E9\u0097\u00A8\u00E5\u0085\u00B3\u00E9\u0094\u00AE\u00E4\u00B8\u0093\u00E5\u008C\u00BA\u00E9\u009D\u009E\u00E5\u00B8\u00B8\u00E8\u008B\u00B1\u00E8\u00AF\u00AD\u00E7\u0099\u00BE\u00E5\u00BA\u00A6\u00E5\u00B8\u008C\u00E6\u009C\u009B\u00E7\u00BE\u008E\u00E5\u00A5\u00B3\u00E6\u00AF\u0094\u00E8\u00BE\u0083\u00E7\u009F\u00A5\u00E8\u00AF\u0086\u00E8\u00A7\u0084\u00E5\u00AE\u009A\u00E5\u00BB\u00BA\u00E8\u00AE\u00AE\u00E9\u0083\u00A8\u00E9\u0097\u00A8\u00E6\u0084\u008F\u00E8\u00A7\u0081\u00E7\u00B2\u00BE\u00E5\u00BD\u00A9\u00E6\u0097\u00A5\u00E6\u009C\u00AC\u00E6\u008F\u0090\u00E9\u00AB\u0098\u00E5\u008F\u0091\u00E8\u00A8\u0080\u00E6\u0096\u00B9\u00E9\u009D\u00A2\u00E5\u009F\u00BA\u00E9\u0087\u0091\u00E5\u00A4\u0084\u00E7\u0090\u0086\u00E6\u009D\u0083\u00E9\u0099\u0090\u00E5\u00BD\u00B1\u00E7\u0089\u0087\u00E9\u0093\u00B6\u00E8\u00A1\u008C\u00E8\u00BF\u0098\u00E6\u009C\u0089\u00E5\u0088\u0086\u00E4\u00BA\u00AB\u00E7\u0089\u00A9\u00E5\u0093\u0081\u00E7\u00BB\u008F\u00E8\u0090\u00A5\u00E6\u00B7\u00BB\u00E5\u008A\u00A0\u00E4\u00B8\u0093\u00E5\u00AE\u00B6\u00E8\u00BF\u0099\u00E7\u00A7\u008D\u00E8\u00AF\u009D\u00E9\u00A2\u0098\u00E8\u00B5\u00B7\u00E6\u009D\u00A5\u00E4\u00B8\u009A\u00E5\u008A\u00A1\u00E5\u0085\u00AC\u00E5\u0091\u008A\u00E8\u00AE\u00B0\u00E5\u00BD\u0095\u00E7\u00AE\u0080\u00E4\u00BB\u008B\u00E8\u00B4\u00A8\u00E9\u0087\u008F\u00E7\u0094\u00B7\u00E4\u00BA\u00BA\u00E5\u00BD\u00B1\u00E5\u0093\u008D\u00E5\u00BC\u0095\u00E7\u0094\u00A8\u00E6\u008A\u00A5\u00E5\u0091\u008A\u00E9\u0083\u00A8\u00E5\u0088\u0086\u00E5\u00BF\u00AB\u00E9\u0080\u009F\u00E5\u0092\u00A8\u00E8\u00AF\u00A2\u00E6\u0097\u00B6\u00E5\u00B0\u009A\u00E6\u00B3\u00A8\u00E6\u0084\u008F\u00E7\u0094\u00B3\u00E8\u00AF\u00B7\u00E5\u00AD\u00A6\u00E6\u00A0\u00A1\u00E5\u00BA\u0094\u00E8\u00AF\u00A5\u00E5\u008E\u0086\u00E5\u008F\u00B2\u00E5\u008F\u00AA\u00E6\u0098\u00AF\u00E8\u00BF\u0094\u00E5\u009B\u009E\u00E8\u00B4\u00AD\u00E4\u00B9\u00B0\u00E5\u0090\u008D\u00E7\u00A7\u00B0\u00E4\u00B8\u00BA\u00E4\u00BA\u0086\u00E6\u0088\u0090\u00E5\u008A\u009F\u00E8\u00AF\u00B4\u00E6\u0098\u008E\u00E4\u00BE\u009B\u00E5\u00BA\u0094\u00E5\u00AD\u00A9\u00E5\u00AD\u0090\u00E4\u00B8\u0093\u00E9\u00A2\u0098\u00E7\u00A8\u008B\u00E5\u00BA\u008F\u00E4\u00B8\u0080\u00E8\u0088\u00AC\u00E6\u009C\u0083\u00E5\u0093\u00A1\u00E5\u008F\u00AA\u00E6\u009C\u0089\u00E5\u0085\u00B6\u00E5\u00AE\u0083\u00E4\u00BF\u009D\u00E6\u008A\u00A4\u00E8\u0080\u008C\u00E4\u00B8\u0094\u00E4\u00BB\u008A\u00E5\u00A4\u00A9\u00E7\u00AA\u0097\u00E5\u008F\u00A3\u00E5\u008A\u00A8\u00E6\u0080\u0081\u00E7\u008A\u00B6\u00E6\u0080\u0081\u00E7\u0089\u00B9\u00E5\u0088\u00AB\u00E8\u00AE\u00A4\u00E4\u00B8\u00BA\u00E5\u00BF\u0085\u00E9\u00A1\u00BB\u00E6\u009B\u00B4\u00E6\u0096\u00B0\u00E5\u00B0\u008F\u00E8\u00AF\u00B4\u00E6\u0088\u0091\u00E5\u0080\u0091\u00E4\u00BD\u009C\u00E4\u00B8\u00BA\u00E5\u00AA\u0092\u00E4\u00BD\u0093\u00E5\u008C\u0085\u00E6\u008B\u00AC\u00E9\u0082\u00A3\u00E4\u00B9\u0088\u00E4\u00B8\u0080\u00E6\u00A0\u00B7\u00E5\u009B\u00BD\u00E5\u0086\u0085\u00E6\u0098\u00AF\u00E5\u0090\u00A6\u00E6\u00A0\u00B9\u00E6\u008D\u00AE\u00E7\u0094\u00B5\u00E8\u00A7\u0086\u00E5\u00AD\u00A6\u00E9\u0099\u00A2\u00E5\u0085\u00B7\u00E6\u009C\u0089\u00E8\u00BF\u0087\u00E7\u00A8\u008B\u00E7\u0094\u00B1\u00E4\u00BA\u008E\u00E4\u00BA\u00BA\u00E6\u0089\u008D\u00E5\u0087\u00BA\u00E6\u009D\u00A5\u00E4\u00B8\u008D\u00E8\u00BF\u0087\u00E6\u00AD\u00A3\u00E5\u009C\u00A8\u00E6\u0098\u008E\u00E6\u0098\u009F\u00E6\u0095\u0085\u00E4\u00BA\u008B\u00E5\u0085\u00B3\u00E7\u00B3\u00BB\u00E6\u00A0\u0087\u00E9\u00A2\u0098\u00E5\u0095\u0086\u00E5\u008A\u00A1\u00E8\u00BE\u0093\u00E5\u0085\u00A5\u00E4\u00B8\u0080\u00E7\u009B\u00B4\u00E5\u009F\u00BA\u00E7\u00A1\u0080\u00E6\u0095\u0099\u00E5\u00AD\u00A6\u00E4\u00BA\u0086\u00E8\u00A7\u00A3\u00E5\u00BB\u00BA\u00E7\u00AD\u0091\u00E7\u00BB\u0093\u00E6\u009E\u009C\u00E5\u0085\u00A8\u00E7\u0090\u0083\u00E9\u0080\u009A\u00E7\u009F\u00A5\u00E8\u00AE\u00A1\u00E5\u0088\u0092\u00E5\u00AF\u00B9\u00E4\u00BA\u008E\u00E8\u0089\u00BA\u00E6\u009C\u00AF\u00E7\u009B\u00B8\u00E5\u0086\u008C\u00E5\u008F\u0091\u00E7\u0094\u009F\u00E7\u009C\u009F\u00E7\u009A\u0084\u00E5\u00BB\u00BA\u00E7\u00AB\u008B\u00E7\u00AD\u0089\u00E7\u00BA\u00A7\u00E7\u00B1\u00BB\u00E5\u009E\u008B\u00E7\u00BB\u008F\u00E9\u00AA\u008C\u00E5\u00AE\u009E\u00E7\u008E\u00B0\u00E5\u0088\u00B6\u00E4\u00BD\u009C\u00E6\u009D\u00A5\u00E8\u0087\u00AA\u00E6\u00A0\u0087\u00E7\u00AD\u00BE\u00E4\u00BB\u00A5\u00E4\u00B8\u008B\u00E5\u008E\u009F\u00E5\u0088\u009B\u00E6\u0097\u00A0\u00E6\u00B3\u0095\u00E5\u0085\u00B6\u00E4\u00B8\u00AD\u00E5\u0080\u008B\u00E4\u00BA\u00BA\u00E4\u00B8\u0080\u00E5\u0088\u0087\u00E6\u008C\u0087\u00E5\u008D\u0097\u00E5\u0085\u00B3\u00E9\u0097\u00AD\u00E9\u009B\u0086\u00E5\u009B\u00A2\u00E7\u00AC\u00AC\u00E4\u00B8\u0089\u00E5\u0085\u00B3\u00E6\u00B3\u00A8\u00E5\u009B\u00A0\u00E6\u00AD\u00A4\u00E7\u0085\u00A7\u00E7\u0089\u0087\u00E6\u00B7\u00B1\u00E5\u009C\u00B3\u00E5\u0095\u0086\u00E4\u00B8\u009A\u00E5\u00B9\u00BF\u00E5\u00B7\u009E\u00E6\u0097\u00A5\u00E6\u009C\u009F\u00E9\u00AB\u0098\u00E7\u00BA\u00A7\u00E6\u009C\u0080\u00E8\u00BF\u0091\u00E7\u00BB\u00BC\u00E5\u0090\u0088\u00E8\u00A1\u00A8\u00E7\u00A4\u00BA\u00E4\u00B8\u0093\u00E8\u00BE\u0091\u00E8\u00A1\u008C\u00E4\u00B8\u00BA\u00E4\u00BA\u00A4\u00E9\u0080\u009A\u00E8\u00AF\u0084\u00E4\u00BB\u00B7\u00E8\u00A7\u0089\u00E5\u00BE\u0097\u00E7\u00B2\u00BE\u00E5\u008D\u008E\u00E5\u00AE\u00B6\u00E5\u00BA\u00AD\u00E5\u00AE\u008C\u00E6\u0088\u0090\u00E6\u0084\u009F\u00E8\u00A7\u0089\u00E5\u00AE\u0089\u00E8\u00A3\u0085\u00E5\u00BE\u0097\u00E5\u0088\u00B0\u00E9\u0082\u00AE\u00E4\u00BB\u00B6\u00E5\u0088\u00B6\u00E5\u00BA\u00A6\u00E9\u00A3\u009F\u00E5\u0093\u0081\u00E8\u0099\u00BD\u00E7\u0084\u00B6\u00E8\u00BD\u00AC\u00E8\u00BD\u00BD\u00E6\u008A\u00A5\u00E4\u00BB\u00B7\u00E8\u00AE\u00B0\u00E8\u0080\u0085\u00E6\u0096\u00B9\u00E6\u00A1\u0088\u00E8\u00A1\u008C\u00E6\u0094\u00BF\u00E4\u00BA\u00BA\u00E6\u00B0\u0091\u00E7\u0094\u00A8\u00E5\u0093\u0081\u00E4\u00B8\u009C\u00E8\u00A5\u00BF\u00E6\u008F\u0090\u00E5\u0087\u00BA\u00E9\u0085\u0092\u00E5\u00BA\u0097\u00E7\u0084\u00B6\u00E5\u0090\u008E\u00E4\u00BB\u0098\u00E6\u00AC\u00BE\u00E7\u0083\u00AD\u00E7\u0082\u00B9\u00E4\u00BB\u00A5\u00E5\u0089\u008D\u00E5\u00AE\u008C\u00E5\u0085\u00A8\u00E5\u008F\u0091\u00E5\u00B8\u0096\u00E8\u00AE\u00BE\u00E7\u00BD\u00AE\u00E9\u00A2\u0086\u00E5\u00AF\u00BC\u00E5\u00B7\u00A5\u00E4\u00B8\u009A\u00E5\u008C\u00BB\u00E9\u0099\u00A2\u00E7\u009C\u008B\u00E7\u009C\u008B\u00E7\u00BB\u008F\u00E5\u0085\u00B8\u00E5\u008E\u009F\u00E5\u009B\u00A0\u00E5\u00B9\u00B3\u00E5\u008F\u00B0\u00E5\u0090\u0084\u00E7\u00A7\u008D\u00E5\u00A2\u009E\u00E5\u008A\u00A0\u00E6\u009D\u0090\u00E6\u0096\u0099\u00E6\u0096\u00B0\u00E5\u00A2\u009E\u00E4\u00B9\u008B\u00E5\u0090\u008E\u00E8\u0081\u008C\u00E4\u00B8\u009A\u00E6\u0095\u0088\u00E6\u009E\u009C\u00E4\u00BB\u008A\u00E5\u00B9\u00B4\u00E8\u00AE\u00BA\u00E6\u0096\u0087\u00E6\u0088\u0091\u00E5\u009B\u00BD\u00E5\u0091\u008A\u00E8\u00AF\u0089\u00E7\u0089\u0088\u00E4\u00B8\u00BB\u00E4\u00BF\u00AE\u00E6\u0094\u00B9\u00E5\u008F\u0082\u00E4\u00B8\u008E\u00E6\u0089\u0093\u00E5\u008D\u00B0\u00E5\u00BF\u00AB\u00E4\u00B9\u0090\u00E6\u009C\u00BA\u00E6\u00A2\u00B0\u00E8\u00A7\u0082\u00E7\u0082\u00B9\u00E5\u00AD\u0098\u00E5\u009C\u00A8\u00E7\u00B2\u00BE\u00E7\u00A5\u009E\u00E8\u008E\u00B7\u00E5\u00BE\u0097\u00E5\u0088\u00A9\u00E7\u0094\u00A8\u00E7\u00BB\u00A7\u00E7\u00BB\u00AD\u00E4\u00BD\u00A0\u00E4\u00BB\u00AC\u00E8\u00BF\u0099\u00E4\u00B9\u0088\u00E6\u00A8\u00A1\u00E5\u00BC\u008F\u00E8\u00AF\u00AD\u00E8\u00A8\u0080\u00E8\u0083\u00BD\u00E5\u00A4\u009F\u00E9\u009B\u0085\u00E8\u0099\u008E\u00E6\u0093\u008D\u00E4\u00BD\u009C\u00E9\u00A3\u008E\u00E6\u00A0\u00BC\u00E4\u00B8\u0080\u00E8\u00B5\u00B7\u00E7\u00A7\u0091\u00E5\u00AD\u00A6\u00E4\u00BD\u0093\u00E8\u0082\u00B2\u00E7\u009F\u00AD\u00E4\u00BF\u00A1\u00E6\u009D\u00A1\u00E4\u00BB\u00B6\u00E6\u00B2\u00BB\u00E7\u0096\u0097\u00E8\u00BF\u0090\u00E5\u008A\u00A8\u00E4\u00BA\u00A7\u00E4\u00B8\u009A\u00E4\u00BC\u009A\u00E8\u00AE\u00AE\u00E5\u00AF\u00BC\u00E8\u0088\u00AA\u00E5\u0085\u0088\u00E7\u0094\u009F\u00E8\u0081\u0094\u00E7\u009B\u009F\u00E5\u008F\u00AF\u00E6\u0098\u00AF\u00E5\u0095\u008F\u00E9\u00A1\u008C\u00E7\u00BB\u0093\u00E6\u009E\u0084\u00E4\u00BD\u009C\u00E7\u0094\u00A8\u00E8\u00B0\u0083\u00E6\u009F\u00A5\u00E8\u00B3\u0087\u00E6\u0096\u0099\u00E8\u0087\u00AA\u00E5\u008A\u00A8\u00E8\u00B4\u009F\u00E8\u00B4\u00A3\u00E5\u0086\u009C\u00E4\u00B8\u009A\u00E8\u00AE\u00BF\u00E9\u0097\u00AE\u00E5\u00AE\u009E\u00E6\u0096\u00BD\u00E6\u008E\u00A5\u00E5\u008F\u0097\u00E8\u00AE\u00A8\u00E8\u00AE\u00BA\u00E9\u0082\u00A3\u00E4\u00B8\u00AA\u00E5\u008F\u008D\u00E9\u00A6\u0088\u00E5\u008A\u00A0\u00E5\u00BC\u00BA\u00E5\u00A5\u00B3\u00E6\u0080\u00A7\u00E8\u008C\u0083\u00E5\u009B\u00B4\u00E6\u009C\u008D\u00E5\u008B\u0099\u00E4\u00BC\u0091\u00E9\u0097\u00B2\u00E4\u00BB\u008A\u00E6\u0097\u00A5\u00E5\u00AE\u00A2\u00E6\u009C\u008D\u00E8\u00A7\u0080\u00E7\u009C\u008B\u00E5\u008F\u0082\u00E5\u008A\u00A0\u00E7\u009A\u0084\u00E8\u00AF\u009D\u00E4\u00B8\u0080\u00E7\u0082\u00B9\u00E4\u00BF\u009D\u00E8\u00AF\u0081\u00E5\u009B\u00BE\u00E4\u00B9\u00A6\u00E6\u009C\u0089\u00E6\u0095\u0088\u00E6\u00B5\u008B\u00E8\u00AF\u0095\u00E7\u00A7\u00BB\u00E5\u008A\u00A8\u00E6\u0089\u008D\u00E8\u0083\u00BD\u00E5\u0086\u00B3\u00E5\u00AE\u009A\u00E8\u0082\u00A1\u00E7\u00A5\u00A8\u00E4\u00B8\u008D\u00E6\u0096\u00AD\u00E9\u009C\u0080\u00E6\u00B1\u0082\u00E4\u00B8\u008D\u00E5\u00BE\u0097\u00E5\u008A\u009E\u00E6\u00B3\u0095\u00E4\u00B9\u008B\u00E9\u0097\u00B4\u00E9\u0087\u0087\u00E7\u0094\u00A8\u00E8\u0090\u00A5\u00E9\u0094\u0080\u00E6\u008A\u0095\u00E8\u00AF\u0089\u00E7\u009B\u00AE\u00E6\u00A0\u0087\u00E7\u0088\u00B1\u00E6\u0083\u0085\u00E6\u0091\u0084\u00E5\u00BD\u00B1\u00E6\u009C\u0089\u00E4\u00BA\u009B\u00E8\u00A4\u0087\u00E8\u00A3\u00BD\u00E6\u0096\u0087\u00E5\u00AD\u00A6\u00E6\u009C\u00BA\u00E4\u00BC\u009A\u00E6\u0095\u00B0\u00E5\u00AD\u0097\u00E8\u00A3\u0085\u00E4\u00BF\u00AE\u00E8\u00B4\u00AD\u00E7\u0089\u00A9\u00E5\u0086\u009C\u00E6\u009D\u0091\u00E5\u0085\u00A8\u00E9\u009D\u00A2\u00E7\u00B2\u00BE\u00E5\u0093\u0081\u00E5\u0085\u00B6\u00E5\u00AE\u009E\u00E4\u00BA\u008B\u00E6\u0083\u0085\u00E6\u00B0\u00B4\u00E5\u00B9\u00B3\u00E6\u008F\u0090\u00E7\u00A4\u00BA\u00E4\u00B8\u008A\u00E5\u00B8\u0082\u00E8\u00B0\u00A2\u00E8\u00B0\u00A2\u00E6\u0099\u00AE\u00E9\u0080\u009A\u00E6\u0095\u0099\u00E5\u00B8\u0088\u00E4\u00B8\u008A\u00E4\u00BC\u00A0\u00E7\u00B1\u00BB\u00E5\u0088\u00AB\u00E6\u00AD\u008C\u00E6\u009B\u00B2\u00E6\u008B\u00A5\u00E6\u009C\u0089\u00E5\u0088\u009B\u00E6\u0096\u00B0\u00E9\u0085\u008D\u00E4\u00BB\u00B6\u00E5\u008F\u00AA\u00E8\u00A6\u0081\u00E6\u0097\u00B6\u00E4\u00BB\u00A3\u00E8\u00B3\u0087\u00E8\u00A8\u008A\u00E8\u00BE\u00BE\u00E5\u0088\u00B0\u00E4\u00BA\u00BA\u00E7\u0094\u009F\u00E8\u00AE\u00A2\u00E9\u0098\u0085\u00E8\u0080\u0081\u00E5\u00B8\u0088\u00E5\u00B1\u0095\u00E7\u00A4\u00BA\u00E5\u00BF\u0083\u00E7\u0090\u0086\u00E8\u00B4\u00B4\u00E5\u00AD\u0090\u00E7\u00B6\u00B2\u00E7\u00AB\u0099\u00E4\u00B8\u00BB\u00E9\u00A1\u008C\u00E8\u0087\u00AA\u00E7\u0084\u00B6\u00E7\u00BA\u00A7\u00E5\u0088\u00AB\u00E7\u00AE\u0080\u00E5\u008D\u0095\u00E6\u0094\u00B9\u00E9\u009D\u00A9\u00E9\u0082\u00A3\u00E4\u00BA\u009B\u00E6\u009D\u00A5\u00E8\u00AF\u00B4\u00E6\u0089\u0093\u00E5\u00BC\u0080\u00E4\u00BB\u00A3\u00E7\u00A0\u0081\u00E5\u0088\u00A0\u00E9\u0099\u00A4\u00E8\u00AF\u0081\u00E5\u0088\u00B8\u00E8\u008A\u0082\u00E7\u009B\u00AE\u00E9\u0087\u008D\u00E7\u0082\u00B9\u00E6\u00AC\u00A1\u00E6\u0095\u00B8\u00E5\u00A4\u009A\u00E5\u00B0\u0091\u00E8\u00A7\u0084\u00E5\u0088\u0092\u00E8\u00B5\u0084\u00E9\u0087\u0091\u00E6\u0089\u00BE\u00E5\u0088\u00B0\u00E4\u00BB\u00A5\u00E5\u0090\u008E\u00E5\u00A4\u00A7\u00E5\u0085\u00A8\u00E4\u00B8\u00BB\u00E9\u00A1\u00B5\u00E6\u009C\u0080\u00E4\u00BD\u00B3\u00E5\u009B\u009E\u00E7\u00AD\u0094\u00E5\u00A4\u00A9\u00E4\u00B8\u008B\u00E4\u00BF\u009D\u00E9\u009A\u009C\u00E7\u008E\u00B0\u00E4\u00BB\u00A3\u00E6\u00A3\u0080\u00E6\u009F\u00A5\u00E6\u008A\u0095\u00E7\u00A5\u00A8\u00E5\u00B0\u008F\u00E6\u0097\u00B6\u00E6\u00B2\u0092\u00E6\u009C\u0089\u00E6\u00AD\u00A3\u00E5\u00B8\u00B8\u00E7\u0094\u009A\u00E8\u0087\u00B3\u00E4\u00BB\u00A3\u00E7\u0090\u0086\u00E7\u009B\u00AE\u00E5\u00BD\u0095\u00E5\u0085\u00AC\u00E5\u00BC\u0080\u00E5\u00A4\u008D\u00E5\u0088\u00B6\u00E9\u0087\u0091\u00E8\u009E\u008D\u00E5\u00B9\u00B8\u00E7\u00A6\u008F\u00E7\u0089\u0088\u00E6\u009C\u00AC\u00E5\u00BD\u00A2\u00E6\u0088\u0090\u00E5\u0087\u0086\u00E5\u00A4\u0087\u00E8\u00A1\u008C\u00E6\u0083\u0085\u00E5\u009B\u009E\u00E5\u0088\u00B0\u00E6\u0080\u009D\u00E6\u0083\u00B3\u00E6\u0080\u008E\u00E6\u00A0\u00B7\u00E5\u008D\u008F\u00E8\u00AE\u00AE\u00E8\u00AE\u00A4\u00E8\u00AF\u0081\u00E6\u009C\u0080\u00E5\u00A5\u00BD\u00E4\u00BA\u00A7\u00E7\u0094\u009F\u00E6\u008C\u0089\u00E7\u0085\u00A7\u00E6\u009C\u008D\u00E8\u00A3\u0085\u00E5\u00B9\u00BF\u00E4\u00B8\u009C\u00E5\u008A\u00A8\u00E6\u00BC\u00AB\u00E9\u0087\u0087\u00E8\u00B4\u00AD\u00E6\u0096\u00B0\u00E6\u0089\u008B\u00E7\u00BB\u0084\u00E5\u009B\u00BE\u00E9\u009D\u00A2\u00E6\u009D\u00BF\u00E5\u008F\u0082\u00E8\u0080\u0083\u00E6\u0094\u00BF\u00E6\u00B2\u00BB\u00E5\u00AE\u00B9\u00E6\u0098\u0093\u00E5\u00A4\u00A9\u00E5\u009C\u00B0\u00E5\u008A\u00AA\u00E5\u008A\u009B\u00E4\u00BA\u00BA\u00E4\u00BB\u00AC\u00E5\u008D\u0087\u00E7\u00BA\u00A7\u00E9\u0080\u009F\u00E5\u00BA\u00A6\u00E4\u00BA\u00BA\u00E7\u0089\u00A9\u00E8\u00B0\u0083\u00E6\u0095\u00B4\u00E6\u00B5\u0081\u00E8\u00A1\u008C\u00E9\u0080\u00A0\u00E6\u0088\u0090\u00E6\u0096\u0087\u00E5\u00AD\u0097\u00E9\u009F\u00A9\u00E5\u009B\u00BD\u00E8\u00B4\u00B8\u00E6\u0098\u0093\u00E5\u00BC\u0080\u00E5\u00B1\u0095\u00E7\u009B\u00B8\u00E9\u0097\u009C\u00E8\u00A1\u00A8\u00E7\u008E\u00B0\u00E5\u00BD\u00B1\u00E8\u00A7\u0086\u00E5\u00A6\u0082\u00E6\u00AD\u00A4\u00E7\u00BE\u008E\u00E5\u00AE\u00B9\u00E5\u00A4\u00A7\u00E5\u00B0\u008F\u00E6\u008A\u00A5\u00E9\u0081\u0093\u00E6\u009D\u00A1\u00E6\u00AC\u00BE\u00E5\u00BF\u0083\u00E6\u0083\u0085\u00E8\u00AE\u00B8\u00E5\u00A4\u009A\u00E6\u00B3\u0095\u00E8\u00A7\u0084\u00E5\u00AE\u00B6\u00E5\u00B1\u0085\u00E4\u00B9\u00A6\u00E5\u00BA\u0097\u00E8\u00BF\u009E\u00E6\u008E\u00A5\u00E7\u00AB\u008B\u00E5\u008D\u00B3\u00E4\u00B8\u00BE\u00E6\u008A\u00A5\u00E6\u008A\u0080\u00E5\u00B7\u00A7\u00E5\u00A5\u00A5\u00E8\u00BF\u0090\u00E7\u0099\u00BB\u00E5\u0085\u00A5\u00E4\u00BB\u00A5\u00E6\u009D\u00A5\u00E7\u0090\u0086\u00E8\u00AE\u00BA\u00E4\u00BA\u008B\u00E4\u00BB\u00B6\u00E8\u0087\u00AA\u00E7\u0094\u00B1\u00E4\u00B8\u00AD\u00E5\u008D\u008E\u00E5\u008A\u009E\u00E5\u0085\u00AC\u00E5\u00A6\u0088\u00E5\u00A6\u0088\u00E7\u009C\u009F\u00E6\u00AD\u00A3\u00E4\u00B8\u008D\u00E9\u0094\u0099\u00E5\u0085\u00A8\u00E6\u0096\u0087\u00E5\u0090\u0088\u00E5\u0090\u008C\u00E4\u00BB\u00B7\u00E5\u0080\u00BC\u00E5\u0088\u00AB\u00E4\u00BA\u00BA\u00E7\u009B\u0091\u00E7\u009D\u00A3\u00E5\u0085\u00B7\u00E4\u00BD\u0093\u00E4\u00B8\u0096\u00E7\u00BA\u00AA\u00E5\u009B\u00A2\u00E9\u0098\u009F\u00E5\u0088\u009B\u00E4\u00B8\u009A\u00E6\u0089\u00BF\u00E6\u008B\u0085\u00E5\u00A2\u009E\u00E9\u0095\u00BF\u00E6\u009C\u0089\u00E4\u00BA\u00BA\u00E4\u00BF\u009D\u00E6\u008C\u0081\u00E5\u0095\u0086\u00E5\u00AE\u00B6\u00E7\u00BB\u00B4\u00E4\u00BF\u00AE\u00E5\u008F\u00B0\u00E6\u00B9\u00BE\u00E5\u00B7\u00A6\u00E5\u008F\u00B3\u00E8\u0082\u00A1\u00E4\u00BB\u00BD\u00E7\u00AD\u0094\u00E6\u00A1\u0088\u00E5\u00AE\u009E\u00E9\u0099\u0085\u00E7\u0094\u00B5\u00E4\u00BF\u00A1\u00E7\u00BB\u008F\u00E7\u0090\u0086\u00E7\u0094\u009F\u00E5\u0091\u00BD\u00E5\u00AE\u00A3\u00E4\u00BC\u00A0\u00E4\u00BB\u00BB\u00E5\u008A\u00A1\u00E6\u00AD\u00A3\u00E5\u00BC\u008F\u00E7\u0089\u00B9\u00E8\u0089\u00B2\u00E4\u00B8\u008B\u00E6\u009D\u00A5\u00E5\u008D\u008F\u00E4\u00BC\u009A\u00E5\u008F\u00AA\u00E8\u0083\u00BD\u00E5\u00BD\u0093\u00E7\u0084\u00B6\u00E9\u0087\u008D\u00E6\u0096\u00B0\u00E5\u0085\u00A7\u00E5\u00AE\u00B9\u00E6\u008C\u0087\u00E5\u00AF\u00BC\u00E8\u00BF\u0090\u00E8\u00A1\u008C\u00E6\u0097\u00A5\u00E5\u00BF\u0097\u00E8\u00B3\u00A3\u00E5\u00AE\u00B6\u00E8\u00B6\u0085\u00E8\u00BF\u0087\u00E5\u009C\u009F\u00E5\u009C\u00B0\u00E6\u00B5\u0099\u00E6\u00B1\u009F\u00E6\u0094\u00AF\u00E4\u00BB\u0098\u00E6\u008E\u00A8\u00E5\u0087\u00BA\u00E7\u00AB\u0099\u00E9\u0095\u00BF\u00E6\u009D\u00AD\u00E5\u00B7\u009E\u00E6\u0089\u00A7\u00E8\u00A1\u008C\u00E5\u0088\u00B6\u00E9\u0080\u00A0\u00E4\u00B9\u008B\u00E4\u00B8\u0080\u00E6\u008E\u00A8\u00E5\u00B9\u00BF\u00E7\u008E\u00B0\u00E5\u009C\u00BA\u00E6\u008F\u008F\u00E8\u00BF\u00B0\u00E5\u008F\u0098\u00E5\u008C\u0096\u00E4\u00BC\u00A0\u00E7\u00BB\u009F\u00E6\u00AD\u008C\u00E6\u0089\u008B\u00E4\u00BF\u009D\u00E9\u0099\u00A9\u00E8\u00AF\u00BE\u00E7\u00A8\u008B\u00E5\u008C\u00BB\u00E7\u0096\u0097\u00E7\u00BB\u008F\u00E8\u00BF\u0087\u00E8\u00BF\u0087\u00E5\u008E\u00BB\u00E4\u00B9\u008B\u00E5\u0089\u008D\u00E6\u0094\u00B6\u00E5\u0085\u00A5\u00E5\u00B9\u00B4\u00E5\u00BA\u00A6\u00E6\u009D\u0082\u00E5\u00BF\u0097\u00E7\u00BE\u008E\u00E4\u00B8\u00BD\u00E6\u009C\u0080\u00E9\u00AB\u0098\u00E7\u0099\u00BB\u00E9\u0099\u0086\u00E6\u009C\u00AA\u00E6\u009D\u00A5\u00E5\u008A\u00A0\u00E5\u00B7\u00A5\u00E5\u0085\u008D\u00E8\u00B4\u00A3\u00E6\u0095\u0099\u00E7\u00A8\u008B\u00E7\u0089\u0088\u00E5\u009D\u0097\u00E8\u00BA\u00AB\u00E4\u00BD\u0093\u00E9\u0087\u008D\u00E5\u00BA\u0086\u00E5\u0087\u00BA\u00E5\u0094\u00AE\u00E6\u0088\u0090\u00E6\u009C\u00AC\u00E5\u00BD\u00A2\u00E5\u00BC\u008F\u00E5\u009C\u009F\u00E8\u00B1\u0086\u00E5\u0087\u00BA\u00E5\u0083\u00B9\u00E4\u00B8\u009C\u00E6\u0096\u00B9\u00E9\u0082\u00AE\u00E7\u00AE\u00B1\u00E5\u008D\u0097\u00E4\u00BA\u00AC\u00E6\u00B1\u0082\u00E8\u0081\u008C\u00E5\u008F\u0096\u00E5\u00BE\u0097\u00E8\u0081\u008C\u00E4\u00BD\u008D\u00E7\u009B\u00B8\u00E4\u00BF\u00A1\u00E9\u00A1\u00B5\u00E9\u009D\u00A2\u00E5\u0088\u0086\u00E9\u0092\u009F\u00E7\u00BD\u0091\u00E9\u00A1\u00B5\u00E7\u00A1\u00AE\u00E5\u00AE\u009A\u00E5\u009B\u00BE\u00E4\u00BE\u008B\u00E7\u00BD\u0091\u00E5\u009D\u0080\u00E7\u00A7\u00AF\u00E6\u009E\u0081\u00E9\u0094\u0099\u00E8\u00AF\u00AF\u00E7\u009B\u00AE\u00E7\u009A\u0084\u00E5\u00AE\u009D\u00E8\u00B4\u009D\u00E6\u009C\u00BA\u00E5\u0085\u00B3\u00E9\u00A3\u008E\u00E9\u0099\u00A9\u00E6\u008E\u0088\u00E6\u009D\u0083\u00E7\u0097\u0085\u00E6\u00AF\u0092\u00E5\u00AE\u00A0\u00E7\u0089\u00A9\u00E9\u0099\u00A4\u00E4\u00BA\u0086\u00E8\u00A9\u0095\u00E8\u00AB\u0096\u00E7\u0096\u00BE\u00E7\u0097\u0085\u00E5\u008F\u008A\u00E6\u0097\u00B6\u00E6\u00B1\u0082\u00E8\u00B4\u00AD\u00E7\u00AB\u0099\u00E7\u0082\u00B9\u00E5\u0084\u00BF\u00E7\u00AB\u00A5\u00E6\u00AF\u008F\u00E5\u00A4\u00A9\u00E4\u00B8\u00AD\u00E5\u00A4\u00AE\u00E8\u00AE\u00A4\u00E8\u00AF\u0086\u00E6\u00AF\u008F\u00E4\u00B8\u00AA\u00E5\u00A4\u00A9\u00E6\u00B4\u00A5\u00E5\u00AD\u0097\u00E4\u00BD\u0093\u00E5\u008F\u00B0\u00E7\u0081\u00A3\u00E7\u00BB\u00B4\u00E6\u008A\u00A4\u00E6\u009C\u00AC\u00E9\u00A1\u00B5\u00E4\u00B8\u00AA\u00E6\u0080\u00A7\u00E5\u00AE\u0098\u00E6\u0096\u00B9\u00E5\u00B8\u00B8\u00E8\u00A7\u0081\u00E7\u009B\u00B8\u00E6\u009C\u00BA\u00E6\u0088\u0098\u00E7\u0095\u00A5\u00E5\u00BA\u0094\u00E5\u00BD\u0093\u00E5\u00BE\u008B\u00E5\u00B8\u0088\u00E6\u0096\u00B9\u00E4\u00BE\u00BF\u00E6\u00A0\u00A1\u00E5\u009B\u00AD\u00E8\u0082\u00A1\u00E5\u00B8\u0082\u00E6\u0088\u00BF\u00E5\u00B1\u008B\u00E6\u00A0\u008F\u00E7\u009B\u00AE\u00E5\u0091\u0098\u00E5\u00B7\u00A5\u00E5\u00AF\u00BC\u00E8\u0087\u00B4\u00E7\u00AA\u0081\u00E7\u0084\u00B6\u00E9\u0081\u0093\u00E5\u0085\u00B7\u00E6\u009C\u00AC\u00E7\u00BD\u0091\u00E7\u00BB\u0093\u00E5\u0090\u0088\u00E6\u00A1\u00A3\u00E6\u00A1\u0088\u00E5\u008A\u00B3\u00E5\u008A\u00A8\u00E5\u008F\u00A6\u00E5\u00A4\u0096\u00E7\u00BE\u008E\u00E5\u0085\u0083\u00E5\u00BC\u0095\u00E8\u00B5\u00B7\u00E6\u0094\u00B9\u00E5\u008F\u0098\u00E7\u00AC\u00AC\u00E5\u009B\u009B\u00E4\u00BC\u009A\u00E8\u00AE\u00A1\u00E8\u00AA\u00AA\u00E6\u0098\u008E\u00E9\u009A\u0090\u00E7\u00A7\u0081\u00E5\u00AE\u009D\u00E5\u00AE\u009D\u00E8\u00A7\u0084\u00E8\u008C\u0083\u00E6\u00B6\u0088\u00E8\u00B4\u00B9\u00E5\u0085\u00B1\u00E5\u0090\u008C\u00E5\u00BF\u0098\u00E8\u00AE\u00B0\u00E4\u00BD\u0093\u00E7\u00B3\u00BB\u00E5\u00B8\u00A6\u00E6\u009D\u00A5\u00E5\u0090\u008D\u00E5\u00AD\u0097\u00E7\u0099\u00BC\u00E8\u00A1\u00A8\u00E5\u00BC\u0080\u00E6\u0094\u00BE\u00E5\u008A\u00A0\u00E7\u009B\u009F\u00E5\u008F\u0097\u00E5\u0088\u00B0\u00E4\u00BA\u008C\u00E6\u0089\u008B\u00E5\u00A4\u00A7\u00E9\u0087\u008F\u00E6\u0088\u0090\u00E4\u00BA\u00BA\u00E6\u0095\u00B0\u00E9\u0087\u008F\u00E5\u0085\u00B1\u00E4\u00BA\u00AB\u00E5\u008C\u00BA\u00E5\u009F\u009F\u00E5\u00A5\u00B3\u00E5\u00AD\u00A9\u00E5\u008E\u009F\u00E5\u0088\u0099\u00E6\u0089\u0080\u00E5\u009C\u00A8\u00E7\u00BB\u0093\u00E6\u009D\u009F\u00E9\u0080\u009A\u00E4\u00BF\u00A1\u00E8\u00B6\u0085\u00E7\u00BA\u00A7\u00E9\u0085\u008D\u00E7\u00BD\u00AE\u00E5\u00BD\u0093\u00E6\u0097\u00B6\u00E4\u00BC\u0098\u00E7\u00A7\u0080\u00E6\u0080\u00A7\u00E6\u0084\u009F\u00E6\u0088\u00BF\u00E4\u00BA\u00A7\u00E9\u0081\u008A\u00E6\u0088\u00B2\u00E5\u0087\u00BA\u00E5\u008F\u00A3\u00E6\u008F\u0090\u00E4\u00BA\u00A4\u00E5\u00B0\u00B1\u00E4\u00B8\u009A\u00E4\u00BF\u009D\u00E5\u0081\u00A5\u00E7\u00A8\u008B\u00E5\u00BA\u00A6\u00E5\u008F\u0082\u00E6\u0095\u00B0\u00E4\u00BA\u008B\u00E4\u00B8\u009A\u00E6\u0095\u00B4\u00E4\u00B8\u00AA\u00E5\u00B1\u00B1\u00E4\u00B8\u009C\u00E6\u0083\u0085\u00E6\u0084\u009F\u00E7\u0089\u00B9\u00E6\u00AE\u008A\u00E5\u0088\u0086\u00E9\u00A1\u009E\u00E6\u0090\u009C\u00E5\u00B0\u008B\u00E5\u00B1\u009E\u00E4\u00BA\u008E\u00E9\u0097\u00A8\u00E6\u0088\u00B7\u00E8\u00B4\u00A2\u00E5\u008A\u00A1\u00E5\u00A3\u00B0\u00E9\u009F\u00B3\u00E5\u008F\u008A\u00E5\u0085\u00B6\u00E8\u00B4\u00A2\u00E7\u00BB\u008F\u00E5\u009D\u009A\u00E6\u008C\u0081\u00E5\u00B9\u00B2\u00E9\u0083\u00A8\u00E6\u0088\u0090\u00E7\u00AB\u008B\u00E5\u0088\u00A9\u00E7\u009B\u008A\u00E8\u0080\u0083\u00E8\u0099\u0091\u00E6\u0088\u0090\u00E9\u0083\u00BD\u00E5\u008C\u0085\u00E8\u00A3\u0085\u00E7\u0094\u00A8\u00E6\u0088\u00B6\u00E6\u00AF\u0094\u00E8\u00B5\u009B\u00E6\u0096\u0087\u00E6\u0098\u008E\u00E6\u008B\u009B\u00E5\u0095\u0086\u00E5\u00AE\u008C\u00E6\u0095\u00B4\u00E7\u009C\u009F\u00E6\u0098\u00AF\u00E7\u009C\u00BC\u00E7\u009D\u009B\u00E4\u00BC\u0099\u00E4\u00BC\u00B4\u00E5\u00A8\u0081\u00E6\u009C\u009B\u00E9\u00A2\u0086\u00E5\u009F\u009F\u00E5\u008D\u00AB\u00E7\u0094\u009F\u00E4\u00BC\u0098\u00E6\u0083\u00A0\u00E8\u00AB\u0096\u00E5\u00A3\u0087\u00E5\u0085\u00AC\u00E5\u0085\u00B1\u00E8\u0089\u00AF\u00E5\u00A5\u00BD\u00E5\u0085\u0085\u00E5\u0088\u0086\u00E7\u00AC\u00A6\u00E5\u0090\u0088\u00E9\u0099\u0084\u00E4\u00BB\u00B6\u00E7\u0089\u00B9\u00E7\u0082\u00B9\u00E4\u00B8\u008D\u00E5\u008F\u00AF\u00E8\u008B\u00B1\u00E6\u0096\u0087\u00E8\u00B5\u0084\u00E4\u00BA\u00A7\u00E6\u00A0\u00B9\u00E6\u009C\u00AC\u00E6\u0098\u008E\u00E6\u0098\u00BE\u00E5\u00AF\u0086\u00E7\u00A2\u00BC\u00E5\u0085\u00AC\u00E4\u00BC\u0097\u00E6\u00B0\u0091\u00E6\u0097\u008F\u00E6\u009B\u00B4\u00E5\u008A\u00A0\u00E4\u00BA\u00AB\u00E5\u008F\u0097\u00E5\u0090\u008C\u00E5\u00AD\u00A6\u00E5\u0090\u00AF\u00E5\u008A\u00A8\u00E9\u0080\u0082\u00E5\u0090\u0088\u00E5\u008E\u009F\u00E6\u009D\u00A5\u00E9\u0097\u00AE\u00E7\u00AD\u0094\u00E6\u009C\u00AC\u00E6\u0096\u0087\u00E7\u00BE\u008E\u00E9\u00A3\u009F\u00E7\u00BB\u00BF\u00E8\u0089\u00B2\u00E7\u00A8\u00B3\u00E5\u00AE\u009A\u00E7\u00BB\u0088\u00E4\u00BA\u008E\u00E7\u0094\u009F\u00E7\u0089\u00A9\u00E4\u00BE\u009B\u00E6\u00B1\u0082\u00E6\u0090\u009C\u00E7\u008B\u0090\u00E5\u008A\u009B\u00E9\u0087\u008F\u00E4\u00B8\u00A5\u00E9\u0087\u008D\u00E6\u00B0\u00B8\u00E8\u00BF\u009C\u00E5\u0086\u0099\u00E7\u009C\u009F\u00E6\u009C\u0089\u00E9\u0099\u0090\u00E7\u00AB\u009E\u00E4\u00BA\u0089\u00E5\u00AF\u00B9\u00E8\u00B1\u00A1\u00E8\u00B4\u00B9\u00E7\u0094\u00A8\u00E4\u00B8\u008D\u00E5\u00A5\u00BD\u00E7\u00BB\u009D\u00E5\u00AF\u00B9\u00E5\u008D\u0081\u00E5\u0088\u0086\u00E4\u00BF\u0083\u00E8\u00BF\u009B\u00E7\u0082\u00B9\u00E8\u00AF\u0084\u00E5\u00BD\u00B1\u00E9\u009F\u00B3\u00E4\u00BC\u0098\u00E5\u008A\u00BF\u00E4\u00B8\u008D\u00E5\u00B0\u0091\u00E6\u00AC\u00A3\u00E8\u00B5\u008F\u00E5\u00B9\u00B6\u00E4\u00B8\u0094\u00E6\u009C\u0089\u00E7\u0082\u00B9\u00E6\u0096\u00B9\u00E5\u0090\u0091\u00E5\u0085\u00A8\u00E6\u0096\u00B0\u00E4\u00BF\u00A1\u00E7\u0094\u00A8\u00E8\u00AE\u00BE\u00E6\u0096\u00BD\u00E5\u00BD\u00A2\u00E8\u00B1\u00A1\u00E8\u00B5\u0084\u00E6\u00A0\u00BC\u00E7\u00AA\u0081\u00E7\u00A0\u00B4\u00E9\u009A\u008F\u00E7\u009D\u0080\u00E9\u0087\u008D\u00E5\u00A4\u00A7\u00E4\u00BA\u008E\u00E6\u0098\u00AF\u00E6\u00AF\u0095\u00E4\u00B8\u009A\u00E6\u0099\u00BA\u00E8\u0083\u00BD\u00E5\u008C\u0096\u00E5\u00B7\u00A5\u00E5\u00AE\u008C\u00E7\u00BE\u008E\u00E5\u0095\u0086\u00E5\u009F\u008E\u00E7\u00BB\u009F\u00E4\u00B8\u0080\u00E5\u0087\u00BA\u00E7\u0089\u0088\u00E6\u0089\u0093\u00E9\u0080\u00A0\u00E7\u0094\u00A2\u00E5\u0093\u0081\u00E6\u00A6\u0082\u00E5\u0086\u00B5\u00E7\u0094\u00A8\u00E4\u00BA\u008E\u00E4\u00BF\u009D\u00E7\u0095\u0099\u00E5\u009B\u00A0\u00E7\u00B4\u00A0\u00E4\u00B8\u00AD\u00E5\u009C\u008B\u00E5\u00AD\u0098\u00E5\u0082\u00A8\u00E8\u00B4\u00B4\u00E5\u009B\u00BE\u00E6\u009C\u0080\u00E6\u0084\u009B\u00E9\u0095\u00BF\u00E6\u009C\u009F\u00E5\u008F\u00A3\u00E4\u00BB\u00B7\u00E7\u0090\u0086\u00E8\u00B4\u00A2\u00E5\u009F\u00BA\u00E5\u009C\u00B0\u00E5\u00AE\u0089\u00E6\u008E\u0092\u00E6\u00AD\u00A6\u00E6\u00B1\u0089\u00E9\u0087\u008C\u00E9\u009D\u00A2\u00E5\u0088\u009B\u00E5\u00BB\u00BA\u00E5\u00A4\u00A9\u00E7\u00A9\u00BA\u00E9\u00A6\u0096\u00E5\u0085\u0088\u00E5\u00AE\u008C\u00E5\u0096\u0084\u00E9\u00A9\u00B1\u00E5\u008A\u00A8\u00E4\u00B8\u008B\u00E9\u009D\u00A2\u00E4\u00B8\u008D\u00E5\u0086\u008D\u00E8\u00AF\u009A\u00E4\u00BF\u00A1\u00E6\u0084\u008F\u00E4\u00B9\u0089\u00E9\u0098\u00B3\u00E5\u0085\u0089\u00E8\u008B\u00B1\u00E5\u009B\u00BD\u00E6\u00BC\u0082\u00E4\u00BA\u00AE\u00E5\u0086\u009B\u00E4\u00BA\u008B\u00E7\u008E\u00A9\u00E5\u00AE\u00B6\u00E7\u00BE\u00A4\u00E4\u00BC\u0097\u00E5\u0086\u009C\u00E6\u00B0\u0091\u00E5\u008D\u00B3\u00E5\u008F\u00AF\u00E5\u0090\u008D\u00E7\u00A8\u00B1\u00E5\u00AE\u00B6\u00E5\u0085\u00B7\u00E5\u008A\u00A8\u00E7\u0094\u00BB\u00E6\u0083\u00B3\u00E5\u0088\u00B0\u00E6\u00B3\u00A8\u00E6\u0098\u008E\u00E5\u00B0\u008F\u00E5\u00AD\u00A6\u00E6\u0080\u00A7\u00E8\u0083\u00BD\u00E8\u0080\u0083\u00E7\u00A0\u0094\u00E7\u00A1\u00AC\u00E4\u00BB\u00B6\u00E8\u00A7\u0082\u00E7\u009C\u008B\u00E6\u00B8\u0085\u00E6\u00A5\u009A\u00E6\u0090\u009E\u00E7\u00AC\u0091\u00E9\u00A6\u0096\u00E9\u00A0\u0081\u00E9\u00BB\u0084\u00E9\u0087\u0091\u00E9\u0080\u0082\u00E7\u0094\u00A8\u00E6\u00B1\u009F\u00E8\u008B\u008F\u00E7\u009C\u009F\u00E5\u00AE\u009E\u00E4\u00B8\u00BB\u00E7\u00AE\u00A1\u00E9\u0098\u00B6\u00E6\u00AE\u00B5\u00E8\u00A8\u00BB\u00E5\u0086\u008A\u00E7\u00BF\u00BB\u00E8\u00AF\u0091\u00E6\u009D\u0083\u00E5\u0088\u00A9\u00E5\u0081\u009A\u00E5\u00A5\u00BD\u00E4\u00BC\u00BC\u00E4\u00B9\u008E\u00E9\u0080\u009A\u00E8\u00AE\u00AF\u00E6\u0096\u00BD\u00E5\u00B7\u00A5\u00E7\u008B\u0080\u00E6\u0085\u008B\u00E4\u00B9\u009F\u00E8\u00AE\u00B8\u00E7\u008E\u00AF\u00E4\u00BF\u009D\u00E5\u009F\u00B9\u00E5\u0085\u00BB\u00E6\u00A6\u0082\u00E5\u00BF\u00B5\u00E5\u00A4\u00A7\u00E5\u009E\u008B\u00E6\u009C\u00BA\u00E7\u00A5\u00A8\u00E7\u0090\u0086\u00E8\u00A7\u00A3\u00E5\u008C\u00BF\u00E5\u0090\u008Dcuandoenviarmadridbuscariniciotiempoporquecuentaestadopuedenjuegoscontraest\u00C3\u00A1nnombretienenperfilmaneraamigosciudadcentroaunquepuedesdentroprimerprecioseg\u00C3\u00BAnbuenosvolverpuntossemanahab\u00C3\u00ADaagostonuevosunidoscarlosequiponi\u00C3\u00B1osmuchosalgunacorreoimagenpartirarribamar\u00C3\u00ADahombreempleoverdadcambiomuchasfueronpasadol\u00C3\u00ADneaparecenuevascursosestabaquierolibroscuantoaccesomiguelvarioscuatrotienesgruposser\u00C3\u00A1neuropamediosfrenteacercadem\u00C3\u00A1sofertacochesmodeloitalialetrasalg\u00C3\u00BAncompracualesexistecuerposiendoprensallegarviajesdineromurciapodr\u00C3\u00A1puestodiariopuebloquieremanuelpropiocrisisciertoseguromuertefuentecerrargrandeefectopartesmedidapropiaofrecetierrae-mailvariasformasfuturoobjetoseguirriesgonormasmismos\u00C3\u00BAnicocaminositiosraz\u00C3\u00B3ndebidopruebatoledoten\u00C3\u00ADajes\u00C3\u00BAsesperococinaorigentiendacientoc\u00C3\u00A1dizhablarser\u00C3\u00ADalatinafuerzaestiloguerraentrar\u00C3\u00A9xitol\u00C3\u00B3pezagendav\u00C3\u00ADdeoevitarpaginametrosjavierpadresf\u00C3\u00A1cilcabeza\u00C3\u00A1reassalidaenv\u00C3\u00ADojap\u00C3\u00B3nabusosbienestextosllevarpuedanfuertecom\u00C3\u00BAnclaseshumanotenidobilbaounidadest\u00C3\u00A1seditarcreado\u00D0\u00B4\u00D0\u00BB\u00D1\u008F\u00D1\u0087\u00D1\u0082\u00D0\u00BE\u00D0\u00BA\u00D0\u00B0\u00D0\u00BA\u00D0\u00B8\u00D0\u00BB\u00D0\u00B8\u00D1\u008D\u00D1\u0082\u00D0\u00BE\u00D0\u00B2\u00D1\u0081\u00D0\u00B5\u00D0\u00B5\u00D0\u00B3\u00D0\u00BE\u00D0\u00BF\u00D1\u0080\u00D0\u00B8\u00D1\u0082\u00D0\u00B0\u00D0\u00BA\u00D0\u00B5\u00D1\u0089\u00D0\u00B5\u00D1\u0083\u00D0\u00B6\u00D0\u00B5\u00D0\u009A\u00D0\u00B0\u00D0\u00BA\u00D0\u00B1\u00D0\u00B5\u00D0\u00B7\u00D0\u00B1\u00D1\u008B\u00D0\u00BB\u00D0\u00BE\u00D0\u00BD\u00D0\u00B8\u00D0\u0092\u00D1\u0081\u00D0\u00B5\u00D0\u00BF\u00D0\u00BE\u00D0\u00B4\u00D0\u00AD\u00D1\u0082\u00D0\u00BE\u00D1\u0082\u00D0\u00BE\u00D0\u00BC\u00D1\u0087\u00D0\u00B5\u00D0\u00BC\u00D0\u00BD\u00D0\u00B5\u00D1\u0082\u00D0\u00BB\u00D0\u00B5\u00D1\u0082\u00D1\u0080\u00D0\u00B0\u00D0\u00B7\u00D0\u00BE\u00D0\u00BD\u00D0\u00B0\u00D0\u00B3\u00D0\u00B4\u00D0\u00B5\u00D0\u00BC\u00D0\u00BD\u00D0\u00B5\u00D0\u0094\u00D0\u00BB\u00D1\u008F\u00D0\u009F\u00D1\u0080\u00D0\u00B8\u00D0\u00BD\u00D0\u00B0\u00D1\u0081\u00D0\u00BD\u00D0\u00B8\u00D1\u0085\u00D1\u0082\u00D0\u00B5\u00D0\u00BC\u00D0\u00BA\u00D1\u0082\u00D0\u00BE\u00D0\u00B3\u00D0\u00BE\u00D0\u00B4\u00D0\u00B2\u00D0\u00BE\u00D1\u0082\u00D1\u0082\u00D0\u00B0\u00D0\u00BC\u00D0\u00A1\u00D0\u00A8\u00D0\u0090\u00D0\u00BC\u00D0\u00B0\u00D1\u008F\u00D0\u00A7\u00D1\u0082\u00D0\u00BE\u00D0\u00B2\u00D0\u00B0\u00D1\u0081\u00D0\u00B2\u00D0\u00B0\u00D0\u00BC\u00D0\u00B5\u00D0\u00BC\u00D1\u0083\u00D0\u00A2\u00D0\u00B0\u00D0\u00BA\u00D0\u00B4\u00D0\u00B2\u00D0\u00B0\u00D0\u00BD\u00D0\u00B0\u00D0\u00BC\u00D1\u008D\u00D1\u0082\u00D0\u00B8\u00D1\u008D\u00D1\u0082\u00D1\u0083\u00D0\u0092\u00D0\u00B0\u00D0\u00BC\u00D1\u0082\u00D0\u00B5\u00D1\u0085\u00D0\u00BF\u00D1\u0080\u00D0\u00BE\u00D1\u0082\u00D1\u0083\u00D1\u0082\u00D0\u00BD\u00D0\u00B0\u00D0\u00B4\u00D0\u00B4\u00D0\u00BD\u00D1\u008F\u00D0\u0092\u00D0\u00BE\u00D1\u0082\u00D1\u0082\u00D1\u0080\u00D0\u00B8\u00D0\u00BD\u00D0\u00B5\u00D0\u00B9\u00D0\u0092\u00D0\u00B0\u00D1\u0081\u00D0\u00BD\u00D0\u00B8\u00D0\u00BC\u00D1\u0081\u00D0\u00B0\u00D0\u00BC\u00D1\u0082\u00D0\u00BE\u00D1\u0082\u00D1\u0080\u00D1\u0083\u00D0\u00B1\u00D0\u009E\u00D0\u00BD\u00D0\u00B8\u00D0\u00BC\u00D0\u00B8\u00D1\u0080\u00D0\u00BD\u00D0\u00B5\u00D0\u00B5\u00D0\u009E\u00D0\u009E\u00D0\u009E\u00D0\u00BB\u00D0\u00B8\u00D1\u0086\u00D1\u008D\u00D1\u0082\u00D0\u00B0\u00D0\u009E\u00D0\u00BD\u00D0\u00B0\u00D0\u00BD\u00D0\u00B5\u00D0\u00BC\u00D0\u00B4\u00D0\u00BE\u00D0\u00BC\u00D0\u00BC\u00D0\u00BE\u00D0\u00B9\u00D0\u00B4\u00D0\u00B2\u00D0\u00B5\u00D0\u00BE\u00D0\u00BD\u00D0\u00BE\u00D1\u0081\u00D1\u0083\u00D0\u00B4\u00E0\u00A4\u0095\u00E0\u00A5\u0087\u00E0\u00A4\u00B9\u00E0\u00A5\u0088\u00E0\u00A4\u0095\u00E0\u00A5\u0080\u00E0\u00A4\u00B8\u00E0\u00A5\u0087\u00E0\u00A4\u0095\u00E0\u00A4\u00BE\u00E0\u00A4\u0095\u00E0\u00A5\u008B\u00E0\u00A4\u0094\u00E0\u00A4\u00B0\u00E0\u00A4\u00AA\u00E0\u00A4\u00B0\u00E0\u00A4\u00A8\u00E0\u00A5\u0087\u00E0\u00A4\u008F\u00E0\u00A4\u0095\u00E0\u00A4\u0095\u00E0\u00A4\u00BF\u00E0\u00A4\u00AD\u00E0\u00A5\u0080\u00E0\u00A4\u0087\u00E0\u00A4\u00B8\u00E0\u00A4\u0095\u00E0\u00A4\u00B0\u00E0\u00A4\u00A4\u00E0\u00A5\u008B\u00E0\u00A4\u00B9\u00E0\u00A5\u008B\u00E0\u00A4\u0086\u00E0\u00A4\u00AA\u00E0\u00A4\u00B9\u00E0\u00A5\u0080\u00E0\u00A4\u00AF\u00E0\u00A4\u00B9\u00E0\u00A4\u00AF\u00E0\u00A4\u00BE\u00E0\u00A4\u00A4\u00E0\u00A4\u0095\u00E0\u00A4\u00A5\u00E0\u00A4\u00BEjagran\u00E0\u00A4\u0086\u00E0\u00A4\u009C\u00E0\u00A4\u009C\u00E0\u00A5\u008B\u00E0\u00A4\u0085\u00E0\u00A4\u00AC\u00E0\u00A4\u00A6\u00E0\u00A5\u008B\u00E0\u00A4\u0097\u00E0\u00A4\u0088\u00E0\u00A4\u009C\u00E0\u00A4\u00BE\u00E0\u00A4\u0097\u00E0\u00A4\u008F\u00E0\u00A4\u00B9\u00E0\u00A4\u00AE\u00E0\u00A4\u0087\u00E0\u00A4\u00A8\u00E0\u00A4\u00B5\u00E0\u00A4\u00B9\u00E0\u00A4\u00AF\u00E0\u00A5\u0087\u00E0\u00A4\u00A5\u00E0\u00A5\u0087\u00E0\u00A4\u00A5\u00E0\u00A5\u0080\u00E0\u00A4\u0098\u00E0\u00A4\u00B0\u00E0\u00A4\u009C\u00E0\u00A4\u00AC\u00E0\u00A4\u00A6\u00E0\u00A5\u0080\u00E0\u00A4\u0095\u00E0\u00A4\u0088\u00E0\u00A4\u009C\u00E0\u00A5\u0080\u00E0\u00A4\u00B5\u00E0\u00A5\u0087\u00E0\u00A4\u00A8\u00E0\u00A4\u0088\u00E0\u00A4\u00A8\u00E0\u00A4\u008F\u00E0\u00A4\u00B9\u00E0\u00A4\u00B0\u00E0\u00A4\u0089\u00E0\u00A4\u00B8\u00E0\u00A4\u00AE\u00E0\u00A5\u0087\u00E0\u00A4\u0095\u00E0\u00A4\u00AE\u00E0\u00A4\u00B5\u00E0\u00A5\u008B\u00E0\u00A4\u00B2\u00E0\u00A5\u0087\u00E0\u00A4\u00B8\u00E0\u00A4\u00AC\u00E0\u00A4\u00AE\u00E0\u00A4\u0088\u00E0\u00A4\u00A6\u00E0\u00A5\u0087\u00E0\u00A4\u0093\u00E0\u00A4\u00B0\u00E0\u00A4\u0086\u00E0\u00A4\u00AE\u00E0\u00A4\u00AC\u00E0\u00A4\u00B8\u00E0\u00A4\u00AD\u00E0\u00A4\u00B0\u00E0\u00A4\u00AC\u00E0\u00A4\u00A8\u00E0\u00A4\u009A\u00E0\u00A4\u00B2\u00E0\u00A4\u00AE\u00E0\u00A4\u00A8\u00E0\u00A4\u0086\u00E0\u00A4\u0097\u00E0\u00A4\u00B8\u00E0\u00A5\u0080\u00E0\u00A4\u00B2\u00E0\u00A5\u0080\u00D8\u00B9\u00D9\u0084\u00D9\u0089\u00D8\u00A5\u00D9\u0084\u00D9\u0089\u00D9\u0087\u00D8\u00B0\u00D8\u00A7\u00D8\u00A2\u00D8\u00AE\u00D8\u00B1\u00D8\u00B9\u00D8\u00AF\u00D8\u00AF\u00D8\u00A7\u00D9\u0084\u00D9\u0089\u00D9\u0087\u00D8\u00B0\u00D9\u0087\u00D8\u00B5\u00D9\u0088\u00D8\u00B1\u00D8\u00BA\u00D9\u008A\u00D8\u00B1\u00D9\u0083\u00D8\u00A7\u00D9\u0086\u00D9\u0088\u00D9\u0084\u00D8\u00A7\u00D8\u00A8\u00D9\u008A\u00D9\u0086\u00D8\u00B9\u00D8\u00B1\u00D8\u00B6\u00D8\u00B0\u00D9\u0084\u00D9\u0083\u00D9\u0087\u00D9\u0086\u00D8\u00A7\u00D9\u008A\u00D9\u0088\u00D9\u0085\u00D9\u0082\u00D8\u00A7\u00D9\u0084\u00D8\u00B9\u00D9\u0084\u00D9\u008A\u00D8\u00A7\u00D9\u0086\u00D8\u00A7\u00D9\u0084\u00D9\u0083\u00D9\u0086\u00D8\u00AD\u00D8\u00AA\u00D9\u0089\u00D9\u0082\u00D8\u00A8\u00D9\u0084\u00D9\u0088\u00D8\u00AD\u00D8\u00A9\u00D8\u00A7\u00D8\u00AE\u00D8\u00B1\u00D9\u0081\u00D9\u0082\u00D8\u00B7\u00D8\u00B9\u00D8\u00A8\u00D8\u00AF\u00D8\u00B1\u00D9\u0083\u00D9\u0086\u00D8\u00A5\u00D8\u00B0\u00D8\u00A7\u00D9\u0083\u00D9\u0085\u00D8\u00A7\u00D8\u00A7\u00D8\u00AD\u00D8\u00AF\u00D8\u00A5\u00D9\u0084\u00D8\u00A7\u00D9\u0081\u00D9\u008A\u00D9\u0087\u00D8\u00A8\u00D8\u00B9\u00D8\u00B6\u00D9\u0083\u00D9\u008A\u00D9\u0081\u00D8\u00A8\u00D8\u00AD\u00D8\u00AB\u00D9\u0088\u00D9\u0085\u00D9\u0086\u00D9\u0088\u00D9\u0087\u00D9\u0088\u00D8\u00A3\u00D9\u0086\u00D8\u00A7\u00D8\u00AC\u00D8\u00AF\u00D8\u00A7\u00D9\u0084\u00D9\u0087\u00D8\u00A7\u00D8\u00B3\u00D9\u0084\u00D9\u0085\u00D8\u00B9\u00D9\u0086\u00D8\u00AF\u00D9\u0084\u00D9\u008A\u00D8\u00B3\u00D8\u00B9\u00D8\u00A8\u00D8\u00B1\u00D8\u00B5\u00D9\u0084\u00D9\u0089\u00D9\u0085\u00D9\u0086\u00D8\u00B0\u00D8\u00A8\u00D9\u0087\u00D8\u00A7\u00D8\u00A3\u00D9\u0086\u00D9\u0087\u00D9\u0085\u00D8\u00AB\u00D9\u0084\u00D9\u0083\u00D9\u0086\u00D8\u00AA\u00D8\u00A7\u00D9\u0084\u00D8\u00A7\u00D8\u00AD\u00D9\u008A\u00D8\u00AB\u00D9\u0085\u00D8\u00B5\u00D8\u00B1\u00D8\u00B4\u00D8\u00B1\u00D8\u00AD\u00D8\u00AD\u00D9\u0088\u00D9\u0084\u00D9\u0088\u00D9\u0081\u00D9\u008A\u00D8\u00A7\u00D8\u00B0\u00D8\u00A7\u00D9\u0084\u00D9\u0083\u00D9\u0084\u00D9\u0085\u00D8\u00B1\u00D8\u00A9\u00D8\u00A7\u00D9\u0086\u00D8\u00AA\u00D8\u00A7\u00D9\u0084\u00D9\u0081\u00D8\u00A3\u00D8\u00A8\u00D9\u0088\u00D8\u00AE\u00D8\u00A7\u00D8\u00B5\u00D8\u00A3\u00D9\u0086\u00D8\u00AA\u00D8\u00A7\u00D9\u0086\u00D9\u0087\u00D8\u00A7\u00D9\u0084\u00D9\u008A\u00D8\u00B9\u00D8\u00B6\u00D9\u0088\u00D9\u0088\u00D9\u0082\u00D8\u00AF\u00D8\u00A7\u00D8\u00A8\u00D9\u0086\u00D8\u00AE\u00D9\u008A\u00D8\u00B1\u00D8\u00A8\u00D9\u0086\u00D8\u00AA\u00D9\u0084\u00D9\u0083\u00D9\u0085\u00D8\u00B4\u00D8\u00A7\u00D8\u00A1\u00D9\u0088\u00D9\u0087\u00D9\u008A\u00D8\u00A7\u00D8\u00A8\u00D9\u0088\u00D9\u0082\u00D8\u00B5\u00D8\u00B5\u00D9\u0088\u00D9\u0085\u00D8\u00A7\u00D8\u00B1\u00D9\u0082\u00D9\u0085\u00D8\u00A3\u00D8\u00AD\u00D8\u00AF\u00D9\u0086\u00D8\u00AD\u00D9\u0086\u00D8\u00B9\u00D8\u00AF\u00D9\u0085\u00D8\u00B1\u00D8\u00A3\u00D9\u008A\u00D8\u00A7\u00D8\u00AD\u00D8\u00A9\u00D9\u0083\u00D8\u00AA\u00D8\u00A8\u00D8\u00AF\u00D9\u0088\u00D9\u0086\u00D9\u008A\u00D8\u00AC\u00D8\u00A8\u00D9\u0085\u00D9\u0086\u00D9\u0087\u00D8\u00AA\u00D8\u00AD\u00D8\u00AA\u00D8\u00AC\u00D9\u0087\u00D8\u00A9\u00D8\u00B3\u00D9\u0086\u00D8\u00A9\u00D9\u008A\u00D8\u00AA\u00D9\u0085\u00D9\u0083\u00D8\u00B1\u00D8\u00A9\u00D8\u00BA\u00D8\u00B2\u00D8\u00A9\u00D9\u0086\u00D9\u0081\u00D8\u00B3\u00D8\u00A8\u00D9\u008A\u00D8\u00AA\u00D9\u0084\u00D9\u0084\u00D9\u0087\u00D9\u0084\u00D9\u0086\u00D8\u00A7\u00D8\u00AA\u00D9\u0084\u00D9\u0083\u00D9\u0082\u00D9\u0084\u00D8\u00A8\u00D9\u0084\u00D9\u0085\u00D8\u00A7\u00D8\u00B9\u00D9\u0086\u00D9\u0087\u00D8\u00A3\u00D9\u0088\u00D9\u0084\u00D8\u00B4\u00D9\u008A\u00D8\u00A1\u00D9\u0086\u00D9\u0088\u00D8\u00B1\u00D8\u00A3\u00D9\u0085\u00D8\u00A7\u00D9\u0081\u00D9\u008A\u00D9\u0083\u00D8\u00A8\u00D9\u0083\u00D9\u0084\u00D8\u00B0\u00D8\u00A7\u00D8\u00AA\u00D8\u00B1\u00D8\u00AA\u00D8\u00A8\u00D8\u00A8\u00D8\u00A3\u00D9\u0086\u00D9\u0087\u00D9\u0085\u00D8\u00B3\u00D8\u00A7\u00D9\u0086\u00D9\u0083\u00D8\u00A8\u00D9\u008A\u00D8\u00B9\u00D9\u0081\u00D9\u0082\u00D8\u00AF\u00D8\u00AD\u00D8\u00B3\u00D9\u0086\u00D9\u0084\u00D9\u0087\u00D9\u0085\u00D8\u00B4\u00D8\u00B9\u00D8\u00B1\u00D8\u00A3\u00D9\u0087\u00D9\u0084\u00D8\u00B4\u00D9\u0087\u00D8\u00B1\u00D9\u0082\u00D8\u00B7\u00D8\u00B1\u00D8\u00B7\u00D9\u0084\u00D8\u00A8profileservicedefaulthimselfdetailscontentsupportstartedmessagesuccessfashioncountryaccountcreatedstoriesresultsrunningprocesswritingobjectsvisiblewelcomearticleunknownnetworkcompanydynamicbrowserprivacyproblemServicerespectdisplayrequestreservewebsitehistoryfriendsoptionsworkingversionmillionchannelwindow.addressvisitedweathercorrectproductedirectforwardyou canremovedsubjectcontrolarchivecurrentreadinglibrarylimitedmanagerfurthersummarymachineminutesprivatecontextprogramsocietynumberswrittenenabledtriggersourcesloadingelementpartnerfinallyperfectmeaningsystemskeepingculture",journalprojectsurfaces"expiresreviewsbalanceEnglishContentthroughPlease opinioncontactaverageprimaryvillageSpanishgallerydeclinemeetingmissionpopularqualitymeasuregeneralspeciessessionsectionwriterscounterinitialreportsfiguresmembersholdingdisputeearlierexpressdigitalpictureAnothermarriedtrafficleadingchangedcentralvictoryimages/reasonsstudiesfeaturelistingmust beschoolsVersionusuallyepisodeplayinggrowingobviousoverlaypresentactions\r\nwrapperalreadycertainrealitystorageanotherdesktopofferedpatternunusualDigitalcapitalWebsitefailureconnectreducedAndroiddecadesregular & animalsreleaseAutomatgettingmethodsnothingPopularcaptionletterscapturesciencelicensechangesEngland=1&History = new CentralupdatedSpecialNetworkrequirecommentwarningCollegetoolbarremainsbecauseelectedDeutschfinanceworkersquicklybetweenexactlysettingdiseaseSocietyweaponsexhibit<!--Controlclassescoveredoutlineattacksdevices(windowpurposetitle=\"Mobile killingshowingItaliandroppedheavilyeffects-1']);\nconfirmCurrentadvancesharingopeningdrawingbillionorderedGermanyrelatedincludewhetherdefinedSciencecatalogArticlebuttonslargestuniformjourneysidebarChicagoholidayGeneralpassage,"animatefeelingarrivedpassingnaturalroughly.\n\nThe but notdensityBritainChineselack oftributeIreland\" data-factorsreceivethat isLibraryhusbandin factaffairsCharlesradicalbroughtfindinglanding:lang=\"return leadersplannedpremiumpackageAmericaEdition]"Messageneed tovalue=\"complexlookingstationbelievesmaller-mobilerecordswant tokind ofFirefoxyou aresimilarstudiedmaximumheadingrapidlyclimatekingdomemergedamountsfoundedpioneerformuladynastyhow to SupportrevenueeconomyResultsbrothersoldierlargelycalling."AccountEdward segmentRobert effortsPacificlearnedup withheight:we haveAngelesnations_searchappliedacquiremassivegranted: falsetreatedbiggestbenefitdrivingStudiesminimumperhapsmorningsellingis usedreversevariant role=\"missingachievepromotestudentsomeoneextremerestorebottom:evolvedall thesitemapenglishway to AugustsymbolsCompanymattersmusicalagainstserving})();\r\npaymenttroubleconceptcompareparentsplayersregionsmonitor ''The winningexploreadaptedGalleryproduceabilityenhancecareers). The collectSearch ancientexistedfooter handlerprintedconsoleEasternexportswindowsChannelillegalneutralsuggest_headersigning.html\">settledwesterncausing-webkitclaimedJusticechaptervictimsThomas mozillapromisepartieseditionoutside:false,hundredOlympic_buttonauthorsreachedchronicdemandssecondsprotectadoptedprepareneithergreatlygreateroverallimprovecommandspecialsearch.worshipfundingthoughthighestinsteadutilityquarterCulturetestingclearlyexposedBrowserliberal} catchProjectexamplehide();FloridaanswersallowedEmperordefenseseriousfreedomSeveral-buttonFurtherout of != nulltrainedDenmarkvoid(0)/all.jspreventRequestStephen\n\nWhen observe\r\nModern provide\" alt=\"borders.\n\nFor \n\nMany artistspoweredperformfictiontype ofmedicalticketsopposedCouncilwitnessjusticeGeorge Belgium...twitternotablywaitingwarfare Other rankingphrasesmentionsurvivescholar\r\n Countryignoredloss ofjust asGeorgiastrange\n severalbecomesselect wedding00.htmlmonarchoff theteacherhighly biologylife ofor evenrise of»plusonehunting(thoughDouglasjoiningcirclesFor theAncientVietnamvehiclesuch ascrystalvalue =Windowsenjoyeda smallassumedconvertviolententeredfirst\">circuitFinlandchemistshe was10px;\">as suchdividedwill beline ofa greatmystery/index.fallingdue to railwaycollegemonsterdescentit withnuclearJewish protestBritishflowerspredictreformsbutton who waslectureinstantsuicidegenericperiodsmarketsSocial fishingcombinegraphicwinnerstooltipSectiondesignsTurkishyounger.match(})();\n\nburningoperatedegreessource=Richardcloselyplasticentries\r\ncolor:#ul id=\"possessrollingphysicsfailingexecutecontestlink toDefault \n: true,chartertourismclassicproceedexplain\r\nonline.?xml vehelpingdiamonduse theairlineend -->).attr(readershosting#ffffffrealizeVincentsignals src=\"/ProductdespitediversetellingPublic held inJoseph theatreaffects\nreductionDecember preferredCambridgeopponentsBusiness confusion>\npresentedexplaineddoes not worldwideinterfacepositionsnewspaper\nmountainslike the essentialfinancialselectionaction=\"/abandonedEducationparseInt(stabilityunable to \nrelationsNote thatefficientperformedtwo yearsSince thethereforewrapper\">alternateincreasedBattle ofperceivedtrying tonecessaryportrayedelectionsElizabethdiscoveryinsurances.length;legendaryGeographycandidatecorporatesometimesservices.inheritedCommunityreligiouslocationsCommitteebuildingsthe worldno longerbeginningreferencecannot befrequencytypicallyinto the relative;recordingpresidentinitiallytechniquethe otherit can beexistenceunderlinethis timetelephoneitemscopepracticesadvantage);return For otherprovidingdemocracyboth the extensivesufferingsupportedcomputers functionpracticalsaid thatit may beEnglish\nsuspectedmargin: 0spiritual\n\nmicrosoftgraduallydiscussedhe becameexecutivejquery.jshouseholdconfirmedpurchasedliterallydestroyedup to thevariationremainingit is notcenturiesJapanese among thecompletedalgorithminterestsrebellionundefinedencourageresizableinvolvingsensitiveuniversalprovision(althoughfeaturingconducted), which continued-header\">February numerous overflow:componentfragmentsexcellentcolspan=\"technicalnear the Advanced source ofexpressedHong Kong Facebookmultiple mechanismelevationoffensive\n\tsponsoreddocument.or "there arethose whomovementsprocessesdifficultsubmittedrecommendconvincedpromoting\" width=\".replace(classicalcoalitionhis firstdecisionsassistantindicatedevolution-wrapper\"enough toalong thedelivered-->\r\n\n\r\nArchbishop class=\"nobeing usedapproachesprivilegesnoscript>\nresults inmay be theEaster eggmechanismsreasonablePopulationCollectionselected\">noscript>\r/index.phparrival of-jssdk'));managed toincompletecasualtiescompletionChristiansSeptember arithmeticproceduresmight haveProductionit appearsPhilosophyfriendshipleading togiving thetoward theguaranteeddocumentedcolor:#000video gamecommissionreflectingchange theassociatedsans-serifonkeypress; padding:He was theunderlyingtypically , and the srcElementsuccessivesince the should be networkingaccountinguse of thelower thanshows that\n\t\tcomplaintscontinuousquantitiesastronomerhe did notdue to itsapplied toan averageefforts tothe futureattempt toTherefore,capabilityRepublicanwas formedElectronickilometerschallengespublishingthe formerindigenousdirectionssubsidiaryconspiracydetails ofand in theaffordablesubstancesreason forconventionitemtype=\"absolutelysupposedlyremained aattractivetravellingseparatelyfocuses onelementaryapplicablefound thatstylesheetmanuscriptstands for no-repeat(sometimesCommercialin Americaundertakenquarter ofan examplepersonallyindex.php?\npercentagebest-knowncreating a\" dir=\"ltrLieutenant\n
is said tostructuralreferendummost oftena separate->\n
soundtracksearchFormtend to beinput id=\"opening ofrestrictedadopted byaddressingtheologianmethods ofvariant ofChristian very largeautomotiveby far therange frompursuit offollow thebrought toin Englandagree thataccused ofcomes frompreventingdiv style=his or hertremendousfreedom ofconcerning0 1em 1em;Basketball/style.cssan earliereven after/\" title=\".com/indextaking thepittsburghcontent\">\rimplementedcan be seenthere was ademonstratecontainer\">connectionsthe Britishwas written!important;px; margin-followed byability to complicatedduring the immigrationalso called
\n acquisitioncalled the persecutiondesignation{font-size:appeared ininvestigateexperiencedmost likelywidely useddiscussionspresence of (document.extensivelyIt has beenit does notcontrary toinhabitantsimprovementscholarshipconsumptioninstructionfor exampleone or morepx; paddingthe currenta series ofare usuallyrole in thepreviously derivativesevidence ofexperiencescolorschemestated thatcertificate
\n selected=\"high schoolresponse tocomfortableadoption ofthree yearsthe countryin Februaryso that thepeople who provided by \nhaving been\r\n\r\n< "The compilationhe had beenproduced byphilosopherconstructedintended toamong othercompared toto say thatEngineeringa differentreferred todifferencesbelief thatphotographsidentifyingHistory of Republic ofnecessarilyprobabilitytechnicallyleaving thespectacularfraction ofelectricityhead of therestaurantspartnershipemphasis onmost recentshare with saying thatfilled withdesigned toit is often\">as follows:merged withthrough thecommercial pointed outopportunityview of therequirementdivision ofprogramminghe receivedsetInterval\">maintainingChristopherMuch of thewritings of\" height=\"2size of theversion of mixture of between theExamples ofeducationalcompetitive onsubmit=\"director ofdistinctive/DTD XHTML relating totendency toprovince ofwhich woulddespite thescientific legislature.innerHTML allegationsAgriculturewas used inapproach tointelligentyears later,sans-serifdeterminingPerformanceappearances, which is foundationsabbreviatedhigher thans from the individual composed ofsupposed toclaims thatattributionfont-size:1elements ofHistorical his brotherat the timeanniversarygoverned byrelated to ultimately innovationsit is stillcan only bedefinitionstoGMTStringA number ofimg class=\"Eventually,was changedoccurred inneighboringdistinguishwhen he wasintroducingterrestrialMany of theargues thatan Americanconquest ofwidespread were killedscreen and In order toexpected todescendantsare locatedlegislativegenerations backgroundmost peopleyears afterthere is nothe highestfrequently they do notargued thatshowed thatpredominanttheologicalby the timeconsideringshort-lived can be usedvery littleone of the had alreadyinterpretedcommunicatefeatures ofgovernment,entered the\" height=\"3Independentpopulationslarge-scale. Although used in thedestructionpossibilitystarting intwo or moreexpressionssubordinatelarger thanhistory and\r\nContinentaleliminatingwill not bepractice ofin front ofsite of theensure thatto create amississippipotentiallyoutstandingbetter thanwhat is nowsituated inmeta name=\"TraditionalsuggestionsTranslationthe form ofatmosphericideologicalenterprisescalculatingeast of theremnants ofpluginspage/index.php?remained intransformedHe was alsowas alreadystatisticalin favor ofMinistry ofmovement offormulationis required\nquestion ofwas electedto become abecause of some peopleinspired bysuccessful a time whenmore commonamongst thean officialwidth:100%;technology,was adoptedto keep thesettlementslive birthsindex.html\"Connecticutassigned to×account foralign=rightthe companyalways beenreturned toinvolvementBecause thethis period\" name=\"q\" confined toa result ofvalue=\"\" />is actuallyEnvironment\r\n\r\nConversely,>\nthis is notthe presentif they areand finallya matter of\r\n\t
\r\n\r\nfaster thanmajority ofafter whichcomparativeto maintainimprove theawarded theer\" class=\"frameborderrestorationin the sameanalysis oftheir firstDuring the continentalsequence offunction(){font-size: work on the\nadopted theproperty ofdirected byeffectivelywas broughtchildren ofProgramminglonger thanmanuscriptswar againstby means ofand most ofsimilar to proprietaryoriginatingprestigiousgrammaticalexperience.to make theIt was alsois found incompetitorsin the U.S.replace thebrought thecalculationfall of thethe generalpracticallyin honor ofreleased inresidentialand some ofking of thereaction to1st Earl ofculture andprincipally \n they can beback to thesome of hisexposure toare similarform of theaddFavoritecitizenshippart in thepeople within practiceto continue−approved by the first allowed theand for thefunctioningplaying thesolution toheight=\"0\" in his bookmore than afollows thecreated thepresence in nationalistthe idea ofa characterwere forced class=\"btndays of thefeatured inshowing theinterest inin place ofturn of thethe head ofLord of thepoliticallyhas its ownEducationalapproval ofsome of theeach other,behavior ofand becauseand anotherappeared onrecorded inblack"may includethe world'scan lead torefers to aborder=\"0\" government winning theresulted in while the Washington,the subjectcity in the>\r\n\t\treflect theto completebecame moreradioactiverejected bywithout anyhis father,which couldcopy of theto indicatea politicalaccounts ofconstitutesworked witherof his lifeaccompaniedclientWidthprevent theLegislativedifferentlytogether inhas severalfor anothertext of thefounded thee with the is used forchanged theusually theplace wherewhereas the> \nHowever thelead to the\t The currentthe site ofsubstantialexperience,in the Westthey shouldsloven\u00C4\u008Dinacomentariosuniversidadcondicionesactividadesexperienciatecnolog\u00C3\u00ADaproducci\u00C3\u00B3npuntuaci\u00C3\u00B3naplicaci\u00C3\u00B3ncontrase\u00C3\u00B1acategor\u00C3\u00ADasregistrarseprofesionaltratamientoreg\u00C3\u00ADstratesecretar\u00C3\u00ADaprincipalesprotecci\u00C3\u00B3nimportantesimportanciaposibilidadinteresantecrecimientonecesidadessuscribirseasociaci\u00C3\u00B3ndisponiblesevaluaci\u00C3\u00B3nestudiantesresponsableresoluci\u00C3\u00B3nguadalajararegistradosoportunidadcomercialesfotograf\u00C3\u00ADaautoridadesingenier\u00C3\u00ADatelevisi\u00C3\u00B3ncompetenciaoperacionesestablecidosimplementeactualmentenavegaci\u00C3\u00B3nconformidadline-height:font-family:\" : \"http://applicationslink\" href=\"specifically//\n/index.html\"window.open( !important;application/independence//www.googleorganizationautocompleterequirementsconservative notification'undefined')Furthermore,believe thatinnerHTML = prior to thedramaticallyreferring tonegotiationsheadquartersSouth AfricaunsuccessfulPennsylvaniaAs a result,\npadding-top:experimentalgetAttributeinstructionstechnologiespart of the =function(){subscriptionl.dtd\">\r\nEnglish (US)appendChild(transmissions. However, intelligence\" tabindex=\"float:right;Commonwealthranging fromin which theat least onereproductionencyclopedia;font-size:1jurisdictionat that time\">compensationchampionshipmedia=\"all\" violation ofreference toreturn true;Strict//EN\" transactionsinterventionverificationInformation difficultiesChampionshipcapabilities}\n\nChristianityfor example,Professionalrestrictionssuggest thatwas released(such as theremoveClass(unemploymentthe Americanstructure of/index.html published inspan class=\"\"> \n\nf (document.border: 1px {font-size:1treatment of0\" height=\"1modificationIndependencedivided intogreater thanachievementsestablishingJavaScript\" neverthelesssignificanceBroadcasting> container\">\nsuch as the influence ofa particularsrc='http://navigation\" half of the substantial advantage ofdiscovery offundamental metropolitanthe opposite\" xml:lang=\"deliberatelyalign=centerevolution ofpreservationimprovementsbeginning inJesus ChristPublicationsdisagreementtext-align:r, function()similaritiesbody>is currentlyalphabeticalis sometimestype=\"image/many of the flow:hidden;available indescribe theexistence ofall over thethe Internet\t\n\n\t\t\n\nan effort toincrease theto the southspacing=\"0\">sufficientlythe Europeanconverted toclearTimeoutdid not haveconsequentlyfor the nextextension ofeconomic andalthough theare producedand with theinsufficientgiven by thestating thatexpenditures\nthought thaton the basiscellpadding=image of thereturning toinformation,separated byassassinateds\" content=\"authority ofnorthwestern
\n
\r\n consultationcommunity ofthe nationalit should beparticipants align=\"leftthe greatestselection ofsupernaturaldependent onis mentionedallowing thewas inventedaccompanyinghis personalavailable atstudy of theon the otherexecution ofHuman Rightsterms of theassociationsresearch andsucceeded bydefeated theand from thebut they arecommander ofstate of theyears of agethe study of