Merge pull request 'Rework Lobby And Use ListViews For Messages' (#6) from lobby-rework into master

Reviewed-on: Moonbase/qtc-net-client#6
This commit is contained in:
Alan Moon 2025-11-15 12:30:43 -08:00
commit 55323321d0
8 changed files with 352 additions and 191 deletions

View File

@ -12,7 +12,6 @@ namespace QtCNETAPI.Services.GatewayService
internal string gwBaseUri = GWUrl; internal string gwBaseUri = GWUrl;
public Room? CurrentRoom { get; private set; } public Room? CurrentRoom { get; private set; }
public bool InLobby { get; private set; }
public HubConnection? HubConnection { get; private set; } public HubConnection? HubConnection { get; private set; }
@ -120,29 +119,18 @@ namespace QtCNETAPI.Services.GatewayService
} }
} }
public async Task JoinLobbyAsync() public async Task JoinRoomAsync(Room? room = null)
{ {
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made."); if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
await HubConnection.SendAsync("JoinLobby", _apiService.CurrentUser); // assume user is trying to join lobby if room is null (does not have db entry)
InLobby = true; room ??= new Room
CurrentRoom = null;
}
public async Task JoinRoomAsync(Room room)
{
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
if (InLobby == true)
{ {
await HubConnection.SendAsync("LeaveLobby", _apiService.CurrentUser); Id = "LOBBY",
InLobby = false; Name = "Lobby"
} };
else if (CurrentRoom != null)
{
await HubConnection.SendAsync("LeaveRoom", _apiService.CurrentUser, CurrentRoom);
}
if (CurrentRoom != null) await HubConnection.SendAsync("LeaveRoom", _apiService.CurrentUser, CurrentRoom);
await HubConnection.SendAsync("JoinRoom", _apiService.CurrentUser, room); await HubConnection.SendAsync("JoinRoom", _apiService.CurrentUser, room);
CurrentRoom = room; CurrentRoom = room;
} }
@ -151,23 +139,15 @@ namespace QtCNETAPI.Services.GatewayService
{ {
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made."); if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
if (InLobby) if (CurrentRoom != null) await HubConnection.SendAsync("LeaveRoom", _apiService.CurrentUser, CurrentRoom);
{ CurrentRoom = null;
await HubConnection.SendAsync("LeaveLobby", _apiService.CurrentUser);
InLobby = false;
}
else
{
await HubConnection.SendAsync("LeaveRoom", _apiService.CurrentUser, CurrentRoom);
CurrentRoom = null;
}
} }
public async Task PostMessageAsync(Message message) public async Task PostMessageAsync(Message message)
{ {
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made."); if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
await HubConnection.SendAsync("SendMessage", _apiService.CurrentUser, message, InLobby, CurrentRoom); await HubConnection.SendAsync("SendMessage", _apiService.CurrentUser, message, CurrentRoom);
} }
public async Task SendDirectMessageAsync(UserInformationDto user, Message message) public async Task SendDirectMessageAsync(UserInformationDto user, Message message)

View File

@ -18,10 +18,7 @@ namespace QtCNETAPI.Services.GatewayService
/// The Current Room The Current User Is In /// The Current Room The Current User Is In
/// </summary> /// </summary>
public Room? CurrentRoom { get; } public Room? CurrentRoom { get; }
/// <summary>
/// Is The User Currently In The Lobby?
/// </summary>
public bool InLobby { get; }
/// <summary> /// <summary>
/// The Current Connection To The Gateway /// The Current Connection To The Gateway
/// </summary> /// </summary>
@ -47,20 +44,13 @@ namespace QtCNETAPI.Services.GatewayService
/// <returns></returns> /// <returns></returns>
public Task DisposeAsync(); public Task DisposeAsync();
/// <summary>
/// Joins The Lobby Of The Server
/// </summary>
/// <returns></returns>
/// <exception cref="InvalidOperationException">Thrown if the function is called before the connection is established.</exception>
public Task JoinLobbyAsync();
/// <summary> /// <summary>
/// Joins The Current User To A Room On The Server /// Joins The Current User To A Room On The Server
/// </summary> /// </summary>
/// <param name="room">Room To Join</param> /// <param name="room">Room To Join</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="InvalidOperationException">Thrown if the function is called before the connection is established.</exception> /// <exception cref="InvalidOperationException">Thrown if the function is called before the connection is established.</exception>
public Task JoinRoomAsync(Room room); public Task JoinRoomAsync(Room? room = null);
/// <summary> /// <summary>
/// Leaves The Current Room The Current User Is In /// Leaves The Current Room The Current User Is In

View File

@ -29,13 +29,16 @@
private void InitializeComponent() private void InitializeComponent()
{ {
components = new System.ComponentModel.Container(); components = new System.ComponentModel.Container();
ListViewItem listViewItem1 = new ListViewItem("TestUser", 1);
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ChatRoom)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ChatRoom));
ListViewItem listViewItem2 = new ListViewItem("TestUser: the quick brown fox jumped over the lazy dog aaaa", 0);
rtxtChatbox = new RichTextBox(); rtxtChatbox = new RichTextBox();
btnSend = new Button(); btnSend = new Button();
rtxtChat = new RichTextBox();
lblRoomName = new Label(); lblRoomName = new Label();
lvUserList = new ListView(); lvUserList = new ListView();
ilStatusIcons = new ImageList(components); ilStatusIcons = new ImageList(components);
lvMessages = new ListView();
ilProfileImages = new ImageList(components);
SuspendLayout(); SuspendLayout();
// //
// rtxtChatbox // rtxtChatbox
@ -59,17 +62,6 @@
btnSend.UseVisualStyleBackColor = true; btnSend.UseVisualStyleBackColor = true;
btnSend.Click += btnSend_Click; btnSend.Click += btnSend_Click;
// //
// rtxtChat
//
rtxtChat.Font = new Font("Segoe UI", 10F);
rtxtChat.HideSelection = false;
rtxtChat.Location = new Point(142, 43);
rtxtChat.Name = "rtxtChat";
rtxtChat.ReadOnly = true;
rtxtChat.Size = new Size(463, 219);
rtxtChat.TabIndex = 3;
rtxtChat.Text = "";
//
// lblRoomName // lblRoomName
// //
lblRoomName.AutoSize = true; lblRoomName.AutoSize = true;
@ -85,6 +77,7 @@
// lvUserList // lvUserList
// //
lvUserList.Alignment = ListViewAlignment.Left; lvUserList.Alignment = ListViewAlignment.Left;
lvUserList.Items.AddRange(new ListViewItem[] { listViewItem1 });
lvUserList.Location = new Point(12, 43); lvUserList.Location = new Point(12, 43);
lvUserList.MultiSelect = false; lvUserList.MultiSelect = false;
lvUserList.Name = "lvUserList"; lvUserList.Name = "lvUserList";
@ -105,15 +98,36 @@
ilStatusIcons.Images.SetKeyName(2, "Away"); ilStatusIcons.Images.SetKeyName(2, "Away");
ilStatusIcons.Images.SetKeyName(3, "DND"); ilStatusIcons.Images.SetKeyName(3, "DND");
// //
// lvMessages
//
lvMessages.Alignment = ListViewAlignment.Left;
lvMessages.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point, 0);
lvMessages.Items.AddRange(new ListViewItem[] { listViewItem2 });
lvMessages.Location = new Point(142, 43);
lvMessages.MultiSelect = false;
lvMessages.Name = "lvMessages";
lvMessages.Size = new Size(463, 219);
lvMessages.SmallImageList = ilProfileImages;
lvMessages.TabIndex = 10;
lvMessages.UseCompatibleStateImageBehavior = false;
lvMessages.View = View.SmallIcon;
//
// ilProfileImages
//
ilProfileImages.ColorDepth = ColorDepth.Depth32Bit;
ilProfileImages.ImageStream = (ImageListStreamer)resources.GetObject("ilProfileImages.ImageStream");
ilProfileImages.TransparentColor = Color.Transparent;
ilProfileImages.Images.SetKeyName(0, "DefaultPFP");
//
// ChatRoom // ChatRoom
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.DodgerBlue; BackColor = Color.DodgerBlue;
ClientSize = new Size(617, 334); ClientSize = new Size(617, 334);
Controls.Add(lvMessages);
Controls.Add(lvUserList); Controls.Add(lvUserList);
Controls.Add(lblRoomName); Controls.Add(lblRoomName);
Controls.Add(rtxtChat);
Controls.Add(btnSend); Controls.Add(btnSend);
Controls.Add(rtxtChatbox); Controls.Add(rtxtChatbox);
FormBorderStyle = FormBorderStyle.FixedSingle; FormBorderStyle = FormBorderStyle.FixedSingle;
@ -131,9 +145,10 @@
#endregion #endregion
private RichTextBox rtxtChatbox; private RichTextBox rtxtChatbox;
private Button btnSend; private Button btnSend;
private RichTextBox rtxtChat;
private Label lblRoomName; private Label lblRoomName;
private ListView lvUserList; private ListView lvUserList;
private ImageList ilStatusIcons; private ImageList ilStatusIcons;
private ListView lvMessages;
private ImageList ilProfileImages;
} }
} }

View File

@ -1,38 +1,62 @@
using qtc_net_client_2.Services; using qtc_net_client_2.Services;
using QtCNETAPI.Dtos.User;
using QtCNETAPI.Events; using QtCNETAPI.Events;
using QtCNETAPI.Models;
using QtCNETAPI.Services.ApiService; using QtCNETAPI.Services.ApiService;
using QtCNETAPI.Services.GatewayService; using QtCNETAPI.Services.GatewayService;
using System.Threading.Tasks;
namespace qtc_net_client_2.Forms namespace qtc_net_client_2.Forms
{ {
public partial class ChatRoom : Form public partial class ChatRoom : Form
{ {
IGatewayService _gatewayService; private readonly IGatewayService _gatewayService;
IApiService _apiService; private readonly IApiService _apiService;
AudioService AudioService = new(); private readonly AudioService AudioService = new();
public ChatRoom(IGatewayService gatewayService, IApiService apiService) private readonly List<User> RoomUserList = new();
private Room? Room;
public ChatRoom(IGatewayService gatewayService, IApiService apiService, Room? room = null)
{ {
_gatewayService = gatewayService; _gatewayService = gatewayService;
_apiService = apiService; _apiService = apiService;
InitializeComponent(); Room = room;
}
private void frmChat_Load(object sender, EventArgs e)
{
// subscribe to server message event // subscribe to server message event
_gatewayService.OnRoomMessageReceived += _gatewayService_OnServerMessageReceived; _gatewayService.OnRoomMessageReceived += _gatewayService_OnServerMessageReceived;
_gatewayService.OnRoomUserListReceived += _gatewayService_OnRoomUserListReceived; _gatewayService.OnRoomUserListReceived += _gatewayService_OnRoomUserListReceived;
_gatewayService.OnRoomDeleted += _gatewayService_OnRoomDeleted; _gatewayService.OnRoomDeleted += _gatewayService_OnRoomDeleted;
_gatewayService.OnGuestUserJoin += _gatewayService_OnGuestUserJoin; _gatewayService.OnGuestUserJoin += _gatewayService_OnGuestUserJoin;
if (_gatewayService.CurrentRoom != null) { Text = $"QtC.NET Client - Chat Room - {_gatewayService.CurrentRoom.Name}"; lblRoomName.Text = _gatewayService.CurrentRoom.Name; } InitializeComponent();
else if (_gatewayService.InLobby) { Text = $"QtC.NET Client - Chat Room - Lobby"; lblRoomName.Text = "Lobby"; } }
private async void frmChat_Load(object sender, EventArgs e)
{
if (Room == null)
{
// join lobby
await _gatewayService.JoinRoomAsync();
Room = new Room
{
Id = "LOBBY",
Name = "Lobby"
};
}
else
{
// join selected room
await _gatewayService.JoinRoomAsync(Room);
}
// init ui
Text = $"QtC.NET Client - Chat Room - {Room.Name}";
lblRoomName.Text = Room.Name;
RoomUserList.Clear();
lvUserList.Clear(); lvUserList.Clear();
lvMessages.Clear();
// always add current user to list i guess
lvUserList.Items.Add(_apiService.CurrentUser.Username, _apiService.CurrentUser.Status);
} }
private async void frmChat_FormClosing(object sender, FormClosingEventArgs e) private async void frmChat_FormClosing(object sender, FormClosingEventArgs e)
@ -41,7 +65,7 @@ namespace qtc_net_client_2.Forms
_gatewayService.OnRoomMessageReceived -= _gatewayService_OnServerMessageReceived; _gatewayService.OnRoomMessageReceived -= _gatewayService_OnServerMessageReceived;
_gatewayService.OnRoomUserListReceived -= _gatewayService_OnRoomUserListReceived; _gatewayService.OnRoomUserListReceived -= _gatewayService_OnRoomUserListReceived;
if (_gatewayService.CurrentRoom != null || _gatewayService.InLobby) if (_gatewayService.CurrentRoom != null)
{ {
// leave any room user is in // leave any room user is in
await _gatewayService.LeaveRoomAsync(); await _gatewayService.LeaveRoomAsync();
@ -57,7 +81,7 @@ namespace qtc_net_client_2.Forms
// send it and clear text box // send it and clear text box
await _gatewayService.PostMessageAsync(message); await _gatewayService.PostMessageAsync(message);
rtxtChatbox.Clear(); rtxtChatbox.Text = string.Empty;
AudioService.PlaySoundEffect("sndSendClick"); AudioService.PlaySoundEffect("sndSendClick");
} }
} }
@ -101,11 +125,12 @@ namespace qtc_net_client_2.Forms
} }
} }
private void _gatewayService_OnServerMessageReceived(object? sender, EventArgs e) private async void _gatewayService_OnServerMessageReceived(object? sender, EventArgs e)
{ {
var msgEventArgs = (ServerMessageEventArgs)e; var msgEventArgs = (ServerMessageEventArgs)e;
var user = RoomUserList.FirstOrDefault(e => e.Username == msgEventArgs.Message.Split(':')[0]);
AddMessage(msgEventArgs.Message); AddMessage(msgEventArgs.Message, user?.Id);
if (!msgEventArgs.Message.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage"); if (!msgEventArgs.Message.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage");
} }
@ -115,12 +140,23 @@ namespace qtc_net_client_2.Forms
if (IsHandleCreated && !IsDisposed) if (IsHandleCreated && !IsDisposed)
{ {
Invoke(delegate () Invoke(async delegate ()
{ {
RoomUserList.Clear();
lvUserList.Clear(); lvUserList.Clear();
foreach (var user in args.UserList) foreach (var user in args.UserList)
{ {
lvUserList.Items.Add(user.Username, user.Status); lvUserList.Items.Add(user.Username, user.Status);
RoomUserList.Add(user);
// TODO - probably do this only when a message is received (requires response model change)
var pfpRes = await _apiService.GetUserProfilePic(user.Id);
if(pfpRes != null && pfpRes.Success && pfpRes.Data != null)
{
using var ms = new MemoryStream(pfpRes.Data);
using var bmp = new Bitmap(ms);
ilProfileImages.Images.Add(user.Id, bmp);
}
} }
}); });
} }
@ -139,6 +175,7 @@ namespace qtc_net_client_2.Forms
{ {
AddMessage($"[SERVER] This Room Was Deleted By An Admin."); AddMessage($"[SERVER] This Room Was Deleted By An Admin.");
lvUserList.Clear(); lvUserList.Clear();
RoomUserList.Clear();
lvUserList.Enabled = false; lvUserList.Enabled = false;
rtxtChatbox.Enabled = false; rtxtChatbox.Enabled = false;
@ -148,13 +185,13 @@ namespace qtc_net_client_2.Forms
} }
private void AddMessage(string message) private void AddMessage(string message, string? userId = null)
{ {
if(IsHandleCreated && !IsDisposed) if(IsHandleCreated && !IsDisposed)
{ {
Invoke(delegate () Invoke(delegate ()
{ {
rtxtChat.AppendText(message + Environment.NewLine); lvMessages.Items.Add(message, userId ?? "DefaultPfp");
}); });
} }
} }

View File

@ -124,93 +124,219 @@
<value> <value>
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA+hMAAAJNU0Z0AUkBTAIBAQQB SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAuhMAAAJNU0Z0AUkBTAIBAQQB
AAHAAQABwAEAARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/ AAEQAQEBEAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AC4AAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AC4AAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B
0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYB 0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYB
BwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekD BwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekD
YAHoA10B0QNQAZ8DMQFNAwUBBhQAAyABLQNUAasDWwHkA1UB9QMkAfsDPAH+AzwB/gMkAfsDUwH0A2IB YAHoA10B0QNQAZ8DMQFNAwUBBhQAAyABLQNUAasDWwHkA1oB9QMkAfsDRgH+A0YB/gMkAfsDUwH0A2IB
4QNRAaEDHgEqEAADIAEtA1QBqwNbAeQBSwFaAUsB9QEhAVgBIQH7ARgBWAEYAf4BGAFYARgB/gEhAVgB 4QNRAaEDHgEqEAADIAEtA1QBqwNbAeQBWQFaAVkB9QEhAV4BIQH7ASIBYgEiAf4BIgFiASIB/gEhAV4B
IQH7A1MB9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkAUsCWgH1ASECWAH7ARgCWAH+ARgCWAH+ASEC IQH7A1MB9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkAVkCWgH1ASECXgH7ASICYgH+ASICYgH+ASEC
WAH7A1MB9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkAksBWgH1AiEBWAH7AhgBWAH+AhgBWAH+AiEB XgH7A1MB9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkAlkBWgH1AiEBXgH7AiIBYgH+AiIBYgH+AiEB
WAH7A1MB9ANiAeEDUQGhAx4BKgwAAxsBJQNYAb0DWgHyA0AB/gMwAf8DOQH/AzwB/wM2Af8DKgH/AyQB XgH7A1MB9ANiAeEDUQGhAx4BKgwAAxsBJQNYAb0DWgHyA0oB/gMwAf8DOQH/AzwB/wM2Af8DKgH/AyQB
/wNAAf0DXgHwA1YBsgMaASMIAAMbASUDWAG9A1oB8gEYAWABGAH+AQABVwEAAf8BAAFnAQAB/wEAAWwB /wNAAf0DXgHwA1YBsgMaASMIAAMbASUDWAG9A1oB8gEiAWoBIgH+AQABVwEAAf8BAAFnAQAB/wEAAWwB
AAH/AQABYQEAAf8BAAFMAQAB/wEAAUABAAH/ATABQAEwAf0BWgFeAVoB8ANWAbIBGQEaARkBIwgAAxsB AAH/AQABYQEAAf8BAAFMAQAB/wEAAUABAAH/A0AB/QNeAfADVgGyARkBGgEZASMIAAMbASUDWAG9A1oB
JQNYAb0DWgHyARgCYAH+AQACVwH/AQACZwH/AQACbAH/AQACYQH/AQACTAH/AQACQAH/ATACQAH9AVoC 8gEiAmoB/gEAAlcB/wEAAmcB/wEAAmwB/wEAAmEB/wEAAkwB/wEAAkAB/wNAAf0DXgHwA1YBsgEZAhoB
XgHwA1YBsgEZAhoBIwgAAxsBJQNYAb0DWgHyAhgBYAH+AgABVwH/AgABZwH/AgABbAH/AgABYQH/AgAB IwgAAxsBJQNYAb0DWgHyAiIBagH+AgABVwH/AgABZwH/AgABbAH/AgABYQH/AgABTAH/AgABQAH/A0AB
TAH/AgABQAH/AjABQAH9AloBXgHwA1YBsgIZARoBIwQAAwMBBANSAaUDYAHzA0kB/wNVAf8DZQH/A3EB /QNeAfADVgGyAhkBGgEjBAADAwEEA1IBpQNgAfMDSQH/A1UB/wNlAf8DcQH/A3UB/wNxAf8DZAH/A0wB
/wN1Af8DcQH/A2QB/wNMAf8DMQH/AzwB/gNiAe4DUAGaAwMBBAMDAQQBUgFTAVIBpQFWAW8BVgHzAQAB /wMxAf8DRgH+A2IB7gNQAZoDAwEEAwMBBAFSAVMBUgGlAWABbwFgAfMBAAGCAQAB/wEAAZkBAAH/AQAB
ggEAAf8BAAGZAQAB/wEAAbYBAAH/AQABzAEAAf8BAAHTAQAB/wEAAcsBAAH/AQABswEAAf8BAAGIAQAB tgEAAf8BAAHMAQAB/wEAAdMBAAH/AQABywEAAf8BAAGzAQAB/wEAAYgBAAH/AQABVwEAAf8BIgFiASIB
/wEAAVcBAAH/ARgBWAEYAf4BXwFiAV8B7gNQAZoDAwEEAwMBBAFSAlMBpQFWAm8B8wEAAoIB/wEAApkB /gNiAe4DUAGaAwMBBAMDAQQBUgJTAaUBYAJvAfMBAAKCAf8BAAKZAf8BAAK2Af8BAALMAf8BAALTAf8B
/wEAArYB/wEAAswB/wEAAtMB/wEAAssB/wEAArMB/wEAAogB/wEAAlcB/wEYAlgB/gFfAmIB7gNQAZoD AALLAf8BAAKzAf8BAAKIAf8BAAJXAf8BIgJiAf4DYgHuA1ABmgMDAQQDAwEEAlIBUwGlAmABbwHzAgAB
AwEEAwMBBAJSAVMBpQJWAW8B8wIAAYIB/wIAAZkB/wIAAbYB/wIAAcwB/wIAAdMB/wIAAcsB/wIAAbMB ggH/AgABmQH/AgABtgH/AgABzAH/AgAB0wH/AgABywH/AgABswH/AgABiAH/AgABVwH/AiIBYgH+A2IB
/wIAAYgB/wIAAVcB/wIYAVgB/gJfAWIB7gNQAZoDAwEEAy0BRANgAegDewH+A24B/wN7Af8DhQH/A4oB 7gNQAZoDAwEEAy0BRANgAegDgAH+A24B/wN7Af8DhQH/A4oB/wOMAf8DigH/A4UB/wN2Af8DVwH/AzIB
/wOMAf8DigH/A4UB/wN2Af8DVwH/AzIB/wNAAf0DXgHdAyoBPwMtAUQBYAFpAWAB6AEYAYQBGAH+AQAB /wNAAf0DXgHdAyoBPwMtAUQBYAFpAWAB6AEiAYABIgH+AQABxgEAAf8BAAHcAQAB/wEAAe4BAAH/AQAB
xgEAAf8BAAHcAQAB/wEAAe4BAAH/AQAB+AEAAf8BAAH7AQAB/wEAAfkBAAH/AQAB7wEAAf8BAAHUAQAB +AEAAf8BAAH7AQAB/wEAAfkBAAH/AQAB7wEAAf8BAAHUAQAB/wEAAZwBAAH/AQABWgEAAf8DQAH9A14B
/wEAAZwBAAH/AQABWgEAAf8BMAFAATAB/QNeAd0DKgE/Ay0BRAFgAmkB6AEYAoQB/gEAAsYB/wEAAtwB 3QMqAT8DLQFEAWACaQHoASICgAH+AQACxgH/AQAC3AH/AQAC7gH/AQAC+AH/AQAC+wH/AQAC+QH/AQAC
/wEAAu4B/wEAAvgB/wEAAvsB/wEAAvkB/wEAAu8B/wEAAtQB/wEAApwB/wEAAloB/wEwAkAB/QNeAd0D 7wH/AQAC1AH/AQACnAH/AQACWgH/A0AB/QNeAd0DKgE/Ay0BRAJgAWkB6AIiAYAB/gIAAcYB/wIAAdwB
KgE/Ay0BRAJgAWkB6AIYAYQB/gIAAcYB/wIAAdwB/wIAAe4B/wIAAfgB/wIAAfsB/wIAAfkB/wIAAe8B /wIAAe4B/wIAAfgB/wIAAfsB/wIAAfkB/wIAAe8B/wIAAdQB/wIAAZwB/wIAAVoB/wNAAf0DXgHdAyoB
/wIAAdQB/wIAAZwB/wIAAVoB/wIwAUAB/QNeAd0DKgE/A04BlQN3AfgDfwH/A4UB/wOKAf8DjQH/A44B PwNOAZUDdwH4A38B/wOFAf8DigH/A40B/wOOAf8DjgH/A44B/wONAf8DiQH/A3cB/wNNAf8DJQH/A1oB
/wOOAf8DjgH/A40B/wOJAf8DdwH/A00B/wMlAf8DWgHyA0oBiwNOAZUBQgGBAUIB+AEAAeUBAAH/AQAB 8gNKAYsDTgGVAU8BfAFPAfgBAAHlAQAB/wEAAe8BAAH/AQAB+AEAAf8BAAH9AQAB/wEAAf8BAAH/AQAB
7wEAAf8BAAH4AQAB/wEAAf0BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/gEAAf8BAAH2AQAB /wEAAf8BAAH/AQAB/wEAAf4BAAH/AQAB9gEAAf8BAAHVAQAB/wEAAYsBAAH/AQABQQEAAf8DWgHyA0oB
/wEAAdUBAAH/AQABiwEAAf8BAAFBAQAB/wNaAfIDSgGLA04BlQFCAoEB+AEAAuUB/wEAAu8B/wEAAvgB iwNOAZUBTwJ8AfgBAALlAf8BAALvAf8BAAL4Af8BAAL9Af8BAAP/AQAD/wEAA/8BAAL+Af8BAAL2Af8B
/wEAAv0B/wEAA/8BAAP/AQAD/wEAAv4B/wEAAvYB/wEAAtUB/wEAAosB/wEAAkEB/wNaAfIDSgGLA04B AALVAf8BAAKLAf8BAAJBAf8DWgHyA0oBiwNOAZUCTwF8AfgCAAHlAf8CAAHvAf8CAAH4Af8CAAH9Af8C
lQJCAYEB+AIAAeUB/wIAAe8B/wIAAfgB/wIAAf0B/wIAAv8CAAL/AgAC/wIAAf4B/wIAAfYB/wIAAdUB AAL/AgAC/wIAAv8CAAH+Af8CAAH2Af8CAAHVAf8CAAGLAf8CAAFBAf8DWgHyA0oBiwNfAdMDfgH8A5MB
/wIAAYsB/wIAAUEB/wNaAfIDSgGLA18B0wN+AfwDkwH/A44B/wONAf8DjgH/A44B/wOOAf8DjgH/A44B /wOOAf8DjQH/A44B/wOOAf8DjgH/A44B/wOOAf8DjQH/A4UB/wNnAf8DNAH/A0EB+QNaAcQBWwFfAVsB
/wONAf8DhQH/A2cB/wM0Af8DQQH5A1oBxAFbAV8BWwHTASsBsAErAfwBDgH7AQ4B/wEDAf0BAwH/AQAB 0wErAZUBKwH8AQ4B+wEOAf8BAwH9AQMB/wEAAf4BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
/gEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/QEAAf8BAAHvAQAB /wEAAf8BAAH/AQAB/wEAAf0BAAH/AQAB7wEAAf8BAAG5AQAB/wEAAV0BAAH/A0EB+QNaAcQBWwJfAdMB
/wEAAbkBAAH/AQABXQEAAf8DQQH5A1oBxAFbAl8B0wErArAB/AEOAvsB/wEDAv0B/wEAAv4B/wEAA/8B KwKVAfwBDgL7Af8BAwL9Af8BAAL+Af8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAAv0B/wEAAu8B/wEAArkB
AAP/AQAD/wEAA/8BAAP/AQAC/QH/AQAC7wH/AQACuQH/AQACXQH/A0EB+QNaAcQCWwFfAdMCKwGwAfwC /wEAAl0B/wNBAfkDWgHEAlsBXwHTAisBlQH8Ag4B+wH/AgMB/QH/AgAB/gH/AgAC/wIAAv8CAAL/AgAC
DgH7Af8CAwH9Af8CAAH+Af8CAAL/AgAC/wIAAv8CAAL/AgAC/wIAAf0B/wIAAe8B/wIAAbkB/wIAAV0B /wIAAv8CAAH9Af8CAAHvAf8CAAG5Af8CAAFdAf8DQQH5A1oBxANuAfUDgAH+A58B/wOTAf8DjwH/A44B
/wNBAfkDWgHEA24B9QOAAf4DnwH/A5MB/wOPAf8DjgH/A44B/wOOAf8DjgH/A44B/wOOAf8DiwH/A3cB /wOOAf8DjgH/A44B/wOOAf8DjgH/A4sB/wN3Af8DSAH/A0AB/QNiAeEBWgFuAVoB9QFGAbsBRgH+AScB
/wNIAf8DQAH9A2IB4QFTAXYBUwH1ATwBzwE8Af4BJwH/AScB/wELAf8BCwH/AQEB/wEBAf8BAAH/AQAB /wEnAf8BCwH/AQsB/wEBAf8BAQH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH5AQAB/wEAAdYBAAH/AQAB /wEAAf8BAAH/AQAB+QEAAf8BAAHWAQAB/wEAAYEBAAH/A0AB/QNiAeEBWgJuAfUBRgK7Af4BJwP/AQsD
gQEAAf8BMAFAATAB/QNiAeEBUwJ2AfUBPALPAf4BJwP/AQsD/wEBA/8BAAP/AQAD/wEAA/8BAAP/AQAD /wEBA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAL5Af8BAALWAf8BAAKBAf8DQAH9A2IB4QJaAW4B
/wEAA/8BAAL5Af8BAALWAf8BAAKBAf8BMAJAAf0DYgHhAlMBdgH1AjwBzwH+AicC/wILAv8CAQL/AgAC 9QJGAbsB/gInAv8CCwL/AgEC/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAC/wIAAfkB/wIAAdYB/wIAAYEB
/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAB+QH/AgAB1gH/AgABgQH/AjABQAH9A2IB4QNtAfYDgAH+A6sB /wNAAf0DYgHhA2MB9gOAAf4DqwH/A5kB/wOQAf8DjgH/A44B/wOOAf8DjgH/A44B/wOOAf8DjQH/A38B
/wOZAf8DkAH/A44B/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B/wN/Af8DVQH/A0AB/QNeAeIBSAF6AUgB /wNVAf8DQAH9A14B4gFIAW8BSAH2AWkBuwFpAf4BQgH/AUIB/wEZAf8BGQH/AQQB/wEEAf8BAAH/AQAB
9gFfAc8BXwH+AUIB/wFCAf8BGQH/ARkB/wEEAf8BBAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB /wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH9AQAB/wEAAeQBAAH/AQAB
/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/QEAAf8BAAHkAQAB/wEAAZgBAAH/ATABQAEwAf0DXgHiAUgC mAEAAf8DQAH9A14B4gFIAm8B9gFpArsB/gFCA/8BGQP/AQQD/wEAA/8BAAP/AQAD/wEAA/8BAAP/AQAD
egH2AV8CzwH+AUID/wEZA/8BBAP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAP/AQAC/QH/AQAC5AH/AQAC /wEAAv0B/wEAAuQB/wEAApgB/wNAAf0DXgHiAkgBbwH2AmkBuwH+AkIC/wIZAv8CBAL/AgAC/wIAAv8C
mAH/ATACQAH9A14B4gJIAXoB9gJfAc8B/gJCAv8CGQL/AgQC/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAC AAL/AgAC/wIAAv8CAAL/AgAB/QH/AgAB5AH/AgABmAH/A0AB/QNeAeIDYQHWA34B/AO4Af8DowH/A5MB
/wIAAf0B/wIAAeQB/wIAAZgB/wIwAUAB/QNeAeIDYQHWA34B/AO4Af8DowH/A5MB/wOOAf8DjgH/A44B /wOOAf8DjgH/A44B/wOOAf8DjgH/A44B/wONAf8DggH/A1wB/wNNAfoDWgHHAVwBYQFcAdYBZAGbAWQB
/wOOAf8DjgH/A44B/wONAf8DggH/A1wB/wNNAfoDWgHHAVwBYQFcAdYBZAG0AWQB/AFfAf8BXwH/AS8B /AFfAf8BXwH/AS8B/wEvAf8BDAH/AQwB/wEBAf8BAQH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
/wEvAf8BDAH/AQwB/wEBAf8BAQH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB /wEAAf8BAAH/AQAB/wEAAf4BAAH/AQAB6gEAAf8BAAGlAQAB/wE4AU0BOAH6A1oBxwFcAmEB1gFkApsB
/wEAAf4BAAH/AQAB6gEAAf8BAAGlAQAB/wEsAU0BLAH6A1oBxwFcAmEB1gFkArQB/AFfA/8BLwP/AQwD /AFfA/8BLwP/AQwD/wEBA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAAv4B/wEAAuoB/wEAAqUB/wE4Ak0B
/wEBA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAAv4B/wEAAuoB/wEAAqUB/wEsAk0B+gNaAccCXAFhAdYC +gNaAccCXAFhAdYCZAGbAfwCXwL/Ai8C/wIMAv8CAQL/AgAC/wIAAv8CAAL/AgAC/wIAAv8CAAH+Af8C
ZAG0AfwCXwL/Ai8C/wIMAv8CAQL/AgAC/wIAAv8CAAL/AgAC/wIAAv8CAAH+Af8CAAHqAf8CAAGlAf8C AAHqAf8CAAGlAf8COAFNAfoDWgHHA1ABmgN9AfkDxQH/A7IB/wOcAf8DkQH/A44B/wOOAf8DjgH/A44B
LAFNAfoDWgHHA1ABmgOIAfkDxQH/A7IB/wOcAf8DkQH/A44B/wOOAf8DjgH/A44B/wOPAf8DjgH/A4MB /wOPAf8DjgH/A4MB/wNgAf8DWgHyA0wBkANQAZoBagGHAWoB+QF8Af8BfAH/AVEB/wFRAf8BHwH/AR8B
/wNgAf8DWgHyA0wBkANQAZoBagGRAWoB+QF8Af8BfAH/AVEB/wFRAf8BHwH/AR8B/wEHAf8BBwH/AQEB /wEHAf8BBwH/AQEB/wEBAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAgH/AQIB/wECAf4BAgH/AQAB
/wEBAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAgH/AQIB/wECAf4BAgH/AQAB6wEAAf8BAAGtAQAB 6wEAAf8BAAGtAQAB/wFaAWsBWgHyA0wBkANQAZoBagKHAfkBfAP/AVED/wEfA/8BBwP/AQED/wEAA/8B
/wFaAWsBWgHyA0wBkANQAZoBagKRAfkBfAP/AVED/wEfA/8BBwP/AQED/wEAA/8BAAP/AQAD/wECA/8B AAP/AQAD/wECA/8BAgL+Af8BAALrAf8BAAKtAf8BWgJrAfIDTAGQA1ABmgJqAYcB+QJ8Av8CUQL/Ah8C
AgL+Af8BAALrAf8BAAKtAf8BWgJrAfIDTAGQA1ABmgJqAZEB+QJ8Av8CUQL/Ah8C/wIHAv8CAQL/AgAC /wIHAv8CAQL/AgAC/wIAAv8CAAL/AgIC/wICAf4B/wIAAesB/wIAAa0B/wJaAWsB8gNMAZADLwFJA2wB
/wIAAv8CAAL/AgIC/wICAf4B/wIAAesB/wIAAa0B/wJaAWsB8gNMAZADLwFJA2wB6wOgAf4DxgH/A64B 6wOMAf4DxgH/A64B/wOcAf8DkwH/A5AB/wOPAf8DkAH/A5MB/wOTAf8DhQH/A0QB/QNgAeADLQFFAy8B
/wOcAf8DkwH/A5AB/wOPAf8DkAH/A5MB/wOTAf8DhQH/A04B/QNgAeADLQFFAy8BSQNsAesBgAHPAYAB SQNsAesBgAG7AYAB/gF/Af8BfwH/AUkB/wFJAf8BHwH/AR8B/wEMAf8BDAH/AQUB/wEFAf8BAwH/AQMB
/gF/Af8BfwH/AUkB/wFJAf8BHwH/AR8B/wEMAf8BDAH/AQUB/wEFAf8BAwH/AQMB/wEFAf8BBQH/AQoB /wEFAf8BBQH/AQoB/wEKAf8BCgH+AQoB/wEBAe0BAQH/AUABtgFAAf0BYAFmAWAB4AMtAUUDLwFJA2wB
/wEKAf8BCgH+AQoB/wEBAe0BAQH/ATABtgEwAf0BYAFmAWAB4AMtAUUDLwFJA2wB6wGAAs8B/gF/A/8B 6wGAArsB/gF/A/8BSQP/AR8D/wEMA/8BBQP/AQMD/wEFA/8BCgP/AQoC/gH/AQEC7QH/AUACtgH9AWAC
SQP/AR8D/wEMA/8BBQP/AQMD/wEFA/8BCgP/AQoC/gH/AQEC7QH/ATACtgH9AWACZgHgAy0BRQMvAUkD ZgHgAy0BRQMvAUkDbAHrAoABuwH+An8C/wJJAv8CHwL/AgwC/wIFAv8CAwL/AgUC/wIKAv8CCgH+Af8C
bAHrAoABzwH+An8C/wJJAv8CHwL/AgwC/wIFAv8CAwL/AgUC/wIKAv8CCgH+Af8CAQHtAf8CMAG2Af0C AQHtAf8CQAG2Af0CYAFmAeADLQFFAwMBBANWAa4DbgH1A9kB/wPLAf8DtwH/A6cB/wOdAf8DmgH/A5wB
YAFmAeADLQFFAwMBBANWAa4DcAH1A9kB/wPLAf8DtwH/A6cB/wOdAf8DmgH/A5wB/wOfAf8DmwH/A4kB /wOfAf8DmwH/A4kB/wNoAfADUgGjAwMBBAMDAQQDVgGuA24B9QGoAf8BqAH/AYkB/wGJAf8BXAH/AVwB
/wNoAfADUgGjAwMBBAMDAQQDVgGuAW4BdgFuAfUBqAH/AagB/wGJAf8BiQH/AVwB/wFcAf8BNwH/ATcB /wE3Af8BNwH/ASIB/wEiAf8BGwH/ARsB/wEfAf8BHwH/ASYB/wEmAf8BHQH/AR0B/wEFAfMBBQH/AV4B
/wEiAf8BIgH/ARsB/wEbAf8BHwH/AR8B/wEmAf8BJgH/AR0B/wEdAf8BBQHzAQUB/wFaAWgBWgHwA1IB aAFeAfADUgGjAwMBBAMDAQQDVgGuA24B9QGoA/8BiQP/AVwD/wE3A/8BIgP/ARsD/wEfA/8BJgP/AR0D
owMDAQQDAwEEA1YBrgFuAnYB9QGoA/8BiQP/AVwD/wE3A/8BIgP/ARsD/wEfA/8BJgP/AR0D/wEFAvMB /wEFAvMB/wFeAmgB8ANSAaMDAwEEAwMBBANWAa4DbgH1AqgC/wKJAv8CXAL/AjcC/wIiAv8CGwL/Ah8C
/wFaAmgB8ANSAaMDAwEEAwMBBANWAa4CbgF2AfUCqAL/AokC/wJcAv8CNwL/AiIC/wIbAv8CHwL/AiYC /wImAv8CHQL/AgUB8wH/Al4BaAHwA1IBowMDAQQEAAMcAScDXQHHA2kB9gObAf4D1wH/A8wB/wPCAf8D
/wIdAv8CBQHzAf8CWgFoAfADUgGjAwMBBAQAAxwBJwNdAccDdwH2A68B/gPXAf8DzAH/A8IB/wO7Af8D uwH/A7cB/wOxAf8DgAH+A2gB9ANZAbwDGwEmCAADHAEnA10BxwFjAW8BYwH2AYABuwGAAf4BpQH/AaUB
twH/A7EB/wOAAf4DaAH0A1kBvAMbASYIAAMcAScDXQHHAXIBegFyAfYBhwHPAYcB/gGlAf8BpQH/AYsB /wGLAf8BiwH/AXQB/wF0Af8BZgH/AWYB/wFcAf8BXAH/AU4B/wFOAf8BUgG7AVIB/gFTAWgBUwH0AVcB
/wGLAf8BdAH/AXQB/wFmAf8BZgH/AVwB/wFcAf8BTgH/AU4B/wFIAc8BSAH+AVMBdwFTAfQBVwFZAVcB WQFXAbwDGwEmCAADHAEnA10BxwFjAm8B9gGAArsB/gGlA/8BiwP/AXQD/wFmA/8BXAP/AU4D/wFSArsB
vAMbASYIAAMcAScDXQHHAXICegH2AYcCzwH+AaUD/wGLA/8BdAP/AWYD/wFcA/8BTgP/AUgCzwH+AVMC /gFTAmgB9AFXAlkBvAMbASYIAAMcAScDXQHHAmMBbwH2AoABuwH+AqUC/wKLAv8CdAL/AmYC/wJcAv8C
dwH0AVcCWQG8AxsBJggAAxwBJwNdAccCcgF6AfYChwHPAf4CpQL/AosC/wJ0Av8CZgL/AlwC/wJOAv8C TgL/AlIBuwH+AlMBaAH0AlcBWQG8AxsBJgwAAyEBMANZAbYDYgHuA30B+gO+Af0D1AH/A8wB/wO+Af0D
SAHPAf4CUwF3AfQCVwFZAbwDGwEmDAADIQEwA1kBtgNnAe4DkwH6A74B/QPUAf8DzAH/A74B/QOEAfkD dQH5A2wB6wNVAawDHwEsEAADIQEwA1kBtgNiAe4BfQGEAX0B+gGuAb4BrgH9AZ8B/wGfAf8BjAH/AYwB
bAHrA1UBrAMfASwQAAMhATADWQG2AWUBaQFlAe4BfQGfAX0B+gGuAb4BrgH9AZ8B/wGfAf8BjAH/AYwB /wFUAb4BVAH9AWgBhwFoAfkBYQFsAWEB6wNVAawDHwEsEAADIQEwA1kBtgNiAe4BfQKEAfoBrgK+Af0B
/wFeAb4BXgH9AWgBkQFoAfkBYQFsAWEB6wNVAawDHwEsEAADIQEwA1kBtgFlAmkB7gF9Ap8B+gGuAr4B nwP/AYwD/wFUAr4B/QFoAocB+QFhAmwB6wNVAawDHwEsEAADIQEwA1kBtgNiAe4CfQGEAfoCrgG+Af0C
/QGfA/8BjAP/AV4CvgH9AWgCkQH5AWECbAHrA1UBrAMfASwQAAMhATADWQG2AmUBaQHuAn0BnwH6Aq4B nwL/AowC/wJUAb4B/QJoAYcB+QJhAWwB6wNVAawDHwEsFAADBgEHAzYBWANVAawDZgHlA4IB/AOJAfsD
vgH9Ap8C/wKMAv8CXgG+Af0CaAGRAfkCYQFsAesDVQGsAx8BLBQAAwYBBwM2AVgDVQGsA2YB5QOgAfwD ZQHiA1MBpwMzAVEDBgEHGAADBgEHAzYBWANVAawDZgHlAX4BmwF+AfwBXwGUAV8B+wNlAeIDUwGnAzMB
kwH7A2UB4gNTAacDMwFRAwYBBxgAAwYBBwM2AVgDVQGsA2YB5QF+AbQBfgH8AW0BngFtAfsDZQHiA1MB UQMGAQcYAAMGAQcDNgFYA1UBrANmAeUBfgKbAfwBXwKUAfsDZQHiA1MBpwMzAVEDBgEHGAADBgEHAzYB
pwMzAVEDBgEHGAADBgEHAzYBWANVAawDZgHlAX4CtAH8AW0CngH7A2UB4gNTAacDMwFRAwYBBxgAAwYB WANVAawDZgHlAn4BmwH8Al8BlAH7A2UB4gNTAacDMwFRAwYBBwwAAUIBTQE+BwABPgMAASgDAAFAAwAB
BwM2AVgDVQGsA2YB5QJ+AbQB/AJtAZ4B+wNlAeIDUwGnAzMBUQMGAQcMAAFCAU0BPgcAAT4DAAEoAwAB IAMAAQEBAAEBBgABARYAA/+BAAHgAQcB4AEHAeABBwHgAQcBwAEDAcABAwHAAQMBwAEDAYABAQGAAQEB
QAMAASADAAEBAQABAQYAAQEWAAP/gQAB4AEHAeABBwHgAQcB4AEHAcABAwHAAQMBwAEDAcABAwGAAQEB gAEBAYABAVAAAYABAQGAAQEBgAEBAYABAQHAAQMBwAEDAcABAwHAAQMB4AEHAeABBwHgAQcB4AEHCw==
gAEBAYABAQGAAQFQAAGAAQEBgAEBAYABAQGAAQEBwAEDAcABAwHAAQMBwAEDAeABBwHgAQcB4AEHAeAB </value>
Bws= </data>
<metadata name="ilProfileImages.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>132, 12</value>
</metadata>
<data name="ilProfileImages.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAlhsAAAJNU0Z0AUkBTAMBAQAB
OAEAATgBAAEgAQABIAEABP8BIQEACP8BQgFNATYHAAE2AwABKAMAAYADAAEgAwABAQEAASAGAAFAEgAC
RwFGAYACRwFGAYACRwFGAYABRwJGAYABRwJGAYACRwFGAYACRwFGAYABRwJGAYABRwJGAYABRwJGAYAD
RgGAAkcBRgGAAkcBRgGAAkcBRgGAAkcBRgGAAkcBRgGAAkcBRgGAAkcBRgGAAkcBRgGAAkcBRgGAAkcB
RgGAAkcBRgGAA0YBgAFHAkYBgAFHAkYBgAFHAkYBgAFHAkYBgAFHAkYBgAJHAUYBgAJHAUYBgAJHAUYB
gAMqAUD/AIEAAf8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRgEBAv8BRwEBAv8BSAEAAf8B7QFGAQEB
/wHbAUMBAgH/AZEBNgEBAf8BRgEpAQAB/wF1AVABAQH/AaMBdwECAf8BzAGQAQkB/wH0AagBEAH/AfkB
rQEIAf8B/gGxAQAB/wH3Aa4BBgH/Ae8BqwEMAf8BygGOAQcB/wGlAXABAgH/AXABTgEBAf8BOwEsAQAB
/wFZAScBAAH/AXcBIgEAAf8BuwE0AQIB/wH+AUYBBAL/AUcBAwL/AUcBAQL/AUcBAQL/AUcBAQH/AkcB
RgGA/wCBAAH/AUcBAQL/AUcBAQL/AUcBAQL/AUYBAgL/AUYBAwH/AfsBRwEBAf8B9wFIAQAB/wHaAVAB
AQH/Ab0BWAEBAf8BrgFjAQEB/wGgAW8BAAH/AbgBggEBAf8B0QGWAQEB/wHkAaMBBQH/AfgBrwEJAf8B
+wGxAQUC/wGzAQEB/wH7AbEBBAH/AfcBsAEIAf8B5AGiAQQB/wHRAZQBAQH/AbcBgwECAf8BnQFyAQIB
/wGDAVEBAQH/AWgBMQEAAf8BlAEzAQEB/wHBATYBAwH/AeABPwECAv8BSAEBAv8BRwEBAv8BRwEBAf8C
RwFGAYD/AIEAAf8BRwEBAv8BRwEBAv8BRwEBAv8BRgEDAv8BRQEEAf8B9wFGAQIB/wHvAUcBAAH/AccB
WgEAAf8BnwFtAQAB/wHMAZEBAAH/AfkBtAEAAf8B/AG1AQAC/wG1AQAB/wH9AbYBAQH/AfsBtgEBAf8B
/QG1AQEC/wG0AQEC/wG0AQIC/wG0AQMB/wH+AbYBAgH/Af0BtwEAAf8B/gG3AQIC/wG3AQQB/wGsAXwB
AgH/AVkBQAEAAf8BbgEzAQEB/wGDASUBAQH/AcEBNwEBAf8B/gFIAQAC/wFIAQEC/wFHAQEB/wJHAUYB
gP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQIC/wFHAQIB/wHyAUwBAQH/AeYBUgEAAf8B2gFxAQAB
/wHPAZABAAH/AeYBogEAAf8B/AG1AQEB/wH+AbUBAQL/AbUBAQH/Af4BtQEBAf8B/QG2AQEB/wH+AbUB
AQL/AbUBAQL/AbUBAgL/AbUBAgL/AbUBAQH/Af4BtgEBAf8B/QG0AQEB/wH7AbIBAgH/AdQBmAEDAf8B
rAF/AQMB/wGHAVUBAgH/AWMBKwEBAf8BrwE5AQEB/wH8AUgBAQH/Af4BRwEBAv8BRwEBAf8CRwFGAYD/
AIEAAf8BRwEBAv8BRwEBAv8BRwEBAv8BSAEBAv8BSQEAAf8B7gFTAQAB/wHcAVwBAAH/Ae4BiAEAAv8B
swEAAv8BtAEBAv8BtQEBAv8BtQEBAv8BtQEBAv8BtQEBAv8BtQEBAv8BtQEBAv8BtQEBAv8BtQEBAv8B
tQEBAv8BtQEBAv8BtQEBAf8B+wGxAQEB/wH3AawBAAH/AfsBtQEDAv8BvgEGAf8BoQF3AQQB/wFCATAB
AQH/AZ4BPAECAf8B+gFHAQIB/wH9AUcBAgL/AUcBAQH/AkcBRgGA/wCBAAH/AUcBAQL/AUcBAQL/AUcB
AQL/AUgBAQL/AUkBAAH/AfYBZAEQAf8B7gF/ASEB/wH2AZoBEAL/AbUBAAL/AbUBAQL/AbUBAQL/AbUB
AgL/AbUBAgL/AbUBAgL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQH/Af0B
swEBAf8B+wGxAQEB/wH9AbUBAwL/AboBBQH/AaQBdwEDAf8BSQE0AQEB/wGjAT0BAgH/Af0BRgEDAf8B
/gFHAQIC/wFHAQEB/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFIAQEB/wH+AUgBAAL/AXUB
IQL/AaIBQQL/AawBIQL/AbYBAAL/AbYBAQL/AbUBAQL/AbUBAgL/AbQBAwL/AbUBAgL/AbUBAQL/AbUB
AQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbYBAwL/AbYBBAH/AagB
dwECAf8BUAE3AQAB/wGoAT4BAgL/AUUBBAL/AUYBAwL/AUcBAQH/AkcBRgGA/wCBAAH/AUcBAQL/AUcB
AQL/AUcBAQL/AUcBAQL/AUgBAQL/AV8BEwL/AXcBJgL/AZwBKAL/AcIBKgL/AbwBFQL/AbYBAQL/AbUB
AQL/AbUBAgL/AbUBAgL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAgL/AbUBAgL/AbUB
AQL/AbYBAQH/Af4BtgEBAf8B/QG2AQIB/wG9AXkBAQH/AX4BPQEAAf8BvgFCAQEC/wFHAQIC/wFHAQIC
/wFHAQEB/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFJAQYC/wFLAQoC
/wGMAS8C/wHNAVMC/wHCASoC/wG2AQAC/wG2AQEC/wG1AQEC/wG1AQEC/wG1AQEC/wG1AQEC/wG1AQEC
/wG1AQEC/wG1AQEC/wG1AQIC/wG0AQMC/wG1AQIC/wG2AQAB/wH9AbYBAAH/AfoBtQEAAf8B0wF8AQAB
/wGsAUMBAAH/AdUBRgEAAf8B/gFIAQAC/wFIAQEC/wFHAQEB/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC
/wFHAQEC/wFHAQEC/wFGAQIB/wH+AUgBAwH/Af0BSQEFAf8B7wFrARwB/wHhAY0BNAH/AfABrQE7Av8B
zgFDAv8BwQEjAv8BtAEEAv8BtQECAv8BtgEBAv8BtQEBAv8BtQEBAv8BtQEBAv8BtgEBAf8B/gG0AQEB
/wH+AbMBAgH/Af4BtwEJAv8BuwEQAf8B/gG0AQ0B/wH9Aa0BCgH/AekBeAEFAf8B1gFDAQAB/wHqAUYB
AAL/AUgBAAL/AUgBAQL/AUcBAQH/AkcBRgGA/wCBAAH/AUcBAQL/AUcBAQL/AUcBAQL/AUYBAgL/AUUB
AgH/Af0BRgEBAf8B+gFHAQAB/wHfAUoBCgH/AcMBTAEUAf8B4QGZAU0C/wHlAYYC/wHMAUYC/wGzAQYC
/wG1AQMC/wG2AQAC/wG2AQEC/wG1AQEC/wG2AQEC/wG2AQAB/wH+AbQBAAH/AfwBsgEAAf8B/gG5ARAC
/wG/ASAC/wGyARoC/wGkARQC/wF0AQoC/wFDAQAC/wFGAQAC/wFIAQAC/wFIAQEC/wFHAQEB/wJHAUYB
gP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFGAQIB/wH+AUcBAQH/Af0BRwEBAf8B7wFHAQYB
/wHhAUgBCwH/AfABcAEnAv8BmAFDAf8B/gGgATwB/wH9AagBNAH/Af4BugFCAv8BzAFQAv8BzAFOAv8B
ywFNAv8ByAFHAv8BxgFCAf8B/gHBAT8B/wH+Ab0BPAH/Af4BoQEnAv8BhgESAv8BfQEOAv8BdQELAv8B
XQEGAv8BRQEBAv8BRgEBAv8BSAEBAv8BRwEBAv8BRwEBAf8CRwFGAYD/AIEAAf8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRQECAv8BQwECAv8BRwEBAv8BSwEAAf8B/QF0ATEB
/wH7AZ0BYgH/Af0BwAGBAv8B4gGgAv8B4gGcAv8B4QGYAv8B2wGOAv8B1QGEAv8BzgF+Av8BxwF3Av8B
igE9Av8BTAEDAv8BSQEDAv8BRgECAv8BRwECAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAf8C
RwFGAYD/AIEAAf8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAf8B/gFGAQIB
/wH+AUUBAwH/Af4BSAECAv8BSwEAAf8B+QFdARkB/wHyAW8BMwH/Ac0BewFBAf8BpwGHAVAB/wGkAYgB
TgH/AaABigFMAf8BowGGAUoB/wGnAYMBSQH/AbcBfgFCAf8ByAF5ATwB/wHjAWEBHwL/AUoBAgL/AUgB
AgL/AUcBAgL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQH/AkcBRgGA/wCBAAH/AUcB
AQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQH/Af4BRwEDAf8B/AFGAQQB/wH+AUgB
AgL/AUoBAAH/AfQBRQECAf8B6QFAAQMB/wGcATYBAgH/AU8BLAEAAf8BSAEvAQAB/wFBATIBAAH/AUgB
MQEHAf8BTgEwAQ0B/wFvAS0BBwH/AZABKgEAAf8ByAE5AQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEB/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEB/wH+AUcBAgH/Af4BRwECAf8B/gFGAQEC/wFFAQEB/wHhAU0B
AQH/AcMBVAECAf8BtQFhAQEB/wGnAW8BAAH/AaMBcAEAAf8BnwFxAQAB/wGjAXIBAwH/AacBcgEHAf8B
hwFPAQMB/wFoASwBAAH/AaABNQEAAf8B2AE/AQEB/wHrAUMBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcB
AQL/AUcBAQL/AUcBAQL/AUcBAQH/AkcBRgGA/wCBAAH/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcB
AQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAAL/AUQBAQL/AUABAQH/Ac4BVAEBAf8BnQFoAQAB/wHOAY0B
AAL/AbEBAAH/Af4BsQEAAf8B/AGwAQAB/wH+AbIBAAL/AbQBAAH/AaABcQEAAf8BQAEtAQAB/wF4ATIB
AAH/AbABNwEAAf8B2AE/AQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEB
/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQIC
/wFGAQIB/wH2AUUBAQH/Ae0BRQEBAf8B3gFqAQEB/wHOAZABAgH/AecBogEBAv8BtAEAAf8B/gGzAQEB
/wH+AbIBAgH/Af4BtAEDAv8BtQEDAf8BzgGRAQMB/wGdAWwBAgH/AZMBSwEBAf8BiQErAQAB/wHEATkB
AQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQH/AkcBRgGA/wCBAAH/AUcB
AQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUYBAwL/AUUBBAH/Ae0BRwECAf8B
2wFJAQAB/wHtAYABAgL/AbcBBAL/AbcBAgL/AbcBAAL/AbYBAgL/AbQBBAL/AbUBBQL/AbYBBgH/Af0B
sQEFAf8B+gGrAQQB/wGuAWUBAgH/AWIBHgEAAf8BsQEzAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEC/wFHAQEC/wFHAQEB/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEC/wFHAQEC/wFHAQIC/wFHAQIB/wHqAUkBAQH/AdYBSwEAAf8B6wGAAQMC/wG1AQYC/wG2AQMC
/wG2AQEC/wG1AQIC/wG1AQMC/wG1AQMC/wG2AQQB/wH+AbQBAwH/Af0BsgECAf8BrgFrAQEB/wFfASQB
AAH/Aa8BNQEBAv8BRwECAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAf8CRwFGAYD/
AIEAAf8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BSAEBAf8B/gFIAQAB
/wHoAUsBAAH/AdEBTQEAAf8B6AGAAQQC/wGzAQcC/wG0AQQC/wG1AQEC/wG1AQEC/wG1AQEC/wG1AQEC
/wG1AQEC/wG3AQEC/wG4AQAB/wGtAXEBAAH/AVsBKQEAAf8BrQE4AQEC/wFGAQIC/wFHAQIC/wFHAQEC
/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEB/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFIAQEB/wHzAUoBAAH/AecBTQEAAf8B8wGGAQ4C/wG/ARwC
/wG6AQ4B/wH+AbYBAQL/AbYBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQL/AbUBAQH/AcEBcQEAAf8B
gwEuAQAB/wHBAToBAQL/AUcBAgL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQH/AkcB
RgGA/wCBAAH/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcB
AQH/Af4BSgEBAf8B/QFNAQAB/wH+AYwBGQL/AcoBMQH/Af4BwQEZAf8B/QG3AQAB/wH+AbYBAQL/AbUB
AQL/AbUBAQL/AbUBAQL/AbQBAQL/AbIBAQH/AdUBcgEBAf8BqwEyAQAB/wHVAT0BAQL/AUcBAQL/AUcB
AQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQH/AkcBRgGA/wCBAAH/AUcBAQL/AUcBAQL/AUcB
AQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUcBAQL/AUgBAQH/Af4BSgEAAv8BjQE2Av8B
0QFsAf8B+wHHAUcB/wH3Ab4BIgH/AfsBuQESAv8BtQECAf8B/QG1AQgB/wH8AbYBDQH/AfsBrwENAf8B
+wGoAQ0B/wHoAXIBCAH/AdUBPAEDAf8B6gFCAQIC/wFIAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEC/wFHAQEB/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFGAQAC/wGPAVMC/wHYAaYB/wH4Ac4BdQH/AfEBxAFEAf8B
+AG8ASQC/wG0AQMB/wH8AbYBDgH/AfgBtwEZAf8B+AGrARkB/wH3AZ4BGAH/AfsBcgEPAv8BRQEGAv8B
RwEDAv8BSAEAAv8BSAEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAf8CRwFGAYD/AIEAAf8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BSAEBAf8B/QFIAQAB
/wH7AUgBAAH/Af0BbgEsAv8BlAFZAf8B/AGOAT8B/wH4AYgBJQH/Ae8BhAEUAf8B5gGBAQMB/wHtAYEB
CAH/AfUBgQEOAf8B+AF5AQ8B/wH7AXIBEAH/Af0BXQEJAv8BRwEDAv8BRwECAv8BSAEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAf8CRwFGAYD/AIEAAf8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BSAEBAf8B/gFIAQAB/wH6AUkBAAH/AfYBSQEAAf8B+wFNAQYC
/wFQAQsC/wFOAQkC/wFMAQYB/wHmAU0BBAH/AcwBTQECAf8B3wFMAQMB/wHyAUoBAwH/AfkBSAEFAv8B
RgEHAv8BSAEEAf8B/gFJAQAC/wFIAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEB/wJHAUYBgP8AgQAB/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC/wFHAQEC
/wFHAQEC/wFIAQEB/wH9AUgBAQH/AfsBSAEBAf8B/QFKAQMC/wFMAQYC/wFLAQUC/wFKAQQB/wHyAUoB
AwH/AeYBSgECAf8B7wFJAQIB/wH5AUkBAgH/AfwBSAEDAv8BRwEEAv8BRwECAv8BSAEBAv8BSAEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAf8CRwFGAYD/AIEAAf8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAf8C
RwFGAYD/AIEAAf8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAf8CRwFGAYD/AIEAAf8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8B
RwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAv8BRwEBAf8CRwFGAYD/AIEAAUIBTQE+BwABPgMAASgD
AAGAAwABIAMAAQEBAAEBBgABAhYAA///AP8AAwAL
</value> </value>
</data> </data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

View File

@ -29,23 +29,14 @@
private void InitializeComponent() private void InitializeComponent()
{ {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DirectMessage)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DirectMessage));
rtxtChat = new RichTextBox();
btnSend = new Button(); btnSend = new Button();
rtxtChatbox = new RichTextBox(); rtxtChatbox = new RichTextBox();
lblUsername = new Label(); lblUsername = new Label();
pbPfp = new PictureBox();
lvChat = new ListView();
((System.ComponentModel.ISupportInitialize)pbPfp).BeginInit();
SuspendLayout(); SuspendLayout();
// //
// rtxtChat
//
rtxtChat.HideSelection = false;
rtxtChat.Location = new Point(12, 48);
rtxtChat.Margin = new Padding(4, 3, 4, 3);
rtxtChat.Name = "rtxtChat";
rtxtChat.ReadOnly = true;
rtxtChat.Size = new Size(593, 325);
rtxtChat.TabIndex = 6;
rtxtChat.Text = "";
//
// btnSend // btnSend
// //
btnSend.FlatAppearance.BorderSize = 0; btnSend.FlatAppearance.BorderSize = 0;
@ -74,21 +65,44 @@
// //
lblUsername.AutoSize = true; lblUsername.AutoSize = true;
lblUsername.Font = new Font("Segoe UI", 25F, FontStyle.Bold | FontStyle.Italic); lblUsername.Font = new Font("Segoe UI", 25F, FontStyle.Bold | FontStyle.Italic);
lblUsername.Location = new Point(6, 0); lblUsername.Location = new Point(52, 0);
lblUsername.Margin = new Padding(4, 0, 4, 0); lblUsername.Margin = new Padding(4, 0, 4, 0);
lblUsername.Name = "lblUsername"; lblUsername.Name = "lblUsername";
lblUsername.Size = new Size(181, 46); lblUsername.Size = new Size(181, 46);
lblUsername.TabIndex = 7; lblUsername.TabIndex = 7;
lblUsername.Text = "Username"; lblUsername.Text = "Username";
// //
// pbPfp
//
pbPfp.Image = Properties.Resources.DefaultPfp;
pbPfp.Location = new Point(14, 6);
pbPfp.Name = "pbPfp";
pbPfp.Size = new Size(40, 37);
pbPfp.SizeMode = PictureBoxSizeMode.StretchImage;
pbPfp.TabIndex = 9;
pbPfp.TabStop = false;
//
// lvChat
//
lvChat.Alignment = ListViewAlignment.Left;
lvChat.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point, 0);
lvChat.Location = new Point(12, 48);
lvChat.MultiSelect = false;
lvChat.Name = "lvChat";
lvChat.Size = new Size(593, 325);
lvChat.TabIndex = 10;
lvChat.UseCompatibleStateImageBehavior = false;
lvChat.View = View.SmallIcon;
//
// DirectMessage // DirectMessage
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.DodgerBlue; BackColor = Color.DodgerBlue;
ClientSize = new Size(618, 443); ClientSize = new Size(618, 443);
Controls.Add(lvChat);
Controls.Add(pbPfp);
Controls.Add(lblUsername); Controls.Add(lblUsername);
Controls.Add(rtxtChat);
Controls.Add(btnSend); Controls.Add(btnSend);
Controls.Add(rtxtChatbox); Controls.Add(rtxtChatbox);
Font = new Font("Segoe UI", 9F); Font = new Font("Segoe UI", 9F);
@ -101,15 +115,16 @@
StartPosition = FormStartPosition.CenterScreen; StartPosition = FormStartPosition.CenterScreen;
Text = "QtC.NET Client - Direct Message With ${USER}"; Text = "QtC.NET Client - Direct Message With ${USER}";
Load += frmDirectMessage_Load; Load += frmDirectMessage_Load;
((System.ComponentModel.ISupportInitialize)pbPfp).EndInit();
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();
} }
#endregion #endregion
private RichTextBox rtxtChat;
private Button btnSend; private Button btnSend;
private RichTextBox rtxtChatbox; private RichTextBox rtxtChatbox;
private Label lblUsername; private Label lblUsername;
private PictureBox pbPfp;
private ListView lvChat;
} }
} }

View File

@ -36,20 +36,23 @@ namespace qtc_net_client_2.Forms
InitializeComponent(); InitializeComponent();
} }
private void frmDirectMessage_Load(object sender, EventArgs e) private async void frmDirectMessage_Load(object sender, EventArgs e)
{ {
lblUsername.Text = User.Username; lblUsername.Text = User.Username;
Text = $"QtC.NET Client - Direct Message With {User.Username}"; Text = $"QtC.NET Client - Direct Message With {User.Username}";
Messages.CollectionChanged += Messages_CollectionChanged; Messages.CollectionChanged += Messages_CollectionChanged;
if (User.Role == "Admin") var pfpRes = await _apiService.GetUserProfilePic(User.Id);
if(pfpRes != null && pfpRes.Success && pfpRes.Data != null)
{ {
Messages.Add($"[SERVER] This User Is A Server Admin. You should comply with anything this user asks. however admins should not ask for personal information.\n"); using var ms = new MemoryStream(pfpRes.Data);
using var img = Image.FromStream(ms);
pbPfp.Image = new Bitmap(img);
} }
if (InitMessage != null) if (InitMessage != null)
{ {
Messages.Add($"[{User.Username}] {InitMessage.Content}\n"); Messages.Add($"{User.Username}: {InitMessage.Content}");
AudioService.PlaySoundEffect("sndDirectMsg"); AudioService.PlaySoundEffect("sndDirectMsg");
} }
} }
@ -63,7 +66,7 @@ namespace qtc_net_client_2.Forms
if (!string.IsNullOrEmpty(rtxtChatbox.Text)) if (!string.IsNullOrEmpty(rtxtChatbox.Text))
{ {
await _gatewayService.SendDirectMessageAsync(User, new QtCNETAPI.Models.Message { Content = rtxtChatbox.Text, AuthorId = _apiService.CurrentUser.Id }); await _gatewayService.SendDirectMessageAsync(User, new QtCNETAPI.Models.Message { Content = rtxtChatbox.Text, AuthorId = _apiService.CurrentUser.Id });
Messages.Add($"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}\n"); Messages.Add($"{_apiService.CurrentUser.Username}: {rtxtChatbox.Text}");
rtxtChatbox.Clear(); rtxtChatbox.Clear();
AudioService.PlaySoundEffect("sndSendClick"); AudioService.PlaySoundEffect("sndSendClick");
} }
@ -74,7 +77,7 @@ namespace qtc_net_client_2.Forms
if (!string.IsNullOrEmpty(rtxtChatbox.Text)) if (!string.IsNullOrEmpty(rtxtChatbox.Text))
{ {
await _gatewayService.SendDirectMessageAsync(User, new QtCNETAPI.Models.Message { Content = rtxtChatbox.Text, AuthorId = _apiService.CurrentUser.Id }); await _gatewayService.SendDirectMessageAsync(User, new QtCNETAPI.Models.Message { Content = rtxtChatbox.Text, AuthorId = _apiService.CurrentUser.Id });
Messages.Add($"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}\n"); Messages.Add($"{_apiService.CurrentUser.Username}: {rtxtChatbox.Text}");
rtxtChatbox.Clear(); rtxtChatbox.Clear();
AudioService.PlaySoundEffect("sndSendClick"); AudioService.PlaySoundEffect("sndSendClick");
} }
@ -97,14 +100,14 @@ namespace qtc_net_client_2.Forms
Invoke(delegate () Invoke(delegate ()
{ {
var msg = e.NewItems.Cast<string>().FirstOrDefault(); var msg = e.NewItems.Cast<string>().FirstOrDefault();
rtxtChat.AppendText(msg); lvChat.Items.Add(msg);
if (!msg!.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage"); if (!msg!.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage");
}); });
} }
else else
{ {
var msg = e.NewItems.Cast<string>().FirstOrDefault(); var msg = e.NewItems.Cast<string>().FirstOrDefault();
rtxtChat.AppendText(msg); lvChat.Items.Add(msg);
if (!msg!.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage"); if (!msg!.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage");
} }
} }

View File

@ -79,9 +79,6 @@ namespace qtc_net_client_2
{ {
if (selectedRoom == "Lobby") if (selectedRoom == "Lobby")
{ {
// join lobby
if (!_gatewayService.InLobby) await _gatewayService.JoinLobbyAsync();
ChatRoom frmChat = new ChatRoom(_gatewayService, _apiService); ChatRoom frmChat = new ChatRoom(_gatewayService, _apiService);
frmChat.Show(); frmChat.Show();
@ -93,9 +90,7 @@ namespace qtc_net_client_2
Room? room = RoomList.FirstOrDefault(e => e.Name == selectedRoom); Room? room = RoomList.FirstOrDefault(e => e.Name == selectedRoom);
if (room != null) if (room != null)
{ {
if (_gatewayService.CurrentRoom != room) await _gatewayService.JoinRoomAsync(room); ChatRoom frmChat = new ChatRoom(_gatewayService, _apiService, room);
ChatRoom frmChat = new ChatRoom(_gatewayService, _apiService);
frmChat.Show(); frmChat.Show();
LoggingService.LogString($"User Has Joined {room.Name}"); LoggingService.LogString($"User Has Joined {room.Name}");
@ -1094,7 +1089,7 @@ namespace qtc_net_client_2
if (existingForm != null && existingForm.User.Id == args.User.Id) if (existingForm != null && existingForm.User.Id == args.User.Id)
{ {
// we want to just add to its text box // we want to just add to its text box
existingForm.Messages.Add($"[{args.User.Username}] {args.Message.Content}\n"); existingForm.Messages.Add($"{args.User.Username}: {args.Message.Content}");
} }
else else
{ {