From 1564e9ff8117d04ab3e53e1c83dea7061a9ab176 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Sat, 19 Sep 2015 11:06:15 +0800 Subject: [PATCH 01/23] support onetime auth --- .../Controller/Service/TCPRelay.cs | 2 +- shadowsocks-csharp/Data/cn.txt | 1 + shadowsocks-csharp/Data/libsscrypto2.dll.gz | Bin 0 -> 45874 bytes .../Encryption/EncryptorBase.cs | 4 +- .../Encryption/EncryptorFactory.cs | 6 +- shadowsocks-csharp/Encryption/IVEncryptor.cs | 68 ++++++++++- .../Encryption/PolarSSLEncryptor.cs | 4 +- shadowsocks-csharp/Encryption/Sodium.cs | 37 +++++- .../Encryption/SodiumEncryptor.cs | 4 +- .../Encryption/TableEncryptor.cs | 4 +- shadowsocks-csharp/Model/Server.cs | 5 + .../Properties/Resources.Designer.cs | 106 ++++++++++-------- shadowsocks-csharp/Properties/Resources.resx | 3 + .../View/ConfigForm.Designer.cs | 53 +++++---- shadowsocks-csharp/View/ConfigForm.cs | 5 +- shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 16 files changed, 219 insertions(+), 84 deletions(-) create mode 100644 shadowsocks-csharp/Data/libsscrypto2.dll.gz diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index bf0497d4..c1b39a04 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -124,7 +124,7 @@ namespace Shadowsocks.Controller { throw new ArgumentException("No server configured"); } - this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password); + this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.one_time_auth); this.server = server; } diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 81022f99..813578b7 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -39,6 +39,7 @@ Password=密码 Encryption=加密 Proxy Port=代理端口 Remarks=备注 +One-time authorization=一次性授权 OK=确定 Cancel=取消 New server=未配置的服务器 diff --git a/shadowsocks-csharp/Data/libsscrypto2.dll.gz b/shadowsocks-csharp/Data/libsscrypto2.dll.gz new file mode 100644 index 0000000000000000000000000000000000000000..83f7aab1186c37fedb817114cf895fad08b7100b GIT binary patch literal 45874 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 literal 0 HcmV?d00001 diff --git a/shadowsocks-csharp/Encryption/EncryptorBase.cs b/shadowsocks-csharp/Encryption/EncryptorBase.cs index 8b5cd61a..b92233ec 100644 --- a/shadowsocks-csharp/Encryption/EncryptorBase.cs +++ b/shadowsocks-csharp/Encryption/EncryptorBase.cs @@ -8,14 +8,16 @@ namespace Shadowsocks.Encryption { public const int MAX_INPUT_SIZE = 32768; - protected EncryptorBase(string method, string password) + protected EncryptorBase(string method, string password, bool onetimeauth) { Method = method; Password = password; + OnetimeAuth = onetimeauth; } protected string Method; protected string Password; + protected bool OnetimeAuth; protected byte[] GetPasswordHash() { diff --git a/shadowsocks-csharp/Encryption/EncryptorFactory.cs b/shadowsocks-csharp/Encryption/EncryptorFactory.cs index d5ff15e3..120bd53c 100644 --- a/shadowsocks-csharp/Encryption/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encryption/EncryptorFactory.cs @@ -8,7 +8,7 @@ namespace Shadowsocks.Encryption { private static Dictionary _registeredEncryptors; - private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string) }; + private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string), typeof(bool) }; static EncryptorFactory() { @@ -27,7 +27,7 @@ namespace Shadowsocks.Encryption } } - public static IEncryptor GetEncryptor(string method, string password) + public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth = false) { if (string.IsNullOrEmpty(method)) { @@ -36,7 +36,7 @@ namespace Shadowsocks.Encryption method = method.ToLowerInvariant(); Type t = _registeredEncryptors[method]; ConstructorInfo c = t.GetConstructor(_constructorTypes); - IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password }); + IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password, onetimeauth }); return result; } } diff --git a/shadowsocks-csharp/Encryption/IVEncryptor.cs b/shadowsocks-csharp/Encryption/IVEncryptor.cs index b82d3adf..869cdb58 100755 --- a/shadowsocks-csharp/Encryption/IVEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IVEncryptor.cs @@ -2,12 +2,19 @@ using System.Collections.Generic; using System.Security.Cryptography; using System.Text; +using System.Net; namespace Shadowsocks.Encryption { public abstract class IVEncryptor : EncryptorBase { + public const int ONETIMEAUTH_FLAG = 0x10; + public const int ADDRTYPE_MASK = 0xF; + public const int ONETIMEAUTH_BYTES = 16; + public const int CRC_BUF_LEN = 128; + public const int CRC_BYTES = 2; + protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE]; protected Dictionary ciphers; @@ -25,11 +32,17 @@ namespace Shadowsocks.Encryption protected byte[] _key; protected int keyLen; protected int ivLen; + protected byte[] crc_buf; + protected int crc_idx = 0; - public IVEncryptor(string method, string password) - : base(method, password) + public IVEncryptor(string method, string password, bool onetimeauth) + : base(method, password, onetimeauth) { InitKey(method, password); + if (OnetimeAuth) + { + crc_buf = new byte[CRC_BUF_LEN]; + } } protected abstract Dictionary getCiphers(); @@ -112,6 +125,28 @@ namespace Shadowsocks.Encryption protected abstract void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf); + protected int GetSSHeadLength(byte[] buf, int length) + { + int len = 0; + int atyp = length > 0 ? (buf[0] & ADDRTYPE_MASK) : 0; + if (atyp == 1) + { + len = 7; // atyp (1 bytes) + ipv4 (4 bytes) + port (2 bytes) + } + else if (atyp == 3 && length > 1) + { + int nameLen = buf[1]; + len = 4 + nameLen; // atyp (1 bytes) + name length (1 bytes) + name (n bytes) + port (2 bytes) + } + else if (atyp == 4) + { + len = 19; // atyp (1 bytes) + ipv6 (16 bytes) + port (2 bytes) + } + if (len == 0 || len > length) + throw new Exception($"invalid header with addr type {atyp}"); + return len; + } + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { if (!_encryptIVSent) @@ -122,6 +157,24 @@ namespace Shadowsocks.Encryption outlength = length + ivLen; lock (tempbuf) { + if (OnetimeAuth) + { + lock(crc_buf) + { + int headLen = GetSSHeadLength(buf, length); + int data_len = length - headLen; + Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES, data_len); + buf[0] |= ONETIMEAUTH_FLAG; + byte[] auth = new byte[ONETIMEAUTH_BYTES]; + Sodium.ss_onetimeauth(auth, buf, headLen, _encryptIV, ivLen, _key, keyLen); + Buffer.BlockCopy(auth, 0, buf, headLen, ONETIMEAUTH_BYTES); + int buf_offset = headLen + ONETIMEAUTH_BYTES; + int rc = Sodium.ss_gen_crc(buf, ref buf_offset, ref data_len, crc_buf, ref crc_idx, buf.Length); + if (rc != 0) + throw new Exception("failed to generate crc"); + length = headLen + ONETIMEAUTH_BYTES + data_len; + } + } cipherUpdate(true, length, buf, tempbuf); outlength = length + ivLen; Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); @@ -129,6 +182,16 @@ namespace Shadowsocks.Encryption } else { + if (OnetimeAuth) + { + lock(crc_buf) + { + int buf_offset = 0; + int rc = Sodium.ss_gen_crc(buf, ref buf_offset, ref length, crc_buf, ref crc_idx, buf.Length); + if (rc != 0) + throw new Exception("failed to generate crc"); + } + } outlength = length; cipherUpdate(true, length, buf, outbuf); } @@ -154,5 +217,6 @@ namespace Shadowsocks.Encryption cipherUpdate(false, length, buf, outbuf); } } + } } diff --git a/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs index 6216c24d..3aca3f72 100755 --- a/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs +++ b/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs @@ -16,8 +16,8 @@ namespace Shadowsocks.Encryption private IntPtr _encryptCtx = IntPtr.Zero; private IntPtr _decryptCtx = IntPtr.Zero; - public PolarSSLEncryptor(string method, string password) - : base(method, password) + public PolarSSLEncryptor(string method, string password, bool onetimeauth) + : base(method, password, onetimeauth) { InitKey(method, password); } diff --git a/shadowsocks-csharp/Encryption/Sodium.cs b/shadowsocks-csharp/Encryption/Sodium.cs index 564aaeda..14403267 100755 --- a/shadowsocks-csharp/Encryption/Sodium.cs +++ b/shadowsocks-csharp/Encryption/Sodium.cs @@ -12,8 +12,15 @@ namespace Shadowsocks.Encryption public class Sodium { const string DLLNAME = "libsscrypto"; + const string DLLNAME2 = "libsscrypto2"; static Sodium() + { + LoadSSCryptoLibrary(); + LoadSSCrypto2Library(); + } + + static void LoadSSCryptoLibrary() { string tempPath = Utils.GetTempPath(); string dllPath = tempPath + "/libsscrypto.dll"; @@ -29,7 +36,24 @@ namespace Shadowsocks.Encryption { Console.WriteLine(e.ToString()); } - LoadLibrary(dllPath); + } + + static void LoadSSCrypto2Library() + { + string tempPath = Utils.GetTempPath(); + string dllPath = tempPath + "/libsscrypto2.dll"; + try + { + FileManager.UncompressFile(dllPath, Resources.libsscrypto2_dll); + LoadLibrary(dllPath); + } + catch (IOException) + { + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } } [DllImport("Kernel32.dll")] @@ -40,5 +64,16 @@ namespace Shadowsocks.Encryption [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] public extern static void crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); + + [DllImport(DLLNAME2, CallingConvention = CallingConvention.Cdecl)] + public extern static int ss_gen_crc(byte[] buf, ref int buf_offset, ref int data_len, + byte[] crc_buf, ref int crc_idx, int buf_size); + + [DllImport(DLLNAME2, CallingConvention = CallingConvention.Cdecl)] + public extern static int ss_onetimeauth(byte[] auth, + byte[] msg, int msg_len, + byte[] iv, int iv_len, + byte[] key, int key_len); } } + diff --git a/shadowsocks-csharp/Encryption/SodiumEncryptor.cs b/shadowsocks-csharp/Encryption/SodiumEncryptor.cs index af51d0ac..8ab8e255 100755 --- a/shadowsocks-csharp/Encryption/SodiumEncryptor.cs +++ b/shadowsocks-csharp/Encryption/SodiumEncryptor.cs @@ -20,8 +20,8 @@ namespace Shadowsocks.Encryption protected ulong _encryptIC; protected ulong _decryptIC; - public SodiumEncryptor(string method, string password) - : base(method, password) + public SodiumEncryptor(string method, string password, bool onetimeauth) + : base(method, password, onetimeauth) { InitKey(method, password); } diff --git a/shadowsocks-csharp/Encryption/TableEncryptor.cs b/shadowsocks-csharp/Encryption/TableEncryptor.cs index db0a7db0..3de625a6 100644 --- a/shadowsocks-csharp/Encryption/TableEncryptor.cs +++ b/shadowsocks-csharp/Encryption/TableEncryptor.cs @@ -6,8 +6,8 @@ namespace Shadowsocks.Encryption public class TableEncryptor : EncryptorBase { - public TableEncryptor(string method, string password) - : base(method, password) + public TableEncryptor(string method, string password, bool onetimeauth) + : base(method, password, onetimeauth) { byte[] hash = GetPasswordHash(); // TODO endian diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index 24dd1162..55134335 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -17,6 +17,7 @@ namespace Shadowsocks.Model public string password; public string method; public string remarks; + public bool one_time_auth; public override int GetHashCode() { @@ -52,6 +53,7 @@ namespace Shadowsocks.Model this.method = "aes-256-cfb"; this.password = ""; this.remarks = ""; + this.one_time_auth = false; } public Server(string ssURL) : this() @@ -88,6 +90,9 @@ namespace Shadowsocks.Model string[] parts = beforeAt.Split(new[] { ':' }); this.method = parts[0]; this.password = parts[1]; + + //TODO: read one_time_auth + } catch (IndexOutOfRangeException) { diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index 198e9f48..a5891002 100644 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 // //------------------------------------------------------------------------------ @@ -13,12 +13,12 @@ namespace Shadowsocks.Properties { /// - /// A strongly-typed resource class, for looking up localized strings, etc. + /// 一个强类型的资源类,用于查找本地化的字符串等。 /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] @@ -33,7 +33,7 @@ namespace Shadowsocks.Properties { } /// - /// Returns the cached ResourceManager instance used by this class. + /// 返回此类使用的缓存的 ResourceManager 实例。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { @@ -47,8 +47,8 @@ namespace Shadowsocks.Properties { } /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { @@ -61,7 +61,7 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Byte[]. + /// 查找 System.Byte[] 类型的本地化资源。 /// internal static byte[] abp_js { get { @@ -71,30 +71,28 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized string similar to # translation for Simplified Chinese - /// - ///Shadowsocks=Shadowsocks - /// - ///# Menu items - /// - ///Enable System Proxy=启用系统代理 - ///Mode=系统代理模式 - ///PAC=PAC 模式 - ///Global=全局模式 - ///Servers=服务器 - ///Edit Servers...=编辑服务器... - ///Start on Boot=开机启动 - ///Allow Clients from LAN=允许来自局域网的连接 - ///Local PAC=使用本地 PAC - ///Online PAC=使用在线 PAC - ///Edit Local PAC File...=编辑本地 PAC 文件... - ///Update Local PAC from GFWList=从 GFWList 更新本地 PAC - ///Edit User Rule for GFWList...=编辑 GFWList 的用户规则... - ///Show QRCode...=显示二维码... - ///Scan QRCode from Screen...=扫描屏幕上的二维码... - ///Show Logs...=显示日志... - ///About...=关于... - ///Quit=退出 [rest of string was truncated]";. + /// 查找类似 # translation for Simplified Chinese + /// + ///Shadowsocks=Shadowsocks + /// + ///# Menu items + /// + ///Enable System Proxy=启用系统代理 + ///Mode=系统代理模式 + ///PAC=PAC 模式 + ///Global=全局模式 + ///Servers=服务器 + ///Edit Servers...=编辑服务器... + ///Start on Boot=开机启动 + ///Allow Clients from LAN=允许来自局域网的连接 + ///Local PAC=使用本地 PAC + ///Online PAC=使用在线 PAC + ///Edit Local PAC File...=编辑本地 PAC 文件... + ///Update Local PAC from GFWList=从 GFWList 更新本地 PAC + ///Edit User Rule for GFWList...=编辑 GFWList 的用户规则... + ///Show QRCode...=显示二维码... + ///Scan QRCode from Screen...=扫描屏幕上的二维码... + ///Availability Statistic [字符串的其余部分被截断]"; 的本地化字符串。 /// internal static string cn { get { @@ -103,7 +101,7 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Byte[]. + /// 查找 System.Byte[] 类型的本地化资源。 /// internal static byte[] libsscrypto_dll { get { @@ -113,7 +111,17 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Byte[]. + /// 查找 System.Byte[] 类型的本地化资源。 + /// + internal static byte[] libsscrypto2_dll { + get { + object obj = ResourceManager.GetObject("libsscrypto2_dll", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// 查找 System.Byte[] 类型的本地化资源。 /// internal static byte[] mgwz_dll { get { @@ -123,11 +131,11 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized string similar to listen-address __POLIPO_BIND_IP__:8123 + /// 查找类似 listen-address __POLIPO_BIND_IP__:8123 ///show-on-task-bar 0 ///activity-animation 0 ///forward-socks5 / 127.0.0.1:__SOCKS_PORT__ . - ///hide-console. + ///hide-console 的本地化字符串。 /// internal static string privoxy_conf { get { @@ -136,7 +144,7 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Byte[]. + /// 查找 System.Byte[] 类型的本地化资源。 /// internal static byte[] privoxy_exe { get { @@ -146,7 +154,7 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Byte[]. + /// 查找 System.Byte[] 类型的本地化资源。 /// internal static byte[] proxy_pac_txt { get { @@ -156,7 +164,7 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Drawing.Bitmap. + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// internal static System.Drawing.Bitmap ss16 { get { @@ -166,7 +174,7 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Drawing.Bitmap. + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// internal static System.Drawing.Bitmap ss20 { get { @@ -176,7 +184,7 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Drawing.Bitmap. + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// internal static System.Drawing.Bitmap ss24 { get { @@ -186,7 +194,7 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized resource of type System.Drawing.Bitmap. + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// internal static System.Drawing.Bitmap ssw128 { get { @@ -196,9 +204,9 @@ namespace Shadowsocks.Properties { } /// - /// Looks up a localized string similar to ! Put user rules line by line in this file. + /// 查找类似 ! Put user rules line by line in this file. ///! See https://adblockplus.org/en/filter-cheatsheet - ///. + /// 的本地化字符串。 /// internal static string user_rule { get { diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index aa0c2f63..36dc1386 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -124,6 +124,9 @@ ..\data\cn.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + ..\Data\libsscrypto2.dll.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\data\libsscrypto.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index f8b5940a..e985937e 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -55,6 +55,7 @@ this.ProxyPortLabel = new System.Windows.Forms.Label(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); + this.OneTimeAuth = new System.Windows.Forms.CheckBox(); this.tableLayoutPanel1.SuspendLayout(); this.ServerGroupBox.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); @@ -81,18 +82,20 @@ this.tableLayoutPanel1.Controls.Add(this.PasswordTextBox, 1, 2); this.tableLayoutPanel1.Controls.Add(this.EncryptionLabel, 0, 3); this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3); + this.tableLayoutPanel1.Controls.Add(this.OneTimeAuth, 1, 6); this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3); - this.tableLayoutPanel1.RowCount = 6; + this.tableLayoutPanel1.RowCount = 7; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(238, 137); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(238, 160); this.tableLayoutPanel1.TabIndex = 0; // // RemarksTextBox @@ -102,7 +105,7 @@ this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); - this.RemarksTextBox.TabIndex = 10; + this.RemarksTextBox.TabIndex = 4; this.RemarksTextBox.WordWrap = false; // // RemarksLabel @@ -188,7 +191,7 @@ // // EncryptionSelect // - this.EncryptionSelect.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.EncryptionSelect.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.EncryptionSelect.FormattingEnabled = true; @@ -226,7 +229,7 @@ this.OKButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); this.OKButton.Name = "OKButton"; this.OKButton.Size = new System.Drawing.Size(75, 23); - this.OKButton.TabIndex = 8; + this.OKButton.TabIndex = 12; this.OKButton.Text = "OK"; this.OKButton.UseVisualStyleBackColor = true; this.OKButton.Click += new System.EventHandler(this.OKButton_Click); @@ -239,7 +242,7 @@ this.MyCancelButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0); this.MyCancelButton.Name = "MyCancelButton"; this.MyCancelButton.Size = new System.Drawing.Size(75, 23); - this.MyCancelButton.TabIndex = 9; + this.MyCancelButton.TabIndex = 13; this.MyCancelButton.Text = "Cancel"; this.MyCancelButton.UseVisualStyleBackColor = true; this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click); @@ -251,7 +254,7 @@ this.DeleteButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3); this.DeleteButton.Name = "DeleteButton"; this.DeleteButton.Size = new System.Drawing.Size(80, 23); - this.DeleteButton.TabIndex = 7; + this.DeleteButton.TabIndex = 9; this.DeleteButton.Text = "&Delete"; this.DeleteButton.UseVisualStyleBackColor = true; this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); @@ -263,7 +266,7 @@ this.AddButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); this.AddButton.Name = "AddButton"; this.AddButton.Size = new System.Drawing.Size(80, 23); - this.AddButton.TabIndex = 6; + this.AddButton.TabIndex = 8; this.AddButton.Text = "&Add"; this.AddButton.UseVisualStyleBackColor = true; this.AddButton.Click += new System.EventHandler(this.AddButton_Click); @@ -276,8 +279,8 @@ this.ServerGroupBox.Location = new System.Drawing.Point(178, 0); this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Size = new System.Drawing.Size(249, 174); - this.ServerGroupBox.TabIndex = 6; + this.ServerGroupBox.Size = new System.Drawing.Size(249, 197); + this.ServerGroupBox.TabIndex = 0; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; // @@ -285,12 +288,11 @@ // this.ServersListBox.FormattingEnabled = true; this.ServersListBox.IntegralHeight = false; - this.ServersListBox.ItemHeight = 12; this.ServersListBox.Location = new System.Drawing.Point(0, 0); this.ServersListBox.Margin = new System.Windows.Forms.Padding(0); this.ServersListBox.Name = "ServersListBox"; this.ServersListBox.Size = new System.Drawing.Size(166, 148); - this.ServersListBox.TabIndex = 5; + this.ServersListBox.TabIndex = 7; this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); // // tableLayoutPanel2 @@ -313,7 +315,7 @@ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.Size = new System.Drawing.Size(427, 238); + this.tableLayoutPanel2.Size = new System.Drawing.Size(427, 261); this.tableLayoutPanel2.TabIndex = 7; // // tableLayoutPanel6 @@ -326,7 +328,7 @@ this.tableLayoutPanel6.Controls.Add(this.MoveDownButton, 1, 0); this.tableLayoutPanel6.Controls.Add(this.MoveUpButton, 0, 0); this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 211); + this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 229); this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel6.Name = "tableLayoutPanel6"; this.tableLayoutPanel6.RowCount = 1; @@ -341,7 +343,7 @@ this.MoveDownButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3); this.MoveDownButton.Name = "MoveDownButton"; this.MoveDownButton.Size = new System.Drawing.Size(80, 23); - this.MoveDownButton.TabIndex = 7; + this.MoveDownButton.TabIndex = 11; this.MoveDownButton.Text = "Move D&own"; this.MoveDownButton.UseVisualStyleBackColor = true; this.MoveDownButton.Click += new System.EventHandler(this.MoveDownButton_Click); @@ -353,7 +355,7 @@ this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); this.MoveUpButton.Name = "MoveUpButton"; this.MoveUpButton.Size = new System.Drawing.Size(80, 23); - this.MoveUpButton.TabIndex = 6; + this.MoveUpButton.TabIndex = 10; this.MoveUpButton.Text = "Move &Up"; this.MoveUpButton.UseVisualStyleBackColor = true; this.MoveUpButton.Click += new System.EventHandler(this.MoveUpButton_Click); @@ -369,7 +371,7 @@ this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel5.Controls.Add(this.ProxyPortTextBox, 1, 0); this.tableLayoutPanel5.Controls.Add(this.ProxyPortLabel, 0, 0); - this.tableLayoutPanel5.Location = new System.Drawing.Point(241, 174); + this.tableLayoutPanel5.Location = new System.Drawing.Point(241, 197); this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel5.Name = "tableLayoutPanel5"; this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(3); @@ -389,7 +391,7 @@ this.ProxyPortTextBox.MaxLength = 10; this.ProxyPortTextBox.Name = "ProxyPortTextBox"; this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 20); - this.ProxyPortTextBox.TabIndex = 4; + this.ProxyPortTextBox.TabIndex = 6; this.ProxyPortTextBox.WordWrap = false; // // ProxyPortLabel @@ -413,7 +415,7 @@ this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0); this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; - this.tableLayoutPanel3.Location = new System.Drawing.Point(268, 209); + this.tableLayoutPanel3.Location = new System.Drawing.Point(268, 232); this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; this.tableLayoutPanel3.RowCount = 1; @@ -431,7 +433,7 @@ this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0); this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 174); + this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 197); this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.RowCount = 1; @@ -439,6 +441,16 @@ this.tableLayoutPanel4.Size = new System.Drawing.Size(166, 32); this.tableLayoutPanel4.TabIndex = 8; // + // OneTimeAuth + // + this.OneTimeAuth.AutoSize = true; + this.OneTimeAuth.Location = new System.Drawing.Point(72, 137); + this.OneTimeAuth.Name = "OneTimeAuth"; + this.OneTimeAuth.Size = new System.Drawing.Size(131, 17); + this.OneTimeAuth.TabIndex = 5; + this.OneTimeAuth.Text = "One-time authorization"; + this.OneTimeAuth.UseVisualStyleBackColor = true; + // // ConfigForm // this.AcceptButton = this.OKButton; @@ -505,6 +517,7 @@ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6; private System.Windows.Forms.Button MoveDownButton; private System.Windows.Forms.Button MoveUpButton; + private System.Windows.Forms.CheckBox OneTimeAuth; } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index dc290249..b4b1b6bd 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -48,6 +48,7 @@ namespace Shadowsocks.View EncryptionLabel.Text = I18N.GetString("Encryption"); ProxyPortLabel.Text = I18N.GetString("Proxy Port"); RemarksLabel.Text = I18N.GetString("Remarks"); + OneTimeAuth.Text = I18N.GetString("One-time authorization"); ServerGroupBox.Text = I18N.GetString("Server"); OKButton.Text = I18N.GetString("OK"); MyCancelButton.Text = I18N.GetString("Cancel"); @@ -82,7 +83,8 @@ namespace Shadowsocks.View server_port = int.Parse(ServerPortTextBox.Text), password = PasswordTextBox.Text, method = EncryptionSelect.Text, - remarks = RemarksTextBox.Text + remarks = RemarksTextBox.Text, + one_time_auth = OneTimeAuth.Checked }; int localPort = int.Parse(ProxyPortTextBox.Text); Configuration.CheckServer(server); @@ -115,6 +117,7 @@ namespace Shadowsocks.View ProxyPortTextBox.Text = _modifiedConfiguration.localPort.ToString(); EncryptionSelect.Text = server.method ?? "aes-256-cfb"; RemarksTextBox.Text = server.remarks; + OneTimeAuth.Checked = server.one_time_auth; } } diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 8200aa07..89389fab 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -205,6 +205,7 @@ + From ca8df1b51fd83fd0f6d65fc13fd7e1d13df2ebc8 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Sat, 19 Sep 2015 11:19:39 +0800 Subject: [PATCH 02/23] fix buffer size --- shadowsocks-csharp/Controller/Service/TCPRelay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index c1b39a04..64535644 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -93,7 +93,7 @@ namespace Shadowsocks.Controller private int _firstPacketLength; // Size of receive buffer. public const int RecvSize = 8192; - public const int BufferSize = RecvSize + 32; + public const int BufferSize = RecvSize + (RecvSize / IVEncryptor.CRC_BUF_LEN + 1) * IVEncryptor.CRC_BYTES + 48; private int totalRead = 0; private int totalWrite = 0; From eae394355671c31257f4a6f910030b002b183c39 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Sat, 19 Sep 2015 13:51:32 +0800 Subject: [PATCH 03/23] reserve buffer for one-time auth --- shadowsocks-csharp/Controller/Service/TCPRelay.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index 64535644..86907f9a 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -93,17 +93,18 @@ namespace Shadowsocks.Controller private int _firstPacketLength; // Size of receive buffer. public const int RecvSize = 8192; - public const int BufferSize = RecvSize + (RecvSize / IVEncryptor.CRC_BUF_LEN + 1) * IVEncryptor.CRC_BYTES + 48; + public const int RecvReserveSize = (RecvSize / IVEncryptor.CRC_BUF_LEN + 1) * IVEncryptor.CRC_BYTES + 16; // reserve for one-time auth + public const int BufferSize = RecvSize + RecvReserveSize + 32; private int totalRead = 0; private int totalWrite = 0; // remote receive buffer - private byte[] remoteRecvBuffer = new byte[RecvSize]; + private byte[] remoteRecvBuffer = new byte[BufferSize]; // remote send buffer private byte[] remoteSendBuffer = new byte[BufferSize]; // connection receive buffer - private byte[] connetionRecvBuffer = new byte[RecvSize]; + private byte[] connetionRecvBuffer = new byte[BufferSize]; // connection send buffer private byte[] connetionSendBuffer = new byte[BufferSize]; // Received data string. From ff0bc37694f771993779f16d871b434004d7d57d Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Sat, 19 Sep 2015 21:55:29 +0800 Subject: [PATCH 04/23] fix UnitTest --- test/UnitTest.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/UnitTest.cs b/test/UnitTest.cs index 8fdf3f28..bb95fa50 100755 --- a/test/UnitTest.cs +++ b/test/UnitTest.cs @@ -84,8 +84,8 @@ namespace test { IEncryptor encryptor; IEncryptor decryptor; - encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); - decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); + encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false); + decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false); RunEncryptionRound(encryptor, decryptor); } } @@ -124,8 +124,8 @@ namespace test var random = new Random(); IEncryptor encryptor; IEncryptor decryptor; - encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!"); - decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!"); + encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false); + decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false); RunEncryptionRound(encryptor, decryptor); } } @@ -164,8 +164,8 @@ namespace test var random = new Random(); IEncryptor encryptor; IEncryptor decryptor; - encryptor = new SodiumEncryptor("salsa20", "barfoo!"); - decryptor = new SodiumEncryptor("salsa20", "barfoo!"); + encryptor = new SodiumEncryptor("salsa20", "barfoo!", false); + decryptor = new SodiumEncryptor("salsa20", "barfoo!", false); RunEncryptionRound(encryptor, decryptor); } } From ab1f3660495d91dda537a17fc87573f3caa565a0 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Sat, 19 Sep 2015 21:56:03 +0800 Subject: [PATCH 05/23] Combine libsscrypto.dll and libsslcrypto2.dll --- shadowsocks-csharp/Data/libsscrypto.dll.gz | Bin 10603 -> 53459 bytes shadowsocks-csharp/Data/libsscrypto2.dll.gz | Bin 45874 -> 0 bytes shadowsocks-csharp/Encryption/Sodium.cs | 35 +++--------------- .../Properties/Resources.Designer.cs | 10 ----- shadowsocks-csharp/Properties/Resources.resx | 3 -- shadowsocks-csharp/shadowsocks-csharp.csproj | 1 - 6 files changed, 5 insertions(+), 44 deletions(-) delete mode 100644 shadowsocks-csharp/Data/libsscrypto2.dll.gz diff --git a/shadowsocks-csharp/Data/libsscrypto.dll.gz b/shadowsocks-csharp/Data/libsscrypto.dll.gz index 66a1185ec57e06bf2bddd81b0c93b3f72bd525a9..75fe39ba15997f6b322b66bf724071ea52afc02e 100755 GIT binary patch literal 53459 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

838?aT>Gz*c z{;}(b>Fd<6vIhnXR=9n;w6ox)j6DfY>|6QH(7#7K`$JdnFRy=lp#E^;&sonDzOy_| zoa5^fFgD_N<8Lj`wS9Oq(YWxHe(wf;`p4sEAKAC^<)SBtY5OUo20nD>-1%b%Z@*z# z@mdzE`h3`X|0sTT)up5(v&KviM$ePP`+e}+^LMU%_0@%k-uL{X&@}z^zpvR_^7WjK z8G~YjC#8%m?f<6r%c~cD=s7w3VAO}%Z!Ukn`h|BZkA7s?COI{+X2!K87b|4jm_v%6 z>&H^*ginr#Ux1a@jcW#+cK=p_9F5E}NfG_Uk9d-ro6= zv8v>c$9|shwbzj!Lu&oEdRK}Hbkp+u(_E*Xd*{}^SDxMf_qo5U=^9ZV{q30tu7|zg zwtH}9!P2EZ2_YFtEsGob-+Z{O;gvSy`cL0`cWPFCqTBNEg=XK2;-@3F2dq9e>zvv$ z^7c)(`L)mAd-ZeuBWaI^7Y$x{tzXlyk01J5)TBGo--<6JfA!BV*!Q{D8%+`*LN-^lmQt_9G4d(1dUO_+9l^ zKYjK7n|?pD59miN*naGzxQ{9}Tzhs$#}DR5T|-yR_Ur%a;kqSnc3r>xRfE@(3)eQh z7jh`uqw&>v-GUQq*H#V*8~yUIz|tWjVpdKXxqigguT_84a9R4>$XkaS&2!(}@~+{r zt&=}^{W6^h$Qt#n1D*e?2{O!lI{a;qziFGM}SQei>N)L3`EeWtF2sC%CI}#NSTb zEZgqk{X@sCqv5T)8&b=EC@m@PYW(n-*`3QT4Ebz^e(#XNy7#ZHdMZ(LvGV!L59)_* z=Qd;pi3TmI`SQm}ac{od7PDqR`HMpy`e5Sv%#p%fTi)2WWS8c{=Ta06ehJ%WT^jK7 z?V6#(`pvxB`KG_-hsRzU@_u0aQ>emvaQxA(x0j|byYa>vf4AjBZnb_p z<(m_uf>U3}UHZb8!Z}*`&Rr!rRS(|WdVXqr(V%zAjI7z~AHgkO$JM5QDc*a|oTkeDF0sXvxLXBJjbFA_ z{m77K+KKzF{}oRe7s^}j(+HhAeg5 zzuX^oj9;7NI>G#%sa!Lxcdqcu2iM-{)IY?1YZwsG9-rYB^pQ8a;`ie(ZvB0>Rk7#S z(YcFv2*zp_7~lKq>OI4Z_rE(_zwgfE4Cl(TkT?RuBJK+7e;0nU{vDzJ;twCC zlx?H?bokw4=ZaG>?+b?6T??{x9d&EcG8Gu{nf{{cK-cx3ySmyE$QgX7i$33nFZX3E z%$YJXjTz(gs^1vKC1D}GJI@H5(oTZBmoL=alhXeFpHotoKqh%%ZrPIZB?Y=k5LsKc zWa+{@5LN~;f??&_$4(lbp7wF;d9G2k^fSTC)Tya!Cs)0D@aLVAUl=ncYUU2MhKdX4*{PObLvK6JeC9`Jc7w6}cJNZp2&703-e2_Qzhv!eG zO-V~aRnlB&w@EsXosf1Q%)B2apl<)gR8guGFk&ct(!x9t>HNuet$_CAZGlM&MQ#Di z6cU>oD(0Uxg*aOPO+2)@CvK;TRGa(kUEw?bB7FT0M)vLw=kR8S@aCP2 z%(9b)U*i4u+?D^iqkmogqz32ocZWaSM8k^!t_1UE`Sd&c*X2BM_Rq^vv@o)emOrm2 z!iEcf9e(!wUx$bOoAecTh2PzdkNx5te)z8N@3_8qqTc8JoKD~U`qy~ey7Jd_G+zJf z^ijY4b^0OQe;t1P_FvOseD7bU|KhIj<9CIB=qmWj@Npi3zs fr3A+{|bdbwn5Q1 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 literal 10603 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 F008M3pJD(2 diff --git a/shadowsocks-csharp/Data/libsscrypto2.dll.gz b/shadowsocks-csharp/Data/libsscrypto2.dll.gz deleted file mode 100644 index 83f7aab1186c37fedb817114cf895fad08b7100b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45874 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 diff --git a/shadowsocks-csharp/Encryption/Sodium.cs b/shadowsocks-csharp/Encryption/Sodium.cs index 14403267..c2c22839 100755 --- a/shadowsocks-csharp/Encryption/Sodium.cs +++ b/shadowsocks-csharp/Encryption/Sodium.cs @@ -12,40 +12,14 @@ namespace Shadowsocks.Encryption public class Sodium { const string DLLNAME = "libsscrypto"; - const string DLLNAME2 = "libsscrypto2"; static Sodium() - { - LoadSSCryptoLibrary(); - LoadSSCrypto2Library(); - } - - static void LoadSSCryptoLibrary() { string tempPath = Utils.GetTempPath(); string dllPath = tempPath + "/libsscrypto.dll"; try { FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll); - LoadLibrary(dllPath); - } - catch (IOException) - { - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - } - } - - static void LoadSSCrypto2Library() - { - string tempPath = Utils.GetTempPath(); - string dllPath = tempPath + "/libsscrypto2.dll"; - try - { - FileManager.UncompressFile(dllPath, Resources.libsscrypto2_dll); - LoadLibrary(dllPath); } catch (IOException) { @@ -54,22 +28,23 @@ namespace Shadowsocks.Encryption { Console.WriteLine(e.ToString()); } + LoadLibrary(dllPath); } [DllImport("Kernel32.dll")] private static extern IntPtr LoadLibrary(string path); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void crypto_stream_salsa20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); + public extern static int crypto_stream_salsa20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); + public extern static int crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); - [DllImport(DLLNAME2, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] public extern static int ss_gen_crc(byte[] buf, ref int buf_offset, ref int data_len, byte[] crc_buf, ref int crc_idx, int buf_size); - [DllImport(DLLNAME2, CallingConvention = CallingConvention.Cdecl)] + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] public extern static int ss_onetimeauth(byte[] auth, byte[] msg, int msg_len, byte[] iv, int iv_len, diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index a5891002..57242844 100644 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -110,16 +110,6 @@ namespace Shadowsocks.Properties { } } - ///

- /// 查找 System.Byte[] 类型的本地化资源。 - /// - internal static byte[] libsscrypto2_dll { - get { - object obj = ResourceManager.GetObject("libsscrypto2_dll", resourceCulture); - return ((byte[])(obj)); - } - } - /// /// 查找 System.Byte[] 类型的本地化资源。 /// diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index 36dc1386..aa0c2f63 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -124,9 +124,6 @@ ..\data\cn.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - ..\Data\libsscrypto2.dll.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ..\data\libsscrypto.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 89389fab..8200aa07 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -205,7 +205,6 @@
- From 19085a3cd170ef7ce18e4e9321934c772c0e4710 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Sun, 20 Sep 2015 23:25:37 -0400 Subject: [PATCH 06/23] Update the hash function follow with https://github.com/shadowsocks/shadowsocks-libev/commit/5ae4df94e440c4f6826a679a62687ad27303d89b --- .../Controller/Service/TCPRelay.cs | 2 +- shadowsocks-csharp/Data/libsscrypto.dll.gz | Bin 53459 -> 51484 bytes shadowsocks-csharp/Encryption/IVEncryptor.cs | 75 ++++++++++++++---- shadowsocks-csharp/Encryption/Sodium.cs | 13 +-- 4 files changed, 67 insertions(+), 23 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index 86907f9a..ca53a97a 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -93,7 +93,7 @@ namespace Shadowsocks.Controller private int _firstPacketLength; // Size of receive buffer. public const int RecvSize = 8192; - public const int RecvReserveSize = (RecvSize / IVEncryptor.CRC_BUF_LEN + 1) * IVEncryptor.CRC_BYTES + 16; // reserve for one-time auth + public const int RecvReserveSize = (RecvSize / IVEncryptor.HASH_BUF_LEN + 1) * IVEncryptor.HASH_BYTES + IVEncryptor.ONETIMEAUTH_BYTES; // reserve for one-time auth public const int BufferSize = RecvSize + RecvReserveSize + 32; private int totalRead = 0; diff --git a/shadowsocks-csharp/Data/libsscrypto.dll.gz b/shadowsocks-csharp/Data/libsscrypto.dll.gz index 75fe39ba15997f6b322b66bf724071ea52afc02e..5efa66613ad1f21294f50ba365349e1b4e121ab9 100755 GIT binary patch literal 51484 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 literal 53459 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

838?aT>Gz*c z{;}(b>Fd<6vIhnXR=9n;w6ox)j6DfY>|6QH(7#7K`$JdnFRy=lp#E^;&sonDzOy_| zoa5^fFgD_N<8Lj`wS9Oq(YWxHe(wf;`p4sEAKAC^<)SBtY5OUo20nD>-1%b%Z@*z# z@mdzE`h3`X|0sTT)up5(v&KviM$ePP`+e}+^LMU%_0@%k-uL{X&@}z^zpvR_^7WjK z8G~YjC#8%m?f<6r%c~cD=s7w3VAO}%Z!Ukn`h|BZkA7s?COI{+X2!K87b|4jm_v%6 z>&H^*ginr#Ux1a@jcW#+cK=p_9F5E}NfG_Uk9d-ro6= zv8v>c$9|shwbzj!Lu&oEdRK}Hbkp+u(_E*Xd*{}^SDxMf_qo5U=^9ZV{q30tu7|zg zwtH}9!P2EZ2_YFtEsGob-+Z{O;gvSy`cL0`cWPFCqTBNEg=XK2;-@3F2dq9e>zvv$ z^7c)(`L)mAd-ZeuBWaI^7Y$x{tzXlyk01J5)TBGo--<6JfA!BV*!Q{D8%+`*LN-^lmQt_9G4d(1dUO_+9l^ zKYjK7n|?pD59miN*naGzxQ{9}Tzhs$#}DR5T|-yR_Ur%a;kqSnc3r>xRfE@(3)eQh z7jh`uqw&>v-GUQq*H#V*8~yUIz|tWjVpdKXxqigguT_84a9R4>$XkaS&2!(}@~+{r zt&=}^{W6^h$Qt#n1D*e?2{O!lI{a;qziFGM}SQei>N)L3`EeWtF2sC%CI}#NSTb zEZgqk{X@sCqv5T)8&b=EC@m@PYW(n-*`3QT4Ebz^e(#XNy7#ZHdMZ(LvGV!L59)_* z=Qd;pi3TmI`SQm}ac{od7PDqR`HMpy`e5Sv%#p%fTi)2WWS8c{=Ta06ehJ%WT^jK7 z?V6#(`pvxB`KG_-hsRzU@_u0aQ>emvaQxA(x0j|byYa>vf4AjBZnb_p z<(m_uf>U3}UHZb8!Z}*`&Rr!rRS(|WdVXqr(V%zAjI7z~AHgkO$JM5QDc*a|oTkeDF0sXvxLXBJjbFA_ z{m77K+KKzF{}oRe7s^}j(+HhAeg5 zzuX^oj9;7NI>G#%sa!Lxcdqcu2iM-{)IY?1YZwsG9-rYB^pQ8a;`ie(ZvB0>Rk7#S z(YcFv2*zp_7~lKq>OI4Z_rE(_zwgfE4Cl(TkT?RuBJK+7e;0nU{vDzJ;twCC zlx?H?bokw4=ZaG>?+b?6T??{x9d&EcG8Gu{nf{{cK-cx3ySmyE$QgX7i$33nFZX3E z%$YJXjTz(gs^1vKC1D}GJI@H5(oTZBmoL=alhXeFpHotoKqh%%ZrPIZB?Y=k5LsKc zWa+{@5LN~;f??&_$4(lbp7wF;d9G2k^fSTC)Tya!Cs)0D@aLVAUl=ncYUU2MhKdX4*{PObLvK6JeC9`Jc7w6}cJNZp2&703-e2_Qzhv!eG zO-V~aRnlB&w@EsXosf1Q%)B2apl<)gR8guGFk&ct(!x9t>HNuet$_CAZGlM&MQ#Di z6cU>oD(0Uxg*aOPO+2)@CvK;TRGa(kUEw?bB7FT0M)vLw=kR8S@aCP2 z%(9b)U*i4u+?D^iqkmogqz32ocZWaSM8k^!t_1UE`Sd&c*X2BM_Rq^vv@o)emOrm2 z!iEcf9e(!wUx$bOoAecTh2PzdkNx5te)z8N@3_8qqTc8JoKD~U`qy~ey7Jd_G+zJf z^ijY4b^0OQe;t1P_FvOseD7bU|KhIj<9CIB=qmWj@Npi3zs fr3A+{|bdbwn5Q1 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 diff --git a/shadowsocks-csharp/Encryption/IVEncryptor.cs b/shadowsocks-csharp/Encryption/IVEncryptor.cs index 869cdb58..bd600c06 100755 --- a/shadowsocks-csharp/Encryption/IVEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IVEncryptor.cs @@ -9,11 +9,17 @@ namespace Shadowsocks.Encryption public abstract class IVEncryptor : EncryptorBase { + public const int MAX_KEY_LENGTH = 64; + public const int MAX_IV_LENGTH = 16; + public const int ONETIMEAUTH_FLAG = 0x10; public const int ADDRTYPE_MASK = 0xF; + public const int ONETIMEAUTH_BYTES = 16; - public const int CRC_BUF_LEN = 128; - public const int CRC_BYTES = 2; + public const int ONETIMEAUTH_KEYBYTES = 32; + + public const int HASH_BUF_LEN = 128; + public const int HASH_BYTES = 4; protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE]; @@ -32,8 +38,8 @@ namespace Shadowsocks.Encryption protected byte[] _key; protected int keyLen; protected int ivLen; - protected byte[] crc_buf; - protected int crc_idx = 0; + protected byte[] hash_buf; + protected int hash_idx = 0; public IVEncryptor(string method, string password, bool onetimeauth) : base(method, password, onetimeauth) @@ -41,7 +47,7 @@ namespace Shadowsocks.Encryption InitKey(method, password); if (OnetimeAuth) { - crc_buf = new byte[CRC_BUF_LEN]; + hash_buf = new byte[HASH_BUF_LEN]; } } @@ -125,7 +131,7 @@ namespace Shadowsocks.Encryption protected abstract void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf); - protected int GetSSHeadLength(byte[] buf, int length) + protected int ss_headlen(byte[] buf, int length) { int len = 0; int atyp = length > 0 ? (buf[0] & ADDRTYPE_MASK) : 0; @@ -147,6 +153,47 @@ namespace Shadowsocks.Encryption return len; } + protected int ss_onetimeauth(byte[] auth, + byte[] msg, int msg_len, + byte[] iv, int iv_len, + byte[] key, int key_len) + { + byte[] auth_key = new byte[ONETIMEAUTH_KEYBYTES]; + byte[] auth_bytes = new byte[MAX_IV_LENGTH + MAX_KEY_LENGTH]; + Buffer.BlockCopy(iv, 0, auth_bytes, 0, ivLen); + Buffer.BlockCopy(key, 0, auth_bytes, ivLen, key_len); + Sodium.crypto_generichash(auth_key, ONETIMEAUTH_KEYBYTES, auth_bytes, (ulong)(iv_len + key_len), null, 0); + return Sodium.crypto_onetimeauth(auth, msg, (ulong)msg_len, auth_key); + } + + protected void ss_gen_hash(byte[] in_buf, ref int in_offset, ref int in_len, + byte[] hash_buf, ref int hash_idx, int buf_size) + { + int i, j; + int offset = in_offset; + int blen = in_len; + int cidx = hash_idx; + int size = (blen / HASH_BUF_LEN + 1) * HASH_BYTES + blen; + if (buf_size < (size + offset)) + throw new Exception("failed to generate hash: buffer size insufficient"); + byte[] hash = new byte[HASH_BYTES]; + for (i = 0, j = offset; i < blen; i++, j++) + { + if (cidx == HASH_BUF_LEN) + { + Sodium.crypto_generichash(hash, HASH_BYTES, hash_buf, HASH_BUF_LEN, null, 0); + Buffer.BlockCopy(in_buf, j, in_buf, j + HASH_BYTES, blen - i); + Buffer.BlockCopy(hash, 0, in_buf, j, HASH_BYTES); + j += HASH_BYTES; cidx = 0; + } + hash_buf[cidx] = in_buf[j]; + cidx++; + } + in_offset = j; + in_len = j - offset; + hash_idx = cidx; + } + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { if (!_encryptIVSent) @@ -159,19 +206,17 @@ namespace Shadowsocks.Encryption { if (OnetimeAuth) { - lock(crc_buf) + lock (hash_buf) { - int headLen = GetSSHeadLength(buf, length); + int headLen = ss_headlen(buf, length); int data_len = length - headLen; Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES, data_len); buf[0] |= ONETIMEAUTH_FLAG; byte[] auth = new byte[ONETIMEAUTH_BYTES]; - Sodium.ss_onetimeauth(auth, buf, headLen, _encryptIV, ivLen, _key, keyLen); + ss_onetimeauth(auth, buf, headLen, _encryptIV, ivLen, _key, keyLen); Buffer.BlockCopy(auth, 0, buf, headLen, ONETIMEAUTH_BYTES); int buf_offset = headLen + ONETIMEAUTH_BYTES; - int rc = Sodium.ss_gen_crc(buf, ref buf_offset, ref data_len, crc_buf, ref crc_idx, buf.Length); - if (rc != 0) - throw new Exception("failed to generate crc"); + ss_gen_hash(buf, ref buf_offset, ref data_len, hash_buf, ref hash_idx, buf.Length); length = headLen + ONETIMEAUTH_BYTES + data_len; } } @@ -184,12 +229,10 @@ namespace Shadowsocks.Encryption { if (OnetimeAuth) { - lock(crc_buf) + lock (hash_buf) { int buf_offset = 0; - int rc = Sodium.ss_gen_crc(buf, ref buf_offset, ref length, crc_buf, ref crc_idx, buf.Length); - if (rc != 0) - throw new Exception("failed to generate crc"); + ss_gen_hash(buf, ref buf_offset, ref length, hash_buf, ref hash_idx, buf.Length); } } outlength = length; diff --git a/shadowsocks-csharp/Encryption/Sodium.cs b/shadowsocks-csharp/Encryption/Sodium.cs index c2c22839..a6bc909e 100755 --- a/shadowsocks-csharp/Encryption/Sodium.cs +++ b/shadowsocks-csharp/Encryption/Sodium.cs @@ -41,14 +41,15 @@ namespace Shadowsocks.Encryption public extern static int crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int ss_gen_crc(byte[] buf, ref int buf_offset, ref int data_len, - byte[] crc_buf, ref int crc_idx, int buf_size); + public extern static int crypto_generichash(byte[] outbuf, uint outlen, + byte[] inbuf, ulong inlen, + byte[] key, uint keylen); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int ss_onetimeauth(byte[] auth, - byte[] msg, int msg_len, - byte[] iv, int iv_len, - byte[] key, int key_len); + public extern static int crypto_onetimeauth(byte[] outbuf, byte[] inbuf, ulong inlen, byte[] k); + + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] + public extern static int crypto_onetimeauth_verify(byte[] h, byte[] inbuf, ulong inlen, byte[] k); } } From 204d6b856eece6532f94023630f42b20b01721c2 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Mon, 21 Sep 2015 05:28:18 -0400 Subject: [PATCH 07/23] verbiage --- shadowsocks-csharp/Data/cn.txt | 2 +- .../Properties/Resources.Designer.cs | 86 +++++++++---------- .../View/ConfigForm.Designer.cs | 14 +-- shadowsocks-csharp/View/ConfigForm.cs | 2 +- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 813578b7..259081da 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -39,7 +39,7 @@ Password=密码 Encryption=加密 Proxy Port=代理端口 Remarks=备注 -One-time authorization=一次性授权 +Onetime Authentication=一次性认证 OK=确定 Cancel=取消 New server=未配置的服务器 diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index 57242844..1205845f 100644 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -1,24 +1,24 @@ //------------------------------------------------------------------------------ // -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ namespace Shadowsocks.Properties { using System; - - + + ///

- /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// A strongly-typed resource class, for looking up localized strings, etc. /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] @@ -31,9 +31,9 @@ namespace Shadowsocks.Properties { [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } - + /// - /// 返回此类使用的缓存的 ResourceManager 实例。 + /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { @@ -45,10 +45,10 @@ namespace Shadowsocks.Properties { return resourceMan; } } - + /// - /// 使用此强类型资源类,为所有资源查找 - /// 重写当前线程的 CurrentUICulture 属性。 + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { @@ -59,9 +59,9 @@ namespace Shadowsocks.Properties { resourceCulture = value; } } - + /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// internal static byte[] abp_js { get { @@ -69,9 +69,9 @@ namespace Shadowsocks.Properties { return ((byte[])(obj)); } } - + /// - /// 查找类似 # translation for Simplified Chinese + /// Looks up a localized string similar to # translation for Simplified Chinese /// ///Shadowsocks=Shadowsocks /// @@ -92,16 +92,16 @@ namespace Shadowsocks.Properties { ///Edit User Rule for GFWList...=编辑 GFWList 的用户规则... ///Show QRCode...=显示二维码... ///Scan QRCode from Screen...=扫描屏幕上的二维码... - ///Availability Statistic [字符串的其余部分被截断]"; 的本地化字符串。 + ///Availability Statistic [rest of string was truncated]";. /// internal static string cn { get { return ResourceManager.GetString("cn", resourceCulture); } } - + /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// internal static byte[] libsscrypto_dll { get { @@ -109,9 +109,9 @@ namespace Shadowsocks.Properties { return ((byte[])(obj)); } } - + /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// internal static byte[] mgwz_dll { get { @@ -119,22 +119,22 @@ namespace Shadowsocks.Properties { return ((byte[])(obj)); } } - + /// - /// 查找类似 listen-address __POLIPO_BIND_IP__:8123 + /// Looks up a localized string similar to listen-address __POLIPO_BIND_IP__:8123 ///show-on-task-bar 0 ///activity-animation 0 ///forward-socks5 / 127.0.0.1:__SOCKS_PORT__ . - ///hide-console 的本地化字符串。 + ///hide-console. /// internal static string privoxy_conf { get { return ResourceManager.GetString("privoxy_conf", resourceCulture); } } - + /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// internal static byte[] privoxy_exe { get { @@ -142,9 +142,9 @@ namespace Shadowsocks.Properties { return ((byte[])(obj)); } } - + /// - /// 查找 System.Byte[] 类型的本地化资源。 + /// Looks up a localized resource of type System.Byte[]. /// internal static byte[] proxy_pac_txt { get { @@ -152,9 +152,9 @@ namespace Shadowsocks.Properties { return ((byte[])(obj)); } } - + /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap ss16 { get { @@ -162,9 +162,9 @@ namespace Shadowsocks.Properties { return ((System.Drawing.Bitmap)(obj)); } } - + /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap ss20 { get { @@ -172,9 +172,9 @@ namespace Shadowsocks.Properties { return ((System.Drawing.Bitmap)(obj)); } } - + /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap ss24 { get { @@ -182,9 +182,9 @@ namespace Shadowsocks.Properties { return ((System.Drawing.Bitmap)(obj)); } } - + /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap ssw128 { get { @@ -192,11 +192,11 @@ namespace Shadowsocks.Properties { return ((System.Drawing.Bitmap)(obj)); } } - + /// - /// 查找类似 ! Put user rules line by line in this file. + /// Looks up a localized string similar to ! Put user rules line by line in this file. ///! See https://adblockplus.org/en/filter-cheatsheet - /// 的本地化字符串。 + ///. /// internal static string user_rule { get { diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index e985937e..a4754918 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -3,14 +3,14 @@ partial class ConfigForm { /// - /// 必需的设计器变量。 + /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// - /// 清理所有正在使用的资源。 + /// Clean up any resources being used. /// - /// 如果应释放托管资源,为 true;否则为 false。 + /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) @@ -20,11 +20,11 @@ base.Dispose(disposing); } - #region Windows 窗体设计器生成的代码 + #region Windows Form Designer generated code /// - /// 设计器支持所需的方法 - 不要 - /// 使用代码编辑器修改此方法的内容。 + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. /// private void InitializeComponent() { @@ -448,7 +448,7 @@ this.OneTimeAuth.Name = "OneTimeAuth"; this.OneTimeAuth.Size = new System.Drawing.Size(131, 17); this.OneTimeAuth.TabIndex = 5; - this.OneTimeAuth.Text = "One-time authorization"; + this.OneTimeAuth.Text = "Onetime Authentication"; this.OneTimeAuth.UseVisualStyleBackColor = true; // // ConfigForm diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index b4b1b6bd..fd0b8d63 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -48,7 +48,7 @@ namespace Shadowsocks.View EncryptionLabel.Text = I18N.GetString("Encryption"); ProxyPortLabel.Text = I18N.GetString("Proxy Port"); RemarksLabel.Text = I18N.GetString("Remarks"); - OneTimeAuth.Text = I18N.GetString("One-time authorization"); + OneTimeAuth.Text = I18N.GetString("Onetime Authentication"); ServerGroupBox.Text = I18N.GetString("Server"); OKButton.Text = I18N.GetString("OK"); MyCancelButton.Text = I18N.GetString("Cancel"); From 00ccb52bef8444d7bbe93a404d98be7287bed31b Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Mon, 21 Sep 2015 22:42:16 -0400 Subject: [PATCH 08/23] Add an option for checking updates --- .../Controller/Service/UpdateChecker.cs | 19 ++++--- .../Controller/ShadowsocksController.cs | 6 ++ shadowsocks-csharp/Data/cn.txt | 4 ++ shadowsocks-csharp/Model/Configuration.cs | 2 + shadowsocks-csharp/View/MenuViewController.cs | 57 ++++++++++++++++--- 5 files changed, 71 insertions(+), 17 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs index d48c0aae..a6709388 100644 --- a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs @@ -14,9 +14,10 @@ namespace Shadowsocks.Controller { private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases"; + public bool NewVersionFound; public string LatestVersionNumber; public string LatestVersionURL; - public event EventHandler NewVersionFound; + public event EventHandler CheckUpdateCompleted; public const string Version = "2.5.8"; @@ -114,17 +115,17 @@ namespace Shadowsocks.Controller } } - if (versions.Count == 0) + if (versions.Count != 0) { - return; + // sort versions + SortVersions(versions); + NewVersionFound = true; + LatestVersionURL = versions[versions.Count - 1]; + LatestVersionNumber = ParseVersionFromURL(LatestVersionURL); } - // sort versions - SortVersions(versions); - LatestVersionURL = versions[versions.Count - 1]; - LatestVersionNumber = ParseVersionFromURL(LatestVersionURL); - if (NewVersionFound != null) + if (CheckUpdateCompleted != null) { - NewVersionFound(this, new EventArgs()); + CheckUpdateCompleted(this, new EventArgs()); } } catch (Exception ex) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 2e2f5528..7e86354c 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -280,6 +280,12 @@ namespace Shadowsocks.Controller } } + public void ToggleCheckingUpdate(bool enabled) + { + _config.autoCheckUpdate = enabled; + Configuration.Save(_config); + } + protected void Reload() { // some logic in configuration updated the config when saving, we need to read it again diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 259081da..3a641952 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -21,6 +21,9 @@ Show QRCode...=显示二维码... Scan QRCode from Screen...=扫描屏幕上的二维码... Availability Statistics=统计可用性 Show Logs...=显示日志... +Updates...=更新... +Check Updates...=检查更新 +Automatically Check Updates=自动检查更新 About...=关于... Quit=退出 Edit Servers=编辑服务器 @@ -78,6 +81,7 @@ Password can not be blank=密码不能为空 Port out of range=端口超出范围 Port can't be 8123=端口不能为 8123 Shadowsocks {0} Update Found=Shadowsocks {0} 更新 +No update is available=没有可用的更新 Click here to download=点击这里下载 Shadowsocks is here=Shadowsocks 在这里 You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 1ccba56c..35ee5235 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -23,6 +23,7 @@ namespace Shadowsocks.Model public string pacUrl; public bool useOnlinePac; public bool availabilityStatistics; + public bool autoCheckUpdate; private static string CONFIG_FILE = "gui-config.json"; @@ -76,6 +77,7 @@ namespace Shadowsocks.Model index = 0, isDefault = true, localPort = 1080, + autoCheckUpdate = true, configs = new List() { GetDefaultServer() diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index c8a4c0eb..441a27b2 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -26,6 +26,7 @@ namespace Shadowsocks.View private ContextMenu contextMenu1; private bool _isFirstRun; + private bool _isStartupChecking; private MenuItem enableItem; private MenuItem modeItem; private MenuItem AutoStartupItem; @@ -42,6 +43,7 @@ namespace Shadowsocks.View private MenuItem updateFromGFWListItem; private MenuItem editGFWUserRuleItem; private MenuItem editOnlinePACItem; + private MenuItem autoCheckUpdatesToggleItem; private ConfigForm configForm; private string _urlToOpen; @@ -68,13 +70,19 @@ namespace Shadowsocks.View _notifyIcon.MouseDoubleClick += notifyIcon1_DoubleClick; this.updateChecker = new UpdateChecker(); - updateChecker.NewVersionFound += updateChecker_NewVersionFound; + updateChecker.CheckUpdateCompleted += updateChecker_CheckUpdateCompleted; LoadCurrentConfiguration(); - updateChecker.CheckUpdate(controller.GetConfigurationCopy()); + Configuration config = controller.GetConfigurationCopy(); - if (controller.GetConfigurationCopy().isDefault) + if (config.autoCheckUpdate) + { + _isStartupChecking = true; + updateChecker.CheckUpdate(config); + } + + if (config.isDefault) { _isFirstRun = true; ShowConfigForm(); @@ -182,6 +190,11 @@ namespace Shadowsocks.View this.ShareOverLANItem = CreateMenuItem("Allow Clients from LAN", new EventHandler(this.ShareOverLANItem_Click)), new MenuItem("-"), CreateMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)), + CreateMenuGroup("Updates...", new MenuItem[] { + CreateMenuItem("Check Updates...", new EventHandler(this.checkUpdatesItem_Click)), + new MenuItem("-"), + this.autoCheckUpdatesToggleItem = CreateMenuItem("Automatically Check Updates", new EventHandler(this.autoCheckUpdatesToggleItem_Click)), + }), CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)), new MenuItem("-"), CreateMenuItem("Quit", new EventHandler(this.Quit_Click)) @@ -238,11 +251,20 @@ namespace Shadowsocks.View ShowBalloonTip(I18N.GetString("Shadowsocks"), result, ToolTipIcon.Info, 1000); } - void updateChecker_NewVersionFound(object sender, EventArgs e) + void updateChecker_CheckUpdateCompleted(object sender, EventArgs e) { - ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to download"), ToolTipIcon.Info, 5000); - _notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; - _isFirstRun = false; + if (updateChecker.NewVersionFound) + { + ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to download"), ToolTipIcon.Info, 5000); + _notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; + _isFirstRun = false; + } + else if (!_isStartupChecking) + { + ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("No update is available"), ToolTipIcon.Info, 5000); + _isFirstRun = false; + } + _isStartupChecking = false; } void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) @@ -266,6 +288,7 @@ namespace Shadowsocks.View onlinePACItem.Checked = onlinePACItem.Enabled && config.useOnlinePac; localPACItem.Checked = !onlinePACItem.Checked; UpdatePACItemsEnabledStatus(); + UpdateUpdateMenu(); } private void UpdateServersMenu() @@ -343,7 +366,7 @@ namespace Shadowsocks.View if (_isFirstRun) { _notifyIcon.BalloonTipTitle = I18N.GetString("Shadowsocks is here"); - _notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu"); + _notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu"); _notifyIcon.BalloonTipIcon = ToolTipIcon.Info; _notifyIcon.ShowBalloonTip(0); _isFirstRun = false; @@ -591,5 +614,23 @@ namespace Shadowsocks.View this.editOnlinePACItem.Enabled = true; } } + + private void UpdateUpdateMenu() + { + Configuration configuration = controller.GetConfigurationCopy(); + autoCheckUpdatesToggleItem.Checked = configuration.autoCheckUpdate; + } + + private void autoCheckUpdatesToggleItem_Click(object sender, EventArgs e) + { + Configuration configuration = controller.GetConfigurationCopy(); + controller.ToggleCheckingUpdate(!configuration.autoCheckUpdate); + UpdateUpdateMenu(); + } + + private void checkUpdatesItem_Click(object sender, EventArgs e) + { + updateChecker.CheckUpdate(controller.GetConfigurationCopy()); + } } } From ab79dbce0e9d70e42c46488c08c1f7bf3e0dbe3b Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Mon, 21 Sep 2015 23:41:28 -0400 Subject: [PATCH 09/23] Download updates automatically --- .../Controller/Service/UpdateChecker.cs | 216 ++++++++++++------ shadowsocks-csharp/Data/cn.txt | 2 +- shadowsocks-csharp/View/MenuViewController.cs | 5 +- 3 files changed, 149 insertions(+), 74 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs index a6709388..0955b255 100644 --- a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs @@ -1,138 +1,212 @@ -using Shadowsocks.Model; -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Net; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using System.IO; using SimpleJson; +using Shadowsocks.Model; +using Shadowsocks.Util; + namespace Shadowsocks.Controller { public class UpdateChecker { private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases"; + private const string UserAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36"; + private Configuration config; public bool NewVersionFound; public string LatestVersionNumber; + public string LatestVersionName; public string LatestVersionURL; + public string LatestVersionLocalName; public event EventHandler CheckUpdateCompleted; public const string Version = "2.5.8"; public void CheckUpdate(Configuration config) { - // TODO test failures - WebClient http = new WebClient(); - http.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36"); - http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort); - http.DownloadStringCompleted += http_DownloadStringCompleted; - http.DownloadStringAsync(new Uri(UpdateURL)); + this.config = config; + + try + { + WebClient http = CreateWebClient(); + http.DownloadStringCompleted += http_DownloadStringCompleted; + http.DownloadStringAsync(new Uri(UpdateURL)); + } + catch (Exception ex) + { + Logging.LogUsefulException(ex); + } } - public static int CompareVersion(string l, string r) + private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { - var ls = l.Split('.'); - var rs = r.Split('.'); - for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++) + try { - int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0; - int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0; - if (lp != rp) + string response = e.Result; + + JsonArray result = (JsonArray)SimpleJson.SimpleJson.DeserializeObject(e.Result); + + List asserts = new List(); + foreach (JsonObject release in result) { - return lp - rp; + if ((bool)release["prerelease"]) + { + continue; + } + foreach (JsonObject asset in (JsonArray)release["assets"]) + { + Asset ass = new Asset(); + ass.Parse(asset); + if (ass.IsNewVersion(Version)) + { + asserts.Add(ass); + } + } + } + + if (asserts.Count != 0) + { + SortByVersions(asserts); + Asset asset = asserts[asserts.Count - 1]; + NewVersionFound = true; + LatestVersionURL = asset.browser_download_url; + LatestVersionNumber = asset.version; + LatestVersionName = asset.name; + + startDownload(); + } + else if (CheckUpdateCompleted != null) + { + CheckUpdateCompleted(this, new EventArgs()); } } - return 0; + catch (Exception ex) + { + Logging.LogUsefulException(ex); + } } - public class VersionComparer : IComparer + private void startDownload() { - // Calls CaseInsensitiveComparer.Compare with the parameters reversed. - public int Compare(string x, string y) + try + { + string temppath = Utils.GetTempPath(); + LatestVersionLocalName = Path.Combine(temppath, LatestVersionName); + WebClient http = CreateWebClient(); + http.DownloadFileCompleted += Http_DownloadFileCompleted; + http.DownloadFileAsync(new Uri(LatestVersionURL), LatestVersionLocalName); + } + catch (Exception ex) { - return CompareVersion(ParseVersionFromURL(x), ParseVersionFromURL(y)); + Logging.LogUsefulException(ex); } } - private static string ParseVersionFromURL(string url) + private void Http_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { - Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase); - if (match.Success) + try { - if (match.Groups.Count == 2) + if(e.Error != null) { - return match.Groups[1].Value; + Logging.LogUsefulException(e.Error); + return; + } + if (CheckUpdateCompleted != null) + { + CheckUpdateCompleted(this, new EventArgs()); } } - return null; + catch (Exception ex) + { + Logging.LogUsefulException(ex); + } } - private void SortVersions(List versions) + private WebClient CreateWebClient() { - versions.Sort(new VersionComparer()); + WebClient http = new WebClient(); + http.Headers.Add("User-Agent", UserAgent); + http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort); + return http; } - private bool IsNewVersion(string url) + private void SortByVersions(List asserts) { - if (url.IndexOf("prerelease") >= 0) - { - return false; - } - string version = ParseVersionFromURL(url); - if (version == null) - { - return false; - } - string currentVersion = Version; - - return CompareVersion(version, currentVersion) > 0; + asserts.Sort(new VersionComparer()); } - private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) + class Asset { - try + public bool prerelease; + public string name; + public string version; + public string browser_download_url; + + public bool IsNewVersion(string currentVersion) { - string response = e.Result; + if (prerelease) + { + return false; + } + if (version == null) + { + return false; + } + return CompareVersion(version, currentVersion) > 0; + } - JsonArray result = (JsonArray)SimpleJson.SimpleJson.DeserializeObject(e.Result); + public void Parse(JsonObject asset) + { + name = (string)asset["name"]; + browser_download_url = (string)asset["browser_download_url"]; + version = ParseVersionFromURL(browser_download_url); + prerelease = browser_download_url.IndexOf("prerelease") >= 0; + } - List versions = new List(); - foreach (JsonObject release in result) + private static string ParseVersionFromURL(string url) + { + Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase); + if (match.Success) { - if ((bool)release["prerelease"]) - { - continue; - } - foreach (JsonObject asset in (JsonArray)release["assets"]) + if (match.Groups.Count == 2) { - string url = (string)asset["browser_download_url"]; - if (IsNewVersion(url)) - { - versions.Add(url); - } + return match.Groups[1].Value; } } + return null; + } - if (versions.Count != 0) - { - // sort versions - SortVersions(versions); - NewVersionFound = true; - LatestVersionURL = versions[versions.Count - 1]; - LatestVersionNumber = ParseVersionFromURL(LatestVersionURL); - } - if (CheckUpdateCompleted != null) + public static int CompareVersion(string l, string r) + { + var ls = l.Split('.'); + var rs = r.Split('.'); + for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++) { - CheckUpdateCompleted(this, new EventArgs()); + int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0; + int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0; + if (lp != rp) + { + return lp - rp; + } } + return 0; } - catch (Exception ex) + } + + class VersionComparer : IComparer + { + // Calls CaseInsensitiveComparer.Compare with the parameters reversed. + public int Compare(Asset x, Asset y) { - Logging.Debug(ex.ToString()); - return; + return Asset.CompareVersion(x.version, y.version); } } + } } diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 3a641952..f2accf58 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -82,7 +82,7 @@ Port out of range=端口超出范围 Port can't be 8123=端口不能为 8123 Shadowsocks {0} Update Found=Shadowsocks {0} 更新 No update is available=没有可用的更新 -Click here to download=点击这里下载 +Click here to update=点击这里升级 Shadowsocks is here=Shadowsocks 在这里 You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks System Proxy Enabled=系统代理已启用 diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 441a27b2..e729d943 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -255,7 +255,7 @@ namespace Shadowsocks.View { if (updateChecker.NewVersionFound) { - ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to download"), ToolTipIcon.Info, 5000); + ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); _notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; _isFirstRun = false; } @@ -269,8 +269,9 @@ namespace Shadowsocks.View void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) { - System.Diagnostics.Process.Start(updateChecker.LatestVersionURL); _notifyIcon.BalloonTipClicked -= notifyIcon1_BalloonTipClicked; + string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\""; + System.Diagnostics.Process.Start("explorer.exe", argument); } From 1d1c325ce103b19bf5262f74bc35119aa28d5e96 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Tue, 22 Sep 2015 00:11:12 -0400 Subject: [PATCH 10/23] fix UnitTest --- .../Controller/Service/UpdateChecker.cs | 2 +- test/UnitTest.cs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs index 0955b255..643c7014 100644 --- a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs @@ -141,7 +141,7 @@ namespace Shadowsocks.Controller asserts.Sort(new VersionComparer()); } - class Asset + public class Asset { public bool prerelease; public string name; diff --git a/test/UnitTest.cs b/test/UnitTest.cs index bb95fa50..6003770e 100755 --- a/test/UnitTest.cs +++ b/test/UnitTest.cs @@ -13,13 +13,13 @@ namespace test [TestMethod] public void TestCompareVersion() { - Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1.0", "2.3.1") == 0); - Assert.IsTrue(UpdateChecker.CompareVersion("1.2", "1.3") < 0); - Assert.IsTrue(UpdateChecker.CompareVersion("1.3", "1.2") > 0); - Assert.IsTrue(UpdateChecker.CompareVersion("1.3", "1.3") == 0); - Assert.IsTrue(UpdateChecker.CompareVersion("1.2.1", "1.2") > 0); - Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1", "2.4") < 0); - Assert.IsTrue(UpdateChecker.CompareVersion("1.3.2", "1.3.1") > 0); + Assert.IsTrue(UpdateChecker.Asset.CompareVersion("2.3.1.0", "2.3.1") == 0); + Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.2", "1.3") < 0); + Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3", "1.2") > 0); + Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3", "1.3") == 0); + Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.2.1", "1.2") > 0); + Assert.IsTrue(UpdateChecker.Asset.CompareVersion("2.3.1", "2.4") < 0); + Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3.2", "1.3.1") > 0); } private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) From 2ec13402619bd4e2106f6c2a63c0c7929091f169 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Tue, 22 Sep 2015 02:01:23 -0400 Subject: [PATCH 11/23] fix "Only TrueType fonts are supported. This is not a TrueType font." --- shadowsocks-csharp/View/LogForm.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index c4fcaf51..3f4bc847 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -134,11 +134,19 @@ namespace Shadowsocks.View private void ChangeFontButton_Click(object sender, EventArgs e) { - FontDialog fd = new FontDialog(); - fd.Font = LogMessageTextBox.Font; - if (fd.ShowDialog() == DialogResult.OK) + try { - LogMessageTextBox.Font = fd.Font; + FontDialog fd = new FontDialog(); + fd.Font = LogMessageTextBox.Font; + if (fd.ShowDialog() == DialogResult.OK) + { + LogMessageTextBox.Font = new Font(fd.Font.FontFamily, fd.Font.Size, fd.Font.Style); + } + } + catch (Exception ex) + { + Logging.LogUsefulException(ex); + MessageBox.Show(ex.Message); } } From b197af124b1111c1d19010a1515a3c6d42ba8900 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Tue, 22 Sep 2015 06:36:15 -0400 Subject: [PATCH 12/23] fix bug: shadowsocks restart twice, when click Ok button on Edit Servers window --- shadowsocks-csharp/Controller/ShadowsocksController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 7e86354c..1debda15 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -122,7 +122,7 @@ namespace Shadowsocks.Controller { _config.configs = servers; _config.localPort = localPort; - SaveConfig(_config); + Configuration.Save(_config); } public bool AddServerBySSURL(string ssURL) From b632d4a8a984957d86a9d25ff17058a0cc1f3beb Mon Sep 17 00:00:00 2001 From: kimw <1@kimwong.me> Date: Thu, 20 Aug 2015 17:17:21 +0800 Subject: [PATCH 13/23] improved `log viewer`: 1. add menu items for `clear logs`, `change fonts`, `wrap text` and `top most` functions. 2. hide toolbar default. but you can trigger it out by menu. --- shadowsocks-csharp/Data/cn.txt | 6 +- shadowsocks-csharp/View/LogForm.Designer.cs | 159 ++++++++++++++------ shadowsocks-csharp/View/LogForm.cs | 109 +++++++++++++- shadowsocks-csharp/View/LogForm.resx | 5 +- 4 files changed, 217 insertions(+), 62 deletions(-) diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index f2accf58..c8bde1ce 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -54,10 +54,12 @@ Move D&own=下移(&O) &File=文件(&F) &Open Location=在资源管理器中打开(&O) E&xit=退出(&X) -&Clean logs=清空(&C) -&Font=字体(&F) +&View=视图(&V) +&Clean logs=清空日志(&C) +Change &font=设置字体(&F) &Wrap text=自动换行(&W) &Top most=置顶(&T) +&Show toolbar=显示工具栏(&S) Log Viewer=日志查看器 # QRCode Form diff --git a/shadowsocks-csharp/View/LogForm.Designer.cs b/shadowsocks-csharp/View/LogForm.Designer.cs index d0913d16..187ab948 100644 --- a/shadowsocks-csharp/View/LogForm.Designer.cs +++ b/shadowsocks-csharp/View/LogForm.Designer.cs @@ -30,19 +30,25 @@ { this.components = new System.ComponentModel.Container(); this.LogMessageTextBox = new System.Windows.Forms.TextBox(); - this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); - this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components); + this.MainMenu = new System.Windows.Forms.MainMenu(this.components); this.FileMenuItem = new System.Windows.Forms.MenuItem(); this.OpenLocationMenuItem = new System.Windows.Forms.MenuItem(); this.ExitMenuItem = new System.Windows.Forms.MenuItem(); - this.panel1 = new System.Windows.Forms.Panel(); + this.ViewMenuItem = new System.Windows.Forms.MenuItem(); + this.CleanLogsMenuItem = new System.Windows.Forms.MenuItem(); + this.ChangeFontMenuItem = new System.Windows.Forms.MenuItem(); + this.WrapTextMenuItem = new System.Windows.Forms.MenuItem(); + this.TopMostMenuItem = new System.Windows.Forms.MenuItem(); + this.MenuItemSeparater = new System.Windows.Forms.MenuItem(); + this.ShowToolbarMenuItem = new System.Windows.Forms.MenuItem(); + this.TopMostCheckBox = new System.Windows.Forms.CheckBox(); this.ChangeFontButton = new System.Windows.Forms.Button(); this.CleanLogsButton = new System.Windows.Forms.Button(); this.WrapTextCheckBox = new System.Windows.Forms.CheckBox(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.TopMostCheckBox = new System.Windows.Forms.CheckBox(); - this.panel1.SuspendLayout(); + this.ToolbarFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel(); this.tableLayoutPanel1.SuspendLayout(); + this.ToolbarFlowLayoutPanel.SuspendLayout(); this.SuspendLayout(); // // LogMessageTextBox @@ -51,25 +57,20 @@ this.LogMessageTextBox.Dock = System.Windows.Forms.DockStyle.Fill; this.LogMessageTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.LogMessageTextBox.ForeColor = System.Drawing.Color.White; - this.LogMessageTextBox.Location = new System.Drawing.Point(3, 43); + this.LogMessageTextBox.Location = new System.Drawing.Point(3, 38); this.LogMessageTextBox.MaxLength = 2147483647; this.LogMessageTextBox.Multiline = true; this.LogMessageTextBox.Name = "LogMessageTextBox"; this.LogMessageTextBox.ReadOnly = true; this.LogMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.LogMessageTextBox.Size = new System.Drawing.Size(541, 307); + this.LogMessageTextBox.Size = new System.Drawing.Size(584, 377); this.LogMessageTextBox.TabIndex = 0; - this.LogMessageTextBox.WordWrap = false; - // - // contextMenuStrip1 // - this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); + // MainMenu // - // mainMenu1 - // - this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { - this.FileMenuItem}); + this.MainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.FileMenuItem, + this.ViewMenuItem}); // // FileMenuItem // @@ -91,21 +92,70 @@ this.ExitMenuItem.Text = "E&xit"; this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click); // - // panel1 + // ViewMenuItem + // + this.ViewMenuItem.Index = 1; + this.ViewMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.CleanLogsMenuItem, + this.ChangeFontMenuItem, + this.WrapTextMenuItem, + this.TopMostMenuItem, + this.MenuItemSeparater, + this.ShowToolbarMenuItem}); + this.ViewMenuItem.Text = "&View"; + // + // CleanLogsMenuItem + // + this.CleanLogsMenuItem.Index = 0; + this.CleanLogsMenuItem.Text = "&Clean logs"; + this.CleanLogsMenuItem.Click += new System.EventHandler(this.CleanLogsMenuItem_Click); + // + // ChangeFontMenuItem + // + this.ChangeFontMenuItem.Index = 1; + this.ChangeFontMenuItem.Text = "Change &font"; + this.ChangeFontMenuItem.Click += new System.EventHandler(this.ChangeFontMenuItem_Click); // - this.panel1.Controls.Add(this.TopMostCheckBox); - this.panel1.Controls.Add(this.ChangeFontButton); - this.panel1.Controls.Add(this.CleanLogsButton); - this.panel1.Controls.Add(this.WrapTextCheckBox); - this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.panel1.Location = new System.Drawing.Point(3, 3); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(541, 34); - this.panel1.TabIndex = 1; + // WrapTextMenuItem + // + this.WrapTextMenuItem.Index = 2; + this.WrapTextMenuItem.Text = "&Wrap text"; + this.WrapTextMenuItem.Click += new System.EventHandler(this.WrapTextMenuItem_Click); + // + // TopMostMenuItem + // + this.TopMostMenuItem.Index = 3; + this.TopMostMenuItem.Text = "&Top most"; + this.TopMostMenuItem.Click += new System.EventHandler(this.TopMostMenuItem_Click); + // + // MenuItemSeparater + // + this.MenuItemSeparater.Index = 4; + this.MenuItemSeparater.Text = "-"; + // + // ShowToolbarMenuItem + // + this.ShowToolbarMenuItem.Index = 5; + this.ShowToolbarMenuItem.Text = "&Show toolbar"; + this.ShowToolbarMenuItem.Click += new System.EventHandler(this.ShowToolbarMenuItem_Click); + // + // TopMostCheckBox + // + this.TopMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.TopMostCheckBox.AutoSize = true; + this.TopMostCheckBox.Location = new System.Drawing.Point(249, 3); + this.TopMostCheckBox.Name = "TopMostCheckBox"; + this.TopMostCheckBox.Size = new System.Drawing.Size(72, 23); + this.TopMostCheckBox.TabIndex = 3; + this.TopMostCheckBox.Text = "&Top most"; + this.TopMostCheckBox.UseVisualStyleBackColor = true; + this.TopMostCheckBox.CheckedChanged += new System.EventHandler(this.TopMostCheckBox_CheckedChanged); // // ChangeFontButton // - this.ChangeFontButton.Location = new System.Drawing.Point(107, 4); + this.ChangeFontButton.AutoSize = true; + this.ChangeFontButton.Location = new System.Drawing.Point(84, 3); this.ChangeFontButton.Name = "ChangeFontButton"; this.ChangeFontButton.Size = new System.Drawing.Size(75, 23); this.ChangeFontButton.TabIndex = 2; @@ -115,7 +165,8 @@ // // CleanLogsButton // - this.CleanLogsButton.Location = new System.Drawing.Point(9, 4); + this.CleanLogsButton.AutoSize = true; + this.CleanLogsButton.Location = new System.Drawing.Point(3, 3); this.CleanLogsButton.Name = "CleanLogsButton"; this.CleanLogsButton.Size = new System.Drawing.Size(75, 23); this.CleanLogsButton.TabIndex = 1; @@ -125,10 +176,12 @@ // // WrapTextCheckBox // + this.WrapTextCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); this.WrapTextCheckBox.AutoSize = true; - this.WrapTextCheckBox.Location = new System.Drawing.Point(209, 9); + this.WrapTextCheckBox.Location = new System.Drawing.Point(165, 3); this.WrapTextCheckBox.Name = "WrapTextCheckBox"; - this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 16); + this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 23); this.WrapTextCheckBox.TabIndex = 0; this.WrapTextCheckBox.Text = "&Wrap text"; this.WrapTextCheckBox.UseVisualStyleBackColor = true; @@ -138,45 +191,47 @@ // this.tableLayoutPanel1.ColumnCount = 1; this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.Controls.Add(this.panel1, 0, 0); this.tableLayoutPanel1.Controls.Add(this.LogMessageTextBox, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.ToolbarFlowLayoutPanel, 0, 0); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.RowCount = 2; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(547, 353); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(590, 418); this.tableLayoutPanel1.TabIndex = 2; // - // TopMostCheckBox + // ToolbarFlowLayoutPanel // - this.TopMostCheckBox.AutoSize = true; - this.TopMostCheckBox.Location = new System.Drawing.Point(311, 9); - this.TopMostCheckBox.Name = "TopMostCheckBox"; - this.TopMostCheckBox.Size = new System.Drawing.Size(72, 16); - this.TopMostCheckBox.TabIndex = 3; - this.TopMostCheckBox.Text = "&Top most"; - this.TopMostCheckBox.UseVisualStyleBackColor = true; - this.TopMostCheckBox.CheckedChanged += new System.EventHandler(this.TopMostCheckBox_CheckedChanged); + this.ToolbarFlowLayoutPanel.AutoSize = true; + this.ToolbarFlowLayoutPanel.Controls.Add(this.CleanLogsButton); + this.ToolbarFlowLayoutPanel.Controls.Add(this.ChangeFontButton); + this.ToolbarFlowLayoutPanel.Controls.Add(this.WrapTextCheckBox); + this.ToolbarFlowLayoutPanel.Controls.Add(this.TopMostCheckBox); + this.ToolbarFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.ToolbarFlowLayoutPanel.Location = new System.Drawing.Point(3, 3); + this.ToolbarFlowLayoutPanel.Name = "ToolbarFlowLayoutPanel"; + this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(584, 29); + this.ToolbarFlowLayoutPanel.TabIndex = 2; // // LogForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(547, 353); + this.ClientSize = new System.Drawing.Size(590, 418); this.Controls.Add(this.tableLayoutPanel1); - this.Menu = this.mainMenu1; + this.Menu = this.MainMenu; this.Name = "LogForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Log Viewer"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.LogForm_FormClosing); this.Load += new System.EventHandler(this.LogForm_Load); this.Shown += new System.EventHandler(this.LogForm_Shown); - this.panel1.ResumeLayout(false); - this.panel1.PerformLayout(); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); + this.ToolbarFlowLayoutPanel.ResumeLayout(false); + this.ToolbarFlowLayoutPanel.PerformLayout(); this.ResumeLayout(false); } @@ -184,16 +239,22 @@ #endregion private System.Windows.Forms.TextBox LogMessageTextBox; - private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; - private System.Windows.Forms.MainMenu mainMenu1; + private System.Windows.Forms.MainMenu MainMenu; private System.Windows.Forms.MenuItem FileMenuItem; private System.Windows.Forms.MenuItem OpenLocationMenuItem; private System.Windows.Forms.MenuItem ExitMenuItem; - private System.Windows.Forms.Panel panel1; private System.Windows.Forms.CheckBox WrapTextCheckBox; private System.Windows.Forms.Button CleanLogsButton; private System.Windows.Forms.Button ChangeFontButton; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.CheckBox TopMostCheckBox; + private System.Windows.Forms.MenuItem ViewMenuItem; + private System.Windows.Forms.MenuItem CleanLogsMenuItem; + private System.Windows.Forms.MenuItem ChangeFontMenuItem; + private System.Windows.Forms.MenuItem WrapTextMenuItem; + private System.Windows.Forms.MenuItem TopMostMenuItem; + private System.Windows.Forms.FlowLayoutPanel ToolbarFlowLayoutPanel; + private System.Windows.Forms.MenuItem MenuItemSeparater; + private System.Windows.Forms.MenuItem ShowToolbarMenuItem; } } \ No newline at end of file diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index 3f4bc847..a9b85d52 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -34,9 +34,15 @@ namespace Shadowsocks.View OpenLocationMenuItem.Text = I18N.GetString("&Open Location"); ExitMenuItem.Text = I18N.GetString("E&xit"); CleanLogsButton.Text = I18N.GetString("&Clean logs"); - ChangeFontButton.Text = I18N.GetString("&Font"); + ChangeFontButton.Text = I18N.GetString("Change &font"); WrapTextCheckBox.Text = I18N.GetString("&Wrap text"); TopMostCheckBox.Text = I18N.GetString("&Top most"); + ViewMenuItem.Text = I18N.GetString("&View"); + CleanLogsMenuItem.Text = I18N.GetString("&Clean logs"); + ChangeFontMenuItem.Text = I18N.GetString("Change &font"); + WrapTextMenuItem.Text = I18N.GetString("&Wrap text"); + TopMostMenuItem.Text = I18N.GetString("&Top most"); + ShowToolbarMenuItem.Text = I18N.GetString("&Show toolbar"); this.Text = I18N.GetString("Log Viewer"); } @@ -97,6 +103,9 @@ namespace Shadowsocks.View timer.Interval = 300; timer.Tick += Timer_Tick; timer.Start(); + this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = TopMostTrigger; + LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked = WrapTextMenuItem.Checked = WrapTextTrigger; + ToolbarFlowLayoutPanel.Visible = ShowToolbarTrigger; } private void LogForm_FormClosing(object sender, FormClosingEventArgs e) @@ -121,18 +130,25 @@ namespace Shadowsocks.View LogMessageTextBox.ScrollToCaret(); } - private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e) + #region Clean up the content in LogMessageTextBox. + private void DoCleanLogs() { - LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked; - LogMessageTextBox.ScrollToCaret(); + LogMessageTextBox.Clear(); + } + + private void CleanLogsMenuItem_Click(object sender, EventArgs e) + { + DoCleanLogs(); } private void CleanLogsButton_Click(object sender, EventArgs e) { - LogMessageTextBox.Clear(); + DoCleanLogs(); } + #endregion - private void ChangeFontButton_Click(object sender, EventArgs e) + #region Change the font settings applied in LogMessageTextBox. + private void DoChangeFont() { try { @@ -150,9 +166,88 @@ namespace Shadowsocks.View } } + private void ChangeFontMenuItem_Click(object sender, EventArgs e) + { + DoChangeFont(); + } + + private void ChangeFontButton_Click(object sender, EventArgs e) + { + DoChangeFont(); + } + #endregion + + #region Trigger the log messages wrapable, or not. + bool WrapTextTrigger = false; + bool WrapTextTriggerLock = false; + + private void TriggerWrapText() + { + WrapTextTriggerLock = true; + + WrapTextTrigger = !WrapTextTrigger; + LogMessageTextBox.WordWrap = WrapTextTrigger; + LogMessageTextBox.ScrollToCaret(); + WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = WrapTextTrigger; + + WrapTextTriggerLock = false; + } + + private void WrapTextMenuItem_Click(object sender, EventArgs e) + { + if (!WrapTextTriggerLock) + { + TriggerWrapText(); + } + } + + private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (!WrapTextTriggerLock) + { + TriggerWrapText(); + } + } + #endregion + + #region Trigger this window top most, or not. + bool TopMostTrigger = false; + bool TopMostTriggerLock = false; + + private void TriggerTopMost() + { + TopMostTriggerLock = true; + + TopMostTrigger = !TopMostTrigger; + this.TopMost = TopMostTrigger; + TopMostMenuItem.Checked = TopMostCheckBox.Checked = TopMostTrigger; + + TopMostTriggerLock = false; + } + private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e) { - this.TopMost = TopMostCheckBox.Checked; + if (!TopMostTriggerLock) + { + TriggerTopMost(); + } + } + + private void TopMostMenuItem_Click(object sender, EventArgs e) + { + if (!TopMostTriggerLock) + { + TriggerTopMost(); + } + } + #endregion + + private bool ShowToolbarTrigger = false; + private void ShowToolbarMenuItem_Click(object sender, EventArgs e) + { + ShowToolbarTrigger = !ShowToolbarTrigger; + ToolbarFlowLayoutPanel.Visible = ShowToolbarTrigger; + ShowToolbarMenuItem.Checked = ShowToolbarTrigger; } } } diff --git a/shadowsocks-csharp/View/LogForm.resx b/shadowsocks-csharp/View/LogForm.resx index 34b690ce..e8bf04bf 100644 --- a/shadowsocks-csharp/View/LogForm.resx +++ b/shadowsocks-csharp/View/LogForm.resx @@ -117,10 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + 17, 17 - - 172, 17 - \ No newline at end of file From f1019b4aad868caaecbf46358b09c9d25e0ce585 Mon Sep 17 00:00:00 2001 From: kimw <1@kimwong.me> Date: Thu, 20 Aug 2015 21:01:40 +0800 Subject: [PATCH 14/23] fix variables' name: (first letter uppercase -> lowercase) 1. WrapTextTrigger -> wrapTextTrigger 2. WrapTextTriggerLock -> wrapTextTriggerLock 3. TopMostTrigger -> topMostTrigger 4. TopMostTriggerLock -> topMostTriggerLock 5. ShowToolbarTrigger -> toolbarTrigger --- shadowsocks-csharp/View/LogForm.cs | 50 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index a9b85d52..c906b7d5 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -103,9 +103,9 @@ namespace Shadowsocks.View timer.Interval = 300; timer.Tick += Timer_Tick; timer.Start(); - this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = TopMostTrigger; - LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked = WrapTextMenuItem.Checked = WrapTextTrigger; - ToolbarFlowLayoutPanel.Visible = ShowToolbarTrigger; + this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger; + LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked = WrapTextMenuItem.Checked = wrapTextTrigger; + ToolbarFlowLayoutPanel.Visible = toolbarTrigger; } private void LogForm_FormClosing(object sender, FormClosingEventArgs e) @@ -178,24 +178,24 @@ namespace Shadowsocks.View #endregion #region Trigger the log messages wrapable, or not. - bool WrapTextTrigger = false; - bool WrapTextTriggerLock = false; + bool wrapTextTrigger = false; + bool wrapTextTriggerLock = false; private void TriggerWrapText() { - WrapTextTriggerLock = true; + wrapTextTriggerLock = true; - WrapTextTrigger = !WrapTextTrigger; - LogMessageTextBox.WordWrap = WrapTextTrigger; + wrapTextTrigger = !wrapTextTrigger; + LogMessageTextBox.WordWrap = wrapTextTrigger; LogMessageTextBox.ScrollToCaret(); - WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = WrapTextTrigger; + WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger; - WrapTextTriggerLock = false; + wrapTextTriggerLock = false; } private void WrapTextMenuItem_Click(object sender, EventArgs e) { - if (!WrapTextTriggerLock) + if (!wrapTextTriggerLock) { TriggerWrapText(); } @@ -203,7 +203,7 @@ namespace Shadowsocks.View private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e) { - if (!WrapTextTriggerLock) + if (!wrapTextTriggerLock) { TriggerWrapText(); } @@ -211,23 +211,23 @@ namespace Shadowsocks.View #endregion #region Trigger this window top most, or not. - bool TopMostTrigger = false; - bool TopMostTriggerLock = false; + bool topMostTrigger = false; + bool topMostTriggerLock = false; private void TriggerTopMost() { - TopMostTriggerLock = true; + topMostTriggerLock = true; - TopMostTrigger = !TopMostTrigger; - this.TopMost = TopMostTrigger; - TopMostMenuItem.Checked = TopMostCheckBox.Checked = TopMostTrigger; + topMostTrigger = !topMostTrigger; + this.TopMost = topMostTrigger; + TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger; - TopMostTriggerLock = false; + topMostTriggerLock = false; } private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e) { - if (!TopMostTriggerLock) + if (!topMostTriggerLock) { TriggerTopMost(); } @@ -235,19 +235,19 @@ namespace Shadowsocks.View private void TopMostMenuItem_Click(object sender, EventArgs e) { - if (!TopMostTriggerLock) + if (!topMostTriggerLock) { TriggerTopMost(); } } #endregion - private bool ShowToolbarTrigger = false; + private bool toolbarTrigger = false; private void ShowToolbarMenuItem_Click(object sender, EventArgs e) { - ShowToolbarTrigger = !ShowToolbarTrigger; - ToolbarFlowLayoutPanel.Visible = ShowToolbarTrigger; - ShowToolbarMenuItem.Checked = ShowToolbarTrigger; + toolbarTrigger = !toolbarTrigger; + ToolbarFlowLayoutPanel.Visible = toolbarTrigger; + ShowToolbarMenuItem.Checked = toolbarTrigger; } } } From 0eee5cd98f2e30edb3f4e29b970aba390980668e Mon Sep 17 00:00:00 2001 From: kimw <1@kimwong.me> Date: Thu, 20 Aug 2015 21:03:38 +0800 Subject: [PATCH 15/23] add feature: save LogForm's config into json file. --- shadowsocks-csharp/Model/Configuration.cs | 1 + shadowsocks-csharp/Model/LogViewerConfig.cs | 63 ++++++++++++++++++++ shadowsocks-csharp/View/LogForm.cs | 36 ++++++++++- shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 4 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 shadowsocks-csharp/Model/LogViewerConfig.cs diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 35ee5235..cf506072 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -24,6 +24,7 @@ namespace Shadowsocks.Model public bool useOnlinePac; public bool availabilityStatistics; public bool autoCheckUpdate; + public LogViewerConfig logViewer; private static string CONFIG_FILE = "gui-config.json"; diff --git a/shadowsocks-csharp/Model/LogViewerConfig.cs b/shadowsocks-csharp/Model/LogViewerConfig.cs new file mode 100644 index 00000000..28471084 --- /dev/null +++ b/shadowsocks-csharp/Model/LogViewerConfig.cs @@ -0,0 +1,63 @@ +using System; +using System.Drawing; + +namespace Shadowsocks.Model +{ + [Serializable] + public class LogViewerConfig + { + public string fontName; + public float fontSize; + public string bgColor; + public string textColor; + public bool topMost; + public bool wrapText; + public bool toolbarShown; + + public LogViewerConfig() + { + this.fontName = "Console"; + this.fontSize = 8; + this.bgColor = "black"; + this.textColor = "white"; + this.topMost = false; + this.wrapText = false; + this.toolbarShown = false; + } + + public Color GetBackgroundColor() + { + try + { + return ColorTranslator.FromHtml(bgColor); + } + catch (Exception) + { + return ColorTranslator.FromHtml("black"); + } + } + + public void SetBackgroundColor(Color color) + { + bgColor = ColorTranslator.ToHtml(color); + } + + public Color GetTextColor() + { + try + { + return ColorTranslator.FromHtml(textColor); + } + catch (Exception) + { + return ColorTranslator.FromHtml("white"); + throw; + } + } + + public void SetTextColor(Color color) + { + textColor = ColorTranslator.ToHtml(color); + } + } +} diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index c906b7d5..ab16faf0 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -18,6 +18,7 @@ namespace Shadowsocks.View string filename; Timer timer; const int BACK_OFFSET = 65536; + Model.Configuration config; public LogForm(string filename) { @@ -25,6 +26,21 @@ namespace Shadowsocks.View InitializeComponent(); this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); + config = Model.Configuration.Load(); + if (config.logViewer == null) + { + config.logViewer = new Model.LogViewerConfig(); + } + else + { + topMostTrigger = config.logViewer.topMost; + wrapTextTrigger = config.logViewer.wrapText; + toolbarTrigger = config.logViewer.toolbarShown; + LogMessageTextBox.Font = new Font(config.logViewer.fontName, config.logViewer.fontSize); + LogMessageTextBox.BackColor = config.logViewer.GetBackgroundColor(); + LogMessageTextBox.ForeColor = config.logViewer.GetTextColor(); + } + UpdateTexts(); } @@ -103,14 +119,29 @@ namespace Shadowsocks.View timer.Interval = 300; timer.Tick += Timer_Tick; timer.Start(); + + topMostTriggerLock = true; this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger; - LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked = WrapTextMenuItem.Checked = wrapTextTrigger; - ToolbarFlowLayoutPanel.Visible = toolbarTrigger; + topMostTriggerLock = false; + + wrapTextTriggerLock = true; + LogMessageTextBox.WordWrap = WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger; + wrapTextTriggerLock = false; + + ToolbarFlowLayoutPanel.Visible = ShowToolbarMenuItem.Checked = toolbarTrigger; } private void LogForm_FormClosing(object sender, FormClosingEventArgs e) { timer.Stop(); + config.logViewer.topMost = topMostTrigger; + config.logViewer.wrapText = wrapTextTrigger; + config.logViewer.toolbarShown = toolbarTrigger; + config.logViewer.fontName = LogMessageTextBox.Font.Name; + config.logViewer.fontSize = LogMessageTextBox.Font.Size; + config.logViewer.SetBackgroundColor(LogMessageTextBox.BackColor); + config.logViewer.SetTextColor(LogMessageTextBox.ForeColor); + Model.Configuration.Save(config); } private void OpenLocationMenuItem_Click(object sender, EventArgs e) @@ -243,6 +274,7 @@ namespace Shadowsocks.View #endregion private bool toolbarTrigger = false; + private void ShowToolbarMenuItem_Click(object sender, EventArgs e) { toolbarTrigger = !toolbarTrigger; diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 8200aa07..dd957ffb 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -145,6 +145,7 @@ + From a070c3c98617889c5e92732902c26f4fd23021ed Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Tue, 22 Sep 2015 23:38:38 +0800 Subject: [PATCH 16/23] small fix --- .../Controller/ShadowsocksController.cs | 6 +++ shadowsocks-csharp/Model/LogViewerConfig.cs | 19 ++++++- shadowsocks-csharp/View/LogForm.cs | 54 +++++++++---------- shadowsocks-csharp/View/MenuViewController.cs | 2 +- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 1debda15..40496cfe 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -286,6 +286,12 @@ namespace Shadowsocks.Controller Configuration.Save(_config); } + public void SaveLogViewerConfig(LogViewerConfig newConfig) + { + _config.logViewer = newConfig; + Configuration.Save(_config); + } + protected void Reload() { // some logic in configuration updated the config when saving, we need to read it again diff --git a/shadowsocks-csharp/Model/LogViewerConfig.cs b/shadowsocks-csharp/Model/LogViewerConfig.cs index 28471084..245e5ddb 100644 --- a/shadowsocks-csharp/Model/LogViewerConfig.cs +++ b/shadowsocks-csharp/Model/LogViewerConfig.cs @@ -25,6 +25,24 @@ namespace Shadowsocks.Model this.toolbarShown = false; } + public Font GetFont() + { + try + { + return new Font(fontName, fontSize); + } + catch (Exception) + { + return new Font("Console", 8F); + } + } + + public void SetFont(Font font) + { + fontName = font.Name; + fontSize = font.Size; + } + public Color GetBackgroundColor() { try @@ -51,7 +69,6 @@ namespace Shadowsocks.Model catch (Exception) { return ColorTranslator.FromHtml("white"); - throw; } } diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index ab16faf0..ff1c9bb8 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -1,6 +1,4 @@ -using Shadowsocks.Controller; -using Shadowsocks.Properties; -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; @@ -10,6 +8,10 @@ using System.Linq; using System.Text; using System.Windows.Forms; +using Shadowsocks.Controller; +using Shadowsocks.Properties; +using Shadowsocks.Model; + namespace Shadowsocks.View { public partial class LogForm : Form @@ -18,28 +20,24 @@ namespace Shadowsocks.View string filename; Timer timer; const int BACK_OFFSET = 65536; - Model.Configuration config; + ShadowsocksController controller; - public LogForm(string filename) + public LogForm(ShadowsocksController controller, string filename) { + this.controller = controller; this.filename = filename; InitializeComponent(); this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); - config = Model.Configuration.Load(); - if (config.logViewer == null) - { - config.logViewer = new Model.LogViewerConfig(); - } - else - { - topMostTrigger = config.logViewer.topMost; - wrapTextTrigger = config.logViewer.wrapText; - toolbarTrigger = config.logViewer.toolbarShown; - LogMessageTextBox.Font = new Font(config.logViewer.fontName, config.logViewer.fontSize); - LogMessageTextBox.BackColor = config.logViewer.GetBackgroundColor(); - LogMessageTextBox.ForeColor = config.logViewer.GetTextColor(); - } + LogViewerConfig config = controller.GetConfigurationCopy().logViewer; + if (config == null) + config = new LogViewerConfig(); + topMostTrigger = config.topMost; + wrapTextTrigger = config.wrapText; + toolbarTrigger = config.toolbarShown; + LogMessageTextBox.BackColor = config.GetBackgroundColor(); + LogMessageTextBox.ForeColor = config.GetTextColor(); + LogMessageTextBox.Font = config.GetFont(); UpdateTexts(); } @@ -134,14 +132,16 @@ namespace Shadowsocks.View private void LogForm_FormClosing(object sender, FormClosingEventArgs e) { timer.Stop(); - config.logViewer.topMost = topMostTrigger; - config.logViewer.wrapText = wrapTextTrigger; - config.logViewer.toolbarShown = toolbarTrigger; - config.logViewer.fontName = LogMessageTextBox.Font.Name; - config.logViewer.fontSize = LogMessageTextBox.Font.Size; - config.logViewer.SetBackgroundColor(LogMessageTextBox.BackColor); - config.logViewer.SetTextColor(LogMessageTextBox.ForeColor); - Model.Configuration.Save(config); + LogViewerConfig config = controller.GetConfigurationCopy().logViewer; + if (config == null) + config = new LogViewerConfig(); + config.topMost = topMostTrigger; + config.wrapText = wrapTextTrigger; + config.toolbarShown = toolbarTrigger; + config.SetFont(LogMessageTextBox.Font); + config.SetBackgroundColor(LogMessageTextBox.BackColor); + config.SetTextColor(LogMessageTextBox.ForeColor); + controller.SaveLogViewerConfig(config); } private void OpenLocationMenuItem_Click(object sender, EventArgs e) diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index e729d943..a3c383df 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -439,7 +439,7 @@ namespace Shadowsocks.View { string argument = Logging.LogFile; - new LogForm(argument).Show(); + new LogForm(controller, argument).Show(); } private void QRCodeItem_Click(object sender, EventArgs e) From 969ee15ad64a743aacdb10ee5e85cb6af4921a53 Mon Sep 17 00:00:00 2001 From: kimw <1@kimwong.me> Date: Fri, 21 Aug 2015 17:12:11 +0800 Subject: [PATCH 17/23] convert "\r\n" -> Environment.NewLine --- shadowsocks-csharp/View/LogForm.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index ff1c9bb8..f7d0e4f3 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -78,7 +78,7 @@ namespace Shadowsocks.View string line = ""; while ((line = reader.ReadLine()) != null) - LogMessageTextBox.AppendText(line + "\r\n"); + LogMessageTextBox.AppendText(line + Environment.NewLine); LogMessageTextBox.ScrollToCaret(); @@ -98,7 +98,7 @@ namespace Shadowsocks.View while ((line = reader.ReadLine()) != null) { changed = true; - LogMessageTextBox.AppendText(line + "\r\n"); + LogMessageTextBox.AppendText(line + Environment.NewLine); } if (changed) From f7c9f2049c7f20006067243c13e33e461997bdf2 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Tue, 22 Sep 2015 22:30:05 -0400 Subject: [PATCH 18/23] default font name --- shadowsocks-csharp/Model/LogViewerConfig.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shadowsocks-csharp/Model/LogViewerConfig.cs b/shadowsocks-csharp/Model/LogViewerConfig.cs index 245e5ddb..c82f1b22 100644 --- a/shadowsocks-csharp/Model/LogViewerConfig.cs +++ b/shadowsocks-csharp/Model/LogViewerConfig.cs @@ -16,7 +16,7 @@ namespace Shadowsocks.Model public LogViewerConfig() { - this.fontName = "Console"; + this.fontName = "Consolas"; this.fontSize = 8; this.bgColor = "black"; this.textColor = "white"; @@ -29,7 +29,7 @@ namespace Shadowsocks.Model { try { - return new Font(fontName, fontSize); + return new Font(fontName, fontSize, FontStyle.Regular); } catch (Exception) { From 3aac1cfcfc6bf083f5b6046c0e92c17db4628af8 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Wed, 23 Sep 2015 02:08:41 -0400 Subject: [PATCH 19/23] Refine the authentication for true CCA --- .../Controller/Service/TCPRelay.cs | 2 +- shadowsocks-csharp/Data/cn.txt | 2 +- shadowsocks-csharp/Encryption/IVEncryptor.cs | 96 +++++++++---------- shadowsocks-csharp/View/ConfigForm.cs | 2 +- 4 files changed, 46 insertions(+), 56 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index ca53a97a..a6b20cb0 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -93,7 +93,7 @@ namespace Shadowsocks.Controller private int _firstPacketLength; // Size of receive buffer. public const int RecvSize = 8192; - public const int RecvReserveSize = (RecvSize / IVEncryptor.HASH_BUF_LEN + 1) * IVEncryptor.HASH_BYTES + IVEncryptor.ONETIMEAUTH_BYTES; // reserve for one-time auth + public const int RecvReserveSize = IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES; // reserve for one-time auth public const int BufferSize = RecvSize + RecvReserveSize + 32; private int totalRead = 0; diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index c8bde1ce..77af2154 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -42,7 +42,7 @@ Password=密码 Encryption=加密 Proxy Port=代理端口 Remarks=备注 -Onetime Authentication=一次性认证 +Onetime Authentication (Experimental)=一次性认证(实验性) OK=确定 Cancel=取消 New server=未配置的服务器 diff --git a/shadowsocks-csharp/Encryption/IVEncryptor.cs b/shadowsocks-csharp/Encryption/IVEncryptor.cs index bd600c06..a4b66ce4 100755 --- a/shadowsocks-csharp/Encryption/IVEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IVEncryptor.cs @@ -18,8 +18,9 @@ namespace Shadowsocks.Encryption public const int ONETIMEAUTH_BYTES = 16; public const int ONETIMEAUTH_KEYBYTES = 32; - public const int HASH_BUF_LEN = 128; public const int HASH_BYTES = 4; + public const int CLEN_BYTES = 2; + public const int AUTH_BYTES = HASH_BYTES + CLEN_BYTES; protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE]; @@ -38,17 +39,13 @@ namespace Shadowsocks.Encryption protected byte[] _key; protected int keyLen; protected int ivLen; - protected byte[] hash_buf; - protected int hash_idx = 0; + protected uint counter = 0; + protected byte[] _keyBuffer = null; public IVEncryptor(string method, string password, bool onetimeauth) : base(method, password, onetimeauth) { InitKey(method, password); - if (OnetimeAuth) - { - hash_buf = new byte[HASH_BUF_LEN]; - } } protected abstract Dictionary getCiphers(); @@ -153,45 +150,44 @@ namespace Shadowsocks.Encryption return len; } - protected int ss_onetimeauth(byte[] auth, - byte[] msg, int msg_len, - byte[] iv, int iv_len, - byte[] key, int key_len) + protected int ss_onetimeauth(byte[] auth, byte[] msg, int msg_len) { byte[] auth_key = new byte[ONETIMEAUTH_KEYBYTES]; byte[] auth_bytes = new byte[MAX_IV_LENGTH + MAX_KEY_LENGTH]; - Buffer.BlockCopy(iv, 0, auth_bytes, 0, ivLen); - Buffer.BlockCopy(key, 0, auth_bytes, ivLen, key_len); - Sodium.crypto_generichash(auth_key, ONETIMEAUTH_KEYBYTES, auth_bytes, (ulong)(iv_len + key_len), null, 0); + Buffer.BlockCopy(_encryptIV, 0, auth_bytes, 0, ivLen); + Buffer.BlockCopy(_key, 0, auth_bytes, ivLen, keyLen); + Sodium.crypto_generichash(auth_key, ONETIMEAUTH_KEYBYTES, auth_bytes, (ulong)(ivLen + keyLen), null, 0); return Sodium.crypto_onetimeauth(auth, msg, (ulong)msg_len, auth_key); } - protected void ss_gen_hash(byte[] in_buf, ref int in_offset, ref int in_len, - byte[] hash_buf, ref int hash_idx, int buf_size) + protected void ss_gen_hash(byte[] buf, ref int offset, ref int len, int buf_size) { - int i, j; - int offset = in_offset; - int blen = in_len; - int cidx = hash_idx; - int size = (blen / HASH_BUF_LEN + 1) * HASH_BYTES + blen; + int size = len + AUTH_BYTES; if (buf_size < (size + offset)) throw new Exception("failed to generate hash: buffer size insufficient"); - byte[] hash = new byte[HASH_BYTES]; - for (i = 0, j = offset; i < blen; i++, j++) + + if (_keyBuffer == null) { - if (cidx == HASH_BUF_LEN) - { - Sodium.crypto_generichash(hash, HASH_BYTES, hash_buf, HASH_BUF_LEN, null, 0); - Buffer.BlockCopy(in_buf, j, in_buf, j + HASH_BYTES, blen - i); - Buffer.BlockCopy(hash, 0, in_buf, j, HASH_BYTES); - j += HASH_BYTES; cidx = 0; - } - hash_buf[cidx] = in_buf[j]; - cidx++; + _keyBuffer = new byte[MAX_IV_LENGTH + 4]; + Buffer.BlockCopy(_encryptIV, 0, _keyBuffer, 0, ivLen); } - in_offset = j; - in_len = j - offset; - hash_idx = cidx; + + byte[] counter_bytes = BitConverter.GetBytes((uint)IPAddress.HostToNetworkOrder((int)counter)); + Buffer.BlockCopy(counter_bytes, 0, _keyBuffer, ivLen, 4); + + byte[] hash = new byte[HASH_BYTES]; + byte[] tmp = new byte[len]; + Buffer.BlockCopy(buf, offset, tmp, 0, len); + Sodium.crypto_generichash(hash, HASH_BYTES, tmp, (ulong)len, _keyBuffer, (uint)_keyBuffer.Length); + + Buffer.BlockCopy(buf, offset, buf, offset + AUTH_BYTES, len); + Buffer.BlockCopy(hash, 0, buf, offset + CLEN_BYTES, HASH_BYTES); + byte[] clen = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)len)); + Buffer.BlockCopy(clen, 0, buf, offset, CLEN_BYTES); + + counter++; + len += AUTH_BYTES; + offset += len; } public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) @@ -206,19 +202,16 @@ namespace Shadowsocks.Encryption { if (OnetimeAuth) { - lock (hash_buf) - { - int headLen = ss_headlen(buf, length); - int data_len = length - headLen; - Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES, data_len); - buf[0] |= ONETIMEAUTH_FLAG; - byte[] auth = new byte[ONETIMEAUTH_BYTES]; - ss_onetimeauth(auth, buf, headLen, _encryptIV, ivLen, _key, keyLen); - Buffer.BlockCopy(auth, 0, buf, headLen, ONETIMEAUTH_BYTES); - int buf_offset = headLen + ONETIMEAUTH_BYTES; - ss_gen_hash(buf, ref buf_offset, ref data_len, hash_buf, ref hash_idx, buf.Length); - length = headLen + ONETIMEAUTH_BYTES + data_len; - } + int headLen = ss_headlen(buf, length); + int len = length - headLen; + Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES, len); + buf[0] |= ONETIMEAUTH_FLAG; + byte[] auth = new byte[ONETIMEAUTH_BYTES]; + ss_onetimeauth(auth, buf, headLen); + Buffer.BlockCopy(auth, 0, buf, headLen, ONETIMEAUTH_BYTES); + int offset = headLen + ONETIMEAUTH_BYTES; + ss_gen_hash(buf, ref offset, ref len, buf.Length); + length = headLen + ONETIMEAUTH_BYTES + len; } cipherUpdate(true, length, buf, tempbuf); outlength = length + ivLen; @@ -229,11 +222,8 @@ namespace Shadowsocks.Encryption { if (OnetimeAuth) { - lock (hash_buf) - { - int buf_offset = 0; - ss_gen_hash(buf, ref buf_offset, ref length, hash_buf, ref hash_idx, buf.Length); - } + int offset = 0; + ss_gen_hash(buf, ref offset, ref length, buf.Length); } outlength = length; cipherUpdate(true, length, buf, outbuf); diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index fd0b8d63..38bdf1ad 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -48,7 +48,7 @@ namespace Shadowsocks.View EncryptionLabel.Text = I18N.GetString("Encryption"); ProxyPortLabel.Text = I18N.GetString("Proxy Port"); RemarksLabel.Text = I18N.GetString("Remarks"); - OneTimeAuth.Text = I18N.GetString("Onetime Authentication"); + OneTimeAuth.Text = I18N.GetString("Onetime Authentication (Experimental)"); ServerGroupBox.Text = I18N.GetString("Server"); OKButton.Text = I18N.GetString("OK"); MyCancelButton.Text = I18N.GetString("Cancel"); From d0518e5a114de8ce88081b5e807daa21807945b8 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Thu, 24 Sep 2015 00:34:48 -0400 Subject: [PATCH 20/23] typo --- shadowsocks-csharp/Data/cn.txt | 14 +++++++------- shadowsocks-csharp/View/LogForm.Designer.cs | 16 ++++++++-------- shadowsocks-csharp/View/LogForm.cs | 18 +++++++++--------- shadowsocks-csharp/View/MenuViewController.cs | 4 ++-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 77af2154..b71a2803 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -22,8 +22,8 @@ Scan QRCode from Screen...=扫描屏幕上的二维码... Availability Statistics=统计可用性 Show Logs...=显示日志... Updates...=更新... -Check Updates...=检查更新 -Automatically Check Updates=自动检查更新 +Check for Updates...=检查更新 +Check for Updates at Startup=启动时检查更新 About...=关于... Quit=退出 Edit Servers=编辑服务器 @@ -55,11 +55,11 @@ Move D&own=下移(&O) &Open Location=在资源管理器中打开(&O) E&xit=退出(&X) &View=视图(&V) -&Clean logs=清空日志(&C) -Change &font=设置字体(&F) -&Wrap text=自动换行(&W) -&Top most=置顶(&T) -&Show toolbar=显示工具栏(&S) +&Clean Logs=清空日志(&C) +Change &Font=设置字体(&F) +&Wrap Text=自动换行(&W) +&Top Most=置顶(&T) +&Show Toolbar=显示工具栏(&S) Log Viewer=日志查看器 # QRCode Form diff --git a/shadowsocks-csharp/View/LogForm.Designer.cs b/shadowsocks-csharp/View/LogForm.Designer.cs index 187ab948..a4fcfad1 100644 --- a/shadowsocks-csharp/View/LogForm.Designer.cs +++ b/shadowsocks-csharp/View/LogForm.Designer.cs @@ -107,25 +107,25 @@ // CleanLogsMenuItem // this.CleanLogsMenuItem.Index = 0; - this.CleanLogsMenuItem.Text = "&Clean logs"; + this.CleanLogsMenuItem.Text = "&Clean Logs"; this.CleanLogsMenuItem.Click += new System.EventHandler(this.CleanLogsMenuItem_Click); // // ChangeFontMenuItem // this.ChangeFontMenuItem.Index = 1; - this.ChangeFontMenuItem.Text = "Change &font"; + this.ChangeFontMenuItem.Text = "Change &Font"; this.ChangeFontMenuItem.Click += new System.EventHandler(this.ChangeFontMenuItem_Click); // // WrapTextMenuItem // this.WrapTextMenuItem.Index = 2; - this.WrapTextMenuItem.Text = "&Wrap text"; + this.WrapTextMenuItem.Text = "&Wrap Text"; this.WrapTextMenuItem.Click += new System.EventHandler(this.WrapTextMenuItem_Click); // // TopMostMenuItem // this.TopMostMenuItem.Index = 3; - this.TopMostMenuItem.Text = "&Top most"; + this.TopMostMenuItem.Text = "&Top Most"; this.TopMostMenuItem.Click += new System.EventHandler(this.TopMostMenuItem_Click); // // MenuItemSeparater @@ -136,7 +136,7 @@ // ShowToolbarMenuItem // this.ShowToolbarMenuItem.Index = 5; - this.ShowToolbarMenuItem.Text = "&Show toolbar"; + this.ShowToolbarMenuItem.Text = "&Show Toolbar"; this.ShowToolbarMenuItem.Click += new System.EventHandler(this.ShowToolbarMenuItem_Click); // // TopMostCheckBox @@ -148,7 +148,7 @@ this.TopMostCheckBox.Name = "TopMostCheckBox"; this.TopMostCheckBox.Size = new System.Drawing.Size(72, 23); this.TopMostCheckBox.TabIndex = 3; - this.TopMostCheckBox.Text = "&Top most"; + this.TopMostCheckBox.Text = "&Top Most"; this.TopMostCheckBox.UseVisualStyleBackColor = true; this.TopMostCheckBox.CheckedChanged += new System.EventHandler(this.TopMostCheckBox_CheckedChanged); // @@ -170,7 +170,7 @@ this.CleanLogsButton.Name = "CleanLogsButton"; this.CleanLogsButton.Size = new System.Drawing.Size(75, 23); this.CleanLogsButton.TabIndex = 1; - this.CleanLogsButton.Text = "&Clean logs"; + this.CleanLogsButton.Text = "&Clean Logs"; this.CleanLogsButton.UseVisualStyleBackColor = true; this.CleanLogsButton.Click += new System.EventHandler(this.CleanLogsButton_Click); // @@ -183,7 +183,7 @@ this.WrapTextCheckBox.Name = "WrapTextCheckBox"; this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 23); this.WrapTextCheckBox.TabIndex = 0; - this.WrapTextCheckBox.Text = "&Wrap text"; + this.WrapTextCheckBox.Text = "&Wrap Text"; this.WrapTextCheckBox.UseVisualStyleBackColor = true; this.WrapTextCheckBox.CheckedChanged += new System.EventHandler(this.WrapTextCheckBox_CheckedChanged); // diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs index f7d0e4f3..e2bf9fdd 100644 --- a/shadowsocks-csharp/View/LogForm.cs +++ b/shadowsocks-csharp/View/LogForm.cs @@ -47,16 +47,16 @@ namespace Shadowsocks.View FileMenuItem.Text = I18N.GetString("&File"); OpenLocationMenuItem.Text = I18N.GetString("&Open Location"); ExitMenuItem.Text = I18N.GetString("E&xit"); - CleanLogsButton.Text = I18N.GetString("&Clean logs"); - ChangeFontButton.Text = I18N.GetString("Change &font"); - WrapTextCheckBox.Text = I18N.GetString("&Wrap text"); - TopMostCheckBox.Text = I18N.GetString("&Top most"); + CleanLogsButton.Text = I18N.GetString("&Clean Logs"); + ChangeFontButton.Text = I18N.GetString("Change &Font"); + WrapTextCheckBox.Text = I18N.GetString("&Wrap Text"); + TopMostCheckBox.Text = I18N.GetString("&Top Most"); ViewMenuItem.Text = I18N.GetString("&View"); - CleanLogsMenuItem.Text = I18N.GetString("&Clean logs"); - ChangeFontMenuItem.Text = I18N.GetString("Change &font"); - WrapTextMenuItem.Text = I18N.GetString("&Wrap text"); - TopMostMenuItem.Text = I18N.GetString("&Top most"); - ShowToolbarMenuItem.Text = I18N.GetString("&Show toolbar"); + CleanLogsMenuItem.Text = I18N.GetString("&Clean Logs"); + ChangeFontMenuItem.Text = I18N.GetString("Change &Font"); + WrapTextMenuItem.Text = I18N.GetString("&Wrap Text"); + TopMostMenuItem.Text = I18N.GetString("&Top Most"); + ShowToolbarMenuItem.Text = I18N.GetString("&Show Toolbar"); this.Text = I18N.GetString("Log Viewer"); } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index a3c383df..d4e8a837 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -191,9 +191,9 @@ namespace Shadowsocks.View new MenuItem("-"), CreateMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)), CreateMenuGroup("Updates...", new MenuItem[] { - CreateMenuItem("Check Updates...", new EventHandler(this.checkUpdatesItem_Click)), + CreateMenuItem("Check for Updates...", new EventHandler(this.checkUpdatesItem_Click)), new MenuItem("-"), - this.autoCheckUpdatesToggleItem = CreateMenuItem("Automatically Check Updates", new EventHandler(this.autoCheckUpdatesToggleItem_Click)), + this.autoCheckUpdatesToggleItem = CreateMenuItem("Check for Updates at Startup", new EventHandler(this.autoCheckUpdatesToggleItem_Click)), }), CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)), new MenuItem("-"), From c5e27486fbdf1c0cdf380a23af7d31d62f8278f6 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Fri, 25 Sep 2015 04:03:04 -0400 Subject: [PATCH 21/23] Protocol V2 --- .../Controller/Service/TCPRelay.cs | 2 +- .../Controller/Service/UDPRelay.cs | 12 +-- shadowsocks-csharp/Data/libsscrypto.dll.gz | Bin 51484 -> 47058 bytes .../Encryption/EncryptorBase.cs | 2 +- .../Encryption/EncryptorFactory.cs | 2 +- shadowsocks-csharp/Encryption/IEncryptor.cs | 2 +- shadowsocks-csharp/Encryption/IVEncryptor.cs | 98 ++++++++++-------- shadowsocks-csharp/Encryption/Sodium.cs | 11 +- .../Encryption/TableEncryptor.cs | 2 +- test/UnitTest.cs | 8 +- 10 files changed, 71 insertions(+), 68 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index a6b20cb0..eb676ad2 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -586,7 +586,7 @@ namespace Shadowsocks.Controller { return; } - encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend); + encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend, false); } remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null); diff --git a/shadowsocks-csharp/Controller/Service/UDPRelay.cs b/shadowsocks-csharp/Controller/Service/UDPRelay.cs index a0662dd2..9d3d3dcf 100644 --- a/shadowsocks-csharp/Controller/Service/UDPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/UDPRelay.cs @@ -74,13 +74,13 @@ namespace Shadowsocks.Controller } public void Send(byte[] data, int length) { - IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); - byte[] dataIn = new byte[length - 3]; + IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth); + byte[] dataIn = new byte[length - 3 + IVEncryptor.ONETIMEAUTH_BYTES]; Array.Copy(data, 3, dataIn, 0, length - 3); - byte[] dataOut = new byte[length - 3 + 16]; + byte[] dataOut = new byte[length - 3 + 16 + IVEncryptor.ONETIMEAUTH_BYTES]; int outlen; - encryptor.Encrypt(dataIn, dataIn.Length, dataOut, out outlen); - _remote.SendTo(dataOut, _remoteEndPoint); + encryptor.Encrypt(dataIn, length - 3, dataOut, out outlen, true); + _remote.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint); } public void Receive() { @@ -97,7 +97,7 @@ namespace Shadowsocks.Controller byte[] dataOut = new byte[bytesRead]; int outlen; - IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); + IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth); encryptor.Decrypt(_buffer, bytesRead, dataOut, out outlen); byte[] sendBuf = new byte[outlen + 3]; diff --git a/shadowsocks-csharp/Data/libsscrypto.dll.gz b/shadowsocks-csharp/Data/libsscrypto.dll.gz index 5efa66613ad1f21294f50ba365349e1b4e121ab9..b042986074202b38d3189a9142a2d9ea8f17b772 100755 GIT binary patch literal 47058 zcmV(>K-j+@iwFpWzywwT18iwxb8};Id2n=ZE@W(M0PMXDTvS#10DOlTV1U6H6%-Yf z5(`5Oy;>L=pbnrpI*5FwfG8j$D#45&B?=7`*XxwKTm9W#Yi+e%ch`1l*A&ZY28<6s zL0yCV2#e~{P@xi_67xRKIrk1TXl?)h`@X;TeShyCJ@cH;=RD^*U(b2Y$JIT(n~^gN zqX1*KGfWjj|Du@x{HKvI%#iW#4Pg#@oq3>2w&=_Q%W~Hi1r-!-TvM32K4^93h7B7H zL94QZ3XL0r)@}%zza$}O{l={9slLA6!6J^fNBx%XTl}n2GJfZI@k|e)Y#_a(g*${^L6dZq|en;ma1Hg1rRuH=z!+3~kB*;|CD04}0 zl#C?O&?FR6&=@0Q${=)EoQ#=`p1WmCtL#2Z-zQ@l)eN)pNf}e{Gj-Dl;VyNEbjp4@ z{!~Nu76ZVu%_2dcG7h?>zaYqVYGGEUA(LUk(nXvr!CZ5V2l+-#rO}uW7MTheBd4E~ z4UT7-T3A%L8hI?EWkwz{F|vE{6=vsegos#nhuA`cQv^(Ue;Z8orV5G%u9xbemgd zG2RYs;&n>%T$w3T!I&~t3^$F7RyxupCA0Pqmq9}Q6G%FOCUwi<-AvVPIT3ZnA3~d& z?jQn1A~rv6tAg9A%5cFE0txegQ+%Q(flmtreg&D@8N(x{c9}7x?7YE4edJ`c&HWhm zF;2%Gqf+=f97f?w z=^4w@s)HFyyN_05n8GJ2`Grb;u4;l#H9@QKsfR+$)$j}bCTPJ+6ERm~bdOl*XHZPH zq}5c)2+gJr&AwZaG7X=o;!h%POWUKsS=s<4^x@q&Z5KaR!D)N>xk^*Diqm!SxC0V}K!b(JI2Dc<^)Mq65s@PJLZ;AofJD@)k#9{RXD< zU#8WZCWNG@kIa>Ex-RvRg~|l=k+m{K{hJMJw&poCCgAwcLHK)B=<1MGF-Cw zb2}N~#tg~*m}GfevdrRi0>lWH+)oe-p9WPvH$w89!|D1U(rn57q-2RC z7Eag8>$>=8KX#sG!aNl_&yU}#)I$8(Tf0j_+qjgpW?I~Z0&?P68QvME4NzDxyc(Lls`%Q>e;#pHKnzfh}CvL z@F_QWCtt_b@MkAflNhJjI`BT}#_Kvt>o6XrMPAR>aJnl%ZY_z{$kxc~k-&3&HD7#% zt>tvBBww~#uDd9bRgbx!;_LXdR*Z0klme*I9i|0<2$26th>&=Ntw9V(0}!CAqBKH; zlWy{}d<}1GWvdYb<_=lwj#J`98Xzg5$|4dop^j3(RwD)VVs5ASTBHOxfF+^jsB~mR zD5*h8>Lx%|5RXI<92q%LG674&(mLsL6xN9w6Y3BHv>902hs<`VC7-W^|9J2R(pcgHaA)Llbp7V5{zvK_|(SMOwe|+bs~{g zUf0X&j>|h)sA=6H9+5-4fJ{X80?kmhXSu|KY+@%R9579|B-gddt>7i^g;MZZ3xAH) zo+jCLKzNfyj-wZAJScCHU*NP?__Rv4hfQnbPqJzCY+4(y6k_0QFsYZSZ8GnN- zKEdlcORaC(S~hTLhxoK+`3)$>S**mnfD`Dt15I3akVb*h%5SsU!K zPTS1a0yTs|&7{{Lvq`7w1^)1-NbZL)=0%7}YwjX6MauINrPYXwW&$l)dmJ)hA#-g9 zCTYYZobI4lp^c@rG#=CfutI*4)Ic+-RKi8@#qsewIbdKuIfa zJd80(r#VRCVY9C%jRcrgT1U%fkq;^4mJr8t45=p^_%fM$$;g?Dft$D%7@E3#nEZ6-ap zjnh^(S!ubT5@5dK>#;{d9Uo_bxh^FTuml%LCaruTQlx`Q?&PJhu9FO<4&FCPjRR`n z3U53J(m|62qGBh2v9+14h005;bgqQc>?O!SYDUNT;zR5wkcrrHu_rcR$AI>Cfz>ra z?L(e0Q3{Gr1Wi= z;xvECM|Wt#IZk^JlJGDF9V)HE_?Y^%{47ljDUFAKZql>Jr6%#|ZujI7{c`Ser zW;x;1gjyfSMPM-_h!3d5P!%WmMoxPO>);#`sH^1bCTJ@soW;yeh*_P2 zwnU~gUe|~DS%6{~2{AtlA(qn~o^Xz@!R)k$Fr`IIc@~I-l)y}w%ps*fh$W-4z@PQe z9i9NQY9$u4c7paWrWEAo90e>sEM|CuaHj*4^&wl%xnYuX&eWFHl0>?`dui?!X}%~j zxEBgcc;s^mDTeu9WDrDamBXN?>yXz%R6EDTlEY0E;nY z>i}yHi>y6?i91Q2Rhak+p%zI!2os;9Qm#m>CDe*-rRw(0Z5&(BVcLQm#8x7)m6X`S1H@K}#1aP4jISWE%?@Ha#CAZ4 zZ5~8yugKSnV#B*g=CfW_1&Fk!*^Wx_Sm=%_#gC~)>TK?#M?N#26P5~Kj0g9LK{rz?~=apa&ARH>Cl zwLtI0(M@|=-h`vlNf`Nzhqz*xCoE*J#E}vygP7Wb=65bxSDlpO0t!Yo{;V`<9d^uE zM7TsL3`SJ#A@ea3zn4fzCs1O5@v@3eSG7`PC;$wq+Dh|pNn|Q6SVVCFCoRZ{iVH+i zbjMhw)g&&AtlEPpD+tnbMUWqIkrlLuqpgx_n{f!Q5=Wh0sc*pKd6;w$KuqVrQY$8BYbDlSl-CgXj!!$mrk&d%P@3a3OWs(|8XG|{WsQfLYUQL<)lDG9AEt|#dXz4zxx~YKVigDg z+T&OPm_DnZ;Urqv#CkUIA|g#}B|;twyYkyj)%-awv0h>;a7WhxqzMY5}OQ>2b-$pWa*(j%oW3Y+{YGMrX}{VciCbPV*1#`W^1iGNa=}( zaA|gp)K8~X*GXGoQ=PmH1}|-uwZ>iE%o$;5ZK}3fphuz-r zb5w6C^fC?mF$@n0Ny+?e{!{*OSPm{xScS3H>vEVW{eHlVd25BP$0`JvzKX1X1-sQM zXezWnAXFX;hwut*cj#HZx+3u|M5-VHFUGiyQ2AcS6EbkzsoDZDLu*a_;p(|o{+wQD z=(pSRl;*@P{+#du*wsg3eM~2m6>_k6SIm>~u}Vl@G0zR$0MJ`qF;4+tNX0yNK2}9S zJ;1H1nCA&#c*Q&=fMFH$y!coR3H1iIredBCfRPpRQ~*X)%=6`A{U8*kw2FB{*fZei zS20fwU`)k44S>-V^M>-V0R+J?a6>&;%p1O3m^21hA@ULUSK84EB^qEM*8WnysjfW8 zjyo_6V>Y9$t~^+D*OiBWO*TQhrmlQ4*tox)`M$0^3~c>Z-rG}GJ_Br5$iL+xjvyX6O~Y@raMua0?aU5oYD(1 zc7m=>tMo(q(uBMybL@(|$Mk~g5rzTB(Y@fGw<1aCn*`W(O4Eq|Xr!ZacB_xb&C6wB zF&6VCnfk~)dsvJeRi=m_c}1NkX(i|CV#!WJU96H6GFC-O7^@-0i}fRAiwz(JJKaYL z0>rRqpm_>sMmd*80Ey3qHOnjsGwDkXJGt( z<=ws>yFIvsJN#dRoRb#F(y+Ve8qG>LX31{iw*^*7PAJd#^P|rcsYC zA(d6jO%E<1X&%EgrfLOAr9N__^p0|kOtbB36{e|mZ(S+VtgdyR2Wc6uyce=mkB?&b zUFDdmxx5#Ct=HW`t$YB;k+(g~iZQ4Qw6e`0sNMFITO2OA1>ERr;!l!@!+h#ZH&$b4 zHG~t?6?-td3R7#gOcOH1 zy3*;Vo>RT6d`_mZT9s(q?69qK*r3enBQIgb(BfC}yUbWVzI+DMr`-D6p1XW`5V7*d zUq!wXpD^mPSM>P+Y2(X?ixSV5hma`8kow>D+!h0ED)usK=U&Gsti{@@WJzqa)R2Or zt&UT?t1JTgEK0O(bl7%Cw$@CUCWcnAde=8}Xvj!s&ny?Vk8tfy*q(9&AYLAW`xE0H zBJ+Z4IImTfTMR>wVYJ<~&{?8n*u{U4+AoYRra8^PbjGL_RzT;fb4M4p5?-g_tqD`G zWf>kZ2~md8_~TvG3eB5LJ$#z7PCf*JZGOb6LaP_CdV@77+1l=Io~Hz!kXi9b9(r|) zsn#t=J-&?WZ>f(Y$;_Kz@L$|#{aoqO1eUv!>>`Uxf zt{{kQ0nw3*3+Cfg>?tm-kJD+mxXF;}Q7$EfPYF;TIVNT^)%vvq&24Z`adra>)khj! zeB%7rEgJS5ws5qYHb3rErxa6dW7J;&LN zQ^+;m*ujo%!(!axQlhXd^Fcb{6E$oT7Z=Cr7eT5eTp}R$zy&T* z;PflmOZ-hvpT!#c_-kB2E}N#|Qt~0m#(_H6FsKgJySh&~JK5q64*qW`V2gXXEe2Rl z>44@gE^Z6RlZ5zfK)e_oMi~w{5Vu40m_}UNt=Sr-i%+qu53mi@E50324s1FV*ooMa zd=v7l0vkV+>LjBK@J_W$buqf}^`N7=j-=)V*7(~ z`*xB-_i+{bNM5~!0S6om=;SI6qT>R$`w%VjKL`-pe8t}pu}d?rc>5l&lg>^yO~7un zrxMX#<8N_$4%4Eaw`gFEG%;7bYUT(1yxxH zZ#Br<6B2Ksi1nnrq-IakQl29~><|@a5vfZbs5mpo3+&KQVIc;^9n`eC2u~XaTF*ta zp2c=t(d<;>D^iIi=6-fBbFba&b#;&zo7T&Y?Zp!BLFt(NjN8+OFs+l@BcSC|Zchg- z<@W$G(g(`<-M!`f_8zZO;9Ne?{S!6ZZalrhLjT|0MJ!$1?p|W);CAD(iM5akD9#T` z$Lke*fs)^%8W=Z64jLy%408LsjGHhd2e4yX>6nuyus6As06s;-_CrDSfxzK{ATk?F z#!+ocFw6jhhlfX927{^h3=dQ8KRmRF!$Vvc?HU4m3FZMD?!rmOEtt*T4V&9uC1q!9g8C&e-|b<=qp^xO8ztGwEQV%~#;!3?x%& zLf<@S0^c;qZFC(3JK33JB!bbfU<=#B6>Q`C2|KIEV4S9b?Dv!n3`^MBDk?}ThLL&K zz#u5qG8vl(Dv?$x8K0f&nvTx*R(A*M+a=8gWMn?e-#~u%a1}T_<1kIeW?b#Qy=PBl#lMs_rrU=KDZw#eMrh~i`3!CD4N*G?IuI$C2lv4pX?{xZZh0m z$VlgQlhMvXWl+5e1-}9XzePFFKGlQTh$YX{R_w95QW+BhLR!fJDZ3NsM2~Uf}Pb1c~*!B^RXy z6d+Fx@MYs5K5Q7|UVjf?u=^mf1=6tj35-@ac5Pu#f%ry-)NRhPM%<1;GV1n0?&3k~ z2AF;3V9#Ks0qcS^T47hkQG^ar4OEI8=!q}i+wESu*ULP(C;Bt6R%SoJ&fft&VfSva z^HbSTz}~-yj+@+`y@PxIAMVZIjeEUbzo++iu>OiQ*!%a1ef@yg*PSIqSo~U+51dyE zN>Cqp8V{o3;WRg&Yw#<>V`xwa=3MCIMSPU#^rACpoRSTo@zf**9-SNFMS!n0y9=Uq zA;6Pvurz{2Y+47eX7wtQMbmV90a+upmN%$h!n1mS&)Tj*^$Aeeu0(Oh?^RS_@Ww9I z&x}e9{;ah<0PRGXaSCnEp)ad}lrU72#CgifslV2U;wiCK$>$P%^3*_KnJEgiwOg1&bl@>MI{wk_|H^# zI#GR!)zdO}U}}+1x;BbLO0Da3PA<46_alYwC7E~9Qo9zJON7O;z@OxeSODuc5aT>M zLqygl=7~6Gh>YZn&>*lm5QHv-w7Jw9pVlD}qHAUKfeTEQAV*txx$8%w=(&GeaA54Z zUrS(V!2hr*KtmwOm9!?Mwt&@%$r5|9;*ifL2lx>vH3%nuNY&c`s94m)G@vN$=iC~k z+`C-sgtmqTF0oadO-NP)!WU{b#5#6WcXSeG!+_68iiu5ud8I=fooIV-!Zy(CT-6$F z_xN;@_Cjgv;*mWAxWxSVSKU1m{D$5m*H^EYXkYjpwMbQ zEr3f@aoWC|-Al^5jebBqe<48#y8{hAQDr)z;I%NYs5Cnjcsi4C;qiwm3{fMAV>_e1pb1P)g6$*-wLRHXt=u?$Hp-+YII-=V&>y>p;WaosnNczqSg(iw>zJDNkf7BO87@;Al zMvk#e=;XB^%PKr#L|5QINN z@yDIDMA^cGAAkckcj24@1qO?4Jh^M26as)5sWy$NSi`7awLpko7zrgzO{-Qhd79j) zc`}W#!wV}ynBWfnWfr3+YiUR2gAk&?y~!{BC96pL+LYbLnCA37Ez>Xt&pc1zlqbW~ zxuY8u*up}HT4ph13zw7(le>5!qY>Wm0RPn(O%Z%54m|duM*;N+yuoO4Rq!Lc3KXWM zmRpRIgm2{pNl>m5Llqc0hJ@0L@Vx!>%Roz=wyz)ej^=|$*=2S4B6Q5~B=<6&WDMhy zgb-R3!*IJ%mFEV0;2-193cHnft-$WyoD6;25+$4gcg@bUukFS!1QVvH$y4R7M2@V- zog<7^ZrPz=Ew&|b`_UzgkRwOh2AJVSnDHT&>@b9xCK3)w1dd^(79Nf0Q`v?xi~3b7 zZxxne*1`cuVmG!49#ZBdn0Y6Z1ashvRVKU4;BB(I8Ql3arEMD2X);(61iY2RcXGxy z+$qP^ABH3d%{aA5-ne9i^hVDF;W|`sDvfg5T}+8Vq0pVjfxkXMIP6Z4Bqa#H`4M*o z(Pj`aD9XDH3h2u|2?Fa4m|$RVH`(RJIEr%BK(2P_bVCXx1wCccHudN*`_vg{5G>k}+>$;QkJ1dUfut@QZZU zxwj?LURUSdDcbTBDeEjuT}f9m?IzUClQD!_M|*`rM2 z<7Uh2)kmZK%<%#8MzDCS>kN_KjJRYN1>=0gLRFzRKUXQAtBR;ERGF$nA}$%ffpI;p zhOf5W79R6No*CuSEj3wh;;57KA+sDxq*vG!5se1uaQw+m^*ci#PUmz>dQGJ)y+)9c zLv&@K6y|`Z?OTW}{1Lo_soo?d z6h%1XK`03zErYZiou3|C#cpgPiGFrtpxqcCWcp#3Osf&Lk@yBxt^(*4J|2sGQJ5Hj zp6asRk0md7(Hv<10jJ-_&uN%j9!E;a`Q;IHI6vEA>EtU^=$2q z%SbBRhKG*gZt9mAw+Rf*`w?j957GQrVgBF+m~6?p8uVHMUOmmJqb>aw+kCR2Z8ml# zn_9Er;-@9p)?#YThy<>D2V-Ej4<6IM9OK`7djM# zC+ZU9vKMPPhVAG@%D|F2$aBWvQ38`OR<2U`+gOGSv5zaUK1D_oF7e0_h;F(Lv!U`r zy{Xp@4d*P3$~GU$?CF7!23R}B($hFWs}!&5DTVidB+vePvd^BqDdVRVE+E;k5D zWA_gRY&FC#Bzj^qt_lHrjd1N6bo4ldNvYuC6vEeb(d7oNnkp5ZoN$bO2}wBqZK2~I zNP1@`vE61eD&?Mr){>;>W`-gDF`h(Zm+?+07pH)q$Y z2M93lA>efb0p$e*yp>PD+qnStzFfW+CljrLD}MznX0+_Xt#U#Ej);6zU!I;T-%Uaf zCh3J=d!PWU09xv_2mKi)s!n?dheS?$*zO+!3`sJl*n2KRWb6b4&*;lgBmFgWQZQ?K z^>kK%F~e7Vq^75NjO77$EF=|KO%u`1)FdQ*7zX|1ef){IRTPlSKM50|7k^H`GhFsh zOtp%LTZP|%3fdQGEwTwNGSVC_bILaxtUHvd<)EOXde_xcp#^8BAy^h_9r@ zL6c!W)^pi{-H7K?#eRcj(spL;$8BNliRG|mMFPo6_3aM zTVYfwy|H#f_5xmeW#$G$c0QgZZk`#Ny}{^H-_w#OOBvme$COxQsrMi-%mWk?J0tDt zITjBYW0){!C5%Ldz&Qm7{O9OB3NwV+K;}5VW#>Z>W?EU@e`G8tYwzF5;`Hyb>anJ5c7&vNy$WD3CE_{Z3u+s z>CQIfaO#L!quTC2gSJ@r9B%&R{)}`{fLY|`eB=p6XR{gg9k~jq;&{FA20brjniBv~ z+&4X)oQt>F^O%p&oh389@>W7Lz|h<_FauLZNIxo zX=5#Vy*?K+5xTA9Fj@_D6#(Ycf%Adl`8gHuVe0KS`0|St@^h>zTv&>DVwC)16>&pV zv`2#1J?nQY<2DMtNwKM!YrMXB$C+sABowkb%Sw=iWE9}PcxftmEo{WV`D0O#~ zB1c_*m<(%eW^Ef+Ebz~%xOsghd%wEOLXHsinq%F}ida6d)T}6l@f{j@d4nN`za+d4 zWA!_-3Z1>&vL$bOGN3FCUtP4m)i}d6M`Ob2G&C2X@K_NJ>IxY8NAok$hd-MqBLe$f zpy?8C>@=NF;w5aIO4x$yEv;(S7L_5x_S8QVi5EOYIdPd1~ z>Lc@m@tpCtU`2U@x@H-TRKc^n*X{ythzU~Y?M^S8FWIjNi5)r}f9Q6)QFtHl^ z3BsQ+{E5OJJ^rl3p91qon7Xtbe|xM9F8n^W4VUsQdeV_6kX#se3y|JIq^7zcQ+p8j z6?ODj$K$EBRpxE8S{>mc{XJG30u4hdJY!AmGU_tk?6IP*#-QY&3<^`bqQ}|``5JnCg_Kb|norek&rCggX#_iR25dS(1FEl?)92Ny+BG@ECFL@t6(-pISBQBUAEraUsW;i^o0Q}T zvAMC`5b6aBffqeli)|=h`=TcYQKBqvYm)yxWVF?_9KWKwS{xNne@lA`7 zR5>|j4z*w>YdarE8B80#FnUv=t zOmqN$(3a;RJauo%Z+?(c#yO?5V4^DgL0g`uFmxcLY9R63j>L+R?!o!z~_s|Ic@{X<6s`AWb1{@Z|wF& zJ~zN#pt2We>;-yEk}ut|AxQ8TcLm5azouVgf>99-ToC0BT315%+lQI zBz%)5a2@X5lJ1=!tXvuo+4>28k#t~6#-U9gGN%BTZ}8L${~kh=zzPg|b0rRry>`RH zR5@WBq8D_eGmwzfJVq~UCTsg7;T@nFNHfjB5W7*%T53Q}B}0;ZCi?Ncq-pYFIUQJ6zy~v%xjYPnHY|P&br!wWOG#sxPa;c_5Dm+*_bEnn;AzJt;(0Da5R0m^4u+x~Dx(CtW43587kX z*Q7maczwuHULU+v@FVS5c~5i1P6lhsM15X=?!J`4eM@hK36`!TAyx?XE$mfx!xN@$ z!ISL$iCdZk;MIUZ0Yhmbx5TuD!8_ zx8uf4yz{C;MXr&B)|xExWY%sK+-4b7V=nhxn9ytp+Sxy?zSiP!jKdj zao5=9IQ#$nS9D!KaSysbV;f19@nm zC9MW!2mwVPR6gEQfFxnnQ0yY8!Jmg*9l@W3MSHUOc|0Z((Fj==D`(AuwX0PXQE&W# zKLw(LC%;u$ZYLWzzPOgRyBmF23zw>lYX6by@YQ8Eux4V&OGjE27o#w3RVdZvcm&Km zH`uJtw|Q_WN|QwuQElwz)0I`fVi?OT+2$pN`K7bWU^lR(vtB~@VCk%v5e_Y#1teLF z8|z|}rC8fJV0i&8X<#v-Wf@qWN6S-S!HqfF+|pUU7Lol%M0VJXB6}C0@j-})2WD)e zz=DTqY#OkXqs0>}JIV7(O8#7)QsRFqm#(yF?9V8mxC6BU%llL;WW7COxp?90uWe3M z!dgm;l~^t6SD;GrRJj&ZfnHhzJTl_0!!Tj4jBG}EVNZM(cg#RYxu5}vI?|FkeW*}T zm;aXRIz}DqA}Y!{Z6BFbig7n}Hb0g~f)`AmlU{$4^!gg!w-@3@)EoTS7P9o@PhL31 zpArebkgHh%P2U^0U3_u_!A>@|NTz^uXl@v8jRm3ho*~0#Za8|(K#%X~;Ma|sX(Uf3 zZ9_c_G=cYIEXpHfzqo^E>|w%9GD9d(4J&X;QgkTfV;Z6W9}c{ryb?zF(S5nBH^VS> zRIXJ}9+VmBeu~p33gTbFkgX;NFo4f#+ zYL(*xjF(MY3_~{k+f*fxdn>R|yQhz!78ccZxgB>9e{z{{UIH4T_4_hS`7vykC!@|S%NRkjHE-i?AnEn_h*{{MnHVlVmWQV+-#L7+* z9`}?cJhAWzs)RnQOH@TOy!@HdsXFRYvo2%FoT5ym3b!r<-tN>LekR^9=XgK8C>PN<-LB=WoK{HS89t!=vQY_xbbC9}>rZ!9_z3&eb$(teh^zCPfE-aX@K4D{Dexd{FI&x@y`by8P|xdnBXnIxA3zjih2O{}l2iF=_PkW|3n%ft1DcJDXE^$+S5TnLU@hrn z&{-~wx;BW-z?I%4pePK+48oOhGEq9?>l65Krt9OA`Rxj}nct*jd)ZE4%GnF2BKoOf zF!WXxs@b)xrYGN#RGG!wD(BLP0_C4&MU7<{8H*RmFYI5-oquu>r}~hSq@q2GUnV&zSQ)=O;9B ziG2nQUSG3BaYM}u6cO4!5MDqSiBdqjd=L6f0_Q1={|;D^*30|wUYyJv3*(qC`uHS) zJ6a(y#DS|`a4K0##`1Ir17T1mbElB*B3hZXN~BoZr-!LcPNqyp5^=TT4&}3j@E#E{ zO5^ySkkdI2kS4eoCEf3)V=_VAYu2hr2ECZU$v!EA+{#3m=GZGMfuR5LC5l5zoe3{c zD}u?)z8OaiR7#rf66GW=R!A2h3vIR=Thm!~Ch-zJfHhE(aBK|zt{jWMAC1S~xZ5}p z`QaJ^2Hxp5)LFlI5HdG4*poWdR;6(aaei2l0Afe2!B;P|Acwe_=xd+32T8<(RQ8#B z@yuH{N4*Xcul$vG(g6d6{lueyc%ZlNYx>41NBl7V+}$wy<_5rz5Iq_zp+V-?=kQpB7PHn=}-?|z5;K&%8pD=ek z*$WLy65>bGoq7MH0jw2N@@TR73LX%#j!_YTP{PJ1DwE338(^|hftc=1Wy_JZZj8_j z+2)N%=fZ>{yi|+N#3u81LT~O=JXzrx3(}T59(KEt0sYUX!dv(YMt{(Dj_tNx5EhOh zBq{So2)_esYPWj{?%Ek1$Qvp6EEkWic&472lqbu@9nn0wFyDtv=U{uR$8L9-gjIR1 z?D>?Q?g*`_aEAIHMwL|ZxN%a+lSes9uDnmlRpah0IX;J>Q`W*PMG7wCVikO}!ZzZ~ zLo4xAm2udcxk=EHVij-Z6R5P!PZGX>A=R9$;5?U_H!JzLMVvPu7pLcj2%n6@-Gax3 zJ`}0cH~^IDA#VCXH>0nq-i;$J$V>(@6VCd1%G_LRKyQ6cc2Ho132+~nE`bn~e|Z`B z-*zJh%)}OiuQLlrKBto=nK47?(JW#F|;Hy_i__QiAjl{)4K?7hYfj%cQs!MNU ze=~T-3+r&uamgUjIfFWdn888JpzFGn!5S%pJemb~>F%Y~+Zok12~`}T`ilcq;9y## z;yUe&3!duhPIzW0eu*oBg- zz$O8f)VioRtO~H^;H@_V6@@YqX4upqj!3>#o|*kF9ty!gR(&&EWQ^$J)Mcfm$q9U5IZ7=5*KWlv&$!RZHaDD+X>!Bx zr-E*6Rre3xk#fjB9(MovlKvuHINRj1-gUtmg$N1iy>y=|zu#rgN#%-FKY(@1&tQ#1 zgaq{=x(7DmXR*c&V14jsu<8*ZL2aS?W0re%xdtI#G=R9Fks?;!2eAQh=Hn090rL~q zIBoX%JMDluaJy`Qi8-thb5PwUhi!&k&D@=Gc-U?X!5o6^#-Mw5CmneX4x?ws z@h~kk@~#0oK08P02)+*;uOJD#@CR*q0Yb6UUf(cjXVsA<(Qhj77^H~XbWY-;^QIs6 zTGvg#pwwG`tCVHjM+NU2o=zSC@@6fj+cNbl7TdC<+!UmUR4>}{l)_hco!BF4^zs<} zK<%1(pEV9)8{R`~(Jy+#sHMttOF4$l7iH7MRkU#Ntdle#?LT5q{^|WkEQ_%<9TyrT zl^Mjr#?U5HwLFRKwtnLlVI{{ws|~&&zQ@qjYNxR~-O*%AJ3{2nN0~qtuqRVZ@wrc6 z^vTnk%UkiCD@HHex+A`~sgVzq4fU6R4WxoHgz0CT zY6t?4&4wBjo`>P$K4YMe)r(V~VJ2U>0_W9kL+GH+GSEPXg2E5m?77o43p{#2mdoS- z0y`6PB8Pu97tTrpi19;VD6SJFrQ}v3*!k7K+UcB5TsyhL+9@ed_TfkcV@ZN#y$9V& zO>)t8r=z4TprjpnNs_ex3Di53a&dS>-&x2`yW}KfpTnsCQP};hL)cB?Z{(?X4L(l+*~d|8%fsNH!1A?dvRa<@<)gPkL=>3EqqNy znL9SGsEE44uASxIL2R=be{0LpJIFR(eI#Cnx50cP>WX}8Y3!h=i0Vz>o2+g-Wn~uQ z)dWCqF7Ja>`eZXnr_Ylm2$M%Jj2QGI5+Q{p+mB#r6NKzhs8NUlZx{$L=0KcWR76Vg z=8$;7{3-R(G96}fP-YlXvS`RC&CW7k#BI|YbTjy)PZ0V5wu-VL$S#{_#a?2GjyP9n zwWa3$!TcIJ`BN#O)i6*2E_st2Y;9mOS%OTxqc(dJ%;xAI+i=qd=s#-n5VK-PN!+L) zb98Hko6W6aG*6OJT!{KT$JXzQ^{z`$Vd*VAV%;Zr%jg=9oPyx-G43vYL0m+%!icxS z5sGQ53F%Yuqd{cfgxqm(7hc0N6ELqrH&R;zo-+F5d&pbJq83Kmf;hnoQ`LEr zmV6Fh4YqS}aR9qZuqnG4|J>~!f)|C1Z@?0e3@}}|GAy}^CmvNyYO0}}bmRS~ifP{j zLr%$@71*_m!}4T#KMLRWRvf=mi-~s=y%U9))vRoJj3MTjfMmUJ_21C0((%#)dzt$XJIcISX~L%X zlH%_m<#&b$cE-ud8VsY!g@2{Z16#EsI^yJ}Zj;5WB%CpRW{w$stRL^#D3wt-#PmQ9 z6n=MyZ0K??AV%C5mvh^dti`+?N2PY$Jef5I$2@}%3}V2C_IFT)TW@ba?2zJHprN-H_Y4_4FiWERDEP94lN@~@8FLbyz zh{jD{!XQ&Ji!q+%wQaE`ixN>W~Jc!Znu*ngjJ>alng7g`&3$@S#ClX19E;3erE0MLDycFg%dNpEN(?mcz?{2lU%oXPa)D{TAY*iPl5>>=L zs*12fZ%9fK4&mNFa&j`?oE&Zd`>PfEbS5SwccuJ303wauJp7V;pK>O_5rdq#RK3 z+UDY%m|T9@;FBQyWjHP!dLbXX`XA)h=*i)ZooD}u{-U9wJ!VBj60-H{^MtJ#kTGz~ z?thRFx*zq)xIj;Z(?=xeXi(+k+6@F)mOlVRo*g;@Z6 zK!d-*0#~Z=xH(;l{Vr~fdL3>urgIpu} zjc-e5v{0o4gUCSY&M^55lGL<4z-~~%Z@quyiOM119xOAj#hx)~8;lx>o!S8fajtI{?O zJ?dftaFBfSAknvjXrrjAi_)N1tjR7{mnVV^4`ku)vK9vOXHUTh?J0EPT*BflYc8!X zLGT|=l`m=`w;$gGhD78#xHJU&02w=L1eo#cc#|3s^n6R@T3Ac*FJRg6*r8tduVK*1 z{)BEOm8`;0Mku_BY9qVHv>GL=>xx3Rnv!C-FTA{5W9E zkb%Q9Ff1uewMudp3x6=;Q>hLaS&u#R!0Ni}_^G{-2Qi(Z{>S)MK~ zT8b?{c?b+f0;ORBV5GOY5SioHk%UaEG=7d_RHY1;Ct;RBE1+$-eO7Yg{wtuVjHo;v z>9X3v{TFf<+KrqtL%hu&QM|ZahE;g9fgTV5`FK)?v=9;3L#Sh$iTPeQ>vT-OhaM9+ z(SUO%%%hADjtLQCE@I4Xa6WQy(RM$i6@!tAXAd?uIL;pEH1=u2HQO&)@H}sKJ&F^D zy<-Zl6^5GxFI+HqI4u~eFmnK96zrm)WTj)lu+F#j4x@qGRPy==t3eGT^enx?;Dra> zti~?HA?*``+$$H->@GXRSXqcoxbQvRK~NsUjD%Xzftd@(Lqi_ zcaua+!4uk?tqDk*-T+i^+GbOBBLjkl4-~x{FsAO*ePPPJ!qjR%r%w=Qn<3OsRH2^4 z`qo@H36Wqj(eTxr_6mF6)GJfJQq3jSS0sL3c3xeM12ay&kWdL|zecnGKZHdSbVYA0 zn7gT8VVuCvQ*hcw(`p41(PNAdYEjwAaN5(taj?}f_~;e{Jh;xi4XaQtU*{_jOFgGO z0d+aiv{K1HJ=!{dV$Yt}HFJ(LaMMs$Dz0aY>j39t!dAQlTcAwlbyuWAL|0O6p-?IK z4T7|bJGGy4+WL~>FBnpY2eA+}NiMNn3Ij5EBR3DvAo&Pmzs74yr@1%~y@b<|3{&H{ zjl6p$QAk{L*; zhIv-e(HzYNp9yQ+3HXxkbo$j zQwo2^=EZjsFD?wGap9j|kH*RrYmaR&BO-T~ z9(?q|SPgwr#1O?7cbRr5WZNH($WUyX$XaG;l^|*0V*vKeiljU*`(~xxe;dxU#a(y+ z9ikOZE!i$(3?cjug>9OYg0*8BpddCGQx%A*AjuG62r7`yL4$pSG_gTygu0COX*i_O zvx5T{Qf^Rn`GDlA;yuJYw~}ROB+>erk@cK3J zmgYh7l6h#JB8i)c5ruHTd<}5@-Eh6pjH+VI%Yek{20A9$t;B@SU8Og%!%5PayK zAhpl%5ZZ^J)(Ry-Ug2S~1nKGa704i_ewDG=K9dk!dlmIbgxb^rO%;uv>#~bQ{pijX zYdMC;8KPd4krM(q)U(xg`-iw^I%_7W%t!JR!rnG<-b^AJgaRkW_PHPJ((r`)e8L<^ zTLbYAw>f6Yc;Or#Ifz@t>H5sNzIeTGnkZ`fV3J~-=gCfcl!}kr2E9VwX_xWjx$?t+7fM`X z%ovEV3a@{p+Ba=xU zGvc*JbTwT@Y=}Upy-d2J{Rk=Ff8my6o=1xLjeX?GZJ&92Na+sBq_I5i<@sTDYQ69h zqF{v=FB4+4eWo42xDk9TuF+H&$5SulVIYRpDDc*%AOnQP$|PYa`a9MRbgYJo8BuyW zP5~JW0b#FGZ7s#OVWU8*fsA&z99%O5mG+aE0sISuZx|^PCA-7c9EVQuugS32&9CGa+=c|2jkuQUr6Uvdtng_G$rD9EJCaK`lj1?(HZ!)=^1CD#-XgD%zHZY>~i%{ z#k8D=xnf)~Js*f~?i3KI(zqKIrX1ye+0$H`Dq)nZY{;`0Ab$(P*fKc?Tvk zKCKsm)kn{VHX6p4pWmu9r`mx4n}>O;3}}hCtA1&tolF5XPhN3m{y2R9V7cqbma#ZT z;lu^g=oZZ!e1p8m3&er|Ul|$qVBT*Ad7eCIMW1r9-}?z2e80e~69iie3Pgc;lnt*Q zL@DtTT7fLgsu_MPrF;l=krX_`0ScW3lTICuLWM{%JyiQKA4Eh#2#TPv9MiSxZV`wDWC zY)(G@PuIl^AR1;8l%?TF01gdHJ{dTP?!1SJLuvpt$nAbejqnY=x)o8IYA%qWdV?{bs zC$E%WR+lY;RCRK~O)(Hg&P$>aRb4iP1QU+dC{f*no&iK(-iu0CzdTv8#71?Qom`LU z6*u3K6R1EWyp8Ae$(<*BBfm$hL0Syqyfz3E;j`2co$8mXQT@~qA0H3GSfC^AGg8`e zeA2cZpT0HwJvLCth4&V6lvv0YW&$;R(6h7ZJjLcB7O?Z*l5%Z9ohK<=9Tv_G9^uGm z;56QokZAb!GqP(r7Rv=~+W3TCpOmb}{eGg2Bd0~CCJVUln#y)32sW~hP;1WaaI_Vl zN@))hPXX90$wDngvYnR(6w;YGg*PtYdNTxs-TNLV&IH8UI2ZTYxpC%AVO;t}@T`kzW*Bep+L$ZeB{^4nE7Gq;)EQ4h<4aEv zKDmJWugh3I=q$KlVuJY%%p{rbkGN$RBA#_J)rCdeHQr1T{($K+Pu@XSu;LB zao0Fa=z8`yfh zuuZ;&8@xfdIpK6pOQ$s5?uWKpK?8-~IO5ypl{aj8IKr3EIi9zgu18vXJ=Qez3YiXhkwVE3}uBnKG43xqW+BvOZpz4Gk$3R$uh! zHZ*&mJWWccmj_PVLwOIY;C2v-l=ovw=K~&2vWIx9!7E9aLkbPCIO;K^F>T8jr4qa4(H=;kN1lnD3v$@FZ;eoV;6Xd>L>M4w+#AHN9qMWW9R z>Jt#*t`~jQQ=h;H_hq8ba_SQl;hrM;ETBHY5$-EQpU0_Bc!Ya_=rfV}%#Lt3h(5!q zPgI2a7STsWedb5FZxemKKSO-tBHT+vpR3eoQG|P$=yU1}U4J-F1F5KA2^S;$l_pU{ zxX%`S_D~;XgnN|e^8)n=i*U~seGJrRMudC5=(EZ>Bk7_#EE1sW@b#f*O;)+J-7TV) zTvl%ZiSscb3{u3JHz`tK_URlL2c;^)&vfK@CJBGTBkM7Nd636GVhzs&Ip9@d%|+`@ zw320So||6ShW8ea;L4U9oU$K5xk)%dtf*fTj-AHnhY5DQpd*PJMOP#_E;Zl$0)B-E zaZe?|fimg}A}$meF{fc9r)A(0vI+VWv_4I&E6}=xSXZKT{%P_!SGu#_GF)a*MQBw9 zwAhdL))x24SdPG<%hG93XtrQO+(ESPKwm7$vYYyQ=r8G#NMCXAAl7+uvT{0+d}5Ebf@Di;V#c4NV9(eOyx;D zo&RxboGWg`&nV9i2*3|7YyISPoc4;{|02%UMkTMi!fESa*bwi-Mch`K=HRKOM_Ee_ zep6d}v10v~ydRkocP<(|rQ517jM_PW^wg5;cPq%zlRUSI^*>ZVklyx$F!EdcaIN}1 z9B^~W{o)M45ye;3CM#*GX04E{7p&hnP!k?Uij*`WJSqm~` zp1VFz1`%RmC26dew#`rDQsP(Ss!7`V4gFP;DcWH%7s0PtVe} z7Uq-`f9Y+UoadX8$K;Tg*IEhYHkX9qrs7sv;S=^4r5y$dApiOApsCm<@rf6Adh#k# zYZdcHO%*G!WKqBr1;n%|rN)NO``6MFNbU!mTL>8;SPQ;7Co!DYYOqH7B6^D=)knuC z2*W`KPX)1E5)&9%AG*rW^%h z%26_$xzk2I84AC)Z1V?w03(`<#_g2Po9%7%gwoe~`o>mxnzeUhBYJrfukf0=9OH%d zn#;RvwfB&{7Xyw;(be-_@;Ad1F*Ew5C2SQlf<&Jmq}qk9LH~;-sZ|XFfS;#l^e&U;}K;n zbhjQD7O-R&AQ$QYvJXDgxo}5 z{9-W{BHnDqgrU}^UOjKsC*%~? zVfpJAg(r!CFQ@prP^|_!XT%3cVv(A?+`bs+y?dDzvQONv_siAe^yT?iR7sLKAb=?S zaZU13n>2>EA0fI+b;WC_{~%L>+Jw8S{59)c55AU8Y@Du@SG?}D0+AWkCJ8^>K&kYc zohv4f)r&EBT`QSBUBLc{5LrN=a3wkdBQ57(T2*UjKw0;`J<-rCc6PzG~* zib&<^0h~XA%-5CkbtM*sRQAm{oS!@L>Nbz^Q)m zJ968v7bXvwnv%$QI~CvAzIVVoNiXodWH-U~6-em3iZpm$D|FA7!O$6_{;&p*{Y=H} z{!#FwF8`fN;+nfKh*<~RZ}x%vodNd=$kg^GKVKHWHpJuC>hL?5U9gUU$*wn9FEv!7 zm)HWe9cE*Pxw!eQx88!q5Cp8|waw6wgY(?eBWjI)g6?xi-8~9cF3dJtFSvb|mHVCF5aEQMb$v&fyioIi}VfIi}tn=B!|)F|qx(P(8cF z^stQlZ=`i^*J9OnsIK}23rk_%B+?u{?P6XQtPp;LHoo-tkkGIQu&HuNX9w?aGkCO2 z+4HDO^B0Ec++o0Hf|(LybW2A|L(2`*oZ~CWD?ovO%j~;*icIq!e)6Gxln;G4xWqWp zb`iRPnlX+wZ3_kwb_Bj%S7P}1YV+kOdO%BFys|wgmlC^)EtNkp}wA<-oYZk>djn{(9FR*yM$NV{#~oas<&J1UWe zeL%xabxOTcHdozS!4q<;9%})M2SgjYkC1w4g&0LtEs`-ONqFa5vR|JXQD+<~#D6BW zeZG$W#HJ(X4SM56U8>#x3hhg3>9qjcHS87_@ZpNYz6sS4b%r{$pG7h0HW8ClM3OGa znile7hV$zbPLEOM+XwCaqrS#p`1qP*bjmnG_h;f^1)dDV(uMr2B;ha+pTzeH!#e>A zqgzpXlkQ8nSZ>)$9u^vI+8)RleC?Y8g-+Z`%L&96g_cQA=n*AG0Zu;^`^ogf8CzKk zOf#=q$U%X~0V-NfQz{~e#z>U}Bq#+RL}U}l4&B98X=9u26}jxZiD%1l_tUdwc4Mo6 zA2g>gDx*?4DFNmJp9X`D%qgm)(f@k-NRW8}v-2VEww<1ahrKO$%uZ&ilRfcup~n+n zY<6?|>WMnA)qt(`iB_Wz9(-J*(_?>~Odg=!*xDUZ;$Q+HRv${O38S9mR>-TX=sI!|cbt#ae0xzvrwpwRK(% z42G7g2qrgt8lV{tgBFJp3j@tq$Wi-2-zoYxbfS;XppS1S?Oy)OR07AYq;R5!!kIw? zF0H-NZq>veCr^_Ygi%PBa@^fK!CO-N@YrKcHb zwGewM^t#l`fEhcef8$i_iRccQ5=O&+0Q+B~DE(jN5NcBTFdf8emeRG-xG;)@^yH}h zyTN`6h6iw3X%v486vPUq7EE1^diZ?Wi}77<%3UO{fMj1?4_x`!iezt&!(+YarMLT` ztef)(VoD5OIl$OzNZE)ft1+d)^Q!wE2&{Rp9UlT+0!c~ao9c9+a+vRKu)l}3Yny@2 z5?XNUd#Ji-ABp?HRvGZx6Q6U&-=ZgS)X5Eyy5T*dKIjO9LM#e)jDToSQa}d5U=N0Y z0%}Yr0$2q@BOVY0%s&xH3*?F&9n&Dtlj0A;43pIz;UCyI?CwQ@}u{+2Dg^h_J892l^BTUV=?$m z|JKy&W^n8NHz2!i`$zk`5ZL|{9DzB5^($-;d$+JV;jYD(z*H_@} zopWv_U-$nj(x%9HKXP~u_d336*77#~zP}ym_>y}S=OB?@$^z#1JIz>>#_Nr@8?8I7 z!Rk-cA6iPUD`4{FKb1F|YBcr<{}*J_(m?ZR`BGw6!_K!!#$Pu6*!c0zk0Ilotxi-l zwl%hSpSYJ60YB{C(r~r8M!;7rZQWR@E#K8pP(~}AIE0$ZAFP5LF29Yx-Q{cHH_D(C z2@)FybH#nbqgeM1_lxW$MzVQ|mTT7gA`SXw$z_n7wm}pEOFkfhJETDG1~D+}QK|KM zHyD&x-8W&2Y=E{(%H}LjW7E2F9eQGGODA^pmLIRS)bKEtlzz^j0CsXm4vaS*E&0J7 zH6WQP8G{FDdo@?wccU0e?EGBCL=d#exB`&h60 zfLp<-f-g@FHl6VP3%NZq7euZ3!Ad6_GU8Dqiqi6y$-z(85D|0^ILCn?8f5T?{y;3M zDso8{AE$b{hQ!1!;1|r3!JlHa`Q7Vhm_zf*a3FpJ@fjbG5C;&%raNN|p2BkkyO1`J z$yN8`*j5{mW7zMnj6DQy?4(urNNZ8u72ng~Vf*N+`{6+m4@eR55t&VIT=6}D5nq$! zgA=Wsww2cg;InbsKu+6b^Ky7!P3z@!_$VK*^W(GvEaS|mGj7$#FBO*4rx&kkdvi*Q zm4t8Wl?~ETI@syn`5X(b36hcx8v9H?6Yi%Aav%JiZwOVYS@A+(L9sjZb%}_(cj~V4sC1mqvX*X{v2=A)M>Bacy$$D z5W1Syc9k(}uUt**xay(5n%3pG{7`ODm#3mG|Lz5pAs@h{&;oFCx+@~Sb_KW}vJ4suueikyJfR`kM#U=q}Zcs%z%k5DF~soPvBQ~YPj+N%ff+qQ{0*xqjupa!l6 zwEu-qD5m*M7-<&C~bYukja@O;n#W+>xm*;eW7iQ%v`5 z#t2o76kkoFLlcws(V+bs@&IhIaO;}5Bd%b(ZHwO|=O;ke@#-$YQ?W8w6WQI2f!$Fl zGQ)^GH{k?C&y(?;!uyymHKNu~pDg_28r}P9rHk7m(lbcOf&xSMbEdD!YW5RpHCsD> zXb8T=ph^E`P56NZaSs1AgC9Ow`RYBe_dwbp!l1X1o+q5dJ(<*lyNwGSUR!C$!>*K? zdbI_+Q|J|6eYi{m;n2|_N)qi>pSEKZjNqQI zw9nG{86)t+uSR2w(A=!n?v+ zDgDfW^gfs#BD{T1+Bc{WPf`DhIA-Zo#;JJTOkIw8zLxK5an&3Szn~GX}w$AW%g2tQviWU~ne{ zBbRWb54ajYkK!coSK{Mg?QS}uNaWWkxcp!RKEY7IxNKa^(O%L6PTf8+lMkE*_@U98`dZn+=bWxaY}J(rVO4ET&dB`7dWG za5Ts~FCaNdZ!b~`uQC!}9zrhYAq0#D!c^vYK@fwM`5C+!UK9lL1|}jeH1oZ}!IPw< zlgjOeiC5GgHLO{K?Cl# zZ-#*G8kxH6cjO~*8l}1nZzkj^h3Cj~eVWu`c+7Bu)v$~lNi{q^hp1FXM_7%kU=VBh z?#d|WT81tD{U`^|xO{%4*!y zWv3{K8g&_NyC<{u?i!6j77IA8%38j|VFv~sHBY*<3}-IdEB7kMvlLK)?#vzXOvcs3 z&X(`yoP`1wd$RUx4Y9V=Yc1?~+FxaJd2RPGIkweSwW(f{!)d!Ad4#n%6yJ;P?ACTd zvnsb6WwA{{x3)_LVzWVs({~Bjn$~xrvhUNY+RpOxxcWh{DZnOY?Xl(d41*G6iwExz z-v5Zy4~6ms8GQ1B1QqrD9#x#_>Q^iS8{T*u>z?lfxsxUt=sd6CCll$kmi!TrW1*89 z7pLNN8k`>R9QH@}MFg)DMYq+>fD_P1_;CYMoWc#~7~=6O>Y>0Hgm}C}J(M`@5Rcu| z1Fr(m8(!8{MNcCetu(c2rbR39tLq+ei|C`2e3}H&MP>~7uFFxi3KD@BD*1kuJjlQ!N5 zY2(E!wUaQqQf_+yX_1*)`|){J84PgL`J+#btrMdJ^&u8H!4fnFubq+P50bDiY@@~a zUz_R`HXqSpGu10O8H&z2KkIdOR#|$z)h=VEDG6CYrs5#RFc}f747v`(eG5vIEh!oj zx)PJ61)5f_ypF!|mK4413B(&6L`GdVE;^G~ucqh)V-I;& zQ;**WNVfZTlE>MU-O);oL2i1eA1q3=+y#pQEj?gyL(BJIk)h=?UiO~-7Ip_Y?g!2! zmw@rd7q0+^lny~2+k$wHiFW8wzQ|$D!=^!Z54!Pt@83Nzf|pqZH&d%8;=t`hvQjaQ zeqe-c1n)7S+Lzqu^P*NcqChsK8$4U0^(|v;?pLGrSI1;Hy@Y7$#R<*Q4{&pUFs)Wv zd!*F}!L`z|&hg%b%G43WHt^P2ejf`Uvlx_7rrxpJZrD6|)yEy+0gK%7216n~D29iF z{K%I##T7Bi)A*2%Hi%4Qc4G+nI7u*PY{fTs9_mI8x9SDk3GtgeM$aSxpDjp*i7MST zMoK00{Xni@3$p-R)dt~?tdmFtGXe-#$tXB^U2S3Q?f<}!Q|Iu;A?l;Gf5C;3aT|(_ ziOL=;*?&{O2$OfMU^x zdmt-k!i^lxI0SEjRgtqzKAq?Wa`G5Dd`_d2pKStoTx}*^)kN2{^}IY#_6qymJSGmbOOBq52% zTXQB<=R{N+S%+}DjVy4mQ3g1KB`QjQ7~z(ufQ-qFQ;;N%Hk4kchrlexaU?sa2@i4? zN!`;jronW5x4E>0G(A$M;O3}PuhN|RP&pQypNN++%)zYKno zMB2Z>!TmgbS3~;jx%z0ThshEkx0YWvjKL3m7N{cn3%&R_rTlEf?LzOlCQC@fg+f7m zI&|>&J@fi=D`7cHzvTNSD#Y}r4&}h-dwbcB^^R}#a^%%=wBh1MBWz=&FK;fx7t+Y* zwrR*xvRQ~%ho0c0f~~^%o<>uvbgkX_gTLZguAlqLHohD&IDs=ij?s^^h#x8!da}U3p07nH zZ?eUL9i%lL_e3C0Q+w0prf-^>eHx5iJ-7Hyh~)<{<_BwfzLGZ;4vBzxo0Wy?2#CAM zYjG$9j9C`!$6f}T5^SoTPkWk8pECSO{sP~E`J`8C7$^FE;rEp}ZQFnR#Bv*Z=BAJa zP5Wm1t{0^5ypm6CLD7Bc@oQB^FH}(WTn8EwdajFXfFjAM?YjKJa#!+BCnqJccJ^D! z#bWV7;HndJScL05Cj|u%1+cZmZ`#++Sjp{L<1hu&5=s zql)}XZU+^4sNZh9@J$VVF{9-A_zOY}YhlmVoQ^jy3RZ^Jo35+n)-eq}*3|Ypz;1`H zr{s$l5y^hX0KT`XFSOS1jjRRneJxS>W08)NEFw9F1p zkPezq-G^I1M=ugGHDB%Xb(9p->>ErG$jD!3HCu2oWM z#jCWYMh1CnI?vc9i=ouNnfiaq*!_kukZ|~2))COj9*Ign|GVcg0K5E{iB9lL&?lo`fg?j#vxRoxrm9Dsz&bXDf zBt+b2-qiOCXjZu3Rk-3+IOA2AZfmv;zop&?9MhOL;TL^@V;Y;Fe((Cd+`WE3?(zzA za05($t+b*H!*_aAcrKu4E2x+8TfT|3k-y_NWZKW`l_X zvjU9RMs_1IXZy|=Sw*Z&^uhBS4!@l-ZWXa^Qe5+lY3A9pNUrg;`H2k-uk4GI`thFt zA)zOC#@H)j?TeS-yP3C068ts}-vp#Wxam8E>3hYGx8CXlk{glMR`?OX^ny{HbfPsz zUJ)yIqK&v+>2mgSDN9csb_Iia!Qv%YCh9capk1mkxAZ&mG3D>^7pltx%wi4vBn81w zdKmoVM8VGnJ^XB12|wEl#4jcB(|19p?}MDO5fPc%gLH2s>7;lA^U{LcT@C391ANL?7f~iAJTYF6G0%Om>_%5{osXXuD z5tz`%(3A0eHBIHUb40~Rk_y&W24BPsy$t$Tobgs_dwaj@7vAZdA}h?GAN_8$wkmxZ zbJQC?y{Rs^%&13P#=Y2MYWm#bgp(IqLz|#D-Z|>;&*!KOO<+#tsBHj0IXR)8Jm_Sq z*4VD7k6Y!{IqL17vJFpY)LJXdZaV>g0^bZ707_*~HR&e)JH1WSvL{X%Qp*|)@zm33 z^Jz}zYph>rl6;zZ?~m;L{o7$;=wVOEJLR`cH|(ZPJA00;HB~D>^p?p=jSoyjV7P!l zW>l7bMUF6@NY7Z#T58O5?aOQUxqVO67#=IL7`}Pp3&X=@ZHCXSf(E?&!Rr(7@&K=M zwqK=Zkm%;Q{g4>Ij}-JF5apf!ov;3PzWSN@>f*Wo(R@Xc1)JLd?8cuCFuh<@jsLHm zuS$Tl-Misu514~sjyL}AeD%Nc)&ITo6`sEp=PdQ}Kaxi|l$$rJk0h%2YU}5N<}NaC zO*jXW63kn-+4E2^wd>49W~~5#4HN3sA6Vse)1DB zycoaK457yb8F8Yf6r5GUP5egMV!+c0&cpPRX-`3D2RJK*i|AaU;j|iX9uht#PCQ`* z&V#}c;tb%lZQwj0{FyidIc+OA_X&FlD!_aNoO{VDWu_BR9DW6BPo1`z+yF|v$fq^( z_>4w9uWOT^%=3&FcFW1fBH8*pFMOp;F;p)U6R%FT9$(M3a=OkuU%ik^JloK-6FuAV zhUtX_@MIgwjW@hrJfFnrz&LmpOxKa;r57G0o~`KFfu601Z8Roq=C!Sm5b*ebbDGu< z2>}$qQV=jk2UquJyxYVG@ZVPkNDvF%l72T=49|!g#oe zH6fDGhh*H44REGIgI*1#7f{yA9F-6K3IUXF$V3iZ5jkX*IjUAg zs}}HWkvXcZ%~5TuWsW*&rF8=M7Rw|~nbtSU)a7rIH|{RVtNBEweyI>iu4y&OYxL&1 z3g8EEo|e~wQ>hmoAkKPu9XM5bVHj}&?@oYQqZizW+fS~wfZIrzby}{i1a~mB2jbSqwTHkRq8I)^+|XJMf_t)F zc$vPOQu00@s_w5Dq8Ty59{e{rV|?05^-a*w|Q}-Iq^`$$s$#Rv21e~I3vy#PU6!l zcwYehgwpp%>7oHob?>`I2_P*Ki+T1Zb(`Rgrsn`*(U@l0A=aht-kSTR>vQ zJrwg|yLtZDzsXNUbZ+*6xOg9!L;qO2yaxP~5$DvVE#zY;{3-sLsdaqlXQB1n>qs15 zXHGi=HJes~Rs9)XT*9T5nbS4=yM*+#3blse!6yp&9xib?4EVk%pq0nqs7~ss8cs`M zst$^1Dy$c4k`yZ9LeVIoE3`MX6Izx0)zXuw7-(0Y#;#*QIBV80Yj9Gd`m{^&!rs~UHe~R0NVh=5(*`p zIUFfG<#Uo&A?=EjNnMc|BM0-J`Kiz?oBsC6F^OBbFe}tS6RW&b)|NLO63Au}tR7aVVtgnUp#};mGO(iIdc^8 zoK0>5n`dJqI=?xw&>j2hVz#^deBq4Eit@{bsb=l*&|bbAiH0sSADEGNTz)BLr|O9c zZ?++#zVQ3aiilfOG+@a2n$rIIg?BbLK_`FvtI#A{3H%CWKG zi$pdrzW5bB?EtUaBTqZX)>thXIY=FQSlvOZRV8m>Yd8o@+hesT<;`5$9=3(o?UUyUu9DU5h9olGJ~nZmwOT1ltmG08@`;sf6R+DV*X?3&aJs#` z?y$91BR^}ch9rks-7b=3FKgUutyRj5hh>QexOd6HHsfLT2Cu7<>nhmWoUV%39kSMG zs1;0jpIb(;en?uRwn6No$=apZE$% zaDYubK!`icCBDKZ9!BC0Au)-&`NVzlOKi2sfkW(B9*6=S^vIjoYA$gfpLhtl(8who z!c==ms$G2ILG}{i0&?vf5A;BqyYd_CCC<2)H$pU}{3d7IgQclN>WvjVDIwcKIDwoy z#ivzbvfFGA2MB7F@@rh$!D&zj+Jl~^x3RL^xU@=j`4Swzu=OAU^^s_pco)!#7k#x= z*6b>nj~B?ikYOrx@!Bf&5iblsASXSF6{A9GPl)Ovr3MI2cPG07?fc}U`_WXS*+4=c z2=#VN=;dT5{(I%5yNcQEg;Z(?8seJD*U7E|JL%YR;G&9!S#Y2FNbGR+ktM@KiDJo6 z$)XX_9F&t0fJMI%&?6whNGXoLWbqRt@0OEMfZS!ECFKVU2-y#kjUep zXF=rgQk=1pB~Xl9At$2^iToh+K8QR)it~VE2@)gkk&~WIB0mJH7>N9^6lbDj38stvCH zLvk|m5fY}ukN`+nDb6&>5+;&>O--&VA(0=GT3+nqQnZJ>Mn+QROl5X7zT#DVwjg0=3Svzk}w|_5yUWGF>FYM zUPZ#x(C@{tp)^bn!NW+{a2^H|8s;yC`C&lZhzk8k9)=7WHi|!4p$~vy5;nR*KZZ}N z5W~h|SfCiDAI~T5sfZhgenBMo0g;>sN$>5o-B@?_dCKVOj&$`d)DBJN2e&bFH#GSyh9Xka>TH(7{; zM79HM269H zu7?!aU9u>Mg-=v*i)Z{iMs9KVf55^mo}E5;J(Wn#WvY)XmO~Wvkr+3OA0uI=n7D-+ zh~P;hc#sGZ<`@z4LO+NB!+MOj6yPOUlwynkhyg=*%n&KSSF)(Y7=aK2#_O12QovBj zq7h>RL5z{$9w7zzOBO#dMli$}1MbmMz$nQQAjSxR7{KqCaZP3NpEc zlk4UxHe>~{b#s-|r>xpqH&{d)D_tOO zo zXl>GA0DflVFyC*#M>t%pNd*1@j@8vtZi5^nnR}O2&kNc@oSbFiBvtz-$6j z0p=Aj2f!Q$a}i7jm^)xJi)740U}l4f19J%S&H}gzObM7>VD^CdCz#V~Np!C1gFf@uZw9hha1e)j@e?utc>#+e_}&5Y*G z3yfyO!2$p13P$srcNtCfi>`5{zgB30VJR|AfL`VZ*JZBV5VT;!rj6^ev!+V!rP&5! z;RfPSaf8w91=9@1?A9*Q<(Kk5&Uij`v!oknT<>#lMS{U z@L2`6LK2?OOoLx){&U(QW-IutW^x@Vr-KP2`K}{4H^6VcgBJYLZpz+ZSem_NZIL0n z(Ah5`+pu6m&c?#^nTE9+Hw^eEZYXq)P5hDz*BY{y6=rTI%0X|e1>8W4$uEk|&)>Kj z<2m`o6lP~TyJNErNtyXZ7rz9_&rS4OuwkuXZD#)3XS3%)W@}ex<|kyYM#{8Xn366= zvkS~CVD^DI1f~ki2{0GIw1N@9bb{#vqx^x<=&_Cf27(C&69Q&3m@qIiz=VUD4JHcA zB8(4a8JH9>E5NJ-lLaOhOg@+bFa|JNz-$9k0;UX11(;o6c7u5Z%pNd%!R!Nb0L(!! zhrm>VISi%>%yBRlFekv&gSiN%6^sC;3yi9p(FA~*3}z9Sd@#Gf90GG1OeYvs50nLr z9?TXnuYfrK<{+3#FcvUvU^>9`f>HJYAHd89lMm(P**8J`ZY&g|A)fp~N1E)+RcjFz7z!Vo0kAN;$WXX;wE_K%8=#r2fgZ_7zDP*W zhV0FVCnzgBKiiPa;B(SXKFKh%XEWpy0N%TQ0L=0@k-@B7y|G~HPcUkwG0PBCNahMs9V@kQ%*v(9 zmMs{lJ4bE1y6=w=+cUORu|1=eS-EljhP6T1Hj36_jjtSF294!R&)~4-Y0lNktX!YD zA#+W3)_-E&;CMe-kIwZlh)XW`?&bAQ#$K7VbwlQQXzptrlS5$;Oj$u#J}E5IkiBKC z!I>^GhI8BeX@XY%Qey7Qv!B81(q9d^h1r=|Qn!`HpP&aH3?gIJGU(?)^RtUq7p^T3 zGYguF^vui8EGlvefzk$rxP(O)7G`dR1fnx;Eub!3ox61qItbsmzJRomC9Cp){GdfZ zpBRX@FMLGVU@X`bqWv`|yBX|C(f*Q?{beWnZYTS%ob11Lvj4`(e%Nim{;rcL)VscLnb7wouc{^Z!-$CQ6w+_gTIrp6TG?^#4dV<};8U+ouu2adjfa$%4?$znB(GyBcsH z_YA-Zi62POdf`@ z7Wih8mbwPofykWNEzbTp-DNM%T%Wyc%?S`_m|}wnV7=0OhTps z!?H5BG8j%E#3@1x#M?k^48|`Mt(cD3Ag!@b^jny@fr-gp1?&7mCc2;y;8tcKWDag2J`=shY=YaEPr?C@ zu?W^JfXk4*eid0&1I~?T1H6(K;&<4ibqu2iqtiW_mG$UWf+q|9CI{)@F97isA#DQ64sIkQ8Gf^fI~RO_52PPqd~88dI-Ci%QXL3MKj5Z#iX1)^ z-v$>yio4LsN6KfwP4mN81AYs^wt>XWhQ5J$XEMluXfpCr_f`^*mJMM(2{%G-LY&zU z6ZlE`KLc%PBeMy4Nk$9_zmZ_w>d2?i$w$g_HM!YJ^Ic2wpm}DCbYi|VKF!-m`XJ+= zfsRE~uOrd3(cz|aImeJ_boGk{YRFYw5$fRIqrk5$_}wbzpC$gA%mk5e{1@c#*(&~H zm^k?N1Ylnezc_o*aRx_=M4*}e3D74yz;uG?0@Dko4-6xdX%t{oVEn)Yf(ZdL1I%nN zabOmK(SunACI!q2Fe|}ifyo7v52gT&0n8RKC17@ec}0xB7t8@Lhrk>LV*yhS<|3F@ zFl}H2FkN7jZZeHbq}dPbfnb8cOa?Op%xp08!7Ku^0!%)bZD4kTIRNG`n0hdcV4A_S zf)T)Ug6Rdr$RQ6f8ZZH1g204;2?w(XOp2Vw&jMHgW*eAYVD^Ej1aksRGniJ42c{29 zumaL6sBRHyA0dvnlD^AL96JN3{LSDsXAe>4^%P}br3k%5=q-l%IE9T6(;`%hcr~Km zP;qRQ#`*_D|CypYT6E77-Fh+2Qqey_gvlcQR59;-(SJRzE5KkM#7ET&MOrgsfKj-w%JNV5-`G07{qFnD8#ixt{m|Xhd;8Aaz90MTjLc20aQE<3dU^Y(e21ttLx&Cb^B*xX zVASX_fn&#w4|?Fi3BeN|dN^d#BcYS0Ono$L+H`it%*P%NpY=q<>^VG0>a6>s11|8)8PKhOW@x%1|0V`AeL zEPQH_Zt)U*{L+MFiAl*RsZUe>|8)5OEBKG|Y`C9HgL6X^K%8ge0OCBW2Z;0RN`N>& zTIJfKuh;z#xfH(*31Bh#-g8*^9tptekZ52SAn=Alv zzO4s19AG0rJW$yT5I>083XpuS03go&od8Dx>;*U)JF&k^gP+P!0>n9018^+PaRBkj zogjeYaqj^jj(A}Jab6Dxh%X;S0i1y428ic(^#F1IA_XAsX{-c@I=@_iIOi4s#Ql#g z0CC@=1R(BhQ~<=iklg@r4`dI($FTeWAII_o49D^VoQ35Fh?0c$Hz<4Mu~PlJwwq1Goa99AGX$e4!iHrSAAF7`QzEmH_kwxC@{X z;2wZp08y6n0eAr1Du9&$eE}W^I0RrlKsCUN0I|Wf0vxKKYv5r3aSc2iUm04E_o06qdx02m6e3*clTs6u-H7y$55 zfWZLqQzu~nX8@cHa3;VwfR6!O2Jmr!D+5pt2AL7yEPz`8;_b3BfD!m{9Dq*(+zT)g z;6Z><01pF<2512|58!El^8vO2#1G?i0>m3@eE?$tDn~*40q6&CA;2Jj_-&-g02g8X z0bC4lKENf|9sugGJpja8aJc}JupIzQ#&!VkX`~NeHu4YPI;?kq`A8SQQltx@3fxN4aVPysLwpeMj(0KEXN1n3PgAD{~07J#DxmLVR1yD>csc>6Ftz(bfG zU=^kZcmmS{Y{c{cuV8xo5*wz+fie)%!@vlOPK_79K!Dx=LjbA(&Hy+XU=+XzfGHRs z2FhHF572<|0hVAqfV(grzylZ$2F$}451<9(0X&W20Glx!2226N0d`?H4xnQp9H0uI zEClEQ=mjtYpf|u7=nn&C6#4^Pg#G|i&_4|NC;9^{K!1SS(0>N>PxJ@)3i<=whyF02 z9zr+3Ds;~VexVy+Bf4Qgy@Kv2{AMOV7)ZMi;^C}u02cwB2w{K>0I1jo{S@G6fHTJ7 zz5>-VtRmVIhUm^2CtX~es2Nx->I<^O@GMael1)~ARF6O*jh90-N(d?bTrob?I57}f zBtoh)$rJIS-Vgsah5Wxne#=fPuniM7W7S1JUL%MB`5Np@m}p zS)zNL$cJn(om4KGU%rSZUv%e)^llQ%nJemIGJ$h69i?l%h&K~b(DG%9={Jh$){60p z#PD?@+$z$sS)}h-k$!{72a0Enn2$kp8$|loiS@DG!Iw+X(t6i0uUJ%fz-Zg;`AEZvg7hzC>&zQy4w*FCg*f z68wckm%Nn3DJ1xp68yP@hBy)j+YOfYDY5NLfs!v0+YkC{#WsX`=s2+*p?#^?mN4I^ z#P)=A&KKJh>eiygc7^n$ifs#VE)d%n@>46eu_=&ilGx7BzD#Uuh;ymf-ljl|#bTSA zB5DY+-J$(yk_z>z8yxLWs;~8g9vz|6K=gi36WX?ra#8!UBtErco0aVA2o14>PP*e1 zL-?6X=vhGMSx;!z5t@rgd1<}SJq#Tw`#M6yQ>4wTBlJH-+Eo$R{dtPuH-cuF> z!B6XM6``NzTOjghvDhCZyTQrdAhxl^V&52`Ip4`%=&%<#rCm?r>xg|dp*a?6lJ+5q zx3nKgDWv{{wVW!BmupGw>PYP}(86db=MoMv;w}~C^?Jh7#e_$hB2Dp*el?G@KdQH- zbYzSCO>y+AxrC3j&(Qd^&rtsjB(2nE45aPSI-?Zp2l1Wu0ore!+u1x)#(XhOwxgfW z`kqTT;ar!_@ul)>iKbC1rcy|le+9eDM`KSzu+&%w9*F!9 z+7oG-xlTN$t$@Z^NYc|d%fvQUMB3a^r*<;esqD#4ZE>C>&QqfQ27*7%iM~aSIMGh^ zkw|FE6!{kCMB9LWyc3`2igXr{awR$Jabmp`ks4dzglDOXOt(y|k3xr@5ZA!v+0QUmKX9Erb#IK9`b*upQYEj37I-lH!s7}EEuo!h10FR2gAJhfy0k>Av{oqpez(Z8$PzmrwQ5S@| zq2u6=6LmtUBdQ1Y9|2wjh*HQxbbDy$pFtFzX2Y?@&Rl>T@AorWBCB$7Y=g)evIV;h_7~)0K5cn*TcA{4&{27 z>PQX%v|xDvUJ!LxsLMJIZu~YzJ;1A24uH64(hBe-mIL6sSPp>rn!X}Lron648i2U> z5(p4Koe=`?Gk`My{s#FDuod_G0ltsAC4jgmlLhcP@(8qxz0Kalhaz*Yxsay2AWPRA+@cH9VudWfGo&pt?HL;gwCoH5t_*qE2!5 zB&yr05_OAv!Hu7tI0!Ia)GcBMJq+%pq7DvqbQW+IiaIwu5p){dTSVR26W9;I{k*7? z94hL{P)FAW{`fvY7r+EjS4U2aJR;L<6?KHDJ5+&tji@`sC2;__afK5M@Fh_eLuDF#CPf4Aps1rooox`fQ$$_uNbJYpP8D^Mcs@KF+~wGx0pgye9w4r-Rsh^9 z>U2@pn+xvcqHY#-wgzzH%CrO^e)n`YK)e>U4`3y>k5Ky2I}1Sk{zW6eI#D-_I^$Mw zuVCmJAD%Iu?m7>mg210P-9&sasOcWExyq2Li;EcE}W}`ws_* zFXqGn#OGg@0mQxKl>q;V?G4~x5ziE=i!K9L;8+ViOIFczKF%a7ZE9adv8@uT z_H3e6q4u>zBSGzXWc5$&>&Ob9+Vjbo7s|hlPiT!)=%owCGphijeeMyEB_dQn$Hbq{NZl#?x&BlfXuhn?1!WY2Zj zb3{Cajy91a_Mg>`^*YU$>IrDurTQm&#*6ARB>zIOO-pvFWu!VPs>!4}m`u_hsP2bq z6shitYB}jToYG0{RO?C4KIW0LGE~2^hLn-&NY;^dwa%%JNjiqLV&9@?B-as|s4it4 z>6iK9$y9?wr$n`vRIfnWE7b*2?IhKKP^@(2v|h9qI{DLfIbdH;>Uh0)O4Z=d#Ziqd z)i=;Oqjsv%-5~avjSig$?GFWFJJ{gR<57(-)laM+SM-W>%#kv!A0VnP;lS))Ia|oeUHS4O-^OsES`}b z&~FuqdTN6c9}QxE+ThTcQti9JY5X&Yb5o&1uSe^H>P(F!4%Mp`5MI;TG~P33Ir}@8 zf$B*&5f{~O(tPO}82e(8(>@2f4KD5t4tp-ipW4@x+N1U&($}69%eUE~JEi&LZ(K7i z?4Hv&oskk`#Y;329Q=ph&bi-l9!EI&Q#&B}vs{jppr#l7U!E&LOpBjuaKJ5p&<~$~ zAu{D(!^Thhe*7F)yaRtfMgRS&4x8r+JH_;!J7k04?X&+?>&MNEno~L{%j-8vOJdo~ zypo2Amh&@TyW*DD7uoaMfbDhA0gYzvRC89R_l|O%S ztUTwLcYLFyviL^zJT_0YXH@sAKZ+?^Bjwp!3LNQWeoWI}8O^6}Gn&u9$PNv<8E&!L zXIAGv@W)Tp4faUM)<1{~$|$8msYJslRMa^5wZlzH^<)&~==UPUQbv0$B8-xFC8dTo zmB_Kzf2G>eHw$mCzBKjI-$jlt z*ziWvn3;1JOKMN^+xsFxmiCH&WDJC_uI;(AKQi)%(i^KDQ$qOnspCfeIr8$dbCIJz z7y;pRZo8lSYvc-yg{FdI!&qDfrmkNf4R7P&n|09II1@4tM zI>zsPC-P!q!nnv*pwE*1;~4*cMZUUbm!jnJ$07XVl81kDIP%t8tIixc@hH&So?hgB zB=Qf%Z%#N@GZOGEG;dyaH1gRE`-TbfKuF)V*ymDJ{tCfjUgU%vJ5+z%t$b>>^@ zFDF9&dGENJKZ^YG=A(an>!nBLFhR3F{{4DOr1sAB@64ssk)Ma2^tDF*z0-6`yK~$e zrqSRZS!Ip9X#dTPQ9d$oFLCdWua2~A4vF$Q)IXbP?FtO*sg8_ZJ=(YKhp;(}eyh6R zm72(`!qHnJ+o8YiJDgycbRu%bQ^!B{I*a`1zY~1&L}YyKS99kDO`XGpc?~nJ`Z#jR z$iM!p<1ltXohp&~rX^e0xJ=Q1H$CAuP0yC^>&%!^y}U%R`SHvayhU>BmQz zQ;|h~&04g!3-T+tz3r=tQ;~)Hwmdk&4*ZIm`ra2Frz5w0ka))b6!I_s;_JUU9a(tj zt5;%<44K319-eu3=$S~L*Z%&i%QHsLVKhJfE%gs)B8&1rIX>Yzpl{{&rE^A{jcohP z)SGKxp9b{1U77s5vym^}DBb;o4Z?T7vMFW!xkzUB$Zu@_@Pzy?k1zS{xyantZuS%x zJqYFT(k}OIjNCCXVZ!otz;EI1<0Wy8k+s8)9s5llw8w)FBu#shT z8~aRcW8`#en0aA4l=tBIGcESU$dcD@bPt&c?R`u2hmS@zMe^@GI5%iE(6f8(sQ-Gl zDe|`~raZ9qCba*QLt)Rp+Z4II%)aW$bHIH=F!T%l#WE8O>Ciwi7C zbA@`jD-8NevkPoZbcG@IPh8;2f4IUu8LqHV?Fvh3F1f&i&$`0KX|AxK%s<)2((?mAc4JJ}U(`Qd^KEP2lrGA38pyVwo;bRLofMRROHH7O#?D=w-#&!sU-&@kaUG&_|`Bm)4*(CGC=S_ z-Al%X>@9}O9LGa7sIzT-lW%Hv{hu%1g>VBJN(Y>LRaH>le9;G_? z&PS;(ePuY+o#%$ry`J7jsgAKAoa&Yh;Zz5?C7kN~w}sO^g|cv}E8Z1Ob(^n*QyuQ! zaH>l`5Ki|14uw-4@!@c)8$KRRb-O3R>0U>DIMtn>4yQWx#&EjF(F_pyOZW~v&UKRS zcDTxrObNbUhA)@lvt{^Z*Mcl$M^l~FOg@yIP>-&0>9)RGLB!f z|I|BC@09Gi@#2B5&n!>5&)k+4IOLlXwHyD?bMvb+^}ZXg-q`iG8P%y?4Zn*vtU0@5 zN9oAN9(ZkZXu-&_bDo_#Zs*v4|Gwg#`mfaAj=OWB!IJTZy?-$+**Ev^FTa=al$ZU= z_Og#Y-8$l_?Ptnf*pn8%a+dvDzle}`>ZcE#y?WZ0QO|v*86NEayoD{xtj!ol#@|h1qi~inOUc9+<{LIOo5t+(QrtHz|_wxI!>(0r? zTPy1miasmYP}I}#j~CLqw_F|h-eTjCk-4>Rf4}XyIK}nSm%o~19JOEAl{`%`e4X{f z&!=ai1tL^LBZLM)%jC*6^nt+?Xo-}Rms2j@< zxbHgm=~tOLLxU$@%va&DQtJ&%b>~cpJ<~FgkD>}<*|SNZpAl$zoki-_)pJAo#WRm za-VGZ)Lf(;-Jc=%2~ACOJZ zuHpW6=KFiPndm<_+<5fGlHay|{F>pF>aR6VDYsq=;G*|Go`ze7OqoTIB;6gyJ=v(oBVvNE^8p9&#eh+hF(28DM z1g~5SasuSMFGYO+Y*}&`Mtot2q9W9N=lkyN12^dK!6*6z9KQaRv^I0z(q+tpE-%A9 z$hgINKfP2eY!#yb-Z^*eMbqi&5YgZR;EZUf3m7DjNL5a|p5XmXVkBGN9h3 z8elF)-ofO!;gaYMUQZQnw6`%+*Jgo;5KO*P3%n=yS*M1Dtka(IKv~7ugM86d18jqw6a`DrXw81y%-B{6&)c9oAcqte$%+-(Jo8jWO zjNl7*^&|13z^_9GeuY?mzy*DS&`aFGMO&yh6BQ{V4N~-f7TX<>@xXtxt3P?jqYnHh zyZV#u_*;=O(v+S2aod&j$#D6A|Fh3#t-?uq@;n)(xzMmWctLbD)zUfpJx$B&?6-`@ z3wQCO@uI+Q7v@6>7QBV5b7Evn8Mc9JTG(ZAG6n}cu}u)Vw}GGEfFDcbVeoTmJ2Qyi z0vWSU;qZHmUV@h~&CtN7io9%2mNEKJaIX?y``IlcXCS8*78R}z4kP?q34SFqhu`#{ z8Z-JuU1y^RCHI|ZI(|s*i-W?AbALKKc^;$LG|x4>*(rQ=EQH6>@V1}8@191(zg@v- zegyMVbeLEEJe}88{&YS^vKh^L**{GuLeI57A3i+y=fe&EA^fADyWH^Xb3hUBgcg3jg5OuHh#Jg@69)z&!Wvs{`$1 zaC`pnwV$Ws@!$PC9h2U44Ihj@RD{^;!U?5=S z1JeZNGMKNx+yN5+nd>uF=VrqH>0udLHWp^AT|FpNOd|yrZOmG0T%WN%d;PQ7 zg&Ub7pei?WT1M{r%+(p$TbMm@vVj3|v5Zl6iet6-_aMGG-1)!n5#R4U;^*BHH{`;? zJ3l*1yJdBD0X|y`Vjj_B%yUo3HvD9;mz&d@OX5>@neNN73)ipRkZH(vyl%H%zMx2S zY%Gk)#y5;0FuMqnF;f)r#_Yna`s_mTn(v0y+4D9UHz0QJd$BLbVum>RE+g*}f+uqc zeG|488M4{Z4!YqAR^NLEKTCf`_; zOY&yoj(_hpXPiH&G?yh6MQU5@vM4d@~-7QZ1wuxRb7LVVik zb)*WJ7M+zYS+^vS}WgC-W2{A7>vyeICE?Jjt zbc8dk9ICH?6qtFG*eR1QDNb8(Xft$!4&HHxqq*< zP|+ySP)V7hg5)F`3JNGD873Jvj8ah#Q`Df6QJPUQWfLV9HB^*THp37p7MbIimnrJn zh<3ky4whw3&7J?ccR$ZzpS{oCd#&}Y_kF*2oxRTj`WGTJFMDEMwm&s%u3xJQfwIR> zOoefiSBtAAP4(Vy^Y%_m^}1V&^Y%|#xMbeqyoKJ(qrr<6z||fK#P)|i+HfMy&^)g; zn${ddQFgF_nkK#N02-I&`?c0Ud3g%}=+GAn{o}RQzPD$#_Db*yUJ2egP`(*x=}f?k zrs;wAGyK7J$9VmAQfd1J2PV7r%G2%%2>{P~KcVQRoBWFb1zo|?78c~?`n~oaK4}{| z2Ci@{bY`%=sd@7}2zb+^-KI^<%_|t_Gp##V#=u##wd3CGUtXAlCulEe6M>e&O3c<0 zLuX{oEAW3K9hx>}(u`@7QYZ{i0az-q*>!ruQ+kU|1UqU<*DI2 zlBVrXeE!5U8z*IMtyP6YobJ5Mm4~j6X?{BCkq?e7njdrNuoL^gKcD{hp9S#^zIXV^ z+k*y<2^ka`c>19Z#)g@yI@X^e?eBkm<1>9b&Q#lx4_OSSTJ@8j`M+QpLdhLpm5g7 zrNO0qKDTgjQ9Mf0b@99dAOK&PVq1C=lXKJzalQHAb9U*ah$Jc-uOA*SVhF$l$BfHkMoWDwvchB zFU1}AojSSWzG<8nws9xo1{*&qJp}K&#iFOsL9_>dii5YGyx(jZ>_K)5KSS@-cN(3> zXmhH0jhSV>X6`aSH!rrvScWy;O1A!N?X&)7ePQL;OKjaqa?+e^XOZ)ev)OsxdDHoa z6Xr&_@viA!@8-HC?ppU{_icBd`*-&%ca#_>l$a)N6>CMUcv|cf$HX~ultgl#yj9*K zAC=F@!}4o+o*JcorRJ+!Ri%1R?N%SFBgz9~D&XyGGzDd#Jajwy4QfJfqHffS2u{SQ zI1?|xHTVg<1HX;C@i1};G0BzWSL7a2OBzTsd4rrmhtbiL(?ohZy`OHT&2$$X&Msww zrLt>T9s50NW$&~7jPOLB$}{x>7CSB!U!kBrX^%^YhgbB5_R7nmE&ZRV@yU(6o! zh&9MQ$BweO?b^xq)pn6xVz069x1Y41v0t`#*?+S?vyaz_ zAy#c>hk4XY0MvbHY4%WiqC(_yIY;hW$qs|a_C`2UH zz0S>X7rCYGgYMJrn{KbGi6}8q%o7!&Ml_1OB1E1mi{)1`M4hj)RfX~`vIKCno;*RGCm)bc$!Fxh$rwtgLGx)5y@ftbpQMfSb9#gx zqp@rZBg_Cq&1Jc45xbAAXPek&_72;_K4J%06!-DVxXGsh!gBe2d_CW;{}mz<1<^<} zCL7lpON})~mGPLd&Dd#l8J`+o8N*C&PBgDHQz1Hq<}$Ow{JVL~EV9;F)z%K{b8Cdn z>{7eYdEE(dF<@dAaBr1+mwUha7$D*g?hd!zwZ(WbQ)Gxb@r-y;w2HUIhoVoMD;+sO z7Rg&=t=bMu(=xs3+C1@(K*P{QC>D)FHkyWhhbH1#*pFA^z4#!u$aL}`!8Dn^N{6s$ zHiOLu4CJ#ltcL9hw6l->gAL|q^C*5H|0N&C1)t2P@SAx)zngF6UHn7d$BAz0JM;u- z_k5$kSZ=&y#6bVAGT$;^xAs`q*ylSVoC!{bQ{ddnD3N1%l|^l+9t-(Bji zbT_(J*VDN-4K<7%KPz^_q+A8&;`gq6VT-- z1>J@=q8;dUv)Xt3GsOCZ zHPjkyA?tE$sa0V;U~RNItaI&2cDjAgzR;QER648NO>Uce*ewzzVm09XJuz7Nq2=qCCiZ3oO>#%=(#m$G}->KiNH|j6y zNA+PwEcCWCt~An(9OG6%`LodLdjaD|jbE72CNeEE$(&}UnK^)S&6;YBw%6L*?N98f z&T6N|dBNe3Q;xdv;!05|hRe(3YG_fWSN}@zO5Xi7bT&R8FUG}q1gKXbSw-$9TgfwI zFWFB9(KD%!>U0q;rmeJ#UdkjJ4onpMQhka(L(kDy=)cx0^@sHfj4_5XrWtti5cc&)>BrG^_4ZmuCzDV`|Ux_C}+C!fzuCl%y8!dIuE;} zMUuEiWQ$dxz7f)rH_B3ZT*j$Xm8-r`TCMj?sis|w(ojBNsTqBUvhWM|I?_h|L}KY; z`ZOI0N|MA1K~*=h2KEvg!Y}5J@+QE>TRcjS(NpyQ(mRY#AbJ;?^UOt{4J*wx0rebe zjkK^OtShW}R)f`PeQ13RIJv;S)E?{H;H-B#oG+X+-AG{4U)@wd$TE4q+$4|6ex)@8 z|0h{E8i__DjwYim=vnjCEGO&8ePka!PT%2&d7plUG1{QUJ~PU?$cnY%tps4hYU>TF-P#RY z=&~lbb>dk-{YT<%)v9)ZgXmCQz+4E{&)2 z49LORJO}b{J}>0Oyo8tXGG5LrcqL%A8dSKJ*YSEDEn-CiWEL0roFdX7i)M>lQ3(24 z29BZ%G`3D`0bkK1T11=JExJUHI0V_XA97E)jFizb7BUc%u1u0CGEHX4Y?&(yWr-}4 z6|zd!fHH4^jMOAsWSiVAyJU|%B>QB)3{~MOQbns+m7th%Rgy{po@9V$$yJ4rsmdTz zRe_4vsV%BeHK`WW26*pMJ?aqXI&c|GUOB`)6osQm6b<=20WsvFB*QTeJ^m8xT`) zw1et&s{^Xn8@+(=glIVdUlj((m}e(0n!T!r-8affU@~O)etCJBB)s^C|M?`SUxCNDX3Q^C|510Rs$$jGpJQN zC{;J8R4*u$2I>?6%H#u8LZC>Aphl^n0-2xy`M~~CV16aAz7`nY0BmmtrndvjyMf`o z>3?34BflE~j%_Ni{)DhH+v@;QNU~W}n$_hFalPq!kTWBEe#oYb9AJ zR+^PzWm~ycp;cm)frF~DYOFeIi`8f~SuIwZ6&~nmEiokUKP}RsO`Z~a>e~@eTMg>& z>1Za@wHE5v4R!KCJu*Q%YI!s7=9(U^$Lq=9C(8ADy+v=;gU_US&zwa=Z`bn%II0(p zi_m@Gfs^3a6gWCpH(@-KXe1fQMv9SYq=8Gy0H2g=5W-6}5zwHi zPTZ&gVzNlg`9IIhIh)-iyjk1(`}{vQaQ4jWGtWFT^SsQ=naTP72Eix@f(af~6@*;^ z|H}|A{%11?!srRFjuv*ry>_`su&KITmR!LsB^ z*Q3b~J(@gkVP5hhk1btxOG3h^6b;6amnI$kkE8cItv?g9Uw!)5?7i#hAbY>^^v~d3 z>B)ZTDfV9Q)KA!Z;ZqyoefQ+*r~i%Rz5D5UcrVk!mwDzs^>6Hb&r|=--aDS=@4J}) z-iID6$MVisH-}vi<{P4g+2v}!9@Z{IT_0~4EeJE9;=ko#qrL+_R?J`!m8;{I%t`2B8UJ%eNYYSs2)D5ZVnRVHhQJSp*^NR|a9l1=?r} z#7DFx;%PX4`dggK);Qrk@w*&FR##JGnq)y(a!cjX2b>QG!n_g<<`Q_%iUbVhX57M) z2^kXnY=?Le-kXM{^WIXqvhqQsv4PhaX(+rn0=&v)%O8V;Sa+5Pas2JDbaRFO{kx>U ze9}d7%msy{N_027jGl$b#BNox(uh4#$(rWLvN;ONCyo)UxisMxK_K1o9;>_8negOw zmX~{L4hTYQbzm%6XtKO)aO74*71B6>32916LrJk8fUB-VVi#4HRdt!w6-nv}8#Ud6 zNfO=OCq>K4-UNifk`@q`sIE#vy%^z9MLn^AU|Ld9RI=gMrevFyMOI}^VjxCN79gO2tVja_0wJcUu9U*OTqMwedyzUW zk>&zhRNpQsU0htBB5>T}?N;Z_Bwr+Vi)5~OVvc#D-5TEnm6&TKcPCD?Ly$FnuGJNt zes`kNbgQ@6zumxambZ&q@; zNlubt?O$_lsPt!z1z_^CkaQO)_BiP z!S+omA%8FS@85+H^=4te_6LZSqui(vu)eq7gh|biE-W7U3lMwEE0}CUgCKY^3`pfK zSSr?~SeCt9O<~!2d@{tVt|UkTwcr(?(p9Y2g{Rf=5kvU=G4%rYh!@4@PgjkM zPa?y|ib?ue5;2ry*NhJh*2wfVU1ngC&zrUztkRp%B6-k#dtXI5S|$jjUU~MV{ytSr zsaAG8*MCk`Ew49uOjq=^UE7=~pS)ITlJ;759;z9@j=1*F>zM7;V1vPGnNW@6oir%7 zrc|>$-^Dy~y@}^xQTWpbmzy7mNXvWDoO*I<3HA$l?76%=<6inL6~5XdubEY#x; z!msaS)MOvAk$t|iu^!X4@c_jqwUQ?A8oeQ((F=a`9U^;K!YksNubroo!QOPkGV@Uy>yQX)vb%H|#jE8Ae%`R|yL)U!(TwE;A!1h0XQK;?ZW#ju|y z#r#t8F@x3T6Vdff$h9xzf;wAv{uB##H#?V*XFOOx;-1#8sz%>0`pyw|GINsGo6j~_iT@tif8{QlJi8l+Cgc^6 z(=gCoSJ3Ca!c5(b(HM^HO^QY0zZtuTbCOImoHqQ4FWJ?us_J5d*ocac5E$KPFylL> z(J%_$g}y+vXO0MUnqzVwbEe4+QI?$r2G1&!W#@u^-v?s+A#j}29bYnslDI1?{aoeS zfB=b;J4ab+;{lf38D*(eqq)O<9OMFVBmq|?i$u%LKVzd?c4klTeFQ!QebOoLUpK@* zKHN{TO;VaP9eclYKv|J2wJAAWN_Gm#HcR`I;(jGZRI;Z)uJ0&|QpqBlW#=neF}L_W z4uLrf{+q-7FpMobn7cSE4a*2B#XZWR8PdB-_B6}ReafO)N^!Sk=Pxwi zclbUGWo-lh?L+*t!~M{*(tE_!C5`XLYMfCPWnf+ADLMTh6r@8+cDCY}54jd9`H<`9 zS{Vy~&^inte0EN_U#mbwNKkr5+N!k4KNz&#&ti% zp&rq5>pa7P_Jw;TSC`_V%JvNiypIeh+n+^ORS!9+?AnMfS)O5nZM3 z_2EIghXhGg{nBhRRuX#9E-$04h_v0K(-x}O#Oljhc0aG>LH5!HMBM=d8Zidy-Wn1F zZWyQ}A3DR{AziD7(X?f-_Z&s%0qn2I`J%F+8^OZ(-_XMx zJ<5h4b95;i`qAMfWlm`bOW zMK-d?Dh)tI9Z5jp70FB*OhK-;CIuwGQ1m~@yoWUOXqg^$VX%%P(++dlFT6|^Cmoeg*}4CaSn;6M!S zW8-JVBJ5yYoTCrYw{!?SONRK1BYRK3G#)u2IS0ZG#)`6N33(p|E!n56Sqg(>Q8^YZ zV$sWiD>_!N?n{+yCo5DJ=&Oea@KrElp>f2)N;jHBz6lVl5e9IRq<5cE zhwK^IG~>+-!%cj2A%w{uwBDzM+h&*O^dsfjhvP48${)e;pM(QJZSews3amP8@&2}XIwPDTiL)^ z=-bK$nj+B-t8yL6qGF_86%&7RSFp)LlVE?oX>5rp__!A=fr#|@4D5zV& zxQD8)NCc*~#>Pfn(x4tQVTj&x-4OryVYOpp90=`5=88-TA6KcIaWkGWi1&Af;Cags z|ILx(N|eS6+PD&>FO@}UU9ZYC13UM4JHZ_j(^%O`Xyjknv zpg|rXU!n$y?YgEMwFOil_YKnJu_1JLbcp|vVRXUagUGJX+2%XIt&n%Ek@kW5##rjw za9tyN-4Gr1$szu#A$9{upV>GvB%NU$(YX~4RpcU^MKyCRa&RR6Z1}MI>F^-W(2+RK zhK0R@gTD(#!iEjn;ODv{#nHc!^G#*rrlF(%*TW0=)$pLr!$yCXG%ksa{w>;Ae^DFj z;Tj^Ct9-2QA2uH&cO~apc7ERoeXGE-vob3FJ@_?%FaEtka+dYDQSs3G?v4c}PO?m( zeuF0_E+^<)7KF&VqvKeJ3BBM%<0e~66|W1~yGO<4^m93ScU&9`5z!mRK~{J-uXSXVm3%Or zDcMV0SOMQBkm9g3O#{}Um5DH?X@pc<&>^rpFn|$=bVRfpDelq{$!V7yNq5QK zkovkJ(HF3lVsNh6_ld2ft|-24&gi;a%X#^+nfOSKS+V!z6_BZHspzn))U8@-|BUh^ zCz0gaChsN1II@7vE_C<0#^#YDq>0}0C3N}xet8dcz~Fk*b(WpxF}M2aqUIv<=Ib&c zRQ|{U+1#qDiP+7hN}A*?VR*PzX93Bvk^DpioD+mZIR6|5{Lon(PeBBp-w(iVjhb6$ zm{Vs0u=XAV%Q6AveUXq$m8rUu)h{=%pb!#zegwLUz?9I&Ic&uf%d0b`W$>BkFQmgb zd7F;YZ07G>>z&v_?7%KfQFDzxqu;W#b-hWdGkq_s&MeiaEXUE(l3^s}^aTC{q&%g# zdJ4(yo&_Q)0r}MLKJ3gS`R1GQMPN;yEQ4id&~q>RnrC`US3?23JX@XVcA#ApoA5qB zT;h6@cD3~@`G4WZkN2JN{NY=pPqng38!6Ar~Ripmly?YWl5%jQQQNSu!Sp~~;UWjqftDv4m#r0;P z!dh;9!CtnWlNp6 z3(o5bsGV2EIaYOeOiZG7ML52K@y5{`JKltF8~}7R=$VFqfwx zMb_hD4kmMZ*O?@5U}5$P=%bPmDbg`Wj3`EozhTV|;lkD=Mj;)+YXyCgsszCoNzJuh z%X2>BqmN2lSf-oTIs=PlR|!1Y##jz8n}ojN$${+VANz7nAbtLBaey@4z7Yc`hULC zT}};x$=&NT!I+HCqYFm?BpBw=vTAf?bC5q6EY&%k2i?Z-3#5SDA%m2k z25PK~!UZ*(pDd$NFJ#o{MH*-!v?5( zRSAOI>x{05Dthat7rJ+W{*lmyzvC$Wj_<(V>FxMC`#AiTJu^;x1z!pM%s0N3y`qn@ z*Q6Hqx_LjmHvKGGfRw~8ywI}?-=-IW@b=in7fcxLKHjgYjnNsqa9kOL=P~kye&~9Q z(cSQicsEA(yv#>kW3;e~yDChJ9`*{2)uvs1m~cN~JVcov9R$Cx9sGjkFQ12l>m;s1 z{hd{vtz63O6DpF6CIeF!k2Fcq7^JPFiv=Wmma)n5@|;9ZuFcp2j+lqLQ;nz7-*#RN zVkZ4=bLA*9S2WHwr#Dra<@(h0w_TqA$1e7h`oLNG-B={3%Xq8Tzw~)zNd>Q4VW1F) zDPT%(al&XMd%G=v9t~-_Z}pb=w;M|Q)W9-1V`(90ZQoDA-6($GR5*iM>n#F?=BHVs z(9J;8A79Vhv2->B20n$vv=V~oEu&aYs0!T{!!WV2Zo|4&PND<5%zErV`H8A4Np;z% za3zk{Vn1EW(mT!NiGVL%IspeN-E%btT5A6T-iXhQP)Jc{U!1@@q$s#z8=|KmZ=}Bj zu+$aD@M0_d)St{eqafe&I4%R7p~ZhQF8RYKik1fquC-L)Wq%t+!MAw%1}qcSqo+9mt7lJP@+qde$}C{xiu8#I0^`5m6R|xt zLNh86pa@b(J_(`{`nw!dq2oL<9y(4uC-xz57XfLn_4c()w2Ru-7?HjTDDmLdY^~uE zP*C{Bf{!x(`a15;OK)^0xEq{teJwBG;0u&_>^;D9k{vksgA!7|UmceO z-l^!Yafip=1&Iinv`r4{aDp}QQ-6MO2Iu2A*PsD z0Bmu`8qO9$(S7SCsn^4pRr!ACCj|~=dIrM3K9+69P~6Wzb1R-Y{C%z#e>Yd-?@Md( zclR3jEqms<7un0Rk-auM*~`6xy?(Qtz5Y-RuT4L5Z$cSkH!1FC!Qny27H~8&43JTh zjQ$FT;@-eww-z|)Mi@Jg0dQ%wZyhHH8IAUB$SD>34s~2A5TwAfNbNfYiLv`LIM*D5 zwixhpS>dq<9b8xdw@9$;^!K%1>%Bf2E6Ei!c@nw>e_p}s0*sKq;!paSl{QcgK|aQj zgLDSU<#*%;Q~H_8Pe852q#`C2hb2uInpB-60EgD}&+?X;f_14no$Upgmts|xr&vAk zOl}7)nDsd5GSZt4Wf@gnLC`q0af3CpcQ1Vb^PToXPg<&AK|)a}S8{Vtv)(&t9#%x| znvy3SyEAUQ72s8jqK&IKk8>Ju3Yu@bASHYp25 zrO-_5N5L`zu2OUAp+}e9MeN6?Kk8hzJRXEf>-4N;kGkTU`r0ZCi>_&|5UPEKqG14> zcLIn>-FK*#+1?m~;G8&nNlcXBOq#s{U*l#wVvK@wGz7vc76OfeYYds4jU)M>L1B(S zj22MU6HDxXOb4LB*dASbYenoLshOARDL$$gm6ayt9#P2y%v*nlJWl~uWDh#yt8-;K|bmrsB>Rcc-TMR9Vy&J7kdpFqAa(j%_EC*v;lDpaU zo#!#L+$8esxPQ0T-j)0UhB~j1o054ra#j|mO|?nhnbFBG6j9dk{dS-NR+$S5nKCm2 z`)98+3HoTX)Lf=m(i>bBb=)-GZKKPSd8-FXOEl$XepL7lC1B1T4^D5Co1ler9rRZ! z)0yPiHb@e^>idP|xM{RPcmw@~^oBMT4NCPL9`{kqw+MQugI?K+JBtvI!{hG27fokD z$nYH%rV0R2e*Lcz#I+1WYAH_Ey+yA%6Vg5|id)o$aeJzDC~oBpw;#VV47XpuGZeRC zhTFQ7(V?LCZfxw@eX(+$X_s{r9i zA~HA;s@h`Xwc(M>c*35WtF2^_h)=IWf4g|n8WIBeB z0~H38hmLcA)7!+=E$Zl1Zu>?{r3vpz>9=j3w(7WYa>S=;RVP5@*- zt|totoBV`%z}Dzlqzh3o~u%IJSGJzgaC9?dM*(!E2PXaX+-(o}BM_k!{`AUK`3R>tf-_ zvf@uN{-ohg2L3qkX9@nS@VtS!YdZ0_&nKW&_-0_NUhc}dr;vvy{CC|<+A4~<{o5qA zS+Bt_@fV~;mPu|DHGz1<5uA1&jbY7!=mlg?3#dduMrLil~)y4BlUTDvoz`O*lU=iwN-H>-| z0rkRYE_&J+c!ehmwDC8ouSflV4*9apdb_zh?06CHV$iWrG|g z#p zA(S(l=i~yW+>6`{PYE>$LJT5uX!Btq&b z($!>zSsoa0rUQ&=@|OcnQ~K#uw|J(l^4$LyD~VUK&GHi_!L`5K06Z2%EB#MkHLtM! zv*6hQp1}5{KSR9>=cG{i2C$~SIVSuJi0!L(N(7m8wkS2xrJty3J}I}UE6nN&tGXhQ z-p+NCVwMJ~p+xOMUgpnNohc%Hl7Te=NRiy6{wPWPkxl(kDvi@J)tiL;g2FuViR6`z zNr$CgNmUOmMwN|xLQWAM46ZX#IK2(A%@D7uA0ZDZD6A0fEx%$ee&dnyFs{t9vAsM+ zyf+t$O{BlmC%{C(AKDH-dUiDs-Wltld#r2<*o5;H&o4pN7*w4%^4SO1Xa`-$h60Nz zst_FX31++(&_4s(fSWuUV^o(>^7=s&WeiE3j$tH7$FjUd*c~BiDdRnXxfQ8UmC7+V zEm(wcR}}CJG+CP$aOtTfH4w@;AoUi|s}NbzSX$yQ{|?lc-VR;&1%?{h>?qL7v0e`P zw|)&&EXC#w{2e56sCH1RJ0M<8V5p;D2Qz&uN{C)i0=HNMp^zTxXH)}HjZ>q&*o7Nx za-&TiuvH%0ZU}I&w*o8o7m(=~k1Xfm23w(L*9Pzb)+>+_2`ua9Hu*DyD^QAaSrOA~ zgX89fJ!psT=PjDgv{8Dez~=22JR}Ikn$k0@KiS3E%D>0 zNY%*act`PMCOhb8AoTN?h`i(bGDexUi!{pZcRbvbMoiBo?}p%cq7D0992x{BM6of` zirTH*Fe9sGAob6{0{>Jhc}x66Euh~89g%j7!>=Y7P<2`iHQKZiiijyj_9i=c_W}+o z513u8>U4(iSu-v>Fl>tu79Z_Ac{!WejtpBq7*_O1XJPTaK=37RSgBpN$ppK)M znrC)(NM3{@y;VYM!h!5UTWF?Tbebe@u^;t6iW(};4G*h80sZgs$l!4GC%PjC-UdJ7a?CC;1)UBYKhZ*qM>_5s~v$>XA1Ws7bJIMt#?yW%CUQY2<{e#O^c zEVZX_U}drozwBlu(vNyQ+(f0GxKNo9#bBI_?1n?sp2z zt(p068nFMP0oxJ9fxQH8*A0*mcQXa91_$nR3RuD6MhEnLaXtImOe6;@M4kRcN{JY- zsy{M8bq8C8*n>q_$tJaQF*CeSEYCudRG7;*;0*PRWk4ert{7cG z=Ni~TVjMEkALD8#D3}8D+ajF8uAZHUgT>25`9- zu!*2s7*L$j_n3}s=CKfhYr(Xc2ZBS>TIKWDm%7qn(ziY~V4F4DX_!k6c!~_` z4RhFMu=_HNr`E@Sv%@pjfKuxoY|mEc4#%92D8>DOd&xmhZYcTQ>N{qGsR+!#`MnB* zgN_$NN>y4R5T}4X$|vCg+d0JEUm+-IvKN>~KYfc$iU*5~!Rk8%*Y5&j^5{)$iJJZ; zhOJK@1LszBmX;9z;?NA3!$Cib6NLS&LfRVD1QJt71_HnjS3?HRIunUS`g9l2A94UA zap6;io+nLUo92iGIujR*kOTL*0y_JRdY?6@E+L>viI5(Rq(;s4aTpXugRPBG$y!ti zk1D701uJVG`UHfO8*{*$gx=-gRj0E?yOlXHC%qA~75O{AfL;O2WEWfir_e)|b>IXW zjI}qf)#ug@}eTtpt5rNp; z$6O*X>CR5XcN|~%BI)EbS!|L&njn3txVp#z>D?m-kL<&JN3Sz!29B3-3a6?^DelJd z4lveQF9%HN?^iCFX>@);B$Cr5oj!7a98iq<;3syf&8(aT;0RiPe*SLY3dxfusgy1gHi7f?nrOwcc1g>jRo#L}HOZi|B?p2R5z zPZsd87cnHh0Q_@I^goyf)k5%!lDBkmNr-^Jl$q?LB@wEX$1Wnq_I?M5HX{?6p)8uM ziu!pVmBgfHimnOgv9gpH&?b~jk#9%fJeh$GdO(}P0)kk;-hRD+@)@A+zLEw?F#S6_ z0mIL+gU+Kino^i#UyWP?=Zrn)*xWH+_+|4WQZII;1JZOBM8|=?SU_(`#^2`a@i#RE zfA2YqQYaD4L*Tmq-iZqe&)Z&x8Z@f~-4>tdx|Vrg5AFb+qrsWrpr{}gDbq0&_!#1M z4wb6usc)betMDMof;M__iwZ{2cUZtC7J$LDfuHxFurMqi@Mm=K%rTLc$%o{6V}aD` z`y?ve$JV~sME!ao2Caz@ym0Q#Yz3nbid;k+4Of;ut% zSud`5*YX80TLJw5M@u)KqHxf~MkHWNNmwV62ijNTpuH+HkVpeJuodp)0{YZ-e5b{@ zfGh`D>teG&J&VS}2~L&5fQ_#kMQ_36Hv|q!y@4Zi-2{e`SaBsih`T>}qtSGX za$a9?6`fe5?Nf>^dh4bNLpiQ$)cogB!)spCm1+!Mzk?Q03%UCJH&D-tDjXhnI}9(JN>V@4_6&I3 zX-26OwhwN6JU|rW&(vR7oxSr@WS&|+#UT|wk~k+ zO#~GJ32OTV7}|qd2F3ydw;&xj84dvVD`K*vlwSXKnCyVaS2CEc0@+7UnP{nnHOzFf z{eB~w0?x@p=C%jN2;=&Rs6)N}H(mtJ#WOaTP=S*~KA+qkwH&1wgrqNdF5tE$L=K zN*Z)II)60V!xghD?a!#bdlUV1rXDnf2U$ZJB3}yHh!Zu&f8H|CE3KEa45Z^$=$Ylt zM$9ac>pz8gB*`7T|C?R_T3k9p2P@z50I=wd59sS4Mp{2GbR8tbgk#ik^K{Frgf2P~ zp{Yke-HHGi=uLceW%)qFN{2ZTs$&pp)CHh!M}Q3UHoo$5YxI8OsCjsW;L!aVwbzUq=le;BsJG%jq_B?LQS*+nbi)FEDid4v)= z5I8FaT_7W(!%DbOb){knDXJ@Z_?lR#%%O37$1)B#=;Y4~;_;A%N6H9z^dkyA_=Bzr z8?6dkU%EnH&kGgFcw$)+8p<4Y!XcfC;R{VTY9kk#l8es#e!HP`_`Cv1uzrBS#RLJf^sin#F`gf6(arUTo`$@xd;$JgRLtEf9x79HNT3`<~%)WyCGn%h+6at zdY?Ajs_FluX*(lFz^9g>`YYmoSY7RH7Gw<)^&MjY7cd2l1LkSYa$tT zV%oWgPcWOd!#KW+WSD(4VXMJ;r8Yynoi<#Hxq_%)i1@6Rra>{lg zGq71#qT<+$QU`5sQ&m5pF)==5W1@}j`H`8#q!?#K;p}JN9ul+F>+B_SOoe3Tv+g}MFD*r%5cyzN!kYk?=uCY!hi-3n%YU_GmxqW zS~*qaWyg`S;watLX7lB2(ZFMRO0gd$#Uhfr+vy~?D^;!d@k$~6D_Gq{`dna^M)6za za|YL#LV6dXhV;H3=p9G`1K0*>4pB&ADWsFNSeG%*ejH1rqZxURLi-1v!^3)9?W(Jl zF2^GLdK0kqnsWwd1*ehNkJEfW-w%la_2=S3t-&U+Jx`iREXODX9WmgzR$XPHU-SUP zU2g!q?(2c~qqze%j~Jq|+?DOI?}A=21$sr9T=j`yseO)5CgK)9oSDrlAZeaOCXY#i z!L$o^SEYBajUwFzG!v|q=aa#ZC`#{s5<&_k6$VcMfiWk_XH{p0e0IQ@zJ6?Py}>!H zw_bF`=c?m2a)t4F(nt=Dv#)iz)8vHWGir>S;R`kFt5L59* zAgZEw5!Cuw$gl9M@B{n%2oCQ zG-lecsn`I59HWS7S7QcS%gK^eqs5&ME?nLMOJ)i7!1_Y$?2wDe@ET6N8W|s z`wFgcF#3U)##na7lqm*D&FaJz0Gv325C=7<@FD2TAXPo`I+Nka8`DcoYbQzGnRXHE zKip8St~M1^#Hp)+>90llSM}f;FC?qHrTR&O;7ld!Oo6F-4oSs4fI(Iv=31fUf-Ixy z1mIqvvo#7h|6N_xFF*_Abj#1j5f~~UiC{_`t z-@b?*oPGmthV$vf0O4n&*vCd%d*Gp$wDBmPgkv*s(J_qAh~-{{R~CZzn-Dy^nN3S& zX9MwUz`wwZH@GY{XVHXr#^%!br#N>RETAmBfES~+0@|^F=uiRk^a3h)5fGF!9M@~Z zK^5tssu9$yM|4nUO+#?a$nI8!2slTMguxjTeJQh!bl}ov9amgpy0e#rX4T{;=fmh!SIwv2nS{%Z^NZ4>aW2f6I2-51oC)$8v*3z#(0LP4f5QdI`6Xy* zIOt2r;)?yxPx~|9b8&rvgMP0EH7>N0a3Td`=#L?&fcl_pw)m}WAR*nMd}ap~Fk29e z=)207;&h0CPRAMtf$gZSI0ub_x)lXx6lx%Egyi^vQDNZk<%nz{?PQY+^xaSSmJR?~ zplvF_r5VjlH-E+^Nb&}ekdB3;@%R}Hja(g#KYlidMjn0QQ$%C3j>eWVL(#yG;Pq@8YhDfnWmt2t9;YH}vYG=XbzY`ewt?PW;U=a2JO zD}Nm=3tO48g7yM!Jmm!R!b#8Iftkq5g9ENB8l#`l&dF5Ay@(@jiX8kZGI$dPkCTJ_ zV2Rs%24jGL!}JWDMdJS5fircqp0Tz^Y4HE z`!|prlh3U;eXlMilO03rAxOwqk+ADcGwTd<*juI9XuK9yblDYM}!( zes$bd+$neL4TOLyJf6}<{B^a_*u65+8!LO(yFY`}9uNLDxG^|6Fu}4j*MMJ#C!{y7 zOlaV#lQYumSA8z~qShN~y{;2^0N&&7hg^pIVz}nx^J;`DP*7J<=Px928@`|)$>PRZCziRfUpDBtx?W#7?O-3 z0IjZeG?FV2Tepch=A<92^aYA4e(m{p^pbsxCf6(Oc7SC(WCT|SxWEdQgIBK}#UOj; zBnQUIyD|Lg)uTP8(bd^kCwu0!*F^=Q>aHOyD~E-kUkz<1TJ4QgL+FCD_*GRu9cAEh ze)U&;S{Iki?#fP|V{)OPoCo5hJQ-?B|NUbW7V@&Y1LD0Q> z1SNy>8$~svywA~Gzsz-;kn#QS!bU$M$?UWKm%A`FpMld+dZJH+xu(Q zFvZ3Rs&h8|=p)oJV_8o=2$7PiWM{*>w;H>0ld7p+nVwm1IqIN zXC?*Ig4JS(DOuTsrG-r0YK+cQ*{07e#MJ?ii@s#+w1Gx9qdmem3Y%vJUDaJ!QnYKa){p2m^S0(thqI67o z9S6#tGmGh}-0G^&Am?Y!>(^%+YMY(curqzcKn(V3)136Zt9oT`RP_wO^}Z+bnpXzU zJ`%+YWHEg>FYtfAWSfMPrw}6UwK6JCg6ZdZ61h?*F38WEjXcj8UqB}S9Xj!B5L_|d z7Kz?HZ!z`dVS7iKVsH0UTmKtZiaVfS(&U`Jehx4W=VZ&yG00l3s`(O`(#o;xpYDh5 zBhI_>>baJka}4P%tNsp5rh2B}Iza3lVDy6?+99i^%3XO-^~Ow*9VGGb*)Ws|6t=)z z5#!llf)Y#1NR;Q^C@@GpcSXsc8(g0k&;wtx2E)&`*ob}ewXhKjOfwOB8xF}wxaKmJ z9>$Kxmg3AfHX8zYg`~;~qcd@)%Uo$GfZFb!%jU2k*LT@$DAa#{NPVL}X8;0bNWO9` zmC<(tg4_KO181zba#3m6iXil&vYEGmCQSBveiT(k3_t^ZeEoq#XFZ8`<7xIYZ*!e2 z@yv}1P0urRbQ@Pk*vP|l2kje9r{84ndYG1{*WoAP?aQH z%28eYg?R<=W~m@a40&Ht15whkLi*+hsI^9s_W?Gp4{Ud^FNXb#L!>M2WLtrC1rgF+ z8(KNEuC!3{5wa=13K*D+GO^Ho%o(3Y=i|C52|_ulF?364p|c1 zimF+8`^Zazw+MW58h)!2wmQQmP4TphD7Kds;qH8e!^N2?a*rGc+l&;?HzU2_M=lDSRiG+nM2K4u;u3%O#-?A62z19#pxO?n3V&#aQ;t=g zN`KRHDJt+!)W{8g*{CkwjN0Q^nZ}_C855>L?!v<1wVl6q@z*wQNQHbjp&hJpD9vna zO7}S}FlJ{uOwKsmPU~~^APjvs3TQ$`TC7IwL&3&EX!Nh|;fHAAD_9WyqvpZF>GPTg z%cjr1hiyuuPoat;`YWcCS0fo8N{5kjOesEkeer($8uLTY_bSBF^uBdA=X6h|iuJjH z)$~UEb3yzr+JLh{f@0rKUmHM#@!Um-xZ&aG z4s1fB@!cVw2!{7+`*vJ_vTLxA;m}6+dok3P1RK&3ak>HIJ4(3h)5k#8PL*Nlsj>!V?2$;sf?Wc zN;U{%`tnRc@Q041c+JaJ=#MnvQgC1EU?;-}T5x_E&Tc= zK7^k4LUIipt;C6q?D2N^0H|vh`q{$vULAy{1Uq7#xqm zF)Y|CH$=&g^c$R`%G`&Y(Pil^&U(CbpsI%y2O-+>^5MxX&I#_rkBgon6%Yu-cpf(Z zF6rkiKYdJPlM#VfVtQ-dlPJ^{N6ylXN3DG-UtwBfosEZQuZ$z6H*Jp?*z85*veY>G z!uz3-ar`|FJC|gd3+00*#0rnK`ksEmm&t<7~t5Soz5$ z!I_}0N}_ii12A|+P64gCTH7himIS@X2gbY(M0er3l;m~yf)r%aE#n8VDA2G-XA5KI z0zg5eGZ0XKA|Iw-zNN9?0$$IEt)&__Ked~4bJf*O-+N1A=j~Yj&v$DoJm=>h;NltT z=WMcg2K&@y$agNi^Tbqx^ZG*S!L>tBH}>#(`|>Iv)O>1 z5__Vt5xAl{Za?aGFgkON10RvR`Yy%vvle+a&I^1;@|G!fO6*7L9{D>-bR)R+^RKzN z*JpBGy?)*`w^W}zSI3OEim19rzNmvJN8mPk3z#sLot9UHYC$M-CuTcS(yNYJWFPMH zjshzL6x^1N_-P73)lz#H!m|Rl3PT}UDDSDjs&+%=ZEB{df~o}Q|Kv01DuJ6w{?YZZ#LQZ)Zr;_mXbo6B-*&SJ zQU*l5v*8(-4cvzR%l7ad!X{EAFCNvP6P(zs*dqPu!IgJdUY?LgU&phbfFZe3wb7<)1pE$Ab)g+PmOuF z7rNhW-u=>2tDO_*X$pvD%-5ITuF#^Z*QVVhu*}zB-_$}?XPQkN*TSvI=e(tZy>gc| z5jyKD(<08($T1V2FBl`AyyM~KG|<+q#Kig&Kel4NXoGGke@ig>R5$^tgKhY-?X3 z4}o5zH|+$%;tZ%yS6;(25>{AxYvq58*n+4282&vLtKPfPWmnJW=XH_}^I9oaDg`E` zKn%D-wVP~t*(m#?0BS&$zvSR3SAv`=MpYzyzf8Fbnz>AYihhahtylHXu&T-*5Ad+U zOReqGBi7a!QCl0g`jm1N&NGh$tmudXq(d z6qdYmmbYJDMyu9*!;ME=vRwCEq z!HkoAhk_2`bL5rd+z00iD8Ae@z^3Kr17~2>o$Lqpz^ZTbJJgpDw-AwTG;YQugk=J{ z>?4hn?N%6^>AMldl@{q(=K}m*V>q$i-lo|%iRHp?aWZ=+6Q3vpZ1m_mz{`>a`u;mQ z5AWQ`zNWI&{X1%oOe9!j)JDmBzH>38feSVzr=6HKBTX$kK{Uwi2IoTs^c~zf46h-ZB|*ro%RRh`i8KOJ0~t`&Q9yrTWZ!OG zr(u25Ah;jA%_I-KZRg-rR$6$6z_V8M6KFu%fKHE}6CS|1VbwK(?t}c-&!F$T9nvDK z9AfA1AxR#{M65nmz9mg5?$D~H*pDjtbp8F-o2t)6Iisu38CId}i%2=M4k<0H)>X&)Ax2 z5QGParUEu&WhUL7n+AgmK%WY-CD*`5#NI*7tiuyK?VV=;)|qK}-H*FJZb9?tYWT6Z z|8GQQ|2be{zCr)(jJaxReVc^YSF(u2<13p}fnNia|Qg1Oy6=VMP>5LA`xJgd@_lA{pVnAs`_ zqeeAk9v@X*b|P3;@?LtQYd@(9mgLb5EvQX4mM$Lh4Tf`4p66Fs2*|edGtSZ4vYFhN zmVVB4x_~aie5E+U1EVw&p@6Hje8mI_oI#&^Vk%TXlq;1G*5B_?aSF z5lihI+AQ$^+lQo7;Rm^EC(NA2M4@Xc?STQMaKQ+zkyv3a3DYmfp%S=_<&?b{FW@^X z@K?ehOC6yZ2VA1p6u5`IX-2NT4f}?A#3W&#R5Sge5H!voY8oe~1R(O;naFP)6!}Kb zIOoZ0jW*ReoBrEq7#=}`Yog?x-0e)1Kf^;`KQp+-Ix2bsqNC!AfYDLWtByO0+?7L+ z=R;QLE>}{+kx*az@UY%p!gd+wi1OJ1U{4J^k{&u7(v0tPH?O%dJ%Qmlf%rh6fLH;U z64o;f&KMLa#eVvfmjCCW{B-Xjed$-T4N)u4>88K-vCTx5ojD>A!1BwUgv#i7SJc9{ zaU%U}K))vw3se|LPlCWHN^dCgtT5naG*Xp<$I!Cx{>U0psY=29L#d3(KypxoJf=5s z8rf0E_Ybj8#x1oToXJiUJa>!fhpzRyea?F|=R_YkX5(GCtH*Oc{nKRNV8`9ZEVc6? zSEF(NexQ^V>7Z}ErL7iNYHw!ICr&`y`9+*p#XuWd7z*O*LL%tY`Yt9*t;)VF4r-h1 z3-h>Spx-{qcSl%i@%E=ayA^S9&LH+=%!C)Nq<33>R?jr?+}vEyl9NJtKRcr3b>n3X zop`B(C-J+3mArd+C9l>hx%buYRz*|Tcu#FCf2YZ!>z3Q$va2hQY?41#JG&|^@*skrA^Y$~o|LqEyiZwH^ zX1IstulpiCC+$`<%p`lQyV+^%Rt;aequ48RI^T z5mEBvJ%~wezwY;0aag~tZb#up7vR@iB@vcMA$h8fO^!L2&rZd)uw^83E%-|08G@^b zJXOmhZRj2ApkM6;lI+AB^m^1DAVqa#ierN*zG5lVRcmR(VBlZ(vf0e1p5fW-m@R`m zh36IAjLS(5`U^-wp2EvV*l}Q!8y)m17PL|Gtzpm*0DXi_=v&pDtbYH2%~%n$$n&c$ z>}o}3d6Z|$I5sR}p=yU`j(OWn&_I`OC5bjEng)19oOam=71|u=fZ^Glv zr~v@FwinQ|%_v^N%r3rl@yeRBE0#e)qa|-fx5Zb3S14r^`*%S>>mtQha?JosX(LZ< z=M$5o3#iM8pXhBy*r6sG0+_E*GQio9fO$t-*{x;|cBZ)S&J-8knc~7bQ{4GF)2Jbx zY1EL;^nIMMC}A`G87O0$e$VIS=`Y_MwiFvnR?mlVd1r-*esWx!EmGO$98cDK2mjPP za^A?yPazmXA8AGfy906tk82C8FaBQFN^$7}c(-#FC%|+vBYnVyAJ*Jl0Fr$puB`$a z`Mi+6jg!>t%tDdtgBq1>Dtot(eu43ULt&f4HQALw$L|lxtQjD)QZ$*BG+btB8auQ! zrTapH>iT_nb!$Yk^VM9EX-A zN#G&#(xaDaA?F%cNOpSk3N56Qhs;lpc4{H-H1Mtw-sy{Q%U7zFU? zqc55HP&L4ku3#nI2R`~E27VDb%b4?ibS`GjCFpd#$xaw88R?_?Ja(R|Cx_Apcj3}N z5`GDaM}1^~#;MqoB(J1`cr7gCS`J7&UD3&nP;~Gt0Z)?PxkpTI({upt1Rda>kPg87 zwBZKm|2@zbmNdp_IzSuO0owQICwSQ#W0(%m06GBagMevyg#~ohADEGbXH9VNi|2qQ z>ADUytjp#oz-`#$yr=^N3+P%f--@cM7zeXcd5gAn+q3L=NDYYJ%+&z8;RFm;yeNU6 z0|PQ^?p{*r=(V5ug3GhM#Rzg~#f|qmp9XgPbLWFJ!yo3hA4E46w=r?W-nH zZ{y%nc1bB9fZJ!F8XpzVnh*G=D97-;HNBAIyq2wj!?>!7y!QUzhOdGC@r=F($|lXz z$lEw+-Y~+Xd3*u=faycsfzfnk;{~V3Z~txNX%G*exsTjtwx2!;EI>k zC|6Q%#v+6B%8DrZJxE?*Al>v9%m=oBv#F5YfNn6n+PPi6Q{TH=NLS-pA~`63%#5^m z(ukQEX$|wnq~f=;<^uZ5H?jOC+zAmTX>jAXBH~{0Y!mxMx14QNnJ1C`+SqRrJ4ws@ zv>38p7?&%cp403zg(9$+$Iyr0)CoZv$vc4@_L)U6S5sBhaUC3Ui~eDHG-4Gvf`=;P z_fM=(Z*(@I`v6WBpJkK9ydu?0r>1^Y8h&y@*ddq8Rqc}pZGo^F_htqMT%%|s9@++m*iwt4OriGzrP)Zqvwl4HrI_efq9EM+OUUS)575kI zHM3IIMLA>IZr=JcgY|cU(7n!y$9fCZt~qU8ZOv_`A=b}Up9!15$)@EEMG;{7e1 zSI6;#zN=kV1&;nsRV{*Ryu3CANN^>dMOp29^F-^ho0kAsc7k2t23n4%3SY~UzR8om zj%h|=8vIx-RMvJeqAdD5DC_(F5IsMOzbtxM+`Az|KsaN05)zkLQparv$nb80Cs<}# z*)pxn@}#%Sa$j@{i})80?joRi(J_FG z4K%L(r`QtcPrW&V$A1Ct|L5TN|GkW1v#1~QLAq8wUpG$+y(qP>%rdSQ-20$=fY-;9 zjPpW8eDE~D(^zI1JCC;_9;D8xi|AFe;_I7$DsTD_?bX@%VPQ$l*#W5Q>g9teb%L)L zBy2t8Y{8uMn9~`1B6=%C`d{tDgIyOwR+jj*r3A3NB4G=-@whZ0Fb%yMc*T9Mf`OrS zUWI0f&j7TJ#pAc}cjawmmcnMp-TW#O&0R@QiTNp^5r7Vnzt|v1i4g>-pjFr3ay#mk~81<0FG(;^jOD83ISQeTMUzF&rx$1}_pLK81+Rw)Vi^PqcO>L}50D z+@hf<7+e+|(+E(e&UXyMt6@as{-lTb+q`WjkKKG7INxgG&MbqwKn^pmXZ zn@36{`c9!bogy>&AiJ_SK0tKLK7+^MQZ@c<;J0;5RXC%Tr?fpqYq*Glum&|MBQ8 zsA4cTnQNMaYR+t?>ljZ&VTjx{3bZ73oiZ;a2E1gH<;A9W-^qCJn-p`(u_-C?o>9MJ zTYu-8{CI?L7z_go@N24+v29Aq_x(%-nGN3SKoLoHj)U>Q9Ohl@3#T>#^%<5Dhd^Qq zVa%UH4I~Z^bI#^vm4*O+8{xUG*8$rYVEN1O&RF^cgHDSF3po+JANy)EQVhra@$s*L z9|!3!JhgRY`7o| z1>!=%CyIkg4%%fTCsDCeC8x`S_E@_k_g?yM(M%~lVGowoREdmkkBH5>;g%A1X434V zs1p_xg8e*w%7>`cbTjKY5dDU*O0eP%jo>wwpIvXjj|?n$RBUjxvnd?y%z6<62C&SFZbN57IX1X|Lo%Mt818cPs0)K6z&;loHoxfv6UF%$ol(<`_N|0N3JRhM zbA=eVgBpO?C-Q?Q@D>^I#L4&Dd-u%y@f8Ip+VW1c(%&;6K>%`HuRqzhX7cq z*@Rs?X~g?d3k&i{jy1m7nZvd>m|vdrm+$XP_S_|`|JJCE^|8(yM|p9Fyg_a>-1c#0 z%xxd8j*9x|wnlLI!PRhEyDJ{QVmTx=-`4Jodj+T2Dx><^h;MO8sWy6YPgM0E`@r&s zy+4d_zig{w8)WQa-=VUJIsFsu=Cb&vG9@S2_DC=yElw_XnR|T(=cr>h+kisHiu-@r z>l2;G1$YQF-Y>z^>$75-6fFez-^I0khDz6oR`4Z*RT;pDK{S2|s0~33h|C&{?!|qL zMO!zx?hXY#9>v-VTcD`uL>sokPI>GMT>t5G(62w5aIx{EHm5!Icx?F9v^$<33^p7nk+CU^lxBmiqGk)iR;aKb( z;BOZ9yG(y;`>gX2ejjAl^G_elACLJV!5@a@{T0{!IOv}<&&(XN>lU2Av$%13pzX60 zb}I)o$5M;;0kyU+&|N9b``NXzdT6HX@sMW6P1~jF(PSplGt^PFrDtLtQD-=LDTD-$E)lAO;>Q#F;&JCPNBd=O5wMU@Mb> z-C!nm(k}_ph89-So7}2%(uq55plsWKL0O@nAe*|=3LOXF6w*8OYQ$dLqE~R*d7{sGADfwXes4CL ziMb}-=lTIKv9`~SUk!sRnnM4D9{t4pKz1k;{Zn{U;MVZaA77`1UKbH6@=+4d-fitC zu9iO<=sb#;`J*hg`#6eLOD%2`E|k<>ztw5T0vIO@ZJ#0A0j6UiY)Bh$@|TawO{l|z z?y|=mEquv7jXjay-S*k+15m-LSV?`aIV(`~UYm57k5|K7V()#$h<&x)A~#vf6nigZ zPxn<##&d_ed+puOt=y{1kadXm+ItM3Z8=4p*Q*BCp+|a9CcJyX-t9h&N;67ZTfiu( zS#Gt|DS}A4;Y&vQuMqn&P@iOHd_^)f^U%+6OMQvuS?}OlF&-E*?5?0_)+Lj|r-t!n zL_RZI_y(Zk<@3Wzwi$#RiU-`1@&=x)AGgTV>x*)t0D1!t$(OTDQ7B_rz|VPr2_*;% z_$dz%QS7jQ4Lkrpo8ad%_}Wch7rCdJuNtj$35L zV*z;Qoz6S&4ZQQ>M^iUpa?u#L9&s_q?E`rIg8>*E_kI=c4|HRavOa|!}jl6(@_ zeH&_cZHufdb_r%HPLh`_IfZ3uTxGUK{Y%A8~r5lkx#<;lT3WX=*j2|_tx zJh8|@U48606$hR*U#O1jVMpbOy>mpX((jy`Ziq2qIK7|`)PF}$jt z!Qo)U9gNf2XI}V|fFF6K){I6P2a-w5Bo#(f0#aCs30TqJhkhV@;Ir$mBnBUilG|eu z25x|43a;y#>#q!4Nn$3}C$PIw;<(d@AdpNY&e*m&j<#z9(I@6OPF!0Wb}pqHM1kfV zfcI(}{q;6oWi9s8f7_;81EFtR&2m?=)J%Lc6W^quvpB^JIXHgpsX#0-zu5%=U>muc zo%wi%Dt^w8$S&B_3@KbY!H?(d$xM)`u2go(MT+8T$M5XF)r%BvchIS^SRskIs-T-L=<>sx> zjtZ8Mr6azwiS=da^)4x-+^%J7gxD!xn9~O;<4Cq>Jdl32a@1Ve zo0@*4l4>Wq4uw}SP+t98gO%Uh`#eslIOHyI@Vefh^rj;Zr2rhHqyM3+ly8_uuj*vDir=;F0gyDCI_bDs(j*DKY+#$Vn znmVA5pYGiBlzy)(yLt<%9^ZtwSGnSFf~)T&;E>mMQX>OY$;e$NjYk$oqPM@WAYW3Y zPdOE<#%0;@95~}gZ6VSpYNWSv(%XRGNsRQY5po`n9Y+0yEDsQ2%@_$o* zq}@+iBrlf#fmXgeo85@*{GPrrh$i@H%M?>evtN(9R_-#j%}QCMufIBv=vS29CGfLG zzz%Bjwn1~ezc$7C{&Lp8u}N@|eb#%OAUv*XOG+W;lp4I=sk+98I|$_#0oy`8ECi-# zu{^w$hrcTX64B9DkD;zzZTF|x@M-o(^dI6(!JE?($yyjvK61#|kUp?VOb=Rq@+>Zz zpG~&>TdPFKrMehQ(T9~vTVoP808a7n43G)fJ>v*5RBqX#pz8$)RYi~Kvt z+1H2@a~AhzbT@GKHU{zIsFev|L3f%wt4vC)XPpUxj4Q{Su{=3i?i4+%#4^j<7SB4d zuOSw1xm#v=^&_K2-och%A6wAlS=B>SaFtl)&NO&uCd1F8X`WSS@>%pBDYM*WX)~8u z)=dCkJNoL)+C8_Ay@lQ`^gfpCS(jGzvS*c9K^{m1he1T%t0JXe&ayWHQjznEz^3?7S ztZF-NDCgMqF?F$b@wqr2tML^Si>}tyaR|# z-n%|it;bXV!+#r8u zz^bsjD70F#^=RC@X2JCU{OTXN#>sWQPhy>A8pC7#I|h3@_SpjL;3a9=71Il`gBIcy z)1}zk%QCR{JIb)iWmx4htRMDoymopuUOT;Rg=Z($k6%80x9bJKtrVK}lW5S$ujlta z53i_a6%3H%yIp^mPfl>A5g+sfr-fXJA8(rQzC>0d5Culw+cUH7a`g@JYrO~P^?4Py zP)u%_yf>HB^IUQ3udKU@>P-^(fxn<@Bi}O3-Vvnt6z)% zvTP}yM0jn$pCouv;hFX7|7ZE{cEr^SKTYto!qfHY|MK7e<-h-2{)_96Tu+Do`xX1} zPF%g(vNPXI>U|%G@hxSRN8dedS#eCTTzTvj>^Bn+%1!E#_Q_|Z!%#6xndS4tWftcl zc=nZ9-q|~`$z_9g^Ta00ZlAHy-E6V9KnA(d8feLbh_;EXhfYe~$-aqAcTL>4SWh&s zzO>no#RBPON?xtUjEUn)L0Hu0>2OQ_YtnLiYd`q`wuFv%;0N4fA zk2rPpzz?tFI|aRY=%|#S~1M6I=d{dy<@Bo?8dt%y>hd9`j4{D z(ANh2Y`xw575EwrGh*4r4pF4BzckE(&}dg#YT1dFY>Tgb2+eRW3c~}4FmW%??GR9H zR3y~`hcwFJ*;8`8HE`VWn$K8YW_j{msrfdm#qI-ZYdyfvBdt&XfE4@c8Jiimew18q zxNV=asJ7Xe%L843_|`(=_kCzBh;JpM-cSbyo&>?#C+#zK8_&w8RJmJ~4oVGjy{YD; zU@+9UuAhW2=Mj7vTw={fYzyz6lG4SJ*YBCDF7}hT{kQp@->vmJKe_Eg=Z&=;&JTRl z3PIx_=p6`(fuMtdpO=)f4ti!Sf`ZsC@NTCa=v`=4>{jq@qkm&w+@S*At+au8ZHm1E zyf4z1nKwzXw}W>J-O4}#N;Y}o`!??F1 zHkU5pw-ZWD6>)fylxd8E=CGh{sR{3Y@F_Xn6$uVHg9UbAU^fPKR9xYp6CqG)VTX0# zr#Oi$O&6xYV=QvID&ibeW!D?FV_+8swj;DpAW&*0_IAh!aE^g@syz`9CibAwZbe{? zEZ=d=XT^NS5g6{1l)8!ixUm7jyui`~r6wgOSaF5NG}S>jFi?2dfYEM7IO{MA-otEc zLl}1ED*?;@o`YJWI7#}A_C(Ak=qPG52_g~!gN6iF7Xo{*GH)BSmeA1XM>KqfLCSP# zl=*`pgs+w33m`WdLXAd4jV2pH4bsgU1VBD&&?t0VqfoIS)U;;av;Z&L5NfuLP_s#f zP@A;#HUW6o8FWg?kF**r?&sM>Y)6gtBwuvgOD*h#i58>Z;hAd!dNA*PV*_|a2W2;9 z+nbDy;59qg=QWIWd%$mX(8J81XtaC5pXi|V%nx1UHSpV@KQMof(Y_1(Ne=p-%-;>T z80|YCDA_@O#_vrr+P8y01^NT?TaET@;7@hX$Cw{_%U1ADanMqJ#g5VbBKXrB?2=`y zu6+ymr#a{y%n!8N1pXNg`W@ys8|@pxKg&TUu*u*IHqWe0(P~E#^qSWZh)djleW@1Y(9Kw%9~iqM4obl_?g4vN4|85cH>zGdy*rHWCvbv zh}?ORlgQ5T@yGj=&1+OVV9g~eFX4_##p6`*8rc}&4uus^MvBM&jDyC0irvJ93qLtY zbvZqtcLN=hE!%vkc-y;tRIJPS0=>-D8*=r9T)~j*Y{>N`y6SSy;c_Dt-Oa89`CP_I z+|tzfBLllG+>^77GhEV#pyzb$?5N^`oac6Azf(+^hOM2hQ(tGa9hL>XH$)|+p= zbyS`C8abFz`6*$fAPjt9HhG&IocvCiWdeR;49dIJ;JGW=Vx5mt`|~EtnE9jHE!H{R z7}BnV#8}x0*%_6GEjx31EIaLA%mJc7moYYhrx!@2yZeAxx;qHu(%ol)V7mKDAQ^KL zH#QcK4SYh*IoazathwYvs=}gVdtHXykRjV^Gvolgsx#!q4Bn(#^RhaD_Vo0dpw?B! z0ge{=RXq8T^#kHpc4LBgAOC`PIBg&0N5x2o@jQk`cDoW-D7XgWS)h96jsLxIUwZfI zcu0#!At@N1r5gPZCZ->>$ZOb1>SP~zPi~(u`TfaF%4S54GtZS4f3GrD=8c`UDqT%VkNsIp0GNmi-!BP*{4 zye0=HcSEl-?wz~dH1k$NooQ=UPHc;=<|0i=?mVIvU9@@@-Nx zuwhif6weH#=)U;9yvuRcF@^Ol*2CCFc1!IK@Z$8*if0<81{KSb#vG#JDQ6C|;#tZZ zR>iY~IRNzi%wbbJit9Z>t+6HK#XKe!kk2ex|aMk3CP$Yl@o@00gR;Q-HWx)i$%5ay;{E$x94@-Lu%T z))wL}XO2z8y_7k25%&`2*h<{@GsgzvUc?;F5chq|QAgbKnPWR~XEVnR;-1GG+lalo z(T#%xZ#WCYk*a4&@rxv9qp^6a};7vTTxEn|uwT!L`GX|Dy5|+tKIRA)O*QyNo$?(pe>E z7s=V?YqS~<`WhhPHYul$W!xoI?eaB>hN^7}RHJH}be7~iE9JcC^H~i!JCvMfp*(4? zuQ8V7Kg%+_DCNJ%klUf;KTGm=AadIfnfwhTe~a;Lsa~VNHt7HXq<{u}#zRuQlD~!I zZ$m1yDEZqk*G87>8Ir$MdYe%JsdkV6K9J{}@s#wo;@U)9kW4h5R$LpgHro+JYkaGJ-@pjC1R_ap#K!a#}PbuCy723eQHCFxuHdd5Uyxrnni2N3N4+604oMW`? zyekULKp%$Mclnm>5+TSChXgaDkJxuvcE(}+i$*r0BrPfAj)kN#dTw}wH#*F1LiZLU z8-6?&>o$-v9%4sDW{eASv+zwuHe9vhHbE{6M2(Kjl@R7OgPRR(BT&&Sfz;k&*_k!g zvUA}TEE71!=nks}W~-5L013mcgb@K5uF}(t(;bOg;tfW|C0OEXVAMe3YxOi&>kgZi z_!%SPBrNfDFtQ-=1U=1o-I1gvt}`-j!xG;BqYn~K)YDwAJCe1;8;xwFv&7#5s|^z0 zsHd5vJ5qRJ#OW!y6fYlOSs0 zEezPrI@Bo|3fqi~^Dz`|1(pCnBt6Yk-I1oDfL+a)Q_T{8SMPaQ-_w&#*B#R|;I+oR zEbVQ;eIQ}F9zRoe%+LTMn=`^Ft7XY=2Ob5<@6c1t)*Z7nxX&6HGnRayoEQ}Qvz)EE zOqq(SmgMgud%2E{Z!2iobynXewmOHAJjc`o9viL2#?(1XEE*WYCM_;biyKwv5LsM2 za0D$bL5mw*=P$JG>7?-5QIVO<&jdj`AVOTPYzFtG;1{OV$vSe3m@BV~!X^i)9Ce*l!qQjpI#aQS>K$mOfZb0}sf*Kb&FwtDV0)ZMMh0fXx_ zaZh2JajKQ%{#PS3&EP)O=Q-geWBBTJeo;ga7h|?XSmcj-pfQ4s{)*}*hhgnOJ z1Sx=DXI`O4jL{udEk!bJj5~N1~P@1yWoK{%iDzt96G>OOXmGfZmzc=@H{~ zM-p>1MlD;j;sNFEDUEYYk1kD?8t00)-u#2d8|Rvx%aR`sCm@?2yf5OcXr>>fpx$J+ z#@o@>6)m;wgQT1!;v@NB)^11p)BXkV`KYzd-b?D4|17@2|E0&i0}Qshe6Yc6(9<1Y znbqZ=qYie(UylP6YDnRr8@@v3l?ZOotMgPB7)ZN&Fv$)yCO$aBQdfu$`VMYG-7|yP z64+m#C=BnfHC=cBPIwi>SCVn-nj5cvWY>)rdYBD!<~O8?7`O;0b4&_TE6E&DVV^^i zIUwDcRz1h6>85iM$>T|+C`DoFCYfU+KT0OK846Q6Yfc~f$wz-6bF!yTSbqCtWj9l{ zAD^eNi=}G%*4;Zgm&}}Fz5pgCWG&j3GuDQX2KdT{*dyV$c!TsGZI)cIZ_d?XUK{v zh}s53ZK;MDi)ZwgR78!n=4PaQd=S+3MzXKQm;PUSYq^0l&i%(9{uMCcbvZ0Ga5{uh z0m^w63)yJ!Fwj~-5-SLazLalP+~+%KwQM_QjrT*{;}0rsftfE%x(5}HIYhCsK81y9 zWgdev4@!H_Q}b>-I&^cQ8k%2lq#;I|2ykvdY75qUiB@xNN+qj$%~^llJYTQ*LE?{| z9DH^_aijiFbExvnqq8(Sv58ww(q3qT!yyX9A3_>13cQGgZ8dmU5n6!~D-bEb3fd=m zhf=^6GT@K`sSLeE8U>hH$9z!x2Es-TP@$DkAuvHYY;2Bi0X+^_P|h}GGaD_Nkt)h_ zY#imyFzzKQXYsGY$2K4x*kIxQAlMR{nZoXk_wivVz0XG_w*RT`jxXf~@wnT*Soj-k ze>MQmN)5h`Me-8Uj}J34U@rh=GCl|vgmLfKM&l{Mlw2S9o5rpPFpxNTA%&~sGbg7ZFNUGiof>8fM#LZgXgT25AhVye+)>yljD|5y} z%I@I6ARkb;idWBvBQ|Ax3pqttb4zE)W+b+;fj2)4!*?YHm-rPHBk{7@7#mPQiN>m* zjc+9fjX8UWf2_Sp=Q{X1hVe~cAe?`m0)z1*E7le`2vimZj`AEc=UHjSdgUd?#Gd2b zZS30`7QlX3*?uq?Tcl%J<)P}WWH)OO#x#Kto@Aze?^m8nWGt|SJhy_AVDpr)QK_&{ za!MPOFERd7FS(KPK+k4SfGCWwA}R1a_DiXWmqXel;6?L!yKy4KpG7jXD!UmZ7(&LJ zqlA4zKi1xAJWCEL%rk}w4I~F+H>U_oFV$-l`H1y^Ls}2$<}DAVGV_mZP@ZG>wQBv~ ztnw0X7~rQbo-_F9g!p|%HNH_{=#!k|Mi2G_#m#WCw~uwRUhv!+Mi4$c73Le;gq0U~ z3%z7!y*j={8?cNCBN5o_PtzDK2vmsy=kqy05C)r#1g%GqoDOImJ2f60>(?2=8b*R8 z8VQyR?GeaGtk@&WgXKbxV0f`od5>U1;UE`CfVV$P9IzhYHfeo9WPPDa+02JSH)jII zHsv`!9JKMdnU7Cfh#@lRyg8Lwg)pG`3>V|V#(i8IjBS({bWLcUl31AEyQ0?IYxho{~ z*r?o$-3ThmDcffB>*9Y57r1+QD~~MpNCONv7-&Oujm_b@#?UH~%}nGUG(uNq(wf1? z%5kDD=Ypa^*~}GyVFG`O*20Obg*Pdz1|a6R*vA%TI>ZoRZ&o9Py`b`HbNgSju)|t7 zF`|X1oTr6f!xr|AB=t4!a&{z{XO58i!g-`VN_-&tAj{*`Pu8m6!}$Fkg{dvTdAaPz z>Q4z1z`Ddw9U}2jXt*&$YF}oM>)@JazC`JM#YYcDX4t`;gk97wUVCDV8MgCwp z!$kgGP2{7(p$q-^7U<$2@+mIYdxA{$LFC4A!5tdqTqsUsf}W3Z5cgaf4-xvD<4W&y zX##z~t>xn3tPIj9aT$J?^L}!c5#wV{4A4GM_HQ3q_OqG9%aHvV=hrlV^T>Xb{P96e zetM>`p-`*M-?({?s6#$KveZ|0r}B0MP7hL_xBUpRe~KC|`>p4d{l`)Ew_l>{4{`dG ze@ON-RU{ZOZ&&JCIL zf(mvqZup|IIf=FX)(^R1$XfWgvbl?i z`}RR`-!p=^pEg9?r(Q(d2P0aze_%v$&(F_jV3RB7xAR95d8rW+pK+;?C4K{1`A~Nx zfpiQhfEFGb-kM7LqAu~b4oduKBS?JP5Q%TTsKgi5i%a}x*j&mbO8oN}`QrJFeCzrDDmmY5M`q7L>UndFVBtl`{hVjH#R!ad z(ApPK*+jJQNykKq+#N|7R7zt z$l{)8LSL$90)$U(4AJ>?ai4U#;=XHOi1EX%`=-mY?!}7;gPsUs&^59!$l1guS1%;) z&nF4E9e*C7KavI5JA%01F%}fAVd8$;5OF_ch`0}_c9$gX_h1#9E>YYMv+k!wSoc#R z1ifb6H$;x^L(s37(u2wro0EcZ%_aVY#eK>Uai4UN7B=&N!Q$#vG3*u&QCZCNYF6;HVI^D+Ct$V0A=d~lqdQ*g~?;aRQ z)*r{}w_mQTPmPfEw)4t*eL6qFy5|zV6(#=Bi(B_IBCLB&iiadVSoC}jJ!IF<2(#-o z&d$mJ1i0kZto)(YeHY65?vZ8vjDLo8k2Cv&vOb0Ng=e_<1nuimW&KDq`^f7t1Z927 zCCPf6&fdnv+~vu7CZoQ-tmphbQr5qyJZI8W-wVn5(9Hf6&A^|gUTkLn;->w6l=Us= zm-Q&_7!R@PGx;!x!q#xYWqrzdWc{>}WIYpTxJ7IR8$7H|_ATd;^&!(<3{!K=7o5qT zaba1{Y#tQ%)t6!2hn9C{oJZVqG{(LS-H{`5a0GFWmJgrG<>J0a+00eF;2U~`1pHJeqaxp(B@?O++x~&(U&u4r$Lf-35D}@?6ypc^2^ZDnK_&c!ryDqkhKUCzI z{*n3opeFIBXk1>i?l%lt_bFdvK40hagA#vAgv7^Eq3TG15megqOZ<_lKjj};!pHf1 zV#ihdoc%_=1f)rPvpQVjv!xzQ;%iIr`z}78KO^7nF?|4)$kUAn~Y{?|%;RDAtR@xAo5d@k?Nu>D3Q{!!&Q8(&8sl=$K$ ztmS_b5?^1`_y??eK0DLEB|8owrg`$#*X4inc_jWeUE;HGVBdZ*>s}bLn(?(Ie$Hzs z?!8}UGJnQJt^2{vWFxHT^hZqQKg+c}uHxbRj>Zd!rfJ`=jmIgPBnVr%=f=-@*6zD5 zWvVx)16d)x*kpbrE7UA`T@rA{7@Evay`0JXXS5w_mnZJIm?urhV&;Wf`Fz&BZr^=V zvi=g*?nP~M+t}#drpx;6mmupe!@9Rc$a*nc){n4t;qrFu*&<}Us9ty`|2(qZJh)`3 ziTmmci~A`<#C_^T#l3l$xF6mDj$#LB9ZB44Ol8E~3se5l9ecoBP~5*}9lMBIl@=3lC~??6dMFL&$S z#SQ$6ZrvN)y~xG=4&A`tH7M@Qmn`mq9DE`CYl-_8kqBGAnaTW=^Q_%-1AoYdJudEh zbaBtdfjt;0?!&k0*}}FjT*_9xi;4R#6!+c#9C3fat$LB-zLsltpmz>(0ow@H{ge^5 z>RtNU{rSYbKGS`9Yxh$wuy%i0;{G@Y;>#EJm$OxGaDVnUF78J%?YX=&N0|1ty11|V zX2pG^X>Y#BX3R@pxaWpFsCAbznSUX1FX($wt(rOa56SxBllj6W$a-C$y}Ye@moDp3 z%7cW*`fFnUu)bAq3!A>Qg~@vHpCs#TnyeSq^KaGLkFvhyUpSc`xp1Enwp)!c{M|{K z0;manJ~X+oXAHkV8~zvFt#_&7eg{grUElnC{-y8M1I=Hv>$hLft`Du+Pt#-`+cA%V zUfcQq^|$Ihi$vJ?uMqbmTK9V*#eLJo=JQSGna>}xc7J|h5B1k7pYsd>+wxy2?jtvH zb!i`}Xp{NgK}KNu=ZgClI1g*|T7>lwJLt$LBx z{SIB+@A{Wn_hHrV!s>Tl?%Mq&Tld4(?%CD_F6fVQ$qy=B`11X~R^01b7cOt@{!+#L z1=j92qG|tZxM{EN)-#8RdtK1$Vx4WN_3C0j-bb`K^^2SKfPlv3x#~Am-0wkg-}FB# z?s4IIhQ4rpsr&TwU3x=J`?2qmCSBHZDKDv9=5uKuA?Em!onZ+%x9ur|1eV%_nVLiTfRAQf0@houSJS`@5Ltb^-mLQ7u~9NG3$OCTKC&8 zF7AhK)%!-p{WH3Czu|wvy5Eo7u;p^M>P?9d2B{%oz(v7WA6Ee`VXGc)pZRBtd)>VK zCbsHb%EG;7)yKDTq0VJJie0x^H*!~K%QZ_w$CibbPa_xZFZikDrCIm-{LSTwd(%I% zRWH)IKdM{zt(PF~BZR%wCWQq4*A@5rrziiMh5HML`)UyP{Me(*H1IEPw_c=aA8y#| zAL47`{xy{RL0rE4pWUr@T$lLm|LV1S{TsCZ@!fhIx{Xi&^=tR~6vsuxy|!WR8{e&0 z8!7JVE++2H-`LvyCKUHuzR9h6gW~=GpFm*0B3t#?&RI>|@7JySmVcRbKf*~Q|D?71 zy_$93a31R(mz8yK&xJk8y%de{4+?ut?s1x5rnuL?!}=HQ(~Gq3U(>C7@7J;J2isPo zaU*YI&gZ4Wk@o%hzrDD;eR|)>+P$DpZdkRI%5Qk#{=DKoV(S9mk^N8Fr#I4f_gvi9 zp>Pm$Ow*-=xQzm;oO9B^UTolh*K@-Gk8AR_+IP zt6lD?dW;U2Dek?RxZlUbedmODzfldH&TVhi3T)XcWda9l{^i;h|S-VfXtjYY2^GxQS|5QDF=qK_|mHhljSm@8&&RTu#*7!D* zi>$QxMzUL*USL=v8_LjTyE_K-Q^WCca%nf~QG@IF@!f+*trJn=*I;FsBsLx;F2(t^ zQ}JZq)W^-_oHEBm+zdLqE@0{$k=$jK_=POI8M6{4ewI4FohmDl_fv`8NHsMpiK`RJ zLaS7-u~An0sS9mWvy%DQUm62EFm+)HKhSAvRx0r%g;?vycMA_GYzjpXw003_aHQ8&cNFb8Z&3%^#}SL6?x>i z+$G8#UU`oxpFC_*mZzBT%7fkGYcwOP)MG@+vHN+sx!syb$*xJlU&>E z{0>=}nCtMkGcbvR?ulae)49Em-zhh#r6qW`#9Q=+FBmn*hl~A?Je2qGCU75rat1E5lONfPoo;C_X0S_(Y_u)Y{c~6q`7T%XhUmnaoh4Tb?-8^A+Vr5*- zIu^7tZWp8yq~^eAOQE;SGSl zsf}4USXA;eEMT(F;mKNJ^i>EB`U9h?g2z!vML>|mD)!e%mPr9qJxf&Vdq@^uSxmC5 zihVx}M8)1hvTTa|D9K7v?5!j#S+O4{St*LWon)md_70LYMX^(om8RIcU_>ck^JL9X z>^&rFmSPWDcKRJ2`)g3=dmcv-0S%YT8*VZE>U7wUVeK_3HK2sYexR(;zFROrO&aWP7#i(fybTixvJF7PF*mC%uOSAPn(*VHg&-?GIs{Kd)Cy<8B-U`lDtFj zBa*wUBqveH>4z4uDpiT@W|!zz`IVr65#Fa$5V{YQ$k@+c$DTjATX6;5&6c114#HQ9 z=>wLhek~vmd1A@E#zqJAtx{FPUzV`WVXnE8kMTSheots){E737@ooa9hrQcyXLjM3 zd*7T{ws?txVv2?Mm@cQj+2^RV&3kq&U%i47j1k zqyPu>nEnm;oyYWslGBP;g66l7f@I`+nMq33Yvjp9rFai1KC0w&Ljx%JLDwj`%4)Uz ztmGst__~KUpnabfasG@%>vWg-X(j#f*#?Z*R!VS^3f<3XRvqE(cth= zljiSdiH#20hlkS87=xW>k8#kyvk(zjN4(!)$KKhutb??Yy~N(%x9qsF6~C0-+qY~# zx_Z#%1y>_FC<{`Go6yrig5+IdPwZRPg1B{$eYbB}E4up8)sC(px+uC5m8xCnc}*$a z!Si)%`T9fof}wmpp?v*H)pqoBD8<`Iag$}+zH5A)*GSDFERTn;QOE(kVc5)V2n+2y_MMa z)O?ISxuF}oNPd^xqJoTddo51~zG62Y4_Ga7JKlco5(!>$8&sfAWhOzLN)_mD(AhFm zLYIOM)o+p+4=f~i&LB-BZ&v(X=N%36Y#9dGYmg5M?!&9Et&Ej})|H868ye;rGXx&) ziiWVt&nkoptLM&)hC3YwM;_hZ&u&yEc{cJTS((hMO72PVeSVGci6qj<>wzTcR;s#5 zL(NCJze#a*5g)HL_KR{f;ng$rB z{fvM{0Pmv{vY~w#l_$0;#T}%$pZK}=%tR=%UH7#Rf8P=2BxjW3{)w)hiNT4*-SMY@ zt;N4fd`fZmM0?l792(z)dTAL5#MJqKttaLiScifm8oR$6yvFa zv0h-KyjymUZ8p9Oj7L5s_&y%(qvrUaueDw<^qAvg=@hOVD2fN zOq+u)W$rXjW|D(0`Vwo90+v%_)(oC`7QPy?971VH@o@bduX45)pui#vXAmD*JuAM! zQriq!c3I))Rm_Z6uJ>R2HgP2?`C|IpmDbg!bpNVR#1D;4-d14P^@wXx!MG_ zN(PJ{a*E`4L$^UKbbgLUa_#iYKM5Wus$`1kLk;)Tz7riSHZ_&=j zu{gQ)+SA4+11Phu{xOBKG z^%YcrfLYD+y@1{!@|$L}jAl8gTArR^0d)hr@j9^eQC+?f0>YYHo{bO$XF_8%bD(DB z#cRd=5%HE<8Tz?j>mP{`$_>yF<+y`gbqLyp6^73jy{JKVfwF&Xm|<8#pZ_S*91pwS zve2^g#}?2XMq74fTBIP}LMgE;DC5sUXaaMancK|V@ys31+@qL#6m!QhcN}wz%q=o^ zEOW;)cMNmKFn2U_M>DsHxlPP%WNssKM=^I4a~qi3VA**E-f25JzEL_9U!RS_zTHro z4Z}(J-@pI={k!3h2KIjMcLw1!JTd>zAlv}YEO_pPryQQ2z_SsaZScGf&tZ5zfF}r# z_4fv020ZiNxfh-#@KnIF2A=isY=UPiJiFj&frr8)Y%>U>;Yoq#Hh3KH+z(GVJYK+I z4ZQ2%`FD7>!1LemybjM^csk%2fXDg=z!RQn@MOaCeR#^?Sp`oWJR9M85uX2s#|zI< zcsk%Y4Nnx*`NiMydfzfvu!hqk)-G62{8X??&kctEwoI@lf&ZXAGOhmC4ICw7m%(b= zZV1KaJn+z?$#*@v>amBHExkqe-@DA|s(h3M)a4qio8W1MC-Gi`^#Nh2uu6D9SRp(l zNW!fQ2KU`8JR+=w-__uL6y6UCj|r8+GH{ha$Pd6($>Ns_Q{k6C7tgy=cpO3=6v{(6 zZ-pm~mHRM*`6&D@58;A;_EpOsb>6$|hYziEE~^X=%UkBW>(R2uDj#{k`OssJ4u=!tVEIEoUUnxG_Rxb5EYDl^AYx`;BUImKus#FNv+!(zXB#}b;MoJu zQFz+nq40FW(+`iBZ?HPBjo_UGPYOJ#@JxXx4W4Q6%z$SWJQ?uJ$Mo>r2hSpS?uTay zJWJszhi5rFE8ua$vj(2E@KnQ73r`(9&%m<*o@e3N2+t;Xw!rfuJX_(}2G4eQcEGa> zp4Z^i_QTT+kGT-)0*?cpHSjzO z&x`PEg=afFUU)j->4GN+kGKfv0M9&lmc#QbJg>n+;V~5fec+i7&l-4MgvVRNY1jhq z4tRv`13lrH22W|}4<1;#Y-uXCdui!|OP4*k9NsG)SP8Ah!&W+%f_pi0JIfzh$vvf| zWe==$>h4w0zK>OE$q>%+%21wV5B%UEe6Mg;es>zYE0?WwRzCEg6T@7OLO1y#j7UKb zMMRPxUA7wGBrjdIe3^5ZFdN*r-!2HVK-an++_NFzdUzHW3&LY7mQ_9gWn=oAAJl|q*-xj_D?@2hjhY#ex9pS=z3cOQq5`-t=T>{Tq%mbO$g5%o|KN+5z z;rR|clQ17-ngsy91@5)*l)$rORhjdFA1q&Xqk!%ogt?IrHwsIfkFQwvSQ!QhOJJNm zusnIC6Nc-9$v<>GP`Q+cBMBb;A$PCBb^!`Nm|_6d0++BZ&`WrMNkM&Ga?#c@fSivSn}XwD;_@&p_aIoI+H7ztYFQt z#GWlIx%a;N?iy^nP-{o}M+S)f8T+c%pV28SdF+u#A4bn|jI8#~*#*5$Ns@g@i+8GKj2X zte+nDfOFZJhn(SfX(__{=J^p?a;eCSNV5yTjTo=a^2%ioEY*jt&VQ0`xPjTx$@jrH zPoB4I<%5+Et&ApdDLC^^uKNPHQuMn&sui$A8LE6796RZY^+gK`CKZEDg3ZA}l`JnEI zetf^1%j2Gbcctb=z2-`IqO`~O|6}LuesL>LM2pAEVyh4B^ zge1sIQ8UR5nUI;uFfSpAC;=k^g3^i_6*VdrR#C&6Dz>OmQL&<;QjJP2THM9ft?{LW zT9p2tmwR&);>zy+vAdt$%;({I&bjCPoO|y%zd3`F`fiZ)uh9>7qPD4zwlQ9rpzN#H zPO@D)UDFc#YrakmI|VjCjlxH0_&D`vs6R{ng_@>F!;6)3H2-;8wqL^oG;d%b80kJ? zt?P*zzd`G~T)9H8U$562H6P3c1FuTsUiIIv_1UE5ZPxIow0>{s_4oAppgz(UxmRMH zb)~Gq_ki(NVT}T7fgQO@*5zqeV+{jqg>}HvOR*+{b->cxSg+~YeU+Qm?>()zDKvzz zYRolSO{bvUFrjc1 zV3*y)e=VPC>}4YO*Uzo<_OLHGp8g4eRDu`RBgn_c;k3Kzx*6hyRBXv^P}~qayrw~{EXo`?E=j>9$Z~=+;yR} z<;a72FN&Tp`-5r}K##g1%Ck5YH1e^BFTs9#4)#SQ zzL+s3Txk@$qjb&Vt~2O56LBKsK)j&142mCCC#7Q-(#FCXHr*XGrg+PYe0SK$2!+8q zV>-&59`hR+u?nNu8!~2Mb5>AYV`O{FDLxiDb(AK|4%SkzDxr5$C|pVJ7o_)c-Z4L4 zM?SF#_IJoD>J5~!`hYyE$%TB)Aj;ozXXN9Z2FuSM?eUDR<9s~$8XkUJ<01tE8_H>e#s|dg-CwE zE@6^)*cM`z)9IJ;C{}0Kbhv^X*NeGLWxM%ZoWV~{@z-%YX&cec*JHRFC{HiH!)NmS zYZwKndkys^-|=StG0wHlDkp3UG0P>>8GV+8Df^$=AB&W1sH9XEaKe@;&+)g%wP`ev+(^I{jcxfzJfw9>Bl! z_L1iV-R-k^eMEoGGOQV3gJ45pNwATyWY{R!SlC2ZHmne~0Oo;(U{P2tY$>b()(Be# zTMJtc+W>2VZG<($w!m6pJ2d`I*lyTf*gn`nSO@F~EWX^~OoTaMLt&{fht_!_+}W@^ zSP5(a%meeoqOeBT2G}OpcGzy%K3E6rFwF2Ef0z?C2$lp(hNZ&NVCk@2SRt$w7KJrv z{I#$q*d|yjY!|E@_BqV(B43yjHWHQxD}^0ch_YcvVDS|W=OWCv6wD}Ev(~fXnT7d5 zIw!rEXYd+U!b^Dl`u~5lR`32vwmwP6@yW%`;@|r;_VDQ%W4Z0)IL?nf{R-Qs*KvN# zv`PQx$G>6uit8J1Sb5{B)oX5AyYA*&*8lA1w{E!Y_B)#HyzB0b_uPA5^ZgGzxapx^ zY~J!u4?nW?(Z?Qd+4j#*wEptRr?x-+t6%SU=Go`ko`2!RoiDxo%C1*`^V;s$-*|J+ zTW`O!_qXr9*Z%$oAMX3zN59|y@h5*c@aez&>%q_d_@~eR?ayCyeEHSa-~8pThYtVk z+rJy-(~DpV0TD#C|9Dcb+of)Pbj+e#W3P2M-x~*0AA8BhEf&F%;}k9T2(uX0h9KM<@AEe=Pbv6>~d zb@e}8aOG83m;UheYnEPn-Ln7g_W!T%|BTG6?3^i6bEi$8k(XaEvv5{Xamnl}=FFWp zU;6)tum6wee|q<&MIBCBZ>NK#!{marb}j@-hbaX~zwm*iwS+)gd)I=bT{M8CWvl{8 zdsq*W_Rs{9M$rt?8h#5%dQ1yQddzl^w2L;7*6F*zQ^7qT9i(XoPXqUZq>UT|NgL__ z&jb&HgLzZoaME#wc#t#~CwLZVAmA{1#)HG@y9bb-c&Q-iK55|D)Nb$`YBxxya|%KF z{$egj-)WSBr1|+k(quv)eg9Dl()S(>Abq#73Z(Bs)`RpNNE0}o+7Dhz?FZ>JOAB}z zwI8JKM%q9ZwI58U_JgEDwS%NX?FVVoauA$C?FXk)`$5vmjT(n@I<+61LG1_Wy*~(? zN$m$|O^^&;LG1_W{htQTr}l%i8qEcl(VBY})9h4A+R7l0>#J}?fXwMK6+3jc{< z1K0;#3&w*@U_u<})|e0ACioM<7O)?<13Ver1@;H`f;8dwgQtMBt{DK*y5>~ybA%5B z4}+(HaZ4~CKqoi|915NZCWC{)vEUFe9UKbgfoFkp!C{~W91e!SBycG>0$c^24Q>F> z0h_^*;8yTla65P&xDz}d+yh8<+R==TrSaFZCZ- zMdJ?osb1i6su$?M1Ed{{18EK02Rs0O0{Owd;1MtpjIYQ100)Anf=S>&a1?ktmh*q2VM>~fRn+sU>4W}R)H;`0}rY;Fb>=e_5s_$1n>aZ7wiBN!6Q@-7=I1& z1(U!ka1=-A~%k9^6Uk z!9A27+(+rbgOr{gluMBw4@M`L01gHFg2`YaI2IfXrh}J*b16O^ls<|NMkzknK=Ht} z6c5})@$kTGrFdW)#RGTKb+DbTkEFwlxDI|p*XaRzEv|!!pd%Ue0TaMvurD~4!tuaN zr*JTj!oj%|o{IaE!od)QgG(uVEbdPV2RBeS*i7Mgpl&5UxSjkH(O={T_mCeC)P3X! z4-)Yp{f0<~?XCm!P){Nrkb}UurMOSQ!Qj~INbi>Ya~Z1w25Y*8ZGV-kJKl2L2Yd9o zNB8$$-to)+SSaxpvQk2n{CyfHJoI zSMl{aj!Bwn4cC{H&tm?*sEl>|G*9P83TEAGog)-ptn-B2B|0}!u=CGjcNx29>KsWi3OPK) z@iRI9FzW+F94E~A7jgbRu0t-zp?O2?ouP9l1uf6h`9tA3I)_MG$klm7?joH_RPGF& zPgKurol~S4W$3)3`pnb0MR`us`9=MiqjM|;rCy=)jNBzU*C@{-oo^|KQJ`}!MU^j_ zcjTVWsYovjTJz8xuK?F4pX(WAJ!?MKt(My*?s|?dZkn^EyNc^DmFp?rgiPW7^l^Qr zaeV?@=X|bngxf3QBHDUBx4nw%FoWkz71w_T&#MT3D=~xfk8xXOAJdj7=PzSd#`TwS zL)t$DdOw)%s4YCIbF4t`jm|pzZSJt;j@Z%$IDS66%el@|F_Ll*nSCqwk(t80pJGQIZM>n5G*T4*uR%UV!8T##s^mTyyw1E4_t#z7Z-B(#W|3r_JdU&;e=UVqwCikP< zGZJ6!83_+^TJxTX^4yg%lNuLx>vy>a%6$oxKgm)=%1CmR-oTHOtQ9k&?2DxgJt> zo|YH1%8;_B>b)7Z`q-y^FZBrEoo4p3Sw=RGsg#k=SIjb|S!Kw$d-d5`WR;Pp^FE?w zbRQ!rueeK_^0mG)-*c>d3psqD#>uk!t>=8*$F!q_$JT3mhDg5I9Lt_p*D;X1y4GFSQ~GcHHdM68iB)6CPh$e3i>`fH}92_BP1?nFtGY3pN|1rldErH+BO{yi4 zwlwfY(J~rTV@iVmL24KHI`ucWmD&f=51R_XpHurl`hAlRe2Llxwo*ReyWm=I54Gz? z(MUFd^!xD^@Ez5zNXyy*|69}!@ORV>kj~WX2Y*BD0DnpC0H3G&uW~r|lI8-^*_@%^ zqolQfzX!*Hw^F}@^t0wXkbXit7o;;g9`Ix8Kk!4^%7GtIeZcqWTo(AUYEh(7HLnt_ zX1!`qTjBSsCPiA+cKCg&!I37n6aGBaoalW19{3}w&5>5O4}SXD^Fi<-@EhL;*RwK_h@u*Tu6 zQ;m?c!$kNiR6C?C@gVqVhcgnqS+zmZ4pZT$Gh-9M>s6zpbJ)4?uT%~1a_TSm8&xZ$ zlN6=!-$VTc(hjH=q@7M9I9oMT(p1;Oe>?RHNKdsb;2o;1lGfS^|2owaNvmvw|2oxN zNm|&wMl{2Ns>Qai5$*5**hJ~Twfr9jIGpqwJ}0pEi^yC?bIId zHR=!W71f4GGu{vX0z>xrf1vvs{uk(eUh8l^L-#TG3%U;8sai5=%z5zNMfW3krE0X7 z(0vSly=tkX;fCN}quMNKz76m=yX1R_&M0 zDDHrNscP1wW$%K&Of_xNy7$6gs+#dwBK&lQ@Gy9dYSyG>JJ&g!w6h)x(oQ>hooN4Q z;3qWy!1XlmKstL^3etbj;Rhe4eAbB;-3W%Py-+>xqUC+;=AE{<%UE4->#3u9%k5=V zMckFFNQiq8@BYPI#XEd)`}r(~>8`Wf0b9A%dvXT>boz}UY>tE03 ztUA|c_HeJdopGR{-908xu%4_3*sWL;Xu>pOc|(F;Ts61||D`$zUs72ICY4m_+w z$a+}L*Ld_Kn9p*H>g3V$aFsT9%(ll0s8%D|Lj|vLyn2o^X1U9_9$r0j=eD`aEO&*? zUCCvOdl8R;SI>%d<`d$&id&Q#amTp*;;y%qRnKEDYc#jkQ~I&ma+mYym~MM`XMB$> zT+Z*9?ug~C(E5* zbrWr)lJgXONR&g-7(^vosP~xHa?5y`ZlC2|sQHAgIk8ahpK@!zF6D|&AahsrCpo($ zdWIPu);VpuMP(F?N|a2|VB9<(MEem%QM4;jIb|O%^%S?Lo^qaL5ud{neWiliC>lu> z&#NliJ!WbQm3nWQ@ z#L|;xe{R3NsN40RReI;Xx6{9v=b7KyU(2($yvzPN+~YGiqVI%IkMSkke~jK^_Ct-W z?Mw9RZl}H#QJp$!>&K|xPeDsF74+XBx^z?DtmhAhg{;TKWGcJ10Uq8QlxeeSR zaUI>a`MsxaSh#pwzjU)L{n8JO&q{1M^RKskrz!WlPVm--tn`k7#+P>(&TsEBoJV0J z?(FtU@wTH!$GzYi@xTZDUp?wFUEg=>h4}RNxcGQ7BQ8aS(J%v6)prANQe8k+?* zwJFohzA{r|PFeGcDjlj`Vz?ufJmKBt)jXjii^I`l$H!N?LFFHS0%D-ZSSWSMSunf1gm5HpytX{iDZ18(e37{IkT`BbU*yS8u-PgS%XV zL&1CB8ZvH@(Khc;`=iY+tfdoXT{r~S%U?e9?Sn4YUzUGaHa;HLznC}djLohOOWt%1 ze&%#sf2G&@$q&0$zO!f7oVQ0zGSXj6xn#_vuHo75AO5f&>6_mTos!(*swsRt`KGVo zFa7fK;TyNP_RcOI=Gu??wRyiAa@rHF+bY(^HGFa@uD{f9{;jR9uOBLVee2HAsPAW2 zMS4H!y6@Wi&w2C3Gmzi(bxW$Aa@7Z$2OKvu4;NY+(Pv-j&BSac%z_0R6RLy=oQL;({R74Xx0sJk)31ms*wInVA3?EZFz!U%&p|d^~>V zo^#i8Z|=Qw?#!VVw(9`)Q^VqWeLArqJjUte*n?Q}@%Du~v zkGKjHW$Bu>qhT)W^$bp2rVkV^iyfhjRQBi0jhb zoOA^9b^C7XziS{pdhG6g{|MGY8RYxs9Sp*Gy$e4*id8OO`h3`u+wiFBt&QjWh?U0% zClzxPP+s4LFSh-N9T6-_9maz86`V>g#LBSzL38IEILc9=yW=~%o-D&^3My7^y9)ZM z{MVhD3CFPOwGEl=IG#|Ss<%CE9K$%C_qDD97$3n7^NaMyvF!JKzF&V!0O_NT>_jIp z;yd*y%|j?J?f02=^G;yKf{cNK8bDvce!H)>KZ(u!VO)8y6QusMKYhLEBxYP+wfi42 zurE(xbMMW{dvpurc}vpcJt{Di=XUefrVdd4C6Aot6}dDzzh68B#$)k-@w~Z}*v1F@Kd4qh{dP_1H|=O8#y`OQ^qm{f z-r}nAiw%`n&e!)IyNY1EXB^z;AAA~{zkA?tjvVTfr|GjS^E9@6qVE99eHj1o>$#cR zPh(lL8bJjgHJOMxPWk8ypg3j5uo$eW$j3-ar>Iw`3N>)xlc zpZn(S3Unc~begpavq-*KuaWt{`0bQ_;A|DP-?{6)D>nmRJnUJsweuN_e_=$e}>#G@9o5RFX4<;7uyU4(tNlc7#U?OMj1qRlRW1@G%c?KqKVxl#H ziIrWMm~-eH1B)}6Sjl5z+P}{-kiCY9-Z&G32Qjho+D{BjT+PJPsZ4x2jENbK&M+`% zHxtoEOnmw-6EobHn0B>_fwfzhcp;045$`f_S3f2e!1%Psd54&owv>tS8Yb?-m{`!A ziReZp11}t8qI5YE*#r~QMl!MVEhbtK6Kl6sFfhl!M9xqqmR>u>z{GqeqW74X_a+m$ z=gJvax{QfY6PQ@*&cwv4CmDFRh>2-BCL(_(<~%vUKvdcSVRvLw>ZuoJlyK9Cq&=A2 zc92^RlC8q2&$m#r)<8MXNLD6Mdl8*MO}+G@RnuFn1QjhvNVTLHV3(2%5vX)Vo7}<$ z;sNPV0&H|h+e?BT&oC*In;g}UHru-kY1`q$g|w~n+CtiPS-+6Bp;s=aZNC?m(`Q5R zR@#>SbRlhnM|rd@J<&?r&Qq=QS&wrbZDUNc(za!jm9{}}W{;FrCrW}#au(d1TlBD|G}1{lb5dW|n}?4Y@}JzVD=+I}`1#&~b;5%aT#kJi zVoEucojuD+A|WLEj?Io3(iL|Mb_o`K#aW&Cb(74LfRj2d|V#G?eifv-u?K4>9agU!#V^iozMGP*{fW7);xT6TvEHaEQY8_ z(-TjQZJIObamLSXyWchMa7#V9;m*t%5stsiT39#4+-Ft&f;gUIkEsXt{puH-zx0M8 zs~fS{ZRked+_?S@>sNfU)382l(`RG3Wqrd}O}y6a`X2}SxOa@c^Elr#tY*wtZX0|; zX4GjV?2W0>PrI{IPDVcYHhtXm2j66Qw$E^TR(n45+$j%!%pz6#qJ0jNqd3Lu^~#Tj z{9bT*M97qbryt4V1rCd{rrx+!8*#P&H-l5&xc~VO-iki=-Y;@mQ1N2V38}A#VSN0g z+;_+$K>Mc<7SisxR2myNp*rGXCn{Xan&CA)8+*rX&Rr_pVm#$KJ)i9I-ox3s&S$*O zq<*HDaWVO9z=Z>QKCasEtbRs`<4buA9^@ak-B3Pn%gIj`-o55BY0Sge#g25gTzTV@kX4dN0rqJXsSV>AzfmU7BoF7a(Bb(khODz~&h1&iLOmBSW#nA? z6D0NqnRg4BYm0hL{2Sjekxm^^K7D?J#oMTi`^jsiw=A0Xaiali_)#1Mh#28r-=Sh zu&8g&{kU9JGOQSmjbUh*XMAV~W&2?A-lN74gEx|j#|B>KW**gReVOs7v>XO6ic0GV zJm+Q}dHjloG2_LP5xGnrm7kEoi>30DGI>+eqiL=>Pv+^i3}T?ozJ2y zH#UAIIqs->1AjV`PdSWO2K-@6K6Si)D4#_QWjj83j7t3`r4G&f%uIC>xmZ6hwAI;Y zQhAOHq1u5~+4J6`+Tm!=i>2c^GkA17Ht-gZoYH9a{c;Bw}}l`_}5QVszW}ygj=0avnz`_Ooba`j&c#o5++OZXy45 zQnTfA`=r+E`D;S!`k?mqNo~uG%C_ZaUL)`Sn*8r1x2?ziy0+6-q_mwr!^rH1Z7t+8 z&26WzFt*)K;TdhGzuZE8vW5IqcH8n1AGMu-c5d79KNhyGzabkDTfVV*90l6;29wv& zb6r;(mBBpY2)tmRN?42XfYN|A10}+P9EW_E0}2MpgT;({82CUrKm|aRK-@Bf^pHLq zXdciapaP(EK-+=#104st0(1|^5$34=Kysi7B!_A z9hq8fokp)T;Y}XzbPgj4Tfkrp$4P%ZAjAnshI}2znsK8g3O7<7e)TFm)L_<=xp#au z_mOJkYR8SGd=&x{og=w17Q%$ zH#XK}AC-qmX@ucU`WuczDI{mKL2cIJ5tIhvU=WeKQA)xTW;Bv!B~^2r#{D(KiiJ|4 z4Wt{mYQ*4vRVl#Q)Y;XAQLP_8>$3dXYRT^}a5)F)Ms(+;D}T9anD#e~Ni;@~kPG*xLt z{hmO#7C-Wd{3nhHcqJ|Jz|KaB3WZVe-`HK_f z>YC)C%XA)k!l1>;djDn@26aRG2a^43rw=KmyBHXSFgH^7(KxNiY!s?B5Vrn7FC1fN zy+s)`^e4C$)Gp_ioJD^i(s0u<~Rt<(^B)6{`bWLWgOVWR|m zYRN+G4)o79+^naD3|AmVAtT0zM2&2W@!#wJ?p4xf|A=?%g7-AOqhY@STk~1$*3zxZ z`}gF5rCUaP`}2!wQw9$0)yQw@Prv269~`H}eOfgY|1aI{wBs=A{hy?3_gCZE`B^2~ z^hRp4e=OFkW~EoIrzK2X{@rln<-N0+Z=J$ozoBKZ)9}{&O$zxu-9~>i!)oW~Tm;YV zi62@%9MJf;4r*vz`7MpJ@@t<{c8#nY3X38BfmPM3TI;G=FKG<6;r726Kg5PRAbv&R zwL*7vy|BLU{nqo(T1nlFbpooMT+KlV)l;fpeXO5#=E9ZQ-x1;98$9onjYpMUs_`u}}={4)jyIY*MV2=d!7k~lEW9xi=7W!o-Kh+kIPI<>Sn zHl4p%ne`}!d`f}Xau%Bdgu+Db3SKqn(D;JCMG5!Ya zj+?=6M<2Ys!YBP1McC}CANA04oCI44=DGB8yqEtTGpB3XBtr%WI-$Z}+hWrea!vO6-zfIb1< z0f_}9<#dnImiW3UQpzc8fgZM#;AWP8Ppk+a8g0=)b406W$VSFqE zn~$x)Hem-b>TMVfZFcI-_2LF_M|0!3McggigWM|aW$p`ZC*GSpAD);ukvD~x$;;(^ z!P~<-#=FS7!F$Ma;}7PG_+k7gemZ|Pe+j>czlnc_{|o;fpC#xlkO;yA;{>?CC@2t= z2o4L*3u**Cg@c7sVWe=pFhlgA=rfTOG`Uw)CORv6Bzi7#5%(7Ri^bwl@fh(`u~D2Q zo-ZyCZx;U`J}#~o-w}6|^py0M$Ry#C7|CqOe2G<3C@GcvC^;jkmAsTVOWmcOQa|Yk z=~(GxDIv|4E|abWeV0qGOP@%)%Ld3~vPju`vJ_diY>})kFjAf=&y}wPEgq7W$$yd8 z$sfpr6_XSx3Nz?&g`!%qHK;B~h$*lLYz$_=%-9TU7B(0A6kCFQg%x6JvCY^{Y#(+M zJB6LYe#LHKcd^G9JxNd-V{S*TJ9jAPG?W|5P2nElnt7{vk9f}fH~C(C2|t3b=YPb{ z<>&DW`Rn;z1nzNV*&OhOyuW+n-Yoyee&k>0 z|JuLbf6gEBzx7YkKhaBdg}zH4)oY=;dxODXGI%2VB20;Dq8uYkg{d){%^%EubJ!d= zF?+ftHf|T$CAP+Hun*YRY@a<~zq2Q~8SZj-rAxTmT#eh{9&mfyAKjl^uRDtK_}0bZ z|GN}GU!3^FkekV^q=x*SJW2MFSIJ>=jHIxDEn{nO9uKq4IE_B`0XxjTVaa?BzmQwL zgskE;0hyj-jkP2xVxf2$mjhvXbMCQ$WiliC3i&BXk<7kamO z_j}vC9hmy#gMo z()Z|XdY9g#pVxzWRL6qTg0x^>kROx>b>LG|ur=5hd=z{fd>Nb;o*6C-FAhbxGAs>m z2{(tk!oA^Z;b{1;Fey4K%8nL9UNqnM#+bm~VxP3H;B<())K$SpU$|IFEH?E$1*eb> za)eO2o<2tp(F@rEZum=low!|W7yHCJ;(c+tJVyrda!k1d>fZtN@0ah&5qT13oTHdp zp{`Tg)GqbBdPyBn@2l_BnV9twZ-sZgccWJUVm#tK?#%-M-UlK0C6u4 z3I9d^6aSb$fm4{Tb2QUVFV;WP&+3msR2kJpo1)#(2hnHIchRXPH0w;8 z*=Me@>usC;+#YdLFQZMpfH0F>OqP=&a*%vXJ|`38KjdUOn@YNtHqsa9KR|%lm~n#r zg5A%a!h|oxY(su2U&b5wR=ykVf15ul=E$=pmy6^&*&+w!F!(qFyF6QQwM6Yy=YxRn zdMo{n{x<&^UxI57>Ye%x{iVJq*dBZkB!#JAX1FPQEBqLVF*C}EE|2y`A4N0FdFDye zZ@w_I?PKuo*LEK0b_1w3{dU9DZ_dO{C9BCv^f&ZQaDF@6$G&B=cm|i4#u|Pz--uQ2 ztbJcAUqfz z3r~*bMHfW*(a)pu=&q*hlhcOjo%aZ`(#(nT>@NBYT3I+tEVU!w=; zS2PFoT*-dL9%1h=!>{3`AVU|JIlvF`h2k>trWh87#it@w&XH%yAIghlC^yQ7&Jqp0|uX1v%@@XUN#?^&oHS=+_f&&5u5(z zk=67rT8N!*V4K(_qDtH?YDJx>7Y*Ww_^BjPNMA;B(EF!%ia*zXRZr;eq2ZJu74BVw zzupma23r^Gt-{J{s}S@{ERr~jTmOUDLIe8%%4zeB{xiRTk;R#$jm`FH5q z(ZVPeKhckui}m=Q?}!h@zr_rB;+dDcDaO+@noculHqD{AG>_)f0$N3@X$`HV!HI&-h{Ml;jO%lxAP9(2^Dnn9(0X9-VZel@*(8J2p>g~j`4AR9IBnWazrjtR-l_iA};boz9s@uNE0$R+tm! zh6Kd(!zhf0d0|1A2n)lausAFM1Ixn7usW^&sQ= zWIs}1P!53*BXSh2bWD!R<8lIRDyEWEib_>!DqUr$Y!EV65hawbA{AG8Dqj_#Hx#NO zRjf)>sVYOhlu#*B)Xo^j#DL0j-+SHnQ(}+IRYT8XFx@j+*GiZj*s2M}Am_$=ewdpp~ zX4_mVY-ICnfi1Mfw$zp*ORH_It+$P~*|yqt+iAOPukE*kcG!;EF*Mpqo9t3uy32Ig zF4qYcxja|k3SF@)b>*(oRl8caun~Q?)wR1$*NtA%?*`ql8+BvuxSIsGlVWu^_hgbv z(n%)CCb>kAh~$w1^tNJBO3FzksV23go-~qXwBvTtNxDfds5FR#$w62k9|jhwO+wYRAF6m`ibKF2iNH97mk*;>eYRD?$eOd)9`gJh8$LeLlEB%dU3D=8sm zq=HnTIo6Q|(nMNF8yZ6w=^=e&0C_t?j*@ZYZH%UXLK!p*3?kI0aZo5hi)aZgqZOc0 z4XvXMw28K$eRa?-+C%&303D(u^e7#t6X;?oERAKbESAFv^I05CJ;91t2`gh2tcumJ zI&}6X*23D5-d(H*ZFPVRu@QEZje~G8&@ByQ%L3I1h!zLU5+GR#C{_W2)qq|NAXf{h z)d6DlfK~$_)d(mx4noC1r!^kyuGY1>UN`Dy-KyJlr|#Chx?c}ZPd(O>H2r%LIoRJ6p{J
|=_r1nVxwikq;?A*?I|t0@B8n!v9iFe(EqDgtk&7<1y8wyBpIGBIr*v#P?J znlPgt_+$W18HY2-PCxCixmeYlYidjIeG|6inLHpl?B0RSjq$&mm6 diff --git a/shadowsocks-csharp/Encryption/EncryptorBase.cs b/shadowsocks-csharp/Encryption/EncryptorBase.cs index b92233ec..594e67bf 100644 --- a/shadowsocks-csharp/Encryption/EncryptorBase.cs +++ b/shadowsocks-csharp/Encryption/EncryptorBase.cs @@ -26,7 +26,7 @@ namespace Shadowsocks.Encryption return hash; } - public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength); + public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp); public abstract void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength); diff --git a/shadowsocks-csharp/Encryption/EncryptorFactory.cs b/shadowsocks-csharp/Encryption/EncryptorFactory.cs index 120bd53c..d6c89b9f 100644 --- a/shadowsocks-csharp/Encryption/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encryption/EncryptorFactory.cs @@ -27,7 +27,7 @@ namespace Shadowsocks.Encryption } } - public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth = false) + public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth) { if (string.IsNullOrEmpty(method)) { diff --git a/shadowsocks-csharp/Encryption/IEncryptor.cs b/shadowsocks-csharp/Encryption/IEncryptor.cs index b45c62c7..33ce0816 100644 --- a/shadowsocks-csharp/Encryption/IEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IEncryptor.cs @@ -6,7 +6,7 @@ namespace Shadowsocks.Encryption { public interface IEncryptor : IDisposable { - void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength); + void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp); void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength); } } diff --git a/shadowsocks-csharp/Encryption/IVEncryptor.cs b/shadowsocks-csharp/Encryption/IVEncryptor.cs index a4b66ce4..8af5b9e5 100755 --- a/shadowsocks-csharp/Encryption/IVEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IVEncryptor.cs @@ -15,12 +15,10 @@ namespace Shadowsocks.Encryption public const int ONETIMEAUTH_FLAG = 0x10; public const int ADDRTYPE_MASK = 0xF; - public const int ONETIMEAUTH_BYTES = 16; - public const int ONETIMEAUTH_KEYBYTES = 32; + public const int ONETIMEAUTH_BYTES = 10; - public const int HASH_BYTES = 4; public const int CLEN_BYTES = 2; - public const int AUTH_BYTES = HASH_BYTES + CLEN_BYTES; + public const int AUTH_BYTES = ONETIMEAUTH_BYTES + CLEN_BYTES; protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE]; @@ -128,7 +126,7 @@ namespace Shadowsocks.Encryption protected abstract void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf); - protected int ss_headlen(byte[] buf, int length) + protected int getHeadLen(byte[] buf, int length) { int len = 0; int atyp = length > 0 ? (buf[0] & ADDRTYPE_MASK) : 0; @@ -150,22 +148,21 @@ namespace Shadowsocks.Encryption return len; } - protected int ss_onetimeauth(byte[] auth, byte[] msg, int msg_len) + protected byte[] genOnetimeAuthHash(byte[] msg, int msg_len) { - byte[] auth_key = new byte[ONETIMEAUTH_KEYBYTES]; - byte[] auth_bytes = new byte[MAX_IV_LENGTH + MAX_KEY_LENGTH]; - Buffer.BlockCopy(_encryptIV, 0, auth_bytes, 0, ivLen); - Buffer.BlockCopy(_key, 0, auth_bytes, ivLen, keyLen); - Sodium.crypto_generichash(auth_key, ONETIMEAUTH_KEYBYTES, auth_bytes, (ulong)(ivLen + keyLen), null, 0); - return Sodium.crypto_onetimeauth(auth, msg, (ulong)msg_len, auth_key); + byte[] auth = new byte[ONETIMEAUTH_BYTES]; + byte[] hash = new byte[20]; + byte[] auth_key = new byte[MAX_IV_LENGTH + MAX_KEY_LENGTH]; + Buffer.BlockCopy(_encryptIV, 0, auth_key, 0, ivLen); + Buffer.BlockCopy(_key, 0, auth_key, ivLen, keyLen); + Sodium.ss_sha1_hmac_ex(auth_key, (uint)(ivLen + keyLen), + msg, 0, (uint)msg_len, hash); + Buffer.BlockCopy(hash, 0, auth, 0, ONETIMEAUTH_BYTES); + return auth; } - protected void ss_gen_hash(byte[] buf, ref int offset, ref int len, int buf_size) + protected void updateKeyBuffer() { - int size = len + AUTH_BYTES; - if (buf_size < (size + offset)) - throw new Exception("failed to generate hash: buffer size insufficient"); - if (_keyBuffer == null) { _keyBuffer = new byte[MAX_IV_LENGTH + 4]; @@ -174,23 +171,19 @@ namespace Shadowsocks.Encryption byte[] counter_bytes = BitConverter.GetBytes((uint)IPAddress.HostToNetworkOrder((int)counter)); Buffer.BlockCopy(counter_bytes, 0, _keyBuffer, ivLen, 4); - - byte[] hash = new byte[HASH_BYTES]; - byte[] tmp = new byte[len]; - Buffer.BlockCopy(buf, offset, tmp, 0, len); - Sodium.crypto_generichash(hash, HASH_BYTES, tmp, (ulong)len, _keyBuffer, (uint)_keyBuffer.Length); - - Buffer.BlockCopy(buf, offset, buf, offset + AUTH_BYTES, len); - Buffer.BlockCopy(hash, 0, buf, offset + CLEN_BYTES, HASH_BYTES); - byte[] clen = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)len)); - Buffer.BlockCopy(clen, 0, buf, offset, CLEN_BYTES); - counter++; - len += AUTH_BYTES; - offset += len; } - public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) + protected byte[] genHash(byte[] buf, int offset, int len) + { + byte[] hash = new byte[20]; + updateKeyBuffer(); + Sodium.ss_sha1_hmac_ex(_keyBuffer, (uint)_keyBuffer.Length, + buf, offset, (uint)len, hash); + return hash; + } + + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp) { if (!_encryptIVSent) { @@ -198,21 +191,32 @@ namespace Shadowsocks.Encryption randBytes(outbuf, ivLen); initCipher(outbuf, true); outlength = length + ivLen; - lock (tempbuf) + if (OnetimeAuth && ivLen > 0) { - if (OnetimeAuth) + if(!udp) + { + int headLen = getHeadLen(buf, length); + int dataLen = length - headLen; + buf[0] |= ONETIMEAUTH_FLAG; + byte[] hash = genOnetimeAuthHash(buf, headLen); + Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen); + Buffer.BlockCopy(hash, 0, buf, headLen, ONETIMEAUTH_BYTES); + hash = genHash(buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen); + Buffer.BlockCopy(hash, 0, buf, headLen + ONETIMEAUTH_BYTES + CLEN_BYTES, ONETIMEAUTH_BYTES); + byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)dataLen)); + Buffer.BlockCopy(lenBytes, 0, buf, headLen + ONETIMEAUTH_BYTES, CLEN_BYTES); + length = headLen + ONETIMEAUTH_BYTES + AUTH_BYTES + dataLen; + } + else { - int headLen = ss_headlen(buf, length); - int len = length - headLen; - Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES, len); buf[0] |= ONETIMEAUTH_FLAG; - byte[] auth = new byte[ONETIMEAUTH_BYTES]; - ss_onetimeauth(auth, buf, headLen); - Buffer.BlockCopy(auth, 0, buf, headLen, ONETIMEAUTH_BYTES); - int offset = headLen + ONETIMEAUTH_BYTES; - ss_gen_hash(buf, ref offset, ref len, buf.Length); - length = headLen + ONETIMEAUTH_BYTES + len; + byte[] hash = genOnetimeAuthHash(buf, length); + Buffer.BlockCopy(hash, 0, buf, length, ONETIMEAUTH_BYTES); + length += ONETIMEAUTH_BYTES; } + } + lock (tempbuf) + { cipherUpdate(true, length, buf, tempbuf); outlength = length + ivLen; Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); @@ -220,10 +224,14 @@ namespace Shadowsocks.Encryption } else { - if (OnetimeAuth) + if (OnetimeAuth && ivLen > 0) { - int offset = 0; - ss_gen_hash(buf, ref offset, ref length, buf.Length); + byte[] hash = genHash(buf, 0, length); + Buffer.BlockCopy(buf, 0, buf, AUTH_BYTES, length); + byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)length)); + Buffer.BlockCopy(lenBytes, 0, buf, 0, CLEN_BYTES); + Buffer.BlockCopy(hash, 0, buf, CLEN_BYTES, ONETIMEAUTH_BYTES); + length += AUTH_BYTES; } outlength = length; cipherUpdate(true, length, buf, outbuf); diff --git a/shadowsocks-csharp/Encryption/Sodium.cs b/shadowsocks-csharp/Encryption/Sodium.cs index a6bc909e..8d690dd2 100755 --- a/shadowsocks-csharp/Encryption/Sodium.cs +++ b/shadowsocks-csharp/Encryption/Sodium.cs @@ -41,15 +41,10 @@ namespace Shadowsocks.Encryption public extern static int crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int crypto_generichash(byte[] outbuf, uint outlen, - byte[] inbuf, ulong inlen, - byte[] key, uint keylen); + public extern static void ss_sha1_hmac_ex(byte[] key, uint keylen, + byte[] input, int ioff, uint ilen, + byte[] output); - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int crypto_onetimeauth(byte[] outbuf, byte[] inbuf, ulong inlen, byte[] k); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int crypto_onetimeauth_verify(byte[] h, byte[] inbuf, ulong inlen, byte[] k); } } diff --git a/shadowsocks-csharp/Encryption/TableEncryptor.cs b/shadowsocks-csharp/Encryption/TableEncryptor.cs index 3de625a6..3f3c5f8c 100644 --- a/shadowsocks-csharp/Encryption/TableEncryptor.cs +++ b/shadowsocks-csharp/Encryption/TableEncryptor.cs @@ -31,7 +31,7 @@ namespace Shadowsocks.Encryption return new List(new string[]{"table"}); } - public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp) { byte[] result = new byte[length]; for (int i = 0; i < length; i++) diff --git a/test/UnitTest.cs b/test/UnitTest.cs index 6003770e..70c001f3 100755 --- a/test/UnitTest.cs +++ b/test/UnitTest.cs @@ -25,27 +25,27 @@ namespace test private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) { byte[] plain = new byte[16384]; - byte[] cipher = new byte[plain.Length + 16]; + byte[] cipher = new byte[plain.Length + 16 + IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES]; byte[] plain2 = new byte[plain.Length + 16]; int outLen = 0; int outLen2 = 0; var random = new Random(); random.NextBytes(plain); - encryptor.Encrypt(plain, plain.Length, cipher, out outLen); + encryptor.Encrypt(plain, plain.Length, cipher, out outLen, false); decryptor.Decrypt(cipher, outLen, plain2, out outLen2); Assert.AreEqual(plain.Length, outLen2); for (int j = 0; j < plain.Length; j++) { Assert.AreEqual(plain[j], plain2[j]); } - encryptor.Encrypt(plain, 1000, cipher, out outLen); + encryptor.Encrypt(plain, 1000, cipher, out outLen, false); decryptor.Decrypt(cipher, outLen, plain2, out outLen2); Assert.AreEqual(1000, outLen2); for (int j = 0; j < outLen2; j++) { Assert.AreEqual(plain[j], plain2[j]); } - encryptor.Encrypt(plain, 12333, cipher, out outLen); + encryptor.Encrypt(plain, 12333, cipher, out outLen, false); decryptor.Decrypt(cipher, outLen, plain2, out outLen2); Assert.AreEqual(12333, outLen2); for (int j = 0; j < outLen2; j++) From 098640e792c6abede23735e45adb25bb7eb9ce9d Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Fri, 25 Sep 2015 04:42:56 -0400 Subject: [PATCH 22/23] refact --- .../Controller/Service/TCPRelay.cs | 4 +- .../Controller/Service/UDPRelay.cs | 6 +- .../Encryption/EncryptorBase.cs | 6 +- .../Encryption/EncryptorFactory.cs | 6 +- shadowsocks-csharp/Encryption/IEncryptor.cs | 2 +- shadowsocks-csharp/Encryption/IVEncryptor.cs | 93 +++++++++++-------- .../Encryption/PolarSSLEncryptor.cs | 4 +- .../Encryption/SodiumEncryptor.cs | 4 +- .../Encryption/TableEncryptor.cs | 6 +- test/UnitTest.cs | 18 ++-- 10 files changed, 85 insertions(+), 64 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index eb676ad2..eef5948c 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -125,7 +125,7 @@ namespace Shadowsocks.Controller { throw new ArgumentException("No server configured"); } - this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.one_time_auth); + this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.one_time_auth, false); this.server = server; } @@ -586,7 +586,7 @@ namespace Shadowsocks.Controller { return; } - encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend, false); + encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend); } remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null); diff --git a/shadowsocks-csharp/Controller/Service/UDPRelay.cs b/shadowsocks-csharp/Controller/Service/UDPRelay.cs index 9d3d3dcf..b449c412 100644 --- a/shadowsocks-csharp/Controller/Service/UDPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/UDPRelay.cs @@ -74,12 +74,12 @@ namespace Shadowsocks.Controller } public void Send(byte[] data, int length) { - IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth); + IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth, true); byte[] dataIn = new byte[length - 3 + IVEncryptor.ONETIMEAUTH_BYTES]; Array.Copy(data, 3, dataIn, 0, length - 3); byte[] dataOut = new byte[length - 3 + 16 + IVEncryptor.ONETIMEAUTH_BYTES]; int outlen; - encryptor.Encrypt(dataIn, length - 3, dataOut, out outlen, true); + encryptor.Encrypt(dataIn, length - 3, dataOut, out outlen); _remote.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint); } public void Receive() @@ -97,7 +97,7 @@ namespace Shadowsocks.Controller byte[] dataOut = new byte[bytesRead]; int outlen; - IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth); + IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth, true); encryptor.Decrypt(_buffer, bytesRead, dataOut, out outlen); byte[] sendBuf = new byte[outlen + 3]; diff --git a/shadowsocks-csharp/Encryption/EncryptorBase.cs b/shadowsocks-csharp/Encryption/EncryptorBase.cs index 594e67bf..8285f165 100644 --- a/shadowsocks-csharp/Encryption/EncryptorBase.cs +++ b/shadowsocks-csharp/Encryption/EncryptorBase.cs @@ -8,16 +8,18 @@ namespace Shadowsocks.Encryption { public const int MAX_INPUT_SIZE = 32768; - protected EncryptorBase(string method, string password, bool onetimeauth) + protected EncryptorBase(string method, string password, bool onetimeauth, bool isudp) { Method = method; Password = password; OnetimeAuth = onetimeauth; + IsUDP = isudp; } protected string Method; protected string Password; protected bool OnetimeAuth; + protected bool IsUDP; protected byte[] GetPasswordHash() { @@ -26,7 +28,7 @@ namespace Shadowsocks.Encryption return hash; } - public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp); + public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength); public abstract void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength); diff --git a/shadowsocks-csharp/Encryption/EncryptorFactory.cs b/shadowsocks-csharp/Encryption/EncryptorFactory.cs index d6c89b9f..f0e2d284 100644 --- a/shadowsocks-csharp/Encryption/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encryption/EncryptorFactory.cs @@ -8,7 +8,7 @@ namespace Shadowsocks.Encryption { private static Dictionary _registeredEncryptors; - private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string), typeof(bool) }; + private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string), typeof(bool), typeof(bool) }; static EncryptorFactory() { @@ -27,7 +27,7 @@ namespace Shadowsocks.Encryption } } - public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth) + public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth, bool isudp) { if (string.IsNullOrEmpty(method)) { @@ -36,7 +36,7 @@ namespace Shadowsocks.Encryption method = method.ToLowerInvariant(); Type t = _registeredEncryptors[method]; ConstructorInfo c = t.GetConstructor(_constructorTypes); - IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password, onetimeauth }); + IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password, onetimeauth, isudp }); return result; } } diff --git a/shadowsocks-csharp/Encryption/IEncryptor.cs b/shadowsocks-csharp/Encryption/IEncryptor.cs index 33ce0816..b45c62c7 100644 --- a/shadowsocks-csharp/Encryption/IEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IEncryptor.cs @@ -6,7 +6,7 @@ namespace Shadowsocks.Encryption { public interface IEncryptor : IDisposable { - void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp); + void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength); void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength); } } diff --git a/shadowsocks-csharp/Encryption/IVEncryptor.cs b/shadowsocks-csharp/Encryption/IVEncryptor.cs index 8af5b9e5..52d1970b 100755 --- a/shadowsocks-csharp/Encryption/IVEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IVEncryptor.cs @@ -40,8 +40,8 @@ namespace Shadowsocks.Encryption protected uint counter = 0; protected byte[] _keyBuffer = null; - public IVEncryptor(string method, string password, bool onetimeauth) - : base(method, password, onetimeauth) + public IVEncryptor(string method, string password, bool onetimeauth, bool isudp) + : base(method, password, onetimeauth, isudp) { InitKey(method, password); } @@ -183,38 +183,65 @@ namespace Shadowsocks.Encryption return hash; } - public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp) + protected void reactBuffer4TCP(byte[] buf, ref int length) + { + if (!_encryptIVSent) + { + int headLen = getHeadLen(buf, length); + int dataLen = length - headLen; + buf[0] |= ONETIMEAUTH_FLAG; + byte[] hash = genOnetimeAuthHash(buf, headLen); + Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen); + Buffer.BlockCopy(hash, 0, buf, headLen, ONETIMEAUTH_BYTES); + hash = genHash(buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen); + Buffer.BlockCopy(hash, 0, buf, headLen + ONETIMEAUTH_BYTES + CLEN_BYTES, ONETIMEAUTH_BYTES); + byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)dataLen)); + Buffer.BlockCopy(lenBytes, 0, buf, headLen + ONETIMEAUTH_BYTES, CLEN_BYTES); + length = headLen + ONETIMEAUTH_BYTES + AUTH_BYTES + dataLen; + } + else + { + byte[] hash = genHash(buf, 0, length); + Buffer.BlockCopy(buf, 0, buf, AUTH_BYTES, length); + byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)length)); + Buffer.BlockCopy(lenBytes, 0, buf, 0, CLEN_BYTES); + Buffer.BlockCopy(hash, 0, buf, CLEN_BYTES, ONETIMEAUTH_BYTES); + length += AUTH_BYTES; + } + } + + protected void reactBuffer4UDP(byte[] buf, ref int length) + { + buf[0] |= ONETIMEAUTH_FLAG; + byte[] hash = genOnetimeAuthHash(buf, length); + Buffer.BlockCopy(hash, 0, buf, length, ONETIMEAUTH_BYTES); + length += ONETIMEAUTH_BYTES; + } + + protected void reactBuffer(byte[] buf, ref int length) + { + if (OnetimeAuth && ivLen > 0) + { + if (!IsUDP) + { + reactBuffer4TCP(buf, ref length); + } + else + { + reactBuffer4UDP(buf, ref length); + } + } + } + + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { if (!_encryptIVSent) { - _encryptIVSent = true; randBytes(outbuf, ivLen); initCipher(outbuf, true); outlength = length + ivLen; - if (OnetimeAuth && ivLen > 0) - { - if(!udp) - { - int headLen = getHeadLen(buf, length); - int dataLen = length - headLen; - buf[0] |= ONETIMEAUTH_FLAG; - byte[] hash = genOnetimeAuthHash(buf, headLen); - Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen); - Buffer.BlockCopy(hash, 0, buf, headLen, ONETIMEAUTH_BYTES); - hash = genHash(buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen); - Buffer.BlockCopy(hash, 0, buf, headLen + ONETIMEAUTH_BYTES + CLEN_BYTES, ONETIMEAUTH_BYTES); - byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)dataLen)); - Buffer.BlockCopy(lenBytes, 0, buf, headLen + ONETIMEAUTH_BYTES, CLEN_BYTES); - length = headLen + ONETIMEAUTH_BYTES + AUTH_BYTES + dataLen; - } - else - { - buf[0] |= ONETIMEAUTH_FLAG; - byte[] hash = genOnetimeAuthHash(buf, length); - Buffer.BlockCopy(hash, 0, buf, length, ONETIMEAUTH_BYTES); - length += ONETIMEAUTH_BYTES; - } - } + reactBuffer(buf, ref length); + _encryptIVSent = true; lock (tempbuf) { cipherUpdate(true, length, buf, tempbuf); @@ -224,15 +251,7 @@ namespace Shadowsocks.Encryption } else { - if (OnetimeAuth && ivLen > 0) - { - byte[] hash = genHash(buf, 0, length); - Buffer.BlockCopy(buf, 0, buf, AUTH_BYTES, length); - byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)length)); - Buffer.BlockCopy(lenBytes, 0, buf, 0, CLEN_BYTES); - Buffer.BlockCopy(hash, 0, buf, CLEN_BYTES, ONETIMEAUTH_BYTES); - length += AUTH_BYTES; - } + reactBuffer(buf, ref length); outlength = length; cipherUpdate(true, length, buf, outbuf); } diff --git a/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs index 3aca3f72..3b3331f9 100755 --- a/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs +++ b/shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs @@ -16,8 +16,8 @@ namespace Shadowsocks.Encryption private IntPtr _encryptCtx = IntPtr.Zero; private IntPtr _decryptCtx = IntPtr.Zero; - public PolarSSLEncryptor(string method, string password, bool onetimeauth) - : base(method, password, onetimeauth) + public PolarSSLEncryptor(string method, string password, bool onetimeauth, bool isudp) + : base(method, password, onetimeauth, isudp) { InitKey(method, password); } diff --git a/shadowsocks-csharp/Encryption/SodiumEncryptor.cs b/shadowsocks-csharp/Encryption/SodiumEncryptor.cs index 8ab8e255..a18d2a69 100755 --- a/shadowsocks-csharp/Encryption/SodiumEncryptor.cs +++ b/shadowsocks-csharp/Encryption/SodiumEncryptor.cs @@ -20,8 +20,8 @@ namespace Shadowsocks.Encryption protected ulong _encryptIC; protected ulong _decryptIC; - public SodiumEncryptor(string method, string password, bool onetimeauth) - : base(method, password, onetimeauth) + public SodiumEncryptor(string method, string password, bool onetimeauth, bool isudp) + : base(method, password, onetimeauth, isudp) { InitKey(method, password); } diff --git a/shadowsocks-csharp/Encryption/TableEncryptor.cs b/shadowsocks-csharp/Encryption/TableEncryptor.cs index 3f3c5f8c..4b6c8fe3 100644 --- a/shadowsocks-csharp/Encryption/TableEncryptor.cs +++ b/shadowsocks-csharp/Encryption/TableEncryptor.cs @@ -6,8 +6,8 @@ namespace Shadowsocks.Encryption public class TableEncryptor : EncryptorBase { - public TableEncryptor(string method, string password, bool onetimeauth) - : base(method, password, onetimeauth) + public TableEncryptor(string method, string password, bool onetimeauth, bool isudp) + : base(method, password, onetimeauth, isudp) { byte[] hash = GetPasswordHash(); // TODO endian @@ -31,7 +31,7 @@ namespace Shadowsocks.Encryption return new List(new string[]{"table"}); } - public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp) + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { byte[] result = new byte[length]; for (int i = 0; i < length; i++) diff --git a/test/UnitTest.cs b/test/UnitTest.cs index 70c001f3..1970e85f 100755 --- a/test/UnitTest.cs +++ b/test/UnitTest.cs @@ -31,21 +31,21 @@ namespace test int outLen2 = 0; var random = new Random(); random.NextBytes(plain); - encryptor.Encrypt(plain, plain.Length, cipher, out outLen, false); + encryptor.Encrypt(plain, plain.Length, cipher, out outLen); decryptor.Decrypt(cipher, outLen, plain2, out outLen2); Assert.AreEqual(plain.Length, outLen2); for (int j = 0; j < plain.Length; j++) { Assert.AreEqual(plain[j], plain2[j]); } - encryptor.Encrypt(plain, 1000, cipher, out outLen, false); + encryptor.Encrypt(plain, 1000, cipher, out outLen); decryptor.Decrypt(cipher, outLen, plain2, out outLen2); Assert.AreEqual(1000, outLen2); for (int j = 0; j < outLen2; j++) { Assert.AreEqual(plain[j], plain2[j]); } - encryptor.Encrypt(plain, 12333, cipher, out outLen, false); + encryptor.Encrypt(plain, 12333, cipher, out outLen); decryptor.Decrypt(cipher, outLen, plain2, out outLen2); Assert.AreEqual(12333, outLen2); for (int j = 0; j < outLen2; j++) @@ -84,8 +84,8 @@ namespace test { IEncryptor encryptor; IEncryptor decryptor; - encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false); - decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false); + encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false, false); + decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false, false); RunEncryptionRound(encryptor, decryptor); } } @@ -124,8 +124,8 @@ namespace test var random = new Random(); IEncryptor encryptor; IEncryptor decryptor; - encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false); - decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false); + encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false, false); + decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false, false); RunEncryptionRound(encryptor, decryptor); } } @@ -164,8 +164,8 @@ namespace test var random = new Random(); IEncryptor encryptor; IEncryptor decryptor; - encryptor = new SodiumEncryptor("salsa20", "barfoo!", false); - decryptor = new SodiumEncryptor("salsa20", "barfoo!", false); + encryptor = new SodiumEncryptor("salsa20", "barfoo!", false, false); + decryptor = new SodiumEncryptor("salsa20", "barfoo!", false, false); RunEncryptionRound(encryptor, decryptor); } } From 5c570fbb56a7c20375aa07659967ff7d1c446129 Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Fri, 25 Sep 2015 21:18:15 +0800 Subject: [PATCH 23/23] disable one-time auth when method is table or rc4 --- .../View/ConfigForm.Designer.cs | 98 ++++++++++--------- shadowsocks-csharp/View/ConfigForm.cs | 13 +++ 2 files changed, 63 insertions(+), 48 deletions(-) diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index a4754918..8c5334d0 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -39,6 +39,7 @@ this.PasswordTextBox = new System.Windows.Forms.TextBox(); this.EncryptionLabel = new System.Windows.Forms.Label(); this.EncryptionSelect = new System.Windows.Forms.ComboBox(); + this.OneTimeAuth = new System.Windows.Forms.CheckBox(); this.panel2 = new System.Windows.Forms.Panel(); this.OKButton = new System.Windows.Forms.Button(); this.MyCancelButton = new System.Windows.Forms.Button(); @@ -55,7 +56,6 @@ this.ProxyPortLabel = new System.Windows.Forms.Label(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); - this.OneTimeAuth = new System.Windows.Forms.CheckBox(); this.tableLayoutPanel1.SuspendLayout(); this.ServerGroupBox.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); @@ -95,16 +95,16 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(238, 160); + this.tableLayoutPanel1.Size = new System.Drawing.Size(249, 162); this.tableLayoutPanel1.TabIndex = 0; // // RemarksTextBox // this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.RemarksTextBox.Location = new System.Drawing.Point(72, 111); + this.RemarksTextBox.Location = new System.Drawing.Point(83, 113); this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; - this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); + this.RemarksTextBox.Size = new System.Drawing.Size(160, 21); this.RemarksTextBox.TabIndex = 4; this.RemarksTextBox.WordWrap = false; // @@ -112,9 +112,9 @@ // this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.RemarksLabel.AutoSize = true; - this.RemarksLabel.Location = new System.Drawing.Point(17, 114); + this.RemarksLabel.Location = new System.Drawing.Point(30, 117); this.RemarksLabel.Name = "RemarksLabel"; - this.RemarksLabel.Size = new System.Drawing.Size(49, 13); + this.RemarksLabel.Size = new System.Drawing.Size(47, 12); this.RemarksLabel.TabIndex = 9; this.RemarksLabel.Text = "Remarks"; // @@ -122,9 +122,9 @@ // this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.IPLabel.AutoSize = true; - this.IPLabel.Location = new System.Drawing.Point(15, 9); + this.IPLabel.Location = new System.Drawing.Point(18, 10); this.IPLabel.Name = "IPLabel"; - this.IPLabel.Size = new System.Drawing.Size(51, 13); + this.IPLabel.Size = new System.Drawing.Size(59, 12); this.IPLabel.TabIndex = 0; this.IPLabel.Text = "Server IP"; // @@ -132,9 +132,9 @@ // this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ServerPortLabel.AutoSize = true; - this.ServerPortLabel.Location = new System.Drawing.Point(6, 35); + this.ServerPortLabel.Location = new System.Drawing.Point(6, 37); this.ServerPortLabel.Name = "ServerPortLabel"; - this.ServerPortLabel.Size = new System.Drawing.Size(60, 13); + this.ServerPortLabel.Size = new System.Drawing.Size(71, 12); this.ServerPortLabel.TabIndex = 1; this.ServerPortLabel.Text = "Server Port"; // @@ -142,40 +142,40 @@ // this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PasswordLabel.AutoSize = true; - this.PasswordLabel.Location = new System.Drawing.Point(13, 61); + this.PasswordLabel.Location = new System.Drawing.Point(24, 64); this.PasswordLabel.Name = "PasswordLabel"; - this.PasswordLabel.Size = new System.Drawing.Size(53, 13); + this.PasswordLabel.Size = new System.Drawing.Size(53, 12); this.PasswordLabel.TabIndex = 2; this.PasswordLabel.Text = "Password"; // // IPTextBox // this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.IPTextBox.Location = new System.Drawing.Point(72, 6); + this.IPTextBox.Location = new System.Drawing.Point(83, 6); this.IPTextBox.MaxLength = 512; this.IPTextBox.Name = "IPTextBox"; - this.IPTextBox.Size = new System.Drawing.Size(160, 20); + this.IPTextBox.Size = new System.Drawing.Size(160, 21); this.IPTextBox.TabIndex = 0; this.IPTextBox.WordWrap = false; // // ServerPortTextBox // this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ServerPortTextBox.Location = new System.Drawing.Point(72, 32); + this.ServerPortTextBox.Location = new System.Drawing.Point(83, 33); this.ServerPortTextBox.MaxLength = 10; this.ServerPortTextBox.Name = "ServerPortTextBox"; - this.ServerPortTextBox.Size = new System.Drawing.Size(160, 20); + this.ServerPortTextBox.Size = new System.Drawing.Size(160, 21); this.ServerPortTextBox.TabIndex = 1; this.ServerPortTextBox.WordWrap = false; // // PasswordTextBox // this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PasswordTextBox.Location = new System.Drawing.Point(72, 58); + this.PasswordTextBox.Location = new System.Drawing.Point(83, 60); this.PasswordTextBox.MaxLength = 256; this.PasswordTextBox.Name = "PasswordTextBox"; this.PasswordTextBox.PasswordChar = '*'; - this.PasswordTextBox.Size = new System.Drawing.Size(160, 20); + this.PasswordTextBox.Size = new System.Drawing.Size(160, 21); this.PasswordTextBox.TabIndex = 2; this.PasswordTextBox.WordWrap = false; // @@ -183,9 +183,9 @@ // this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.EncryptionLabel.AutoSize = true; - this.EncryptionLabel.Location = new System.Drawing.Point(9, 88); + this.EncryptionLabel.Location = new System.Drawing.Point(12, 91); this.EncryptionLabel.Name = "EncryptionLabel"; - this.EncryptionLabel.Size = new System.Drawing.Size(57, 13); + this.EncryptionLabel.Size = new System.Drawing.Size(65, 12); this.EncryptionLabel.TabIndex = 8; this.EncryptionLabel.Text = "Encryption"; // @@ -196,7 +196,7 @@ this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.EncryptionSelect.FormattingEnabled = true; this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.EncryptionSelect.ItemHeight = 13; + this.EncryptionSelect.ItemHeight = 12; this.EncryptionSelect.Items.AddRange(new object[] { "table", "rc4-md5", @@ -206,10 +206,21 @@ "aes-192-cfb", "aes-128-cfb", "rc4"}); - this.EncryptionSelect.Location = new System.Drawing.Point(72, 84); + this.EncryptionSelect.Location = new System.Drawing.Point(83, 87); this.EncryptionSelect.Name = "EncryptionSelect"; - this.EncryptionSelect.Size = new System.Drawing.Size(160, 21); + this.EncryptionSelect.Size = new System.Drawing.Size(160, 20); this.EncryptionSelect.TabIndex = 3; + this.EncryptionSelect.SelectedIndexChanged += new System.EventHandler(this.EncryptionSelect_SelectedIndexChanged); + // + // OneTimeAuth + // + this.OneTimeAuth.AutoSize = true; + this.OneTimeAuth.Location = new System.Drawing.Point(83, 140); + this.OneTimeAuth.Name = "OneTimeAuth"; + this.OneTimeAuth.Size = new System.Drawing.Size(156, 16); + this.OneTimeAuth.TabIndex = 5; + this.OneTimeAuth.Text = "Onetime Authentication"; + this.OneTimeAuth.UseVisualStyleBackColor = true; // // panel2 // @@ -279,7 +290,7 @@ this.ServerGroupBox.Location = new System.Drawing.Point(178, 0); this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Size = new System.Drawing.Size(249, 197); + this.ServerGroupBox.Size = new System.Drawing.Size(260, 200); this.ServerGroupBox.TabIndex = 0; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; @@ -288,6 +299,7 @@ // this.ServersListBox.FormattingEnabled = true; this.ServersListBox.IntegralHeight = false; + this.ServersListBox.ItemHeight = 12; this.ServersListBox.Location = new System.Drawing.Point(0, 0); this.ServersListBox.Margin = new System.Windows.Forms.Padding(0); this.ServersListBox.Name = "ServersListBox"; @@ -315,7 +327,7 @@ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.Size = new System.Drawing.Size(427, 261); + this.tableLayoutPanel2.Size = new System.Drawing.Size(438, 265); this.tableLayoutPanel2.TabIndex = 7; // // tableLayoutPanel6 @@ -328,7 +340,7 @@ this.tableLayoutPanel6.Controls.Add(this.MoveDownButton, 1, 0); this.tableLayoutPanel6.Controls.Add(this.MoveUpButton, 0, 0); this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 229); + this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 233); this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel6.Name = "tableLayoutPanel6"; this.tableLayoutPanel6.RowCount = 1; @@ -371,26 +383,26 @@ this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel5.Controls.Add(this.ProxyPortTextBox, 1, 0); this.tableLayoutPanel5.Controls.Add(this.ProxyPortLabel, 0, 0); - this.tableLayoutPanel5.Location = new System.Drawing.Point(241, 197); + this.tableLayoutPanel5.Location = new System.Drawing.Point(242, 200); this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel5.Name = "tableLayoutPanel5"; this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(3); this.tableLayoutPanel5.RowCount = 1; this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); - this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); - this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); - this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); - this.tableLayoutPanel5.Size = new System.Drawing.Size(186, 32); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F)); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F)); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F)); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F)); + this.tableLayoutPanel5.Size = new System.Drawing.Size(196, 33); this.tableLayoutPanel5.TabIndex = 9; // // ProxyPortTextBox // this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.ProxyPortTextBox.Location = new System.Drawing.Point(67, 6); + this.ProxyPortTextBox.Location = new System.Drawing.Point(77, 6); this.ProxyPortTextBox.MaxLength = 10; this.ProxyPortTextBox.Name = "ProxyPortTextBox"; - this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 20); + this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 21); this.ProxyPortTextBox.TabIndex = 6; this.ProxyPortTextBox.WordWrap = false; // @@ -398,9 +410,9 @@ // this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ProxyPortLabel.AutoSize = true; - this.ProxyPortLabel.Location = new System.Drawing.Point(6, 9); + this.ProxyPortLabel.Location = new System.Drawing.Point(6, 10); this.ProxyPortLabel.Name = "ProxyPortLabel"; - this.ProxyPortLabel.Size = new System.Drawing.Size(55, 13); + this.ProxyPortLabel.Size = new System.Drawing.Size(65, 12); this.ProxyPortLabel.TabIndex = 3; this.ProxyPortLabel.Text = "Proxy Port"; // @@ -415,7 +427,7 @@ this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0); this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; - this.tableLayoutPanel3.Location = new System.Drawing.Point(268, 232); + this.tableLayoutPanel3.Location = new System.Drawing.Point(279, 236); this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; this.tableLayoutPanel3.RowCount = 1; @@ -433,7 +445,7 @@ this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0); this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 197); + this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 200); this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.RowCount = 1; @@ -441,16 +453,6 @@ this.tableLayoutPanel4.Size = new System.Drawing.Size(166, 32); this.tableLayoutPanel4.TabIndex = 8; // - // OneTimeAuth - // - this.OneTimeAuth.AutoSize = true; - this.OneTimeAuth.Location = new System.Drawing.Point(72, 137); - this.OneTimeAuth.Name = "OneTimeAuth"; - this.OneTimeAuth.Size = new System.Drawing.Size(131, 17); - this.OneTimeAuth.TabIndex = 5; - this.OneTimeAuth.Text = "Onetime Authentication"; - this.OneTimeAuth.UseVisualStyleBackColor = true; - // // ConfigForm // this.AcceptButton = this.OKButton; diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index 38bdf1ad..9ae26583 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -322,5 +322,18 @@ namespace Shadowsocks.View MoveConfigItem(+1); // +1 means move forward } } + + private void EncryptionSelect_SelectedIndexChanged(object sender, EventArgs e) + { + if (EncryptionSelect.Text == "rc4" || EncryptionSelect.Text == "table") + { + OneTimeAuth.Enabled = false; + OneTimeAuth.Checked = false; + } + else + { + OneTimeAuth.Enabled = true; + } + } } }