From f73227f02fc2db591c6245be10bba997de0595ea Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Wed, 21 Dec 2022 11:00:42 -0330
Subject: [PATCH 01/18] Update to avalonia 11 preview

---
 ObservatoryCore/ObservatoryCore.csproj        | 20 ++++++++++---------
 ObservatoryCore/UI/MainApplication.axaml      |  7 +++----
 ObservatoryCore/UI/Views/BasicUIView.axaml.cs |  6 +++---
 .../ObservatoryExplorer.csproj                |  2 +-
 4 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/ObservatoryCore/ObservatoryCore.csproj b/ObservatoryCore/ObservatoryCore.csproj
index 4ffa43d..723c26a 100644
--- a/ObservatoryCore/ObservatoryCore.csproj
+++ b/ObservatoryCore/ObservatoryCore.csproj
@@ -23,15 +23,17 @@
   </PropertyGroup>
   
   <ItemGroup>
-    <PackageReference Include="Avalonia" Version="0.10.15" />
-    <PackageReference Include="Avalonia.Controls.DataGrid" Version="0.10.15" />
-    <PackageReference Include="Avalonia.Desktop" Version="0.10.15" />
-    <PackageReference Include="Avalonia.Diagnostics" Version="0.10.15" />
-    <PackageReference Include="Avalonia.ReactiveUI" Version="0.10.15" />
-    <PackageReference Include="Egorozh.ColorPicker.Avalonia.Dialog" Version="0.10.7" />
-    <PackageReference Include="MessageBox.Avalonia" Version="2.0.0" />
-    <PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
-    <PackageReference Include="System.Speech" Version="5.0.0" />
+    <PackageReference Include="Avalonia" Version="11.0.0-preview4" />
+    <PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.0-preview4" />
+    <PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview4" />
+    <PackageReference Include="Avalonia.Diagnostics" Version="11.0.0-preview4" />
+    <PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-preview4" />
+    <PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-preview4" />
+    <PackageReference Include="Avalonia.Themes.Simple" Version="11.0.0-preview4" />
+    <PackageReference Include="Egorozh.ColorPicker.Avalonia.Dialog" Version="11.0.0-preview1" />
+    <PackageReference Include="MessageBox.Avalonia" Version="2.3.1-prev2" />
+    <PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
+    <PackageReference Include="System.Speech" Version="7.0.0" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/ObservatoryCore/UI/MainApplication.axaml b/ObservatoryCore/UI/MainApplication.axaml
index 4f68128..d83efaa 100644
--- a/ObservatoryCore/UI/MainApplication.axaml
+++ b/ObservatoryCore/UI/MainApplication.axaml
@@ -7,10 +7,9 @@
     <local:ViewLocator/>
   </Application.DataTemplates>
   <Application.Styles>
-    <FluentTheme Mode="Dark"/>
-    <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Default.xaml"/>
-    <StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseDark.xaml?assembly=Avalonia.Themes.Default"/>
+    <FluentTheme Mode="Light"/>
+    <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
     <StyleInclude Source="avares://Egorozh.ColorPicker.Avalonia.Dialog/Themes/Default.axaml" />
-    <dialog:FluentColorPickerTheme Mode="Dark" />
+    <dialog:FluentColorPickerTheme Mode="Light" />
   </Application.Styles>
 </Application>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/Views/BasicUIView.axaml.cs b/ObservatoryCore/UI/Views/BasicUIView.axaml.cs
index 8e96d93..3b9d239 100644
--- a/ObservatoryCore/UI/Views/BasicUIView.axaml.cs
+++ b/ObservatoryCore/UI/Views/BasicUIView.axaml.cs
@@ -992,9 +992,9 @@ namespace Observatory.UI.Views
                                 NumericUpDown numericUpDown = new() { Value = intSetting, AllowSpin = true };
                                 if (bounds != null)
                                 {
-                                    numericUpDown.Minimum = bounds.Minimum;
-                                    numericUpDown.Maximum = bounds.Maximum;
-                                    numericUpDown.Increment = bounds.Increment;
+                                    numericUpDown.Minimum = (decimal)bounds.Minimum;
+                                    numericUpDown.Maximum = (decimal)bounds.Maximum;
+                                    numericUpDown.Increment = (decimal)bounds.Increment;
                                 }
                                 numericUpDown.ValueChanged += (object sender, NumericUpDownValueChangedEventArgs e) =>
                                 {
diff --git a/ObservatoryExplorer/ObservatoryExplorer.csproj b/ObservatoryExplorer/ObservatoryExplorer.csproj
index 2267812..4b0b304 100644
--- a/ObservatoryExplorer/ObservatoryExplorer.csproj
+++ b/ObservatoryExplorer/ObservatoryExplorer.csproj
@@ -32,7 +32,7 @@
   </Target>
   
   <ItemGroup>
-    <PackageReference Include="NLua" Version="1.5.9" />
+    <PackageReference Include="NLua" Version="1.6.0" />
   </ItemGroup>
 
   <ItemGroup>

From 5c3474dc0ef522a87f0d678f57eddc236ff28aef Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Wed, 4 Jan 2023 09:26:48 -0330
Subject: [PATCH 02/18] Initial overhaul work

---
 ObservatoryCore/UI/MainApplication.axaml      |  4 +-
 .../UI/ViewModels/BasicUIViewModel.cs         | 55 +++++++++++++++----
 .../UI/ViewModels/CoreViewModel.cs            | 12 ++--
 ObservatoryCore/UI/Views/BasicUIView.axaml.cs | 35 ++++++++----
 ObservatoryFramework/PluginUI.cs              | 17 +++++-
 5 files changed, 93 insertions(+), 30 deletions(-)

diff --git a/ObservatoryCore/UI/MainApplication.axaml b/ObservatoryCore/UI/MainApplication.axaml
index d83efaa..f5a24df 100644
--- a/ObservatoryCore/UI/MainApplication.axaml
+++ b/ObservatoryCore/UI/MainApplication.axaml
@@ -7,9 +7,9 @@
     <local:ViewLocator/>
   </Application.DataTemplates>
   <Application.Styles>
-    <FluentTheme Mode="Light"/>
+    <FluentTheme Mode="Dark"/>
     <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
     <StyleInclude Source="avares://Egorozh.ColorPicker.Avalonia.Dialog/Themes/Default.axaml" />
-    <dialog:FluentColorPickerTheme Mode="Light" />
+    <dialog:FluentColorPickerTheme Mode="Dark" />
   </Application.Styles>
 </Application>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs b/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
index 3bfdf93..a2fd62c 100644
--- a/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
+++ b/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
@@ -9,38 +9,73 @@ using Observatory.UI.Models;
 using ReactiveUI;
 using System.Reactive.Linq;
 using Observatory.Framework;
+using System.Collections.Specialized;
 
 namespace Observatory.UI.ViewModels
 {
     public class BasicUIViewModel : ViewModelBase
     {
-        private ObservableCollection<object> basicUIGrid;
+        private ObservableCollection<string> _headers;
+        private ObservableCollection<string> _formats;
+        private ObservableCollection<ObservableCollection<object>> _items;
 
         public System.Collections.IList SelectedItems { get; set; }        
 
-        public ObservableCollection<object> BasicUIGrid
+        
+        public ObservableCollection<string> Headers
         {
-            get => basicUIGrid;
+            get => _headers;
             set
             {
-                basicUIGrid = value;
-                this.RaisePropertyChanged(nameof(BasicUIGrid));
+                _headers = value;
+                _headers.CollectionChanged += (o, e) => this.RaisePropertyChanged(nameof(Headers));
+                this.RaisePropertyChanged(nameof(Headers));
             }
         }
 
-        public BasicUIViewModel(ObservableCollection<object> BasicUIGrid)
+        public ObservableCollection<string> Formats
         {
-            this.BasicUIGrid = BasicUIGrid;
+            get => _formats;
+            set
+            {
+                _formats = value;
+                _formats.CollectionChanged += (o, e) => this.RaisePropertyChanged(nameof(Formats));
+                this.RaisePropertyChanged(nameof(Formats));
+            }
         }
 
-        private PluginUI.UIType uiType;
+        public ObservableCollection<ObservableCollection<object>> Items
+        {
+            get => _items;
+            set
+            {
+                void raiseItemChanged(object o, NotifyCollectionChangedEventArgs e) { this.RaisePropertyChanged(nameof(Items)); }
+
+                _items = value;
+                _items.CollectionChanged += raiseItemChanged;
+                this.RaisePropertyChanged(nameof(Items));
+                foreach (var itemColumn in value)
+                {
+                    itemColumn.CollectionChanged += raiseItemChanged;
+                }
+            }
+        }
+
+
+        public BasicUIViewModel(ObservableCollection<string> headers, ObservableCollection<string> formats)
+        {
+            Headers = headers;
+            Formats = formats;
+        }
+
+        private PluginUI.UIType _uiType;
 
         public PluginUI.UIType UIType
         {
-            get => uiType;
+            get => _uiType;
             set
             {
-                uiType = value;
+                _uiType = value;
                 this.RaisePropertyChanged(nameof(UIType));
             }
         }
diff --git a/ObservatoryCore/UI/ViewModels/CoreViewModel.cs b/ObservatoryCore/UI/ViewModels/CoreViewModel.cs
index e6027d6..dfd8557 100644
--- a/ObservatoryCore/UI/ViewModels/CoreViewModel.cs
+++ b/ObservatoryCore/UI/ViewModels/CoreViewModel.cs
@@ -47,8 +47,8 @@ namespace Observatory.UI.ViewModels
 
             foreach(var notifier in notifiers.Select(p => p.plugin))
             {
-                Panel notifierPanel = new Panel();
-                TextBlock notifierTextBlock = new TextBlock();
+                Panel notifierPanel = new();
+                TextBlock notifierTextBlock = new();
                 notifierTextBlock.Text = notifier.Name;
                 notifierPanel.Children.Add(notifierTextBlock);
                 //tabs.Add(new CoreModel() { Name = notifier.ShortName, UI = (ViewModelBase)notifier.UI });
@@ -65,7 +65,7 @@ namespace Observatory.UI.ViewModels
 
         }
 
-        public void ReadAll()
+        public static void ReadAll()
         {
             LogMonitor.GetInstance.ReadAllJournals();
         }
@@ -86,21 +86,21 @@ namespace Observatory.UI.ViewModels
             }
         }
 
-        public void OpenGithub()
+        public static void OpenGithub()
         {
             ProcessStartInfo githubOpen = new("https://github.com/Xjph/ObservatoryCore");
             githubOpen.UseShellExecute = true;
             Process.Start(githubOpen);
         }
 
-        public void OpenDonate()
+        public static void OpenDonate()
         {
             ProcessStartInfo donateOpen = new("https://paypal.me/eliteobservatory");
             donateOpen.UseShellExecute = true;
             Process.Start(donateOpen);
         }
 
-        public void GetUpdate()
+        public static void GetUpdate()
         {
             ProcessStartInfo githubOpen = new("https://github.com/Xjph/ObservatoryCore/releases");
             githubOpen.UseShellExecute = true;
diff --git a/ObservatoryCore/UI/Views/BasicUIView.axaml.cs b/ObservatoryCore/UI/Views/BasicUIView.axaml.cs
index 3b9d239..403b61d 100644
--- a/ObservatoryCore/UI/Views/BasicUIView.axaml.cs
+++ b/ObservatoryCore/UI/Views/BasicUIView.axaml.cs
@@ -15,6 +15,7 @@ using Avalonia.Media;
 using Avalonia.Controls.ApplicationLifetimes;
 using System.Runtime.InteropServices;
 using System.IO;
+using Avalonia.Platform.Storage;
 
 namespace Observatory.UI.Views
 {
@@ -71,6 +72,7 @@ namespace Observatory.UI.Views
             e.Column.CanUserResize = true;
             e.Column.CanUserSort = true;
         }
+
         private void UITypeChange()
         {
             var uiPanel = this.Find<Panel>("UIPanel");
@@ -83,10 +85,9 @@ namespace Observatory.UI.Views
                 case PluginUI.UIType.Basic:
                     dataGrid = new()
                     {
-                        [!DataGrid.ItemsProperty] = new Binding("BasicUIGrid"),
+                        [!DataGrid.ItemsProperty] = new Binding("Items"),
                         SelectionMode = DataGridSelectionMode.Extended,
                         GridLinesVisibility = DataGridGridLinesVisibility.Vertical,
-                        AutoGenerateColumns = true,
                         IsReadOnly = true
                     };
                     dataGrid.AutoGeneratingColumn += ColumnGeneration;
@@ -1028,21 +1029,33 @@ namespace Observatory.UI.Views
 
                             settingBrowse.Click += (object source, RoutedEventArgs e) =>
                             {
-                                OpenFileDialog openFileDialog = new()
+                                var currentFolder = new Avalonia.Platform.Storage.FileIO.BclStorageFolder(fileSetting.DirectoryName);
+                                var fileOptions = new FilePickerOpenOptions()
                                 {
-                                    Directory = fileSetting.DirectoryName,
-                                    AllowMultiple = false
+                                    AllowMultiple = false,
+                                    SuggestedStartLocation = currentFolder
                                 };
-                                var browseTask = openFileDialog.ShowAsync((Window)((Button)source).GetVisualRoot());
+
+                                var browseTask = ((Window)settingBrowse.FindAncestorOfType<Window>()).StorageProvider.OpenFilePickerAsync(fileOptions);
+                                
+                                //OpenFileDialog openFileDialog = new()
+                                //{
+                                //    Directory = fileSetting.DirectoryName,
+                                //    AllowMultiple = false
+                                //};
+                                
+                                // = openFileDialog.ShowAsync((Window)((Button)source).GetVisualRoot());
+                                
                                 browseTask.ContinueWith((task) => 
                                 {
                                     if (task.Result?.Count() > 0)
                                     {
-                                        string path = browseTask.Result[0];
-                                        Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => { settingPath.Text = path; });
-                                        setting.Key.SetValue(plugin.Settings, new FileInfo(path));
-                                        PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-
+                                        if (browseTask.Result[0].TryGetUri(out Uri path))
+                                        {
+                                            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => { settingPath.Text = path.AbsolutePath; });
+                                            setting.Key.SetValue(plugin.Settings, new FileInfo(path.AbsolutePath));
+                                            PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
+                                        }
                                     }
                                 });
                                 
diff --git a/ObservatoryFramework/PluginUI.cs b/ObservatoryFramework/PluginUI.cs
index e924fb7..0a8e718 100644
--- a/ObservatoryFramework/PluginUI.cs
+++ b/ObservatoryFramework/PluginUI.cs
@@ -23,11 +23,26 @@ namespace Observatory.Framework
         public object UI;
 
         /// <summary>
-        /// <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
+        /// <para>Collection bound to DataGrid used by plugins with UIType.Basic.</para>
         /// <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
         /// </summary>
         public ObservableCollection<object> DataGrid;
 
+        /// <summary>
+        /// <para>Collection bound to DataGrid headers used by plugins with UIType.Basic.</para>
+        /// </summary>
+        public ObservableCollection<string> Headers;
+
+        /// <summary>
+        /// <para>Collection used to specify formatting of items in respective columns.</para>
+        /// </summary>
+        public ObservableCollection<string> Formats;
+
+        /// <summary>
+        /// <para>Two-dimensional collection of items to display in UI grid.</para>
+        /// </summary>
+        public ObservableCollection<ObservableCollection<object>> Items;
+
         /// <summary>
         /// Instantiate PluginUI of UIType.Basic.
         /// </summary>

From fa6966cff03528dd9a10c8474ca8a6f9d7a4ea62 Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Wed, 8 Feb 2023 21:39:37 -0330
Subject: [PATCH 03/18] New UI framework changes

---
 .../PluginManagement/PluginCore.cs            |  49 ++--
 .../UI/ViewModels/BasicUIViewModel.cs         |   8 +-
 .../UI/ViewModels/CoreViewModel.cs            | 216 +++++++-----------
 ObservatoryFramework/BasicGrid.cs             |  23 ++
 ObservatoryFramework/Interfaces.cs            |   5 +-
 ObservatoryFramework/ObservatoryFramework.xml |  19 +-
 ObservatoryFramework/PluginUI.cs              |  24 +-
 7 files changed, 141 insertions(+), 203 deletions(-)
 create mode 100644 ObservatoryFramework/BasicGrid.cs

diff --git a/ObservatoryCore/PluginManagement/PluginCore.cs b/ObservatoryCore/PluginManagement/PluginCore.cs
index 3fa0637..0bb0a33 100644
--- a/ObservatoryCore/PluginManagement/PluginCore.cs
+++ b/ObservatoryCore/PluginManagement/PluginCore.cs
@@ -3,6 +3,7 @@ using Observatory.Framework.Files;
 using Observatory.Framework.Interfaces;
 using Observatory.NativeNotification;
 using System;
+using System.Collections.ObjectModel;
 using System.IO;
 
 namespace Observatory.PluginManagement
@@ -96,47 +97,39 @@ namespace Observatory.PluginManagement
         /// </summary>
         /// <param name="worker"></param>
         /// <param name="item"></param>
-        public void AddGridItem(IObservatoryWorker worker, object item)
+        public void AddGridItem(IObservatoryWorker worker, List<object> item)
         {
             Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
             {
-                worker.PluginUI.DataGrid.Add(item);
+                ObservableCollection<object> newRow = new(item);
+                worker.PluginUI.BasicGrid.Items.Add(newRow);
 
                 //Hacky removal of original empty object if one was used to populate columns
-                if (worker.PluginUI.DataGrid.Count == 2)
+                if (worker.PluginUI.BasicGrid.Items.Count == 2)
                 {
-                    if (FirstRowIsAllNull(worker))
-                        worker.PluginUI.DataGrid.RemoveAt(0);
+                    bool allNull = true;
+                    
+                    foreach (var cell in worker.PluginUI.BasicGrid.Items[0])
+                    {
+                        if (cell != null)
+                        {
+                            allNull = false;
+                            break;
+                        }
+                    }
+
+                    if (allNull)
+                        worker.PluginUI.BasicGrid.Items.RemoveAt(0);
                 }
+
             });
         }
 
-        /// <summary>
-        /// Adds multiple items to the datagrid on UI thread to ensure visual update.
-        /// </summary>
-        /// <param name="worker"></param>
-        /// <param name="items"></param>
-        public void AddGridItems(IObservatoryWorker worker, IEnumerable<object> items)
+        public void ClearGrid(IObservatoryWorker worker)
         {
             Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
             {
-                var cleanEmptyRow = worker.PluginUI.DataGrid.Count == 1 && FirstRowIsAllNull(worker) && items.Count() > 0;
-                foreach (var item in items)
-                {
-                    worker.PluginUI.DataGrid.Add(item);
-                }
-                if (cleanEmptyRow)
-                    worker.PluginUI.DataGrid.RemoveAt(0);
-            });
-        }
-
-        public void ClearGrid(IObservatoryWorker worker, object templateItem)
-        {
-            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-            {
-                worker.PluginUI.DataGrid.Add(templateItem);
-                while (worker.PluginUI.DataGrid.Count > 1)
-                    worker.PluginUI.DataGrid.RemoveAt(0);
+                worker.PluginUI.BasicGrid.Items.Clear();
             });
         }
 
diff --git a/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs b/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
index a2fd62c..e7f472f 100644
--- a/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
+++ b/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
@@ -61,11 +61,11 @@ namespace Observatory.UI.ViewModels
             }
         }
 
-
-        public BasicUIViewModel(ObservableCollection<string> headers, ObservableCollection<string> formats)
+        public BasicUIViewModel(BasicGrid basicGrid)
         {
-            Headers = headers;
-            Formats = formats;
+            Headers = basicGrid.Headers;
+            Formats = basicGrid.Formats;
+            Items = basicGrid.Items;
         }
 
         private PluginUI.UIType _uiType;
diff --git a/ObservatoryCore/UI/ViewModels/CoreViewModel.cs b/ObservatoryCore/UI/ViewModels/CoreViewModel.cs
index dfd8557..bccdc54 100644
--- a/ObservatoryCore/UI/ViewModels/CoreViewModel.cs
+++ b/ObservatoryCore/UI/ViewModels/CoreViewModel.cs
@@ -36,7 +36,7 @@ namespace Observatory.UI.ViewModels
                 {
                     CoreModel coreModel = new();
                     coreModel.Name = worker.ShortName;
-                    coreModel.UI = new BasicUIViewModel(worker.PluginUI.DataGrid)
+                    coreModel.UI = new BasicUIViewModel(worker.PluginUI.BasicGrid)
                     {
                         UIType = worker.PluginUI.PluginUIType
                     };
@@ -55,7 +55,7 @@ namespace Observatory.UI.ViewModels
             }
 
             
-            tabs.Add(new CoreModel() { Name = "Core", UI = new BasicUIViewModel(new ObservableCollection<object>()) { UIType = Framework.PluginUI.UIType.Core } });
+            tabs.Add(new CoreModel() { Name = "Core", UI = new BasicUIViewModel(new Framework.BasicGrid()) { UIType = Framework.PluginUI.UIType.Core } });
 
             if (Properties.Core.Default.StartMonitor)
                 ToggleMonitor();
@@ -112,67 +112,95 @@ namespace Observatory.UI.ViewModels
             try
             {
                 var exportFolder = Properties.Core.Default.ExportFolder;
-                if (string.IsNullOrEmpty(exportFolder) || !Directory.Exists(exportFolder))
+
+                if (string.IsNullOrEmpty(exportFolder))
                 {
                     exportFolder = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
-
-                    OpenFolderDialog openFolderDialog = new()
-                    {
-                        Directory = exportFolder
-                    };
-
-                    var application = (IClassicDesktopStyleApplicationLifetime)Avalonia.Application.Current.ApplicationLifetime;
-
-                    var selectedFolder = await openFolderDialog.ShowAsync(application.MainWindow);
-
-                    if (!string.IsNullOrEmpty(selectedFolder))
-                    {
-                        Properties.Core.Default.ExportFolder = selectedFolder;
-                        Properties.Core.Default.Save();
-                        exportFolder = selectedFolder;
-                    }
                 }
 
-                var exportStyle = Properties.Core.Default.ExportStyle;
-                if (string.IsNullOrEmpty(exportStyle))
+                OpenFolderDialog openFolderDialog = new()
                 {
-                    exportStyle = "Fixed width";
-                    Properties.Core.Default.ExportStyle = exportStyle;
+                    Directory = exportFolder
+                };
+
+                var application = (IClassicDesktopStyleApplicationLifetime)Avalonia.Application.Current.ApplicationLifetime;
+
+                var selectedFolder = await openFolderDialog.ShowAsync(application.MainWindow);
+
+                if (!string.IsNullOrEmpty(selectedFolder))
+                {
+                    Properties.Core.Default.ExportFolder = selectedFolder;
                     Properties.Core.Default.Save();
-                }
+                    exportFolder = selectedFolder;
 
-                foreach (var tab in tabs.Where(t => t.Name != "Core"))
-                {
-                    var ui = (BasicUIViewModel)tab.UI;
-                    List<object> selectedData;
-                    bool specificallySelected = ui.SelectedItems?.Count > 1;
-
-                    if (specificallySelected)
+                    foreach (var tab in tabs.Where(t => t.Name != "Core"))
                     {
-                        selectedData = new();
+                        var ui = (BasicUIViewModel)tab.UI;
+                        List<object> selectedData;
+                        bool specificallySelected = ui.SelectedItems?.Count > 1;
 
-                        foreach (var item in ui.SelectedItems)
-                            selectedData.Add(item);
+                        if (specificallySelected)
+                        {
+                            selectedData = new();
+
+                            foreach (var item in ui.SelectedItems)
+                                selectedData.Add(item);
+                        }
+                        else
+                        {
+                            selectedData = new(); // TODO: Make this work in new UI
+                        }
+
+                        var columns = selectedData[0].GetType().GetProperties();
+                        Dictionary<string, int> colSize = new();
+                        Dictionary<string, List<string>> colContent = new();
+
+                        foreach (var column in columns)
+                        {
+                            colSize.Add(column.Name, 0);
+                            colContent.Add(column.Name, new());
+                        }
+
+                        foreach (var line in selectedData)
+                        {
+                            var lineType = line.GetType(); // some plugins have different line types, so don't move this out of loop
+                            foreach (var column in colContent)
+                            {
+                                var cellValue = lineType.GetProperty(column.Key)?.GetValue(line)?.ToString() ?? string.Empty;
+                                column.Value.Add(cellValue);
+                                if (colSize[column.Key] < cellValue.Length)
+                                    colSize[column.Key] = cellValue.Length;
+                            }
+                        }
+
+                        System.Text.StringBuilder exportData = new();
+
+
+                        foreach (var colTitle in colContent.Keys)
+                        {
+                            if (colSize[colTitle] < colTitle.Length)
+                                colSize[colTitle] = colTitle.Length;
+
+                            exportData.Append(colTitle.PadRight(colSize[colTitle]) + "  ");
+                        }
+                        exportData.AppendLine();
+
+                        for (int i = 0; i < colContent.First().Value.Count; i++)
+                        {
+                            foreach (var column in colContent)
+                            {
+                                if (column.Value[i].Length > 0 && !char.IsNumber(column.Value[i][0]) && column.Value[i].Count(char.IsLetter) / (float)column.Value[i].Length > 0.25)
+                                    exportData.Append(column.Value[i].PadRight(colSize[column.Key]) + "  ");
+                                else
+                                    exportData.Append(column.Value[i].PadLeft(colSize[column.Key]) + "  ");
+                            }
+                            exportData.AppendLine();
+                        }
+
+                        string exportPath = $"{exportFolder}{System.IO.Path.DirectorySeparatorChar}Observatory Export - {DateTime.UtcNow:yyyyMMdd-HHmmss} - {tab.Name}.txt";
+
+                        System.IO.File.WriteAllText(exportPath, exportData.ToString());
                     }
-                    else
-                    {
-                        selectedData = ui.BasicUIGrid.ToList();
-                    }
-
-                    System.Text.StringBuilder exportData;
-                    switch (exportStyle)
-                    {
-                        case "Tab separated":
-                            exportData = ExportTabSeparated(selectedData);
-                            break;
-                        default: // Fixed width.
-                            exportData = ExportFixedWidth(selectedData);
-                            break;
-                    }
-
-                    string exportPath = $"{exportFolder}{System.IO.Path.DirectorySeparatorChar}Observatory Export - {DateTime.UtcNow:yyyyMMdd-HHmmss} - {tab.Name}.txt";
-
-                    System.IO.File.WriteAllText(exportPath, exportData.ToString());
                 }
             }
             catch (Exception e)
@@ -182,78 +210,6 @@ namespace Observatory.UI.ViewModels
                     new List<(string, string)> { ("An error occurred while exporting; output may be missing or incomplete." + Environment.NewLine +
                     "Please check the error log (found in your Documents folder) for more details and visit our discord to report it.", e.Message) });
             }
-
-            static System.Text.StringBuilder ExportTabSeparated(List<object> selectedData)
-            {
-                System.Text.StringBuilder exportData = new();
-
-                var columnNames = selectedData[0].GetType().GetProperties().Select(c => c.Name).ToList();
-                exportData.AppendJoin('\t', columnNames).AppendLine();
-
-                var lastColumn = columnNames.Last();
-                foreach (var line in selectedData)
-                {
-                    var lineType = line.GetType(); // some plugins have different line types, so don't move this out of loop
-                    foreach (var columnName in columnNames)
-                    {
-                        var cellValue = lineType.GetProperty(columnName)?.GetValue(line)?.ToString() ?? string.Empty;
-                        exportData.Append(cellValue).Append('\t');
-                    }
-                    exportData.AppendLine();
-                }
-                return exportData;
-            }
-
-            static System.Text.StringBuilder ExportFixedWidth(List<object> selectedData)
-            {
-                Dictionary<string, int> colSize = new();
-                Dictionary<string, List<string>> colContent = new();
-
-                var columns = selectedData[0].GetType().GetProperties();
-                foreach (var column in columns)
-                {
-                    colSize.Add(column.Name, column.Name.Length);
-                    colContent.Add(column.Name, new());
-                }
-
-                foreach (var line in selectedData)
-                {
-                    var lineType = line.GetType(); // some plugins have different line types, so don't move this out of loop
-                    foreach (var column in colContent)
-                    {
-                        var cellValue = lineType.GetProperty(column.Key)?.GetValue(line)?.ToString() ?? string.Empty;
-                        column.Value.Add(cellValue);
-                        if (colSize[column.Key] < cellValue.Length)
-                            colSize[column.Key] = cellValue.Length;
-                    }
-                }
-
-                System.Text.StringBuilder exportData = new();
-
-
-                foreach (var colTitle in colContent.Keys)
-                {
-                    if (colSize[colTitle] < colTitle.Length)
-                        colSize[colTitle] = colTitle.Length;
-
-                    exportData.Append(colTitle.PadRight(colSize[colTitle]) + "  ");
-                }
-                exportData.AppendLine();
-
-                for (int i = 0; i < colContent.First().Value.Count; i++)
-                {
-                    foreach (var column in colContent)
-                    {
-                        if (column.Value[i].Length > 0 && !char.IsNumber(column.Value[i][0]) && column.Value[i].Count(char.IsLetter) / (float)column.Value[i].Length > 0.25)
-                            exportData.Append(column.Value[i].PadRight(colSize[column.Key]) + "  ");
-                        else
-                            exportData.Append(column.Value[i].PadLeft(colSize[column.Key]) + "  ");
-                    }
-                    exportData.AppendLine();
-                }
-
-                return exportData;
-            }
         }
 
         public void ClearGrid()
@@ -262,15 +218,7 @@ namespace Observatory.UI.ViewModels
             {
                 var ui = (BasicUIViewModel)tab.UI;
 
-                var rowTemplate = ui.BasicUIGrid.First();
-
-                foreach (var property in rowTemplate.GetType().GetProperties())
-                {
-                    property.SetValue(rowTemplate, null);
-                }
-
-                ui.BasicUIGrid.Clear();
-                ui.BasicUIGrid.Add(rowTemplate);
+                ui.Items.Clear();
 
                 // For some reason UIType's change event will properly
                 // redraw the grid, not BasicUIGrid's.
diff --git a/ObservatoryFramework/BasicGrid.cs b/ObservatoryFramework/BasicGrid.cs
new file mode 100644
index 0000000..b36105e
--- /dev/null
+++ b/ObservatoryFramework/BasicGrid.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Observatory.Framework
+{
+    public class BasicGrid
+    {
+        public BasicGrid()
+        {
+            Headers = new();
+            Formats = new();
+            Items = new();
+        }
+
+        public readonly ObservableCollection<string> Headers;
+        public readonly ObservableCollection<string> Formats;
+        public readonly ObservableCollection<ObservableCollection<object>> Items;
+    }
+}
diff --git a/ObservatoryFramework/Interfaces.cs b/ObservatoryFramework/Interfaces.cs
index 3a1a73b..52ad4b2 100644
--- a/ObservatoryFramework/Interfaces.cs
+++ b/ObservatoryFramework/Interfaces.cs
@@ -154,7 +154,7 @@ namespace Observatory.Framework.Interfaces
         /// </summary>
         /// <param name="worker">Reference to the calling plugin's worker interface.</param>
         /// <param name="item">Grid item to be added. Object type should match original template item used to create the grid.</param>
-        public void AddGridItem(IObservatoryWorker worker, object item);
+        public void AddGridItem(IObservatoryWorker worker, List<object> item);
 
         /// <summary>
         /// Add multiple items to the bottom of the basic UI grid.
@@ -167,8 +167,7 @@ namespace Observatory.Framework.Interfaces
         /// Clears basic UI grid, removing all items.
         /// </summary>
         /// <param name="worker">Reference to the calling plugin's worker interface.</param>
-        /// <param name="templateItem">Template item used to re-initialise the grid.</param>
-        public void ClearGrid(IObservatoryWorker worker, object templateItem);
+        public void ClearGrid(IObservatoryWorker worker);
 
         /// <summary>
         /// Requests current Elite Dangerous status.json content.
diff --git a/ObservatoryFramework/ObservatoryFramework.xml b/ObservatoryFramework/ObservatoryFramework.xml
index 8d53c9a..1c9f796 100644
--- a/ObservatoryFramework/ObservatoryFramework.xml
+++ b/ObservatoryFramework/ObservatoryFramework.xml
@@ -1439,26 +1439,18 @@
             <param name="notificationId">Guid of notification to be updated.</param>
             <param name="notificationEventArgs">NotificationArgs object specifying updated notification content and behaviour.</param>
         </member>
-        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.AddGridItem(Observatory.Framework.Interfaces.IObservatoryWorker,System.Object)">
+        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.AddGridItem(Observatory.Framework.Interfaces.IObservatoryWorker,System.Collections.Generic.List{System.Object})">
             <summary>
             Add an item to the bottom of the basic UI grid.
             </summary>
             <param name="worker">Reference to the calling plugin's worker interface.</param>
             <param name="item">Grid item to be added. Object type should match original template item used to create the grid.</param>
         </member>
-        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.AddGridItems(Observatory.Framework.Interfaces.IObservatoryWorker,System.Collections.Generic.IEnumerable{System.Object})">
-            <summary>
-            Add multiple items to the bottom of the basic UI grid.
-            </summary>
-            <param name="worker">Reference to the calling plugin's worker interface.</param>
-            <param name="items">Grid items to be added. Object types should match original template item used to create the grid.</param>
-        </member>
-        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.ClearGrid(Observatory.Framework.Interfaces.IObservatoryWorker,System.Object)">
+        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.ClearGrid(Observatory.Framework.Interfaces.IObservatoryWorker)">
             <summary>
             Clears basic UI grid, removing all items.
             </summary>
             <param name="worker">Reference to the calling plugin's worker interface.</param>
-            <param name="templateItem">Template item used to re-initialise the grid.</param>
         </member>
         <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.GetStatus">
             <summary>
@@ -1520,13 +1512,12 @@
             <para>(Untested/not implemented)</para>
             </summary>
         </member>
-        <member name="F:Observatory.Framework.PluginUI.DataGrid">
+        <member name="F:Observatory.Framework.PluginUI.BasicGrid">
             <summary>
-            <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
-            <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
+            <para>>Two-dimensional collection of items to display in UI grid for UIType.Basic</para>
             </summary>
         </member>
-        <member name="M:Observatory.Framework.PluginUI.#ctor(System.Collections.ObjectModel.ObservableCollection{System.Object})">
+        <member name="M:Observatory.Framework.PluginUI.#ctor(Observatory.Framework.BasicGrid)">
             <summary>
             Instantiate PluginUI of UIType.Basic.
             </summary>
diff --git a/ObservatoryFramework/PluginUI.cs b/ObservatoryFramework/PluginUI.cs
index 0a8e718..d0a3403 100644
--- a/ObservatoryFramework/PluginUI.cs
+++ b/ObservatoryFramework/PluginUI.cs
@@ -23,25 +23,9 @@ namespace Observatory.Framework
         public object UI;
 
         /// <summary>
-        /// <para>Collection bound to DataGrid used by plugins with UIType.Basic.</para>
-        /// <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
+        /// <para>>Two-dimensional collection of items to display in UI grid for UIType.Basic</para>
         /// </summary>
-        public ObservableCollection<object> DataGrid;
-
-        /// <summary>
-        /// <para>Collection bound to DataGrid headers used by plugins with UIType.Basic.</para>
-        /// </summary>
-        public ObservableCollection<string> Headers;
-
-        /// <summary>
-        /// <para>Collection used to specify formatting of items in respective columns.</para>
-        /// </summary>
-        public ObservableCollection<string> Formats;
-
-        /// <summary>
-        /// <para>Two-dimensional collection of items to display in UI grid.</para>
-        /// </summary>
-        public ObservableCollection<ObservableCollection<object>> Items;
+        public BasicGrid BasicGrid;
 
         /// <summary>
         /// Instantiate PluginUI of UIType.Basic.
@@ -50,10 +34,10 @@ namespace Observatory.Framework
         /// <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
         /// <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
         /// </param>
-        public PluginUI(ObservableCollection<object> DataGrid)
+        public PluginUI(BasicGrid basicGrid)
         {
             PluginUIType = UIType.Basic;
-            this.DataGrid = DataGrid;
+            BasicGrid = basicGrid;
         }
 
         /// <summary>

From 7b6d345cbb3da5d0c052881e75dd739356020718 Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Fri, 5 May 2023 09:37:08 -0230
Subject: [PATCH 04/18] Winforms overhal in progress

---
 ObservatoryCore/App.config                    |   75 +
 .../NativeNotification/NativePopup.cs         |   39 +-
 ObservatoryCore/ObservatoryCore.cs            |   40 +-
 ObservatoryCore/ObservatoryCore.csproj        |  133 +-
 ObservatoryCore/ObservatoryCore.sln           |   16 +-
 .../PluginManagement/PluginCore.cs            |   48 +-
 .../PluginManagement/PluginEventHandler.cs    |    1 +
 .../PluginManagement/PluginManager.cs         |  152 +-
 ObservatoryCore/Properties/Core.Designer.cs   |    9 +-
 ObservatoryCore/Properties/Core.settings      |    4 +-
 .../Properties/Resources.Designer.cs          |   63 +
 ObservatoryCore/Properties/Resources.resx     |  120 +
 ObservatoryCore/UI/CoreForm.Designer.cs       |  705 ++++
 ObservatoryCore/UI/CoreForm.cs                |  418 ++
 ObservatoryCore/UI/CoreForm.resx              | 3662 +++++++++++++++++
 ObservatoryCore/UI/DefaultSorter.cs           |  103 +
 ObservatoryCore/UI/MainApplication.axaml      |   15 -
 ObservatoryCore/UI/MainApplication.axaml.cs   |   34 -
 ObservatoryCore/UI/Models/BasicUIModel.cs     |   14 -
 ObservatoryCore/UI/Models/CoreModel.cs        |   17 -
 .../UI/Models/NotificationModel.cs            |   12 -
 .../UI/NotificationForm.Designer.cs           |   39 +
 ObservatoryCore/UI/NotificationForm.cs        |   22 +
 ObservatoryCore/UI/NotificationForm.resx      |  120 +
 ObservatoryCore/UI/PluginHelper.cs            |  126 +
 ObservatoryCore/UI/SettingsPanel.cs           |   96 +
 ObservatoryCore/UI/TabTemplateSelector.cs     |   31 -
 ObservatoryCore/UI/UIHelper.cs                |   12 +
 ObservatoryCore/UI/ViewLocator.cs             |   32 -
 .../UI/ViewModels/BasicUIViewModel.cs         |   83 -
 .../UI/ViewModels/CoreViewModel.cs            |  310 --
 .../UI/ViewModels/MainWindowViewModel.cs      |   19 -
 .../UI/ViewModels/NotificationViewModel.cs    |   24 -
 .../UI/ViewModels/ViewModelBase.cs            |   11 -
 ObservatoryCore/UI/Views/BasicUIView.axaml    |   10 -
 ObservatoryCore/UI/Views/BasicUIView.axaml.cs | 1259 ------
 ObservatoryCore/UI/Views/CoreView.axaml       |  108 -
 ObservatoryCore/UI/Views/CoreView.axaml.cs    |   25 -
 ObservatoryCore/UI/Views/MainWindow.axaml     |   12 -
 ObservatoryCore/UI/Views/MainWindow.axaml.cs  |   60 -
 .../UI/Views/NotificationView.axaml           |   41 -
 .../UI/Views/NotificationView.axaml.cs        |  267 --
 ObservatoryCore/{ => Utils}/ErrorReporter.cs  |   21 +-
 ObservatoryCore/{UI => Utils}/HttpClient.cs   |    4 +-
 ObservatoryCore/{ => Utils}/JournalReader.cs  |    6 +-
 ObservatoryCore/{ => Utils}/LogMonitor.cs     |   54 +-
 ObservatoryFramework/BasicGrid.cs             |   23 -
 ObservatoryFramework/Interfaces.cs            |   16 +-
 ObservatoryFramework/ObservatoryFramework.xml |   25 +-
 ObservatoryFramework/PluginUI.cs              |   15 +-
 50 files changed, 5871 insertions(+), 2680 deletions(-)
 create mode 100644 ObservatoryCore/App.config
 create mode 100644 ObservatoryCore/Properties/Resources.Designer.cs
 create mode 100644 ObservatoryCore/Properties/Resources.resx
 create mode 100644 ObservatoryCore/UI/CoreForm.Designer.cs
 create mode 100644 ObservatoryCore/UI/CoreForm.cs
 create mode 100644 ObservatoryCore/UI/CoreForm.resx
 create mode 100644 ObservatoryCore/UI/DefaultSorter.cs
 delete mode 100644 ObservatoryCore/UI/MainApplication.axaml
 delete mode 100644 ObservatoryCore/UI/MainApplication.axaml.cs
 delete mode 100644 ObservatoryCore/UI/Models/BasicUIModel.cs
 delete mode 100644 ObservatoryCore/UI/Models/CoreModel.cs
 delete mode 100644 ObservatoryCore/UI/Models/NotificationModel.cs
 create mode 100644 ObservatoryCore/UI/NotificationForm.Designer.cs
 create mode 100644 ObservatoryCore/UI/NotificationForm.cs
 create mode 100644 ObservatoryCore/UI/NotificationForm.resx
 create mode 100644 ObservatoryCore/UI/PluginHelper.cs
 create mode 100644 ObservatoryCore/UI/SettingsPanel.cs
 delete mode 100644 ObservatoryCore/UI/TabTemplateSelector.cs
 create mode 100644 ObservatoryCore/UI/UIHelper.cs
 delete mode 100644 ObservatoryCore/UI/ViewLocator.cs
 delete mode 100644 ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
 delete mode 100644 ObservatoryCore/UI/ViewModels/CoreViewModel.cs
 delete mode 100644 ObservatoryCore/UI/ViewModels/MainWindowViewModel.cs
 delete mode 100644 ObservatoryCore/UI/ViewModels/NotificationViewModel.cs
 delete mode 100644 ObservatoryCore/UI/ViewModels/ViewModelBase.cs
 delete mode 100644 ObservatoryCore/UI/Views/BasicUIView.axaml
 delete mode 100644 ObservatoryCore/UI/Views/BasicUIView.axaml.cs
 delete mode 100644 ObservatoryCore/UI/Views/CoreView.axaml
 delete mode 100644 ObservatoryCore/UI/Views/CoreView.axaml.cs
 delete mode 100644 ObservatoryCore/UI/Views/MainWindow.axaml
 delete mode 100644 ObservatoryCore/UI/Views/MainWindow.axaml.cs
 delete mode 100644 ObservatoryCore/UI/Views/NotificationView.axaml
 delete mode 100644 ObservatoryCore/UI/Views/NotificationView.axaml.cs
 rename ObservatoryCore/{ => Utils}/ErrorReporter.cs (56%)
 rename ObservatoryCore/{UI => Utils}/HttpClient.cs (85%)
 rename ObservatoryCore/{ => Utils}/JournalReader.cs (98%)
 rename ObservatoryCore/{ => Utils}/LogMonitor.cs (95%)
 delete mode 100644 ObservatoryFramework/BasicGrid.cs

diff --git a/ObservatoryCore/App.config b/ObservatoryCore/App.config
new file mode 100644
index 0000000..6a8c1b6
--- /dev/null
+++ b/ObservatoryCore/App.config
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <configSections>
+        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="Observatory.Properties.Core" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+        </sectionGroup>
+    </configSections>
+    <userSettings>
+        <Observatory.Properties.Core>
+            <setting name="JournalFolder" serializeAs="String">
+                <value />
+            </setting>
+            <setting name="AllowUnsigned" serializeAs="String">
+                <value>False</value>
+            </setting>
+            <setting name="NativeNotify" serializeAs="String">
+                <value>True</value>
+            </setting>
+            <setting name="NativeNotifyFont" serializeAs="String">
+                <value />
+            </setting>
+            <setting name="NativeNotifyColour" serializeAs="String">
+                <value>4294944000</value>
+            </setting>
+            <setting name="NativeNotifyCorner" serializeAs="String">
+                <value>0</value>
+            </setting>
+            <setting name="NativeNotifyScreen" serializeAs="String">
+                <value>-1</value>
+            </setting>
+            <setting name="TryPrimeSystemContextOnStartMonitor" serializeAs="String">
+                <value>False</value>
+            </setting>
+            <setting name="CoreVersion" serializeAs="String">
+                <value />
+            </setting>
+            <setting name="PluginSettings" serializeAs="String">
+                <value />
+            </setting>
+            <setting name="VoiceNotify" serializeAs="String">
+                <value>False</value>
+            </setting>
+            <setting name="VoiceSelected" serializeAs="String">
+                <value />
+            </setting>
+            <setting name="VoiceVolume" serializeAs="String">
+                <value>75</value>
+            </setting>
+            <setting name="VoiceRate" serializeAs="String">
+                <value>0</value>
+            </setting>
+            <setting name="MainWindowSize" serializeAs="String">
+                <value>800, 500</value>
+            </setting>
+            <setting name="MainWindowPosition" serializeAs="String">
+                <value>100, 100</value>
+            </setting>
+            <setting name="NativeNotifyScale" serializeAs="String">
+                <value>100</value>
+            </setting>
+            <setting name="NativeNotifyTimeout" serializeAs="String">
+                <value>8000</value>
+            </setting>
+            <setting name="StartMonitor" serializeAs="String">
+                <value>False</value>
+            </setting>
+            <setting name="ExportFolder" serializeAs="String">
+                <value />
+            </setting>
+            <setting name="StartReadAll" serializeAs="String">
+                <value>False</value>
+            </setting>
+        </Observatory.Properties.Core>
+    </userSettings>
+</configuration>
\ No newline at end of file
diff --git a/ObservatoryCore/NativeNotification/NativePopup.cs b/ObservatoryCore/NativeNotification/NativePopup.cs
index 3488ab3..2f4aed7 100644
--- a/ObservatoryCore/NativeNotification/NativePopup.cs
+++ b/ObservatoryCore/NativeNotification/NativePopup.cs
@@ -1,14 +1,11 @@
 using Observatory.Framework;
-using System;
-using System.Collections.Generic;
-using Observatory.UI.Views;
-using Observatory.UI.ViewModels;
+using Observatory.UI;
 
 namespace Observatory.NativeNotification
 {
     public class NativePopup
     {
-        private Dictionary<Guid, NotificationView> notifications;
+        private Dictionary<Guid, NotificationForm> notifications;
 
         public NativePopup()
         {
@@ -18,26 +15,21 @@ namespace Observatory.NativeNotification
         public Guid InvokeNativeNotification(NotificationArgs notificationArgs)
         {
             var notificationGuid = Guid.NewGuid();
-            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
+            var notification = new NotificationForm()
             {
-                var notifyWindow = new NotificationView(notificationGuid) { DataContext = new NotificationViewModel(notificationArgs) };
-                notifyWindow.Closed += NotifyWindow_Closed;
-
-                foreach (var notification in notifications)
-                {
-                    notification.Value.AdjustOffset(true);
-                }
-
-                notifications.Add(notificationGuid, notifyWindow);
-                notifyWindow.Show();
-            });
+                Guid = notificationGuid
+            };
+            notification.Show();
+            notifications.Add(notificationGuid, notification);
+            
+            //TODO: Implement winform notification
 
             return notificationGuid;
         }
 
         private void NotifyWindow_Closed(object sender, EventArgs e)
         {
-            var currentNotification = (NotificationView)sender;
+            var currentNotification = (NotificationForm)sender;
 
             if (notifications.ContainsKey(currentNotification.Guid))
             {
@@ -49,10 +41,7 @@ namespace Observatory.NativeNotification
         {
             if (notifications.ContainsKey(guid))
             {
-                Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-                {
-                    notifications[guid].Close();
-                });
+                notifications[guid].Close();
             }
         }
 
@@ -60,10 +49,8 @@ namespace Observatory.NativeNotification
         {
             if (notifications.ContainsKey(guid))
             {
-                Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-                {
-                    notifications[guid].DataContext = new NotificationViewModel(notificationArgs);
-                });
+                //TODO: Update notification content
+                // notifications[guid].DataContext = new NotificationViewModel(notificationArgs);
             }
         }
 
diff --git a/ObservatoryCore/ObservatoryCore.cs b/ObservatoryCore/ObservatoryCore.cs
index 0e16ff6..f3f69cf 100644
--- a/ObservatoryCore/ObservatoryCore.cs
+++ b/ObservatoryCore/ObservatoryCore.cs
@@ -1,24 +1,26 @@
-using System;
-using Avalonia;
-using Avalonia.ReactiveUI;
+using Observatory.PluginManagement;
+using System.Reflection.PortableExecutable;
 
 namespace Observatory
 {
-    class ObservatoryCore
+    internal static class ObservatoryCore
     {
+        /// <summary>
+        ///  The main entry point for the application.
+        /// </summary>
         [STAThread]
         static void Main(string[] args)
         {
-            if (args.Length > 0 && System.IO.File.Exists(args[0]))
+            if (args.Length > 0 && File.Exists(args[0]))
             {
-                var fileInfo = new System.IO.FileInfo(args[0]);
+                var fileInfo = new FileInfo(args[0]);
                 if (fileInfo.Extension == ".eop" || fileInfo.Extension == ".zip")
-                    System.IO.File.Copy(
+                    File.Copy(
                         fileInfo.FullName,
-                         $"{AppDomain.CurrentDomain.BaseDirectory}{System.IO.Path.DirectorySeparatorChar}plugins{System.IO.Path.DirectorySeparatorChar}{fileInfo.Name}");
+                         $"{AppDomain.CurrentDomain.BaseDirectory}{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}{fileInfo.Name}");
             }
 
-            string version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
+            string version = System.Reflection.Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0";
             try
             {
                 if (Properties.Core.Default.CoreVersion != version)
@@ -34,7 +36,14 @@ namespace Observatory
                     Properties.Core.Default.CoreVersion = version;
                     Properties.Core.Default.Save();
                 }
-                BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+
+                
+
+                // To customize application configuration such as set high DPI settings or default font,
+                // see https://aka.ms/applicationconfiguration.
+                ApplicationConfiguration.Initialize();
+                Application.Run(new UI.CoreForm());
+                PluginManagement.PluginManager.GetInstance.Shutdown();
             }
             catch (Exception ex)
             {
@@ -63,16 +72,7 @@ namespace Observatory
                 .AppendLine(ex.StackTrace);
             if (ex.InnerException != null)
                 errorMessage.AppendLine(FormatExceptionMessage(ex.InnerException, true));
-            
             return errorMessage.ToString();
         }
-
-        public static AppBuilder BuildAvaloniaApp()
-        {
-            return AppBuilder.Configure<UI.MainApplication>()
-                .UsePlatformDetect()
-                .LogToTrace()
-                .UseReactiveUI();
-        }
     }
-}
+}
\ No newline at end of file
diff --git a/ObservatoryCore/ObservatoryCore.csproj b/ObservatoryCore/ObservatoryCore.csproj
index 723c26a..ae449bf 100644
--- a/ObservatoryCore/ObservatoryCore.csproj
+++ b/ObservatoryCore/ObservatoryCore.csproj
@@ -1,77 +1,68 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
-  <PropertyGroup>
-    <OutputType>WinExe</OutputType>
-	<TargetFramework>net6.0</TargetFramework>
+	<PropertyGroup>
+	<OutputType>WinExe</OutputType>
+	<TargetFramework>net6.0-windows</TargetFramework>
+	<Nullable>enable</Nullable>
+	<UseWindowsForms>true</UseWindowsForms>
 	<ImplicitUsings>enable</ImplicitUsings>
-    <RootNamespace>Observatory</RootNamespace>
-    <SignAssembly>false</SignAssembly>
-    <DelaySign>false</DelaySign>
-    <AssemblyOriginatorKeyFile>ObservatoryKey.snk</AssemblyOriginatorKeyFile>
-    <!--<PublishTrimmed>true</PublishTrimmed>-->
-    <TrimMode>Link</TrimMode>
-    <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
-  </PropertyGroup>
+	<RootNamespace>Observatory</RootNamespace>
+	</PropertyGroup>
 
-  <PropertyGroup>
-    <VersionSuffix>0.2.$([System.DateTime]::UtcNow.Year.ToString().Substring(2))$([System.DateTime]::UtcNow.DayOfYear.ToString().PadLeft(3, "0")).$([System.DateTime]::UtcNow.ToString(HHmm))</VersionSuffix>
-    <AssemblyVersion Condition=" '$(VersionSuffix)' == '' ">0.0.0.1</AssemblyVersion>
-    <AssemblyVersion Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>
-    <Version Condition=" '$(VersionSuffix)' == '' ">0.0.1.0</Version>
-    <Version Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</Version>
-    <ApplicationIcon>Assets\EOCIcon-Presized.ico</ApplicationIcon>
-  </PropertyGroup>
-  
-  <ItemGroup>
-    <PackageReference Include="Avalonia" Version="11.0.0-preview4" />
-    <PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.0-preview4" />
-    <PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview4" />
-    <PackageReference Include="Avalonia.Diagnostics" Version="11.0.0-preview4" />
-    <PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-preview4" />
-    <PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-preview4" />
-    <PackageReference Include="Avalonia.Themes.Simple" Version="11.0.0-preview4" />
-    <PackageReference Include="Egorozh.ColorPicker.Avalonia.Dialog" Version="11.0.0-preview1" />
-    <PackageReference Include="MessageBox.Avalonia" Version="2.3.1-prev2" />
-    <PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
-    <PackageReference Include="System.Speech" Version="7.0.0" />
-  </ItemGroup>
+    <PropertyGroup>
+	    <VersionSuffix>0.2.$([System.DateTime]::UtcNow.Year.ToString().Substring(2))$([System.DateTime]::UtcNow.DayOfYear.ToString().PadLeft(3, "0")).$([System.DateTime]::UtcNow.ToString(HHmm))</VersionSuffix>
+	    <AssemblyVersion Condition=" '$(VersionSuffix)' == '' ">0.0.0.1</AssemblyVersion>
+	    <AssemblyVersion Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>
+	    <Version Condition=" '$(VersionSuffix)' == '' ">0.0.1.0</Version>
+	    <Version Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</Version>
+	    <ApplicationIcon>Assets\EOCIcon-Presized.ico</ApplicationIcon>
+	    <StartupObject>Observatory.ObservatoryCore</StartupObject>
+	    <SignAssembly>False</SignAssembly>
+    </PropertyGroup>
 
-  <ItemGroup>
-    <AvaloniaResource Include="Assets\**" />
-  </ItemGroup>
-  
-  <ItemGroup>
-    <Reference Include="ObservatoryFramework">
-      <HintPath>..\ObservatoryFramework\bin\Release\net6.0\ObservatoryFramework.dll</HintPath>
-    </Reference>
-  </ItemGroup>
+    <ItemGroup>
+      <PackageReference Include="Microsoft.Security.Extensions" Version="1.2.0" />
+      <PackageReference Include="System.Speech" Version="7.0.0" />
+    </ItemGroup>
+	
+	<ItemGroup>
+	<Reference Include="ObservatoryFramework">
+		<HintPath>..\ObservatoryFramework\bin\Release\net6.0\ObservatoryFramework.dll</HintPath>
+	</Reference>
+	</ItemGroup>
+	
+	<ItemGroup>
+	<Compile Update="Properties\Core.Designer.cs">
+		<DesignTimeSharedInput>True</DesignTimeSharedInput>
+		<AutoGen>True</AutoGen>
+		<DependentUpon>Core.settings</DependentUpon>
+	</Compile>
+	<Compile Update="Properties\Resources.Designer.cs">
+	  <DesignTime>True</DesignTime>
+	  <AutoGen>True</AutoGen>
+	  <DependentUpon>Resources.resx</DependentUpon>
+	</Compile>
+	</ItemGroup>
+	
+	<ItemGroup>
+	  <EmbeddedResource Update="Properties\Resources.resx">
+	    <Generator>ResXFileCodeGenerator</Generator>
+	    <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+	  </EmbeddedResource>
+	</ItemGroup>
+	
+	<ItemGroup>
+		<None Update="Properties\Core.settings">
+			<Generator>SettingsSingleFileGenerator</Generator>
+			<LastGenOutput>Core.Designer.cs</LastGenOutput>
+		</None>
+	</ItemGroup>
 
-  <ItemGroup>
-    <Compile Update="Properties\Core.Designer.cs">
-      <DesignTimeSharedInput>True</DesignTimeSharedInput>
-      <AutoGen>True</AutoGen>
-      <DependentUpon>Core.settings</DependentUpon>
-    </Compile>
-    <Compile Update="UI\Views\CoreView.axaml.cs">
-      <DependentUpon>CoreView.axaml</DependentUpon>
-    </Compile>
-    <Compile Update="UI\Views\NotificationView.axaml.cs">
-      <DependentUpon>NotificationView.axaml</DependentUpon>
-    </Compile>
-  </ItemGroup>
-
-  <ItemGroup>
-    <None Update="Properties\Core.settings">
-      <Generator>SettingsSingleFileGenerator</Generator>
-      <LastGenOutput>Core.Designer.cs</LastGenOutput>
-    </None>
-  </ItemGroup>
-
-  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
-    <Exec Condition=" '$(OS)' == 'Windows_NT'" Command="if not exist &quot;$(ProjectDir)..\ObservatoryFramework\bin\Release\net5.0\ObservatoryFramework.dll&quot; dotnet build &quot;$(ProjectDir)..\ObservatoryFramework\ObservatoryFramework.csproj&quot; -c Release" />
-    <Exec Condition=" '$(OS)' == 'Windows_NT'" Command="if not exist &quot;$(OutDir)plugins\ObservatoryExplorer.dll&quot; dotnet build &quot;$(ProjectDir)..\ObservatoryExplorer\ObservatoryExplorer.csproj&quot; -c $(ConfigurationName)" />
-    <Exec Condition=" '$(OS)' != 'Windows_NT'" Command="[ ! -e &quot;$(ProjectDir)../ObservatoryFramework/bin/Release/net5.0/ObservatoryFramework.dll&quot; ] &amp;&amp; dotnet build &quot;$(ProjectDir)../ObservatoryFramework/ObservatoryFramework.csproj&quot; -c Release || echo No build necessary" />
-    <Exec Condition=" '$(OS)' != 'Windows_NT'" Command="[ ! -e &quot;$(ProjectDir)$(OutDir)plugins/ObservatoryExplorer.dll&quot; ] &amp;&amp; dotnet build &quot;$(ProjectDir)../ObservatoryExplorer/ObservatoryExplorer.csproj&quot; -c $(ConfigurationName) || echo No build necessary" />
-  </Target>
-
-</Project>
+	<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
+		<Exec Condition=" '$(OS)' == 'Windows_NT'" Command="if not exist &quot;$(ProjectDir)..\ObservatoryFramework\bin\Release\net5.0\ObservatoryFramework.dll&quot; dotnet build &quot;$(ProjectDir)..\ObservatoryFramework\ObservatoryFramework.csproj&quot; -c Release" />
+		<Exec Condition=" '$(OS)' == 'Windows_NT'" Command="if not exist &quot;$(OutDir)plugins\ObservatoryExplorer.dll&quot; dotnet build &quot;$(ProjectDir)..\ObservatoryExplorer\ObservatoryExplorer.csproj&quot; -c $(ConfigurationName)" />
+		<Exec Condition=" '$(OS)' != 'Windows_NT'" Command="[ ! -e &quot;$(ProjectDir)../ObservatoryFramework/bin/Release/net5.0/ObservatoryFramework.dll&quot; ] &amp;&amp; dotnet build &quot;$(ProjectDir)../ObservatoryFramework/ObservatoryFramework.csproj&quot; -c Release || echo No build necessary" />
+		<Exec Condition=" '$(OS)' != 'Windows_NT'" Command="[ ! -e &quot;$(ProjectDir)$(OutDir)plugins/ObservatoryExplorer.dll&quot; ] &amp;&amp; dotnet build &quot;$(ProjectDir)../ObservatoryExplorer/ObservatoryExplorer.csproj&quot; -c $(ConfigurationName) || echo No build necessary" />
+	</Target>
+	
+</Project>
\ No newline at end of file
diff --git a/ObservatoryCore/ObservatoryCore.sln b/ObservatoryCore/ObservatoryCore.sln
index 31626d7..799b6bb 100644
--- a/ObservatoryCore/ObservatoryCore.sln
+++ b/ObservatoryCore/ObservatoryCore.sln
@@ -1,9 +1,9 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30128.74
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32922.545
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObservatoryCore", "ObservatoryCore.csproj", "{0E1C4F16-858E-4E53-948A-77D81A8F3395}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObservatoryCore", "ObservatoryCore.csproj", "{036A9A33-8C38-4A0C-BE2E-AC64B1B22090}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -11,15 +11,15 @@ Global
 		Release|Any CPU = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Release|Any CPU.Build.0 = Release|Any CPU
+		{036A9A33-8C38-4A0C-BE2E-AC64B1B22090}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{036A9A33-8C38-4A0C-BE2E-AC64B1B22090}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{036A9A33-8C38-4A0C-BE2E-AC64B1B22090}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{036A9A33-8C38-4A0C-BE2E-AC64B1B22090}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {F41B8681-A5D9-4167-9938-56DE88024000}
+		SolutionGuid = {53E6C705-9815-47F7-8ABF-92A7FA4E2F4B}
 	EndGlobalSection
 EndGlobal
diff --git a/ObservatoryCore/PluginManagement/PluginCore.cs b/ObservatoryCore/PluginManagement/PluginCore.cs
index 0bb0a33..6e696bb 100644
--- a/ObservatoryCore/PluginManagement/PluginCore.cs
+++ b/ObservatoryCore/PluginManagement/PluginCore.cs
@@ -2,6 +2,7 @@
 using Observatory.Framework.Files;
 using Observatory.Framework.Interfaces;
 using Observatory.NativeNotification;
+using Observatory.Utils;
 using System;
 using System.Collections.ObjectModel;
 using System.IO;
@@ -20,7 +21,7 @@ namespace Observatory.PluginManagement
             NativePopup = new();
         }
 
-        public string Version => System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
+        public string Version => System.Reflection.Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0";
 
         public Action<Exception, String> GetPluginErrorLogger(IObservatoryPlugin plugin)
         {
@@ -97,50 +98,29 @@ namespace Observatory.PluginManagement
         /// </summary>
         /// <param name="worker"></param>
         /// <param name="item"></param>
-        public void AddGridItem(IObservatoryWorker worker, List<object> item)
+        public void AddGridItem(IObservatoryWorker worker, object item)
         {
-            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-            {
-                ObservableCollection<object> newRow = new(item);
-                worker.PluginUI.BasicGrid.Items.Add(newRow);
-
-                //Hacky removal of original empty object if one was used to populate columns
-                if (worker.PluginUI.BasicGrid.Items.Count == 2)
-                {
-                    bool allNull = true;
-                    
-                    foreach (var cell in worker.PluginUI.BasicGrid.Items[0])
-                    {
-                        if (cell != null)
-                        {
-                            allNull = false;
-                            break;
-                        }
-                    }
-
-                    if (allNull)
-                        worker.PluginUI.BasicGrid.Items.RemoveAt(0);
-                }
-
-            });
+            worker.PluginUI.DataGrid.Add(item);
         }
 
-        public void ClearGrid(IObservatoryWorker worker)
+        public void AddGridItems(IObservatoryWorker worker, IEnumerable<object> items)
         {
-            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-            {
-                worker.PluginUI.BasicGrid.Items.Clear();
-            });
+            //TODO: Add to winform list
+        }
+
+        public void ClearGrid(IObservatoryWorker worker, object templateItem)
+        {
+            //TODO: Clear winform list
         }
 
         public void ExecuteOnUIThread(Action action)
         {
-            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(action);
+            //TODO: Execute action
         }
 
         public System.Net.Http.HttpClient HttpClient
         {
-            get => Observatory.HttpClient.Client;
+            get => Utils.HttpClient.Client;
         }
 
         public LogMonitorState CurrentLogMonitorState
@@ -162,7 +142,7 @@ namespace Observatory.PluginManagement
                 var context = new System.Diagnostics.StackFrame(1).GetMethod();
 
                 string folderLocation = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
-                    + $"{Path.DirectorySeparatorChar}ObservatoryCore{Path.DirectorySeparatorChar}{context.DeclaringType.Assembly.GetName().Name}{Path.DirectorySeparatorChar}";
+                    + $"{Path.DirectorySeparatorChar}ObservatoryCore{Path.DirectorySeparatorChar}{context?.DeclaringType?.Assembly.GetName().Name}{Path.DirectorySeparatorChar}";
 
                 if (!Directory.Exists(folderLocation))
                     Directory.CreateDirectory(folderLocation);
diff --git a/ObservatoryCore/PluginManagement/PluginEventHandler.cs b/ObservatoryCore/PluginManagement/PluginEventHandler.cs
index 3be434d..44eab77 100644
--- a/ObservatoryCore/PluginManagement/PluginEventHandler.cs
+++ b/ObservatoryCore/PluginManagement/PluginEventHandler.cs
@@ -6,6 +6,7 @@ using System.Collections.Generic;
 using System.Linq;
 using Observatory.Framework.Files.Journal;
 using System.Timers;
+using Observatory.Utils;
 
 namespace Observatory.PluginManagement
 {
diff --git a/ObservatoryCore/PluginManagement/PluginManager.cs b/ObservatoryCore/PluginManagement/PluginManager.cs
index 9968734..59cfa73 100644
--- a/ObservatoryCore/PluginManagement/PluginManager.cs
+++ b/ObservatoryCore/PluginManagement/PluginManager.cs
@@ -1,5 +1,4 @@
-using Avalonia.Controls;
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
@@ -8,6 +7,8 @@ using Observatory.Framework.Interfaces;
 using System.IO;
 using Observatory.Framework;
 using System.Text.Json;
+using Observatory.Utils;
+using Microsoft.Security.Extensions;
 
 namespace Observatory.PluginManagement
 {
@@ -191,54 +192,95 @@ namespace Observatory.PluginManagement
 
             string pluginPath = $"{AppDomain.CurrentDomain.BaseDirectory}{Path.DirectorySeparatorChar}plugins";
 
+            string ownExe = System.Reflection.Assembly.GetExecutingAssembly().Location;
+            FileSignatureInfo ownSig;
+
+            using (var stream = File.OpenRead(ownExe))
+                ownSig = FileSignatureInfo.GetFromFileStream(stream);
+            
+
             if (Directory.Exists(pluginPath))
             {
                 ExtractPlugins(pluginPath);
 
-                //Temporarily skipping signature checks. Need to do this the right way later.
                 var pluginLibraries = Directory.GetFiles($"{AppDomain.CurrentDomain.BaseDirectory}{Path.DirectorySeparatorChar}plugins", "*.dll");
-                //var coreToken = Assembly.GetExecutingAssembly().GetName().GetPublicKeyToken();
                 foreach (var dll in pluginLibraries)
                 {
                     try
                     {
-                        //var pluginToken = AssemblyName.GetAssemblyName(dll).GetPublicKeyToken();
-                        //PluginStatus signed;
+                        PluginStatus pluginStatus = PluginStatus.SigCheckDisabled;
+                        bool loadOkay = true;
 
-                        //if (pluginToken.Length == 0)
-                        //{
-                        //    errorList.Add($"Warning: {dll} not signed.");
-                        //    signed = PluginStatus.Unsigned;
-                        //}
-                        //else if (!coreToken.SequenceEqual(pluginToken))
-                        //{
-                        //    errorList.Add($"Warning: {dll} signature does not match.");
-                        //    signed = PluginStatus.InvalidSignature;
-                        //}
-                        //else
-                        //{
-                        //    errorList.Add($"OK: {dll} signed.");
-                        //    signed = PluginStatus.Signed;
-                        //}
+                        if (!Properties.Core.Default.AllowUnsigned)
+                        {
+                            if (ownSig.Kind == SignatureKind.Embedded)
+                            {
+                                FileSignatureInfo pluginSig;
+                                using (var stream = File.OpenRead(dll))
+                                    pluginSig = FileSignatureInfo.GetFromFileStream(stream);
 
-                        //if (signed == PluginStatus.Signed || Properties.Core.Default.AllowUnsigned)
-                        //{
-                            string error = LoadPluginAssembly(dll, observatoryWorkers, observatoryNotifiers);
+                                if (pluginSig.Kind == SignatureKind.Embedded)
+                                {
+                                    if (pluginSig.SigningCertificate.Thumbprint == ownSig.SigningCertificate.Thumbprint)
+                                    {
+                                        pluginStatus = PluginStatus.Signed;
+                                    }
+                                    else
+                                    {
+                                        pluginStatus = PluginStatus.InvalidSignature;
+                                    }
+                                }
+                                else
+                                {
+                                    pluginStatus = PluginStatus.Unsigned;
+                                }
+                            }
+                            else
+                            {
+                                pluginStatus = PluginStatus.NoCert;
+                            }
+
+                            if (pluginStatus != PluginStatus.Signed && pluginStatus != PluginStatus.NoCert)
+                            {
+                                string pluginHash = ComputeSha512Hash(dll);
+
+                                if (Properties.Core.Default.UnsignedAllowed == null)
+                                    Properties.Core.Default.UnsignedAllowed = new();
+
+                                if (!Properties.Core.Default.UnsignedAllowed.Contains(pluginHash))
+                                {
+                                    string warning;
+                                    warning = $"Unable to confirm signature of plugin library {dll}.\r\n\r\n";
+                                    warning += "Please ensure that you trust the source of this plugin before loading it.\r\n\r\n";
+                                    warning += "Do you wish to continue loading the plugin? If you load this plugin you will not be asked again for this file.";
+
+                                    var response = MessageBox.Show(warning, "Plugin Signature Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
+
+                                    if (response == DialogResult.OK)
+                                    {
+                                        Properties.Core.Default.UnsignedAllowed.Add(pluginHash);
+                                        Properties.Core.Default.Save();
+                                    }
+                                    else
+                                    {
+                                        loadOkay = false;
+                                    }
+                                }
+                            }
+                        }
+
+                        if (loadOkay)
+                        {
+                            string error = LoadPluginAssembly(dll, observatoryWorkers, observatoryNotifiers, pluginStatus);
                             if (!string.IsNullOrWhiteSpace(error))
                             {
                                 errorList.Add((error, string.Empty));
                             }
-                        //}
-                        //else
-                        //{
-                        //    LoadPlaceholderPlugin(dll, signed, observatoryNotifiers);
-                        //}
-                        
-
+                        }
                     }
                     catch (Exception ex)
                     {
-                        errorList.Add(($"ERROR: {new FileInfo(dll).Name}, {ex.Message}", ex.StackTrace));
+                        errorList.Add(($"ERROR: {new FileInfo(dll).Name}, {ex.Message}", ex.StackTrace ?? String.Empty));
                         LoadPlaceholderPlugin(dll, PluginStatus.InvalidLibrary, observatoryNotifiers);
                     }
                 }
@@ -246,6 +288,15 @@ namespace Observatory.PluginManagement
             return errorList;
         }
 
+        private static string ComputeSha512Hash(string filePath)
+        {
+            using (var SHA512 = System.Security.Cryptography.SHA512.Create())
+            {
+                using (FileStream fileStream = File.OpenRead(filePath))
+                    return BitConverter.ToString(SHA512.ComputeHash(fileStream)).Replace("-", "").ToLowerInvariant();
+            }
+        }
+
         private static void ExtractPlugins(string pluginFolder)
         {
             var files = Directory.GetFiles(pluginFolder, "*.zip")
@@ -265,9 +316,8 @@ namespace Observatory.PluginManagement
             }
         }
 
-        private static string LoadPluginAssembly(string dllPath, List<(IObservatoryWorker plugin, PluginStatus signed)> workers, List<(IObservatoryNotifier plugin, PluginStatus signed)> notifiers)
+        private static string LoadPluginAssembly(string dllPath, List<(IObservatoryWorker plugin, PluginStatus signed)> workers, List<(IObservatoryNotifier plugin, PluginStatus signed)> notifiers, PluginStatus pluginStatus)
         {
-
             string recursionGuard = string.Empty;
 
             System.Runtime.Loader.AssemblyLoadContext.Default.Resolving += (context, name) => {
@@ -293,14 +343,12 @@ namespace Observatory.PluginManagement
                 if (name.Name != recursionGuard)
                 {
                     recursionGuard = name.Name;
-
                     return context.LoadFromAssemblyName(name);
                 }
                 else
                 {
                     throw new Exception("Unable to load assembly " + name.Name);
                 }
-    
             };
 
             var pluginAssembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromAssemblyPath(new FileInfo(dllPath).FullName);
@@ -325,12 +373,12 @@ namespace Observatory.PluginManagement
             {
                 ConstructorInfo constructor = worker.GetConstructor(Array.Empty<Type>());
                 object instance = constructor.Invoke(Array.Empty<object>());
-                workers.Add((instance as IObservatoryWorker, PluginStatus.Signed));
+                workers.Add((instance as IObservatoryWorker, pluginStatus));
                 if (instance is IObservatoryNotifier)
                 {
                     // This is also a notifier; add to the notifier list as well, so the work and notifier are
                     // the same instance and can share state.
-                    notifiers.Add((instance as IObservatoryNotifier, PluginStatus.Signed));
+                    notifiers.Add((instance as IObservatoryNotifier, pluginStatus));
                 }
                 pluginCount++;
             }
@@ -366,13 +414,39 @@ namespace Observatory.PluginManagement
             notifiers.Add((placeholder, pluginStatus));
         }
 
+        /// <summary>
+        /// Possible plugin load results and signature statuses.
+        /// </summary>
         public enum PluginStatus
         {
+            /// <summary>
+            /// Plugin valid and signed with matching certificate.
+            /// </summary>
             Signed,
+            /// <summary>
+            /// Plugin valid but not signed with any certificate.
+            /// </summary>
             Unsigned,
+            /// <summary>
+            /// Plugin valid but not signed with valid certificate.
+            /// </summary>
             InvalidSignature,
+            /// <summary>
+            /// Plugin invalid and cannot be loaded. Possible version mismatch.
+            /// </summary>
             InvalidPlugin,
-            InvalidLibrary
+            /// <summary>
+            /// Plugin not a CLR library.
+            /// </summary>
+            InvalidLibrary,
+            /// <summary>
+            /// Plugin valid but executing assembly has no certificate to match against.
+            /// </summary>
+            NoCert,
+            /// <summary>
+            /// Plugin signature checks disabled.
+            /// </summary>
+            SigCheckDisabled
         }
     }
 }
diff --git a/ObservatoryCore/Properties/Core.Designer.cs b/ObservatoryCore/Properties/Core.Designer.cs
index bca9546..dd4d677 100644
--- a/ObservatoryCore/Properties/Core.Designer.cs
+++ b/ObservatoryCore/Properties/Core.Designer.cs
@@ -12,7 +12,7 @@ namespace Observatory.Properties {
     
     
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.2.0.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")]
     internal sealed partial class Core : global::System.Configuration.ApplicationSettingsBase {
         
         private static Core defaultInstance = ((Core)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Core())));
@@ -277,13 +277,12 @@ namespace Observatory.Properties {
         
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("Fixed width")]
-        public string ExportStyle {
+        public global::System.Collections.Specialized.StringCollection UnsignedAllowed {
             get {
-                return ((string)(this["ExportStyle"]));
+                return ((global::System.Collections.Specialized.StringCollection)(this["UnsignedAllowed"]));
             }
             set {
-                this["ExportStyle"] = value;
+                this["UnsignedAllowed"] = value;
             }
         }
     }
diff --git a/ObservatoryCore/Properties/Core.settings b/ObservatoryCore/Properties/Core.settings
index 77b31db..41dcaac 100644
--- a/ObservatoryCore/Properties/Core.settings
+++ b/ObservatoryCore/Properties/Core.settings
@@ -65,8 +65,8 @@
     <Setting Name="StartReadAll" Type="System.Boolean" Scope="User">
       <Value Profile="(Default)">False</Value>
     </Setting>
-    <Setting Name="ExportStyle" Type="System.String" Scope="User">
-      <Value Profile="(Default)">Fixed width</Value>
+    <Setting Name="UnsignedAllowed" Type="System.Collections.Specialized.StringCollection" Scope="User">
+      <Value Profile="(Default)" />
     </Setting>
   </Settings>
 </SettingsFile>
\ No newline at end of file
diff --git a/ObservatoryCore/Properties/Resources.Designer.cs b/ObservatoryCore/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..45bcf5a
--- /dev/null
+++ b/ObservatoryCore/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Observatory.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Observatory.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
diff --git a/ObservatoryCore/Properties/Resources.resx b/ObservatoryCore/Properties/Resources.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/ObservatoryCore/Properties/Resources.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/CoreForm.Designer.cs b/ObservatoryCore/UI/CoreForm.Designer.cs
new file mode 100644
index 0000000..785e87f
--- /dev/null
+++ b/ObservatoryCore/UI/CoreForm.Designer.cs
@@ -0,0 +1,705 @@
+namespace Observatory.UI
+{
+    partial class CoreForm
+    {
+        /// <summary>
+        ///  Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        ///  Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        ///  Required method for Designer support - do not modify
+        ///  the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CoreForm));
+            this.CoreMenu = new System.Windows.Forms.MenuStrip();
+            this.coreToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
+            this.CorePanel = new System.Windows.Forms.Panel();
+            this.VoiceSettingsPanel = new System.Windows.Forms.Panel();
+            this.VoiceSpeedSlider = new System.Windows.Forms.TrackBar();
+            this.VoiceVolumeSlider = new System.Windows.Forms.TrackBar();
+            this.VoiceTestButton = new System.Windows.Forms.Button();
+            this.VoiceCheckbox = new System.Windows.Forms.CheckBox();
+            this.VoiceDropdown = new System.Windows.Forms.ComboBox();
+            this.VoiceLabel = new System.Windows.Forms.Label();
+            this.VoiceSpeedLabel = new System.Windows.Forms.Label();
+            this.VoiceVolumeLabel = new System.Windows.Forms.Label();
+            this.VoiceNotificationLabel = new System.Windows.Forms.Label();
+            this.PopupSettingsPanel = new System.Windows.Forms.Panel();
+            this.DurationSpinner = new System.Windows.Forms.NumericUpDown();
+            this.ScaleSpinner = new System.Windows.Forms.NumericUpDown();
+            this.LabelColour = new System.Windows.Forms.Label();
+            this.TestButton = new System.Windows.Forms.Button();
+            this.ColourButton = new System.Windows.Forms.Button();
+            this.PopupCheckbox = new System.Windows.Forms.CheckBox();
+            this.LabelDuration = new System.Windows.Forms.Label();
+            this.LabelScale = new System.Windows.Forms.Label();
+            this.FontDropdown = new System.Windows.Forms.ComboBox();
+            this.LabelFont = new System.Windows.Forms.Label();
+            this.CornerDropdown = new System.Windows.Forms.ComboBox();
+            this.DisplayDropdown = new System.Windows.Forms.ComboBox();
+            this.CornerLabel = new System.Windows.Forms.Label();
+            this.DisplayLabel = new System.Windows.Forms.Label();
+            this.PopupNotificationLabel = new System.Windows.Forms.Label();
+            this.PluginFolderButton = new System.Windows.Forms.Button();
+            this.PluginList = new System.Windows.Forms.ListView();
+            this.NameColumn = new System.Windows.Forms.ColumnHeader();
+            this.TypeColumn = new System.Windows.Forms.ColumnHeader();
+            this.VersionColumn = new System.Windows.Forms.ColumnHeader();
+            this.StatusColumn = new System.Windows.Forms.ColumnHeader();
+            this.ReadAllButton = new System.Windows.Forms.Button();
+            this.ToggleMonitorButton = new System.Windows.Forms.Button();
+            this.ClearButton = new System.Windows.Forms.Button();
+            this.ExportButton = new System.Windows.Forms.Button();
+            this.GithubLink = new System.Windows.Forms.LinkLabel();
+            this.DonateLink = new System.Windows.Forms.LinkLabel();
+            this.PopupColour = new System.Windows.Forms.ColorDialog();
+            this.CoreMenu.SuspendLayout();
+            this.CorePanel.SuspendLayout();
+            this.VoiceSettingsPanel.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.VoiceSpeedSlider)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.VoiceVolumeSlider)).BeginInit();
+            this.PopupSettingsPanel.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.DurationSpinner)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.ScaleSpinner)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // CoreMenu
+            // 
+            this.CoreMenu.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left)));
+            this.CoreMenu.AutoSize = false;
+            this.CoreMenu.BackColor = System.Drawing.Color.Black;
+            this.CoreMenu.Dock = System.Windows.Forms.DockStyle.None;
+            this.CoreMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.coreToolStripMenuItem,
+            this.toolStripMenuItem1});
+            this.CoreMenu.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
+            this.CoreMenu.Location = new System.Drawing.Point(0, 0);
+            this.CoreMenu.Name = "CoreMenu";
+            this.CoreMenu.Size = new System.Drawing.Size(120, 691);
+            this.CoreMenu.TabIndex = 0;
+            // 
+            // coreToolStripMenuItem
+            // 
+            this.coreToolStripMenuItem.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+            this.coreToolStripMenuItem.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+            this.coreToolStripMenuItem.Name = "coreToolStripMenuItem";
+            this.coreToolStripMenuItem.Size = new System.Drawing.Size(113, 36);
+            this.coreToolStripMenuItem.Text = "Core";
+            this.coreToolStripMenuItem.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // toolStripMenuItem1
+            // 
+            this.toolStripMenuItem1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+            this.toolStripMenuItem1.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+            this.toolStripMenuItem1.ForeColor = System.Drawing.Color.Gainsboro;
+            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+            this.toolStripMenuItem1.Size = new System.Drawing.Size(113, 36);
+            this.toolStripMenuItem1.Text = "<";
+            this.toolStripMenuItem1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // CorePanel
+            // 
+            this.CorePanel.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.CorePanel.AutoScroll = true;
+            this.CorePanel.Controls.Add(this.VoiceSettingsPanel);
+            this.CorePanel.Controls.Add(this.VoiceNotificationLabel);
+            this.CorePanel.Controls.Add(this.PopupSettingsPanel);
+            this.CorePanel.Controls.Add(this.PopupNotificationLabel);
+            this.CorePanel.Controls.Add(this.PluginFolderButton);
+            this.CorePanel.Controls.Add(this.PluginList);
+            this.CorePanel.Location = new System.Drawing.Point(123, 12);
+            this.CorePanel.Name = "CorePanel";
+            this.CorePanel.Size = new System.Drawing.Size(665, 679);
+            this.CorePanel.TabIndex = 1;
+            // 
+            // VoiceSettingsPanel
+            // 
+            this.VoiceSettingsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.VoiceSettingsPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
+            this.VoiceSettingsPanel.Controls.Add(this.VoiceSpeedSlider);
+            this.VoiceSettingsPanel.Controls.Add(this.VoiceVolumeSlider);
+            this.VoiceSettingsPanel.Controls.Add(this.VoiceTestButton);
+            this.VoiceSettingsPanel.Controls.Add(this.VoiceCheckbox);
+            this.VoiceSettingsPanel.Controls.Add(this.VoiceDropdown);
+            this.VoiceSettingsPanel.Controls.Add(this.VoiceLabel);
+            this.VoiceSettingsPanel.Controls.Add(this.VoiceSpeedLabel);
+            this.VoiceSettingsPanel.Controls.Add(this.VoiceVolumeLabel);
+            this.VoiceSettingsPanel.Location = new System.Drawing.Point(3, 426);
+            this.VoiceSettingsPanel.Name = "VoiceSettingsPanel";
+            this.VoiceSettingsPanel.Size = new System.Drawing.Size(659, 177);
+            this.VoiceSettingsPanel.TabIndex = 5;
+            this.VoiceSettingsPanel.Visible = false;
+            // 
+            // VoiceSpeedSlider
+            // 
+            this.VoiceSpeedSlider.Location = new System.Drawing.Point(121, 51);
+            this.VoiceSpeedSlider.Maximum = 100;
+            this.VoiceSpeedSlider.Name = "VoiceSpeedSlider";
+            this.VoiceSpeedSlider.Size = new System.Drawing.Size(120, 45);
+            this.VoiceSpeedSlider.TabIndex = 15;
+            this.VoiceSpeedSlider.TickFrequency = 10;
+            this.VoiceSpeedSlider.TickStyle = System.Windows.Forms.TickStyle.Both;
+            this.VoiceSpeedSlider.Value = 50;
+            this.VoiceSpeedSlider.Scroll += new System.EventHandler(this.VoiceSpeedSlider_Scroll);
+            // 
+            // VoiceVolumeSlider
+            // 
+            this.VoiceVolumeSlider.LargeChange = 10;
+            this.VoiceVolumeSlider.Location = new System.Drawing.Point(120, 0);
+            this.VoiceVolumeSlider.Maximum = 100;
+            this.VoiceVolumeSlider.Name = "VoiceVolumeSlider";
+            this.VoiceVolumeSlider.Size = new System.Drawing.Size(121, 45);
+            this.VoiceVolumeSlider.TabIndex = 14;
+            this.VoiceVolumeSlider.TickFrequency = 10;
+            this.VoiceVolumeSlider.TickStyle = System.Windows.Forms.TickStyle.Both;
+            this.VoiceVolumeSlider.Value = 100;
+            this.VoiceVolumeSlider.Scroll += new System.EventHandler(this.VoiceVolumeSlider_Scroll);
+            // 
+            // VoiceTestButton
+            // 
+            this.VoiceTestButton.BackColor = System.Drawing.Color.DimGray;
+            this.VoiceTestButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.VoiceTestButton.ForeColor = System.Drawing.Color.WhiteSmoke;
+            this.VoiceTestButton.Location = new System.Drawing.Point(190, 131);
+            this.VoiceTestButton.Name = "VoiceTestButton";
+            this.VoiceTestButton.Size = new System.Drawing.Size(51, 23);
+            this.VoiceTestButton.TabIndex = 13;
+            this.VoiceTestButton.Text = "Test";
+            this.VoiceTestButton.UseVisualStyleBackColor = false;
+            // 
+            // VoiceCheckbox
+            // 
+            this.VoiceCheckbox.AutoSize = true;
+            this.VoiceCheckbox.ForeColor = System.Drawing.Color.Gainsboro;
+            this.VoiceCheckbox.Location = new System.Drawing.Point(120, 134);
+            this.VoiceCheckbox.Name = "VoiceCheckbox";
+            this.VoiceCheckbox.Size = new System.Drawing.Size(68, 19);
+            this.VoiceCheckbox.TabIndex = 11;
+            this.VoiceCheckbox.Text = "Enabled";
+            this.VoiceCheckbox.UseVisualStyleBackColor = true;
+            this.VoiceCheckbox.CheckedChanged += new System.EventHandler(this.VoiceCheckbox_CheckedChanged);
+            // 
+            // VoiceDropdown
+            // 
+            this.VoiceDropdown.FormattingEnabled = true;
+            this.VoiceDropdown.Location = new System.Drawing.Point(121, 102);
+            this.VoiceDropdown.Name = "VoiceDropdown";
+            this.VoiceDropdown.Size = new System.Drawing.Size(121, 23);
+            this.VoiceDropdown.TabIndex = 5;
+            this.VoiceDropdown.SelectedIndexChanged += new System.EventHandler(this.VoiceDropdown_SelectedIndexChanged);
+            // 
+            // VoiceLabel
+            // 
+            this.VoiceLabel.AutoSize = true;
+            this.VoiceLabel.ForeColor = System.Drawing.Color.Gainsboro;
+            this.VoiceLabel.Location = new System.Drawing.Point(77, 105);
+            this.VoiceLabel.Name = "VoiceLabel";
+            this.VoiceLabel.Size = new System.Drawing.Size(38, 15);
+            this.VoiceLabel.TabIndex = 4;
+            this.VoiceLabel.Text = "Voice:";
+            this.VoiceLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // VoiceSpeedLabel
+            // 
+            this.VoiceSpeedLabel.AutoSize = true;
+            this.VoiceSpeedLabel.ForeColor = System.Drawing.Color.Gainsboro;
+            this.VoiceSpeedLabel.Location = new System.Drawing.Point(73, 63);
+            this.VoiceSpeedLabel.Name = "VoiceSpeedLabel";
+            this.VoiceSpeedLabel.Size = new System.Drawing.Size(42, 15);
+            this.VoiceSpeedLabel.TabIndex = 1;
+            this.VoiceSpeedLabel.Text = "Speed:";
+            this.VoiceSpeedLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // VoiceVolumeLabel
+            // 
+            this.VoiceVolumeLabel.AutoSize = true;
+            this.VoiceVolumeLabel.ForeColor = System.Drawing.Color.Gainsboro;
+            this.VoiceVolumeLabel.Location = new System.Drawing.Point(64, 12);
+            this.VoiceVolumeLabel.Name = "VoiceVolumeLabel";
+            this.VoiceVolumeLabel.Size = new System.Drawing.Size(50, 15);
+            this.VoiceVolumeLabel.TabIndex = 0;
+            this.VoiceVolumeLabel.Text = "Volume:";
+            this.VoiceVolumeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // VoiceNotificationLabel
+            // 
+            this.VoiceNotificationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.VoiceNotificationLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+            this.VoiceNotificationLabel.ForeColor = System.Drawing.Color.LightGray;
+            this.VoiceNotificationLabel.Location = new System.Drawing.Point(3, 403);
+            this.VoiceNotificationLabel.Name = "VoiceNotificationLabel";
+            this.VoiceNotificationLabel.Size = new System.Drawing.Size(659, 23);
+            this.VoiceNotificationLabel.TabIndex = 4;
+            this.VoiceNotificationLabel.Text = "❯ Voice Notifications";
+            this.VoiceNotificationLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            this.VoiceNotificationLabel.Click += new System.EventHandler(this.VoiceNotificationLabel_Click);
+            // 
+            // PopupSettingsPanel
+            // 
+            this.PopupSettingsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.PopupSettingsPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
+            this.PopupSettingsPanel.Controls.Add(this.DurationSpinner);
+            this.PopupSettingsPanel.Controls.Add(this.ScaleSpinner);
+            this.PopupSettingsPanel.Controls.Add(this.LabelColour);
+            this.PopupSettingsPanel.Controls.Add(this.TestButton);
+            this.PopupSettingsPanel.Controls.Add(this.ColourButton);
+            this.PopupSettingsPanel.Controls.Add(this.PopupCheckbox);
+            this.PopupSettingsPanel.Controls.Add(this.LabelDuration);
+            this.PopupSettingsPanel.Controls.Add(this.LabelScale);
+            this.PopupSettingsPanel.Controls.Add(this.FontDropdown);
+            this.PopupSettingsPanel.Controls.Add(this.LabelFont);
+            this.PopupSettingsPanel.Controls.Add(this.CornerDropdown);
+            this.PopupSettingsPanel.Controls.Add(this.DisplayDropdown);
+            this.PopupSettingsPanel.Controls.Add(this.CornerLabel);
+            this.PopupSettingsPanel.Controls.Add(this.DisplayLabel);
+            this.PopupSettingsPanel.Location = new System.Drawing.Point(3, 195);
+            this.PopupSettingsPanel.Name = "PopupSettingsPanel";
+            this.PopupSettingsPanel.Size = new System.Drawing.Size(659, 208);
+            this.PopupSettingsPanel.TabIndex = 3;
+            this.PopupSettingsPanel.Visible = false;
+            // 
+            // DurationSpinner
+            // 
+            this.DurationSpinner.BackColor = System.Drawing.Color.DimGray;
+            this.DurationSpinner.ForeColor = System.Drawing.Color.Gainsboro;
+            this.DurationSpinner.Increment = new decimal(new int[] {
+            25,
+            0,
+            0,
+            0});
+            this.DurationSpinner.Location = new System.Drawing.Point(121, 119);
+            this.DurationSpinner.Maximum = new decimal(new int[] {
+            60000,
+            0,
+            0,
+            0});
+            this.DurationSpinner.Minimum = new decimal(new int[] {
+            100,
+            0,
+            0,
+            0});
+            this.DurationSpinner.Name = "DurationSpinner";
+            this.DurationSpinner.Size = new System.Drawing.Size(120, 23);
+            this.DurationSpinner.TabIndex = 15;
+            this.DurationSpinner.Value = new decimal(new int[] {
+            8000,
+            0,
+            0,
+            0});
+            this.DurationSpinner.ValueChanged += new System.EventHandler(this.DurationSpinner_ValueChanged);
+            // 
+            // ScaleSpinner
+            // 
+            this.ScaleSpinner.BackColor = System.Drawing.Color.DimGray;
+            this.ScaleSpinner.ForeColor = System.Drawing.Color.Gainsboro;
+            this.ScaleSpinner.Location = new System.Drawing.Point(121, 90);
+            this.ScaleSpinner.Maximum = new decimal(new int[] {
+            500,
+            0,
+            0,
+            0});
+            this.ScaleSpinner.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            this.ScaleSpinner.Name = "ScaleSpinner";
+            this.ScaleSpinner.Size = new System.Drawing.Size(120, 23);
+            this.ScaleSpinner.TabIndex = 14;
+            this.ScaleSpinner.Value = new decimal(new int[] {
+            100,
+            0,
+            0,
+            0});
+            this.ScaleSpinner.ValueChanged += new System.EventHandler(this.ScaleSpinner_ValueChanged);
+            // 
+            // LabelColour
+            // 
+            this.LabelColour.AutoSize = true;
+            this.LabelColour.ForeColor = System.Drawing.Color.Gainsboro;
+            this.LabelColour.Location = new System.Drawing.Point(68, 152);
+            this.LabelColour.Name = "LabelColour";
+            this.LabelColour.Size = new System.Drawing.Size(46, 15);
+            this.LabelColour.TabIndex = 13;
+            this.LabelColour.Text = "Colour:";
+            this.LabelColour.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // TestButton
+            // 
+            this.TestButton.BackColor = System.Drawing.Color.DimGray;
+            this.TestButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.TestButton.ForeColor = System.Drawing.Color.WhiteSmoke;
+            this.TestButton.Location = new System.Drawing.Point(190, 148);
+            this.TestButton.Name = "TestButton";
+            this.TestButton.Size = new System.Drawing.Size(51, 23);
+            this.TestButton.TabIndex = 12;
+            this.TestButton.Text = "Test";
+            this.TestButton.UseVisualStyleBackColor = false;
+            // 
+            // ColourButton
+            // 
+            this.ColourButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.ColourButton.Location = new System.Drawing.Point(121, 148);
+            this.ColourButton.Name = "ColourButton";
+            this.ColourButton.Size = new System.Drawing.Size(51, 23);
+            this.ColourButton.TabIndex = 11;
+            this.ColourButton.UseVisualStyleBackColor = true;
+            this.ColourButton.Click += new System.EventHandler(this.ColourButton_Click);
+            // 
+            // PopupCheckbox
+            // 
+            this.PopupCheckbox.AutoSize = true;
+            this.PopupCheckbox.ForeColor = System.Drawing.Color.Gainsboro;
+            this.PopupCheckbox.Location = new System.Drawing.Point(120, 177);
+            this.PopupCheckbox.Name = "PopupCheckbox";
+            this.PopupCheckbox.Size = new System.Drawing.Size(68, 19);
+            this.PopupCheckbox.TabIndex = 10;
+            this.PopupCheckbox.Text = "Enabled";
+            this.PopupCheckbox.UseVisualStyleBackColor = true;
+            this.PopupCheckbox.CheckedChanged += new System.EventHandler(this.PopupCheckbox_CheckedChanged);
+            // 
+            // LabelDuration
+            // 
+            this.LabelDuration.AutoSize = true;
+            this.LabelDuration.ForeColor = System.Drawing.Color.Gainsboro;
+            this.LabelDuration.Location = new System.Drawing.Point(32, 121);
+            this.LabelDuration.Name = "LabelDuration";
+            this.LabelDuration.Size = new System.Drawing.Size(83, 15);
+            this.LabelDuration.TabIndex = 9;
+            this.LabelDuration.Text = "Duration (ms):";
+            this.LabelDuration.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // LabelScale
+            // 
+            this.LabelScale.AutoSize = true;
+            this.LabelScale.ForeColor = System.Drawing.Color.Gainsboro;
+            this.LabelScale.Location = new System.Drawing.Point(57, 92);
+            this.LabelScale.Name = "LabelScale";
+            this.LabelScale.Size = new System.Drawing.Size(58, 15);
+            this.LabelScale.TabIndex = 7;
+            this.LabelScale.Text = "Scale (%):";
+            this.LabelScale.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // FontDropdown
+            // 
+            this.FontDropdown.FormattingEnabled = true;
+            this.FontDropdown.Location = new System.Drawing.Point(120, 61);
+            this.FontDropdown.Name = "FontDropdown";
+            this.FontDropdown.Size = new System.Drawing.Size(121, 23);
+            this.FontDropdown.TabIndex = 5;
+            this.FontDropdown.SelectedIndexChanged += new System.EventHandler(this.FontDropdown_SelectedIndexChanged);
+            // 
+            // LabelFont
+            // 
+            this.LabelFont.AutoSize = true;
+            this.LabelFont.ForeColor = System.Drawing.Color.Gainsboro;
+            this.LabelFont.Location = new System.Drawing.Point(80, 64);
+            this.LabelFont.Name = "LabelFont";
+            this.LabelFont.Size = new System.Drawing.Size(34, 15);
+            this.LabelFont.TabIndex = 4;
+            this.LabelFont.Text = "Font:";
+            this.LabelFont.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // CornerDropdown
+            // 
+            this.CornerDropdown.FormattingEnabled = true;
+            this.CornerDropdown.Items.AddRange(new object[] {
+            "Bottom-Right",
+            "Bottom-Left",
+            "Top-Right",
+            "Top-Left"});
+            this.CornerDropdown.Location = new System.Drawing.Point(120, 32);
+            this.CornerDropdown.Name = "CornerDropdown";
+            this.CornerDropdown.Size = new System.Drawing.Size(121, 23);
+            this.CornerDropdown.TabIndex = 3;
+            this.CornerDropdown.SelectedIndexChanged += new System.EventHandler(this.CornerDropdown_SelectedIndexChanged);
+            // 
+            // DisplayDropdown
+            // 
+            this.DisplayDropdown.FormattingEnabled = true;
+            this.DisplayDropdown.Location = new System.Drawing.Point(120, 3);
+            this.DisplayDropdown.Name = "DisplayDropdown";
+            this.DisplayDropdown.Size = new System.Drawing.Size(121, 23);
+            this.DisplayDropdown.TabIndex = 2;
+            this.DisplayDropdown.SelectedIndexChanged += new System.EventHandler(this.DisplayDropdown_SelectedIndexChanged);
+            // 
+            // CornerLabel
+            // 
+            this.CornerLabel.AutoSize = true;
+            this.CornerLabel.ForeColor = System.Drawing.Color.Gainsboro;
+            this.CornerLabel.Location = new System.Drawing.Point(68, 35);
+            this.CornerLabel.Name = "CornerLabel";
+            this.CornerLabel.Size = new System.Drawing.Size(46, 15);
+            this.CornerLabel.TabIndex = 1;
+            this.CornerLabel.Text = "Corner:";
+            this.CornerLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // DisplayLabel
+            // 
+            this.DisplayLabel.AutoSize = true;
+            this.DisplayLabel.ForeColor = System.Drawing.Color.Gainsboro;
+            this.DisplayLabel.Location = new System.Drawing.Point(66, 6);
+            this.DisplayLabel.Name = "DisplayLabel";
+            this.DisplayLabel.Size = new System.Drawing.Size(48, 15);
+            this.DisplayLabel.TabIndex = 0;
+            this.DisplayLabel.Text = "Display:";
+            this.DisplayLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            // 
+            // PopupNotificationLabel
+            // 
+            this.PopupNotificationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.PopupNotificationLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+            this.PopupNotificationLabel.ForeColor = System.Drawing.Color.LightGray;
+            this.PopupNotificationLabel.Location = new System.Drawing.Point(3, 172);
+            this.PopupNotificationLabel.Name = "PopupNotificationLabel";
+            this.PopupNotificationLabel.Size = new System.Drawing.Size(659, 23);
+            this.PopupNotificationLabel.TabIndex = 2;
+            this.PopupNotificationLabel.Text = "❯ Popup Notifications";
+            this.PopupNotificationLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            this.PopupNotificationLabel.Click += new System.EventHandler(this.PopupNotificationLabel_Click);
+            // 
+            // PluginFolderButton
+            // 
+            this.PluginFolderButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.PluginFolderButton.BackColor = System.Drawing.Color.DimGray;
+            this.PluginFolderButton.FlatAppearance.BorderSize = 0;
+            this.PluginFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.PluginFolderButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+            this.PluginFolderButton.Location = new System.Drawing.Point(532, 140);
+            this.PluginFolderButton.Name = "PluginFolderButton";
+            this.PluginFolderButton.Size = new System.Drawing.Size(130, 23);
+            this.PluginFolderButton.TabIndex = 1;
+            this.PluginFolderButton.Text = "Open Plugin Folder";
+            this.PluginFolderButton.UseVisualStyleBackColor = false;
+            // 
+            // PluginList
+            // 
+            this.PluginList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.PluginList.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
+            this.PluginList.BorderStyle = System.Windows.Forms.BorderStyle.None;
+            this.PluginList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.NameColumn,
+            this.TypeColumn,
+            this.VersionColumn,
+            this.StatusColumn});
+            this.PluginList.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+            this.PluginList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
+            this.PluginList.Location = new System.Drawing.Point(3, 3);
+            this.PluginList.MultiSelect = false;
+            this.PluginList.Name = "PluginList";
+            this.PluginList.OwnerDraw = true;
+            this.PluginList.Scrollable = false;
+            this.PluginList.Size = new System.Drawing.Size(659, 137);
+            this.PluginList.TabIndex = 0;
+            this.PluginList.UseCompatibleStateImageBehavior = false;
+            this.PluginList.View = System.Windows.Forms.View.Details;
+            this.PluginList.Resize += new System.EventHandler(this.PluginList_Resize);
+            // 
+            // NameColumn
+            // 
+            this.NameColumn.Text = "Plugin";
+            this.NameColumn.Width = 180;
+            // 
+            // TypeColumn
+            // 
+            this.TypeColumn.Text = "Type";
+            this.TypeColumn.Width = 120;
+            // 
+            // VersionColumn
+            // 
+            this.VersionColumn.Text = "Version";
+            this.VersionColumn.Width = 120;
+            // 
+            // StatusColumn
+            // 
+            this.StatusColumn.Text = "Status";
+            // 
+            // ReadAllButton
+            // 
+            this.ReadAllButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.ReadAllButton.BackColor = System.Drawing.Color.DimGray;
+            this.ReadAllButton.FlatAppearance.BorderSize = 0;
+            this.ReadAllButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.ReadAllButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+            this.ReadAllButton.Location = new System.Drawing.Point(713, 698);
+            this.ReadAllButton.Name = "ReadAllButton";
+            this.ReadAllButton.Size = new System.Drawing.Size(75, 23);
+            this.ReadAllButton.TabIndex = 2;
+            this.ReadAllButton.Text = "Read All";
+            this.ReadAllButton.UseVisualStyleBackColor = false;
+            this.ReadAllButton.Click += new System.EventHandler(this.ReadAllButton_Click);
+            // 
+            // ToggleMonitorButton
+            // 
+            this.ToggleMonitorButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.ToggleMonitorButton.BackColor = System.Drawing.Color.DimGray;
+            this.ToggleMonitorButton.FlatAppearance.BorderSize = 0;
+            this.ToggleMonitorButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.ToggleMonitorButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+            this.ToggleMonitorButton.Location = new System.Drawing.Point(610, 698);
+            this.ToggleMonitorButton.Name = "ToggleMonitorButton";
+            this.ToggleMonitorButton.Size = new System.Drawing.Size(97, 23);
+            this.ToggleMonitorButton.TabIndex = 3;
+            this.ToggleMonitorButton.Text = "Start Monitor";
+            this.ToggleMonitorButton.UseVisualStyleBackColor = false;
+            // 
+            // ClearButton
+            // 
+            this.ClearButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.ClearButton.BackColor = System.Drawing.Color.DimGray;
+            this.ClearButton.FlatAppearance.BorderSize = 0;
+            this.ClearButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.ClearButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+            this.ClearButton.Location = new System.Drawing.Point(529, 698);
+            this.ClearButton.Name = "ClearButton";
+            this.ClearButton.Size = new System.Drawing.Size(75, 23);
+            this.ClearButton.TabIndex = 4;
+            this.ClearButton.Text = "Clear";
+            this.ClearButton.UseVisualStyleBackColor = false;
+            // 
+            // ExportButton
+            // 
+            this.ExportButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.ExportButton.BackColor = System.Drawing.Color.DimGray;
+            this.ExportButton.FlatAppearance.BorderSize = 0;
+            this.ExportButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.ExportButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
+            this.ExportButton.Location = new System.Drawing.Point(448, 698);
+            this.ExportButton.Name = "ExportButton";
+            this.ExportButton.Size = new System.Drawing.Size(75, 23);
+            this.ExportButton.TabIndex = 5;
+            this.ExportButton.Text = "Export";
+            this.ExportButton.UseVisualStyleBackColor = false;
+            // 
+            // GithubLink
+            // 
+            this.GithubLink.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.GithubLink.AutoSize = true;
+            this.GithubLink.LinkColor = System.Drawing.Color.White;
+            this.GithubLink.Location = new System.Drawing.Point(12, 694);
+            this.GithubLink.Name = "GithubLink";
+            this.GithubLink.Size = new System.Drawing.Size(42, 15);
+            this.GithubLink.TabIndex = 6;
+            this.GithubLink.TabStop = true;
+            this.GithubLink.Text = "github";
+            // 
+            // DonateLink
+            // 
+            this.DonateLink.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.DonateLink.AutoSize = true;
+            this.DonateLink.LinkColor = System.Drawing.Color.White;
+            this.DonateLink.Location = new System.Drawing.Point(12, 709);
+            this.DonateLink.Name = "DonateLink";
+            this.DonateLink.Size = new System.Drawing.Size(45, 15);
+            this.DonateLink.TabIndex = 7;
+            this.DonateLink.TabStop = true;
+            this.DonateLink.Text = "Donate";
+            // 
+            // CoreForm
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.BackColor = System.Drawing.Color.Black;
+            this.ClientSize = new System.Drawing.Size(800, 733);
+            this.Controls.Add(this.DonateLink);
+            this.Controls.Add(this.GithubLink);
+            this.Controls.Add(this.ExportButton);
+            this.Controls.Add(this.ClearButton);
+            this.Controls.Add(this.ToggleMonitorButton);
+            this.Controls.Add(this.ReadAllButton);
+            this.Controls.Add(this.CorePanel);
+            this.Controls.Add(this.CoreMenu);
+            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+            this.MainMenuStrip = this.CoreMenu;
+            this.Name = "CoreForm";
+            this.Text = "Elite Observatory Core";
+            this.CoreMenu.ResumeLayout(false);
+            this.CoreMenu.PerformLayout();
+            this.CorePanel.ResumeLayout(false);
+            this.VoiceSettingsPanel.ResumeLayout(false);
+            this.VoiceSettingsPanel.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.VoiceSpeedSlider)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.VoiceVolumeSlider)).EndInit();
+            this.PopupSettingsPanel.ResumeLayout(false);
+            this.PopupSettingsPanel.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.DurationSpinner)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.ScaleSpinner)).EndInit();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private MenuStrip CoreMenu;
+        private ToolStripMenuItem coreToolStripMenuItem;
+        private Panel CorePanel;
+        private Button ReadAllButton;
+        private Button ToggleMonitorButton;
+        private Button ClearButton;
+        private Button ExportButton;
+        private LinkLabel GithubLink;
+        private LinkLabel DonateLink;
+        private ListView PluginList;
+        private ColumnHeader NameColumn;
+        private ColumnHeader TypeColumn;
+        private ColumnHeader VersionColumn;
+        private ColumnHeader StatusColumn;
+        private Button PluginFolderButton;
+        private Panel PopupSettingsPanel;
+        private ComboBox CornerDropdown;
+        private ComboBox DisplayDropdown;
+        private Label CornerLabel;
+        private Label DisplayLabel;
+        private Label PopupNotificationLabel;
+        private NumericUpDown DurationSpinner;
+        private NumericUpDown ScaleSpinner;
+        private Label LabelColour;
+        private Button TestButton;
+        private Button ColourButton;
+        private CheckBox PopupCheckbox;
+        private Label LabelDuration;
+        private Label LabelScale;
+        private ComboBox FontDropdown;
+        private Label LabelFont;
+        private ColorDialog PopupColour;
+        private ToolStripMenuItem toolStripMenuItem1;
+        private Panel VoiceSettingsPanel;
+        private TrackBar VoiceSpeedSlider;
+        private TrackBar VoiceVolumeSlider;
+        private Button VoiceTestButton;
+        private CheckBox VoiceCheckbox;
+        private ComboBox VoiceDropdown;
+        private Label VoiceLabel;
+        private Label VoiceSpeedLabel;
+        private Label VoiceVolumeLabel;
+        private Label VoiceNotificationLabel;
+    }
+}
\ No newline at end of file
diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
new file mode 100644
index 0000000..e3da322
--- /dev/null
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -0,0 +1,418 @@
+using Observatory.Framework.Interfaces;
+using Observatory.PluginManagement;
+using Observatory.Utils;
+
+namespace Observatory.UI
+{
+    public partial class CoreForm : Form
+    {
+        private Dictionary<object, Panel> uiPanels;
+
+        public CoreForm()
+        {
+            InitializeComponent();
+
+            PopulateDropdownOptions();
+            PopulateNativeSettings();
+
+            ColourListHeader(ref PluginList, Color.DarkSlateGray, Color.LightGray);
+            PopulatePluginList();
+            FitColumns();
+            string version = System.Reflection.Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0";
+            Text += $" - v{version}";
+            CoreMenu.SizeChanged += CoreMenu_SizeChanged;
+            uiPanels = new();
+            uiPanels.Add(coreToolStripMenuItem, CorePanel);
+            pluginList = new Dictionary<string, ToolStripMenuItem>();
+            CreatePluginTabs();
+            CreatePluginSettings();
+            CoreMenu.ItemClicked += CoreMenu_ItemClicked;
+
+            PreCollapsePanels();
+        }
+
+        private void PreCollapsePanels()
+        {
+            AdjustPanelsBelow(VoiceSettingsPanel, AdjustmentDirection.Up);
+            AdjustPanelsBelow(PopupSettingsPanel, AdjustmentDirection.Up);
+        }
+
+        private void PopulateDropdownOptions()
+        {
+            var fonts = new System.Drawing.Text.InstalledFontCollection().Families;
+            FontDropdown.Items.AddRange(fonts.Select(f => f.Name).ToArray());
+
+            DisplayDropdown.Items.Add("Primary");
+            if (Screen.AllScreens.Length > 1)
+                for (int i = 0; i < Screen.AllScreens.Length; i++)
+                    DisplayDropdown.Items.Add((i + 1).ToString());
+
+            var voices = new System.Speech.Synthesis.SpeechSynthesizer().GetInstalledVoices();
+            foreach (var voice in voices.Select(v => v.VoiceInfo.Name))
+                VoiceDropdown.Items.Add(voice);
+            
+        }
+
+        private void PopulateNativeSettings()
+        {
+            var settings = Properties.Core.Default;
+
+            DisplayDropdown.SelectedIndex = settings.NativeNotifyScreen + 1;
+            CornerDropdown.SelectedIndex = settings.NativeNotifyCorner;
+            FontDropdown.SelectedItem = settings.NativeNotifyFont;
+            ScaleSpinner.Value = settings.NativeNotifyScale;
+            DurationSpinner.Value = settings.NativeNotifyTimeout;
+            ColourButton.BackColor = Color.FromArgb((int)settings.NativeNotifyColour);
+            PopupCheckbox.Checked = settings.NativeNotify;
+            VoiceVolumeSlider.Value = settings.VoiceVolume;
+            VoiceSpeedSlider.Value = settings.VoiceRate;
+            VoiceDropdown.SelectedItem = settings.VoiceSelected;
+            VoiceCheckbox.Checked = settings.VoiceNotify;
+        }
+
+
+        private void CoreMenu_SizeChanged(object? sender, EventArgs e)
+        {
+            CorePanel.Location = new Point(12 + CoreMenu.Width, 12);
+            CorePanel.Width = Width - CoreMenu.Width - 40;
+
+        }
+
+        private Dictionary<string, ToolStripMenuItem> pluginList;
+
+        private void CreatePluginTabs()
+        {
+            var uiPlugins = PluginManager.GetInstance.workerPlugins.Where(p => p.plugin.PluginUI.PluginUIType != Framework.PluginUI.UIType.None);
+
+            PluginHelper.CreatePluginTabs(CoreMenu, uiPlugins, uiPanels);
+
+            foreach(ToolStripMenuItem item in CoreMenu.Items)
+            {
+                pluginList.Add(item.Text, item);
+            }
+        }
+
+        private void CreatePluginSettings()
+        {
+            foreach (var plugin in PluginManager.GetInstance.workerPlugins)
+            {
+                var pluginSettingsPanel = new SettingsPanel(plugin.plugin, AdjustPanelsBelow);
+                AddSettingsPanel(pluginSettingsPanel);
+            }
+            foreach (var plugin in PluginManager.GetInstance.notifyPlugins)
+            {
+                var pluginSettingsPanel = new SettingsPanel(plugin.plugin, AdjustPanelsBelow);
+                AddSettingsPanel(pluginSettingsPanel);
+            }
+        }
+
+        private void AddSettingsPanel(SettingsPanel panel)
+        {
+            int lowestPoint = 0;
+            foreach (Control control in CorePanel.Controls)
+            {
+                if (control.Location.Y + control.Height > lowestPoint)
+                    lowestPoint = control.Location.Y + control.Height;
+            }
+            panel.Header.Location = new Point(PopupNotificationLabel.Location.X, lowestPoint);
+            panel.Header.Width = PopupNotificationLabel.Width;
+            panel.Header.Font = PopupNotificationLabel.Font;
+            panel.Header.ForeColor = PopupNotificationLabel.ForeColor;
+            panel.Header.BackColor = PopupNotificationLabel.BackColor;
+            panel.Header.TextAlign = PopupNotificationLabel.TextAlign;
+            panel.Location = new Point(PopupNotificationLabel.Location.X, lowestPoint + panel.Header.Height);
+            panel.Width = PopupSettingsPanel.Width;
+            CorePanel.Controls.Add(panel.Header);
+            CorePanel.Controls.Add(panel);
+        }
+
+        private void PopulatePluginList()
+        {
+            List<IObservatoryPlugin> uniquePlugins = new();
+
+            
+            foreach (var (plugin, signed) in PluginManager.GetInstance.workerPlugins)
+            {
+                if (!uniquePlugins.Contains(plugin))
+                {
+                    uniquePlugins.Add(plugin);
+                    ListViewItem item = new ListViewItem(new[] { plugin.Name, "Worker", plugin.Version, PluginStatusString(signed) });
+                    PluginList.Items.Add(item);
+                }
+            }
+        }
+
+        private static string PluginStatusString(PluginManager.PluginStatus status)
+        {
+            switch (status)
+            {
+                case PluginManager.PluginStatus.Signed:
+                    return "Signed";
+                    
+                case PluginManager.PluginStatus.Unsigned:
+                    return "Unsigned";
+                    
+                case PluginManager.PluginStatus.InvalidSignature:
+                    return "Invalid Signature";
+                    
+                case PluginManager.PluginStatus.InvalidPlugin:
+                    return "Invalid Plugin";
+                    
+                case PluginManager.PluginStatus.InvalidLibrary:
+                    return "Invalid File";
+                    
+                case PluginManager.PluginStatus.NoCert:
+                    return "Unsigned Observatory (Debug build)";
+                    
+                case PluginManager.PluginStatus.SigCheckDisabled:
+                    return "Signature Checks Disabled";
+                    
+                default:
+                    return string.Empty;
+            }
+        }
+
+        private void CoreMenu_ItemClicked(object? _, ToolStripItemClickedEventArgs e)
+        {
+            
+            if (e.ClickedItem.Text == "<")
+            {
+                foreach (KeyValuePair<string, ToolStripMenuItem> menuItem in pluginList)
+                {
+                    if (menuItem.Value.Text == "<")
+                        menuItem.Value.Text = ">";
+                    else
+                        menuItem.Value.Text = menuItem.Key[..1];
+                }
+                CoreMenu.Width = 40;
+                CorePanel.Location = new Point(43, 12);
+                // CorePanel.Width += 40;
+            }
+            else if (e.ClickedItem.Text == ">")
+            {
+                foreach (KeyValuePair<string, ToolStripMenuItem> menuItem in pluginList)
+                {
+                    if (menuItem.Value.Text == ">")
+                        menuItem.Value.Text = "<";
+                    else
+                        menuItem.Value.Text = menuItem.Key;
+                }
+                CoreMenu.Width = 120;
+                CorePanel.Location = new Point(123, 12);
+                // CorePanel.Width -= 40;
+            }
+            else
+            {
+                foreach (var panel in uiPanels.Where(p => p.Key != e.ClickedItem))
+                {
+                    panel.Value.Visible = false;
+                }
+
+                if (!Controls.Contains(uiPanels[e.ClickedItem]))
+                {
+                    uiPanels[e.ClickedItem].Location = CorePanel.Location;
+                    uiPanels[e.ClickedItem].Size = CorePanel.Size;
+                    uiPanels[e.ClickedItem].BackColor = CorePanel.BackColor;
+                    Controls.Add(uiPanels[e.ClickedItem]);
+                }
+                uiPanels[e.ClickedItem].Visible = true;
+            }
+            
+        }
+
+        private static void ColourListHeader(ref ListView list, Color backColor, Color foreColor)
+        {
+            list.OwnerDraw = true;
+            
+            list.DrawColumnHeader +=
+                new DrawListViewColumnHeaderEventHandler
+                (
+                    (sender, e) => headerDraw(sender, e, backColor, foreColor)
+                );
+            list.DrawItem += new DrawListViewItemEventHandler(bodyDraw);
+        }
+
+        private static void headerDraw(object? _, DrawListViewColumnHeaderEventArgs e, Color backColor, Color foreColor)
+        {
+            using (SolidBrush backBrush = new(backColor))
+            {
+                e.Graphics.FillRectangle(backBrush, e.Bounds);
+            }
+
+            using (Pen borderBrush = new(Color.Black))
+            {
+                e.Graphics.DrawLine(borderBrush, e.Bounds.Left, e.Bounds.Top, e.Bounds.Left, e.Bounds.Bottom);
+                e.Graphics.DrawLine(borderBrush, e.Bounds.Right, e.Bounds.Top, e.Bounds.Right, e.Bounds.Bottom);
+            }
+
+            if (e.Font != null && e.Header != null)
+                using (SolidBrush foreBrush = new(foreColor))
+                {
+                    var format = new StringFormat();
+                    format.Alignment = (StringAlignment)e.Header.TextAlign;
+                    format.LineAlignment = StringAlignment.Center;
+                    
+                    var paddedBounds = new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width - 4, e.Bounds.Height - 4);
+
+                    e.Graphics.DrawString(e.Header?.Text, e.Font, foreBrush, paddedBounds, format);
+                }
+        }
+
+        private static void bodyDraw(object? _, DrawListViewItemEventArgs e)
+        {
+            e.DrawDefault = true;
+        }
+
+        private void PluginList_Resize(object sender, EventArgs e)
+        {
+            FitColumns();
+        }
+
+        private void FitColumns()
+        {
+            int totalWidth = 0;
+            foreach (ColumnHeader col in PluginList.Columns)
+                totalWidth += col.Width;
+
+            PluginList.Columns[3].Width += PluginList.Width - totalWidth;
+        }
+
+        private void ReadAllButton_Click(object sender, EventArgs e)
+        {
+            LogMonitor.GetInstance.ReadAllJournals();
+        }
+
+        private void PopupNotificationLabel_Click(object _, EventArgs e)
+        {
+            CorePanel.SuspendLayout();
+            if (PopupNotificationLabel.Text[0] == '❯')
+            {
+                PopupNotificationLabel.Text = PopupNotificationLabel.Text.Replace('❯', '⌵');
+                PopupSettingsPanel.Visible = true;
+                AdjustPanelsBelow(PopupSettingsPanel, AdjustmentDirection.Down);
+            }
+            else
+            {
+                PopupNotificationLabel.Text = PopupNotificationLabel.Text.Replace('⌵', '❯');
+                PopupSettingsPanel.Visible = false;
+                AdjustPanelsBelow(PopupSettingsPanel, AdjustmentDirection.Up);
+            }
+            CorePanel.ResumeLayout();
+        }
+
+        private void VoiceNotificationLabel_Click(object sender, EventArgs e)
+        {
+            CorePanel.SuspendLayout();
+            if (VoiceNotificationLabel.Text[0] == '❯')
+            {
+                VoiceNotificationLabel.Text = VoiceNotificationLabel.Text.Replace('❯', '⌵');
+                VoiceSettingsPanel.Visible = true;
+                AdjustPanelsBelow(VoiceSettingsPanel, AdjustmentDirection.Down);
+            }
+            else
+            {
+                VoiceNotificationLabel.Text = VoiceNotificationLabel.Text.Replace('⌵', '❯');
+                VoiceSettingsPanel.Visible = false;
+                AdjustPanelsBelow(VoiceSettingsPanel, AdjustmentDirection.Up);
+            }
+            CorePanel.ResumeLayout();
+        }
+
+        private void AdjustPanelsBelow(Control toggledControl, AdjustmentDirection adjustmentDirection)
+        {
+            var distance = adjustmentDirection == AdjustmentDirection.Down ? toggledControl.Height : -toggledControl.Height;
+            foreach (Control control in CorePanel.Controls)
+            {
+                var loc = control.Location;
+                if (loc.Y >= toggledControl.Location.Y && control != toggledControl)
+                {
+                    loc.Y = control.Location.Y + distance;
+                    control.Location = loc;
+                }
+            }
+        }
+
+        internal enum AdjustmentDirection
+        {
+            Up, Down
+        }
+
+        #region Settings Changes
+
+        private void ColourButton_Click(object _, EventArgs e)
+        {
+            var selectionResult = PopupColour.ShowDialog();
+            if (selectionResult == DialogResult.OK)
+            {
+                ColourButton.BackColor = PopupColour.Color;
+                Properties.Core.Default.NativeNotifyColour = (uint)PopupColour.Color.ToArgb();
+                Properties.Core.Default.Save();
+            }
+        }
+
+        private void PopupCheckbox_CheckedChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotify = PopupCheckbox.Checked;
+            Properties.Core.Default.Save();
+        }
+
+        private void DurationSpinner_ValueChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyTimeout = (int)DurationSpinner.Value;
+            Properties.Core.Default.Save();
+        }
+
+        private void ScaleSpinner_ValueChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyScale = (int)ScaleSpinner.Value;
+            Properties.Core.Default.Save();
+        }
+
+        private void FontDropdown_SelectedIndexChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyFont = FontDropdown.SelectedItem.ToString();
+            Properties.Core.Default.Save();
+        }
+
+        private void CornerDropdown_SelectedIndexChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyCorner = CornerDropdown.SelectedIndex;
+            Properties.Core.Default.Save();
+        }
+
+        private void DisplayDropdown_SelectedIndexChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyScreen = DisplayDropdown.SelectedIndex - 1;
+            Properties.Core.Default.Save();
+        }
+
+        private void VoiceVolumeSlider_Scroll(object _, EventArgs e)
+        {
+            Properties.Core.Default.VoiceVolume = VoiceVolumeSlider.Value;
+            Properties.Core.Default.Save();
+        }
+
+        private void VoiceSpeedSlider_Scroll(object _, EventArgs e)
+        {
+            Properties.Core.Default.VoiceRate = VoiceSpeedSlider.Value;
+            Properties.Core.Default.Save();
+        }
+
+        private void VoiceCheckbox_CheckedChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.VoiceNotify = VoiceCheckbox.Checked;
+            Properties.Core.Default.Save();
+        }
+
+        private void VoiceDropdown_SelectedIndexChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.VoiceSelected = VoiceDropdown.SelectedItem.ToString();
+            Properties.Core.Default.Save();
+        }
+
+
+        #endregion
+
+
+    }
+}
\ No newline at end of file
diff --git a/ObservatoryCore/UI/CoreForm.resx b/ObservatoryCore/UI/CoreForm.resx
new file mode 100644
index 0000000..7843956
--- /dev/null
+++ b/ObservatoryCore/UI/CoreForm.resx
@@ -0,0 +1,3662 @@
+<root>
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="CoreMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="PopupColour.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>126, 17</value>
+  </metadata>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        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
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAABXC5FC3Y/SByaTVwhYzdCFz8/PwQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpIVyOgV2ZmpVhon6laas2sW23nr11u6q5dbuquXG7q
+        p1lq3aJXZp2OTFsyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiU5YGqBXZ2+nW2vB
+        rV1v6LJdb+mzW3Dpslpw6bNacemxW3Lqslty6rNcceuwW2/qrl1t66pca+iZUmBsAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAlFBhPKVZaqCuXG7jsl1w6bJacumyW3TqsVh16a9XdOixWHXpsFl06rBYc+qwWHbr
+        sFd167FadOu0WnLsr1xt66tcbOuSUF5JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmlNkTKhaarqwXXDoslty6LJZdemwWXTo
+        slp16bFbdOmvW3Tor1py569Zc+avWnLnsFtz6rNcdeuwWnPqsFhz6rFXdOyzWnLsrlxs66NXZ8YAAAAB
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
+        nVNlSadZa76vXHDoslpz6K9XdOiyWnXpr1pz5qxZceOoV2/gqFZu36hXb+CpWHDhqlhv4qhYcOGmVm7g
+        plZu4KtYceazW3Psrlhy6rFXcuyxW2/tqlts7IpIWC4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAl1BjNqZZabOvW2/nsFp06K9ZdOivWnPnrFlx46lWcN+oV2/g
+        q1pw4qtZcOOqWW7iqFls4adYbOGpWG3iq1lu5KtZcearWG/kplZt4qdWbuOxXHTtr1dy7LBZcO2rWmzs
+        mlJiYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkUhbHKRYZ5mvXG7m
+        sFpz6LBZc+euWnLlq1lx4alYcN+rWXDiqVlt4aZYa96kWGncolZo2qNXaNukV2nbo1Zp3KNWaNyiVmfd
+        pVdp4KlYbeSqWG/mplVt4qtYb+etWHDrsFhz7a9bbe2aVGJ1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAfypVBqBUZW+rW2zdr1px569Zc+etWnHlqVhw4KlYcN+pWG/gplhr3qNWadqjVmjZ
+        oFRn1p9UZtWdVWfUnVRl05tTZdOcU2XVnlRn16FWaNuiVWjco1do3qhXbeWpV27mpFRs4q9acu2uVnLt
+        rltu7pVQYIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJhQYjmmWWrCr1pv569YcuetWnLl
+        qVdw4KlYcN+pWW3fpVhr26JXadigVGjVnVRm0ZpTZNCaVGTQmVRk0ZlUZNGaU2PSmlJj0phSY9KYUWHR
+        mVJk059TZdihVmfdoVZn4KlZb+elVmvjrFhw66tVcOyuW2/unFRkdQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAH9IWw6gVmeKrFtu5a9YcueuWHPmqVlw4alYbt+oWW3fo1Zq2qBVaNadVGXSmVJjz5lTY8+aVGTQ
+        m1Niz5pTY9CaUmPQmlBi0JpQYtCZUWHRmFJi0ZlUY9SZUmHTmFJh051UZtqgVmfepVZq5adVbuWrWHDq
+        q1Vw7K5bbu6aUmFjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWUWBCqFprzK5ZcOeuWHPmq1lv4qdYb96oWW3f
+        o1Zq2qBUaNWbVGTQmVNjz5lTY8+ZUmLPnFJiz5xSYs+bUWLPm1Fiz5lSYs+ZUWLPmlBi0JtQY9OcUGLU
+        mFBh0ZhSYtSYUmDTmFJk1qBVZt2kVmjjp1Zt5qhWbumsVG/trFls7pZOXUQAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/P1UM
+        n1Zmi6xab+WuV3LmrFly5KhWbt+oWW7fpFdp26BWaNWcU2XPmVJkzplSZM6aUWPOmlBjzppSYs2WT2DJ
+        k05dx5FMXMSPS1vDj0tbw5FNW8aTT13KlVBgzplPYNCbUWPVl1Fh0phTYtaVUGDTn1Rm3aFUZuKlVm3n
+        qFdu6qxWb+2rWWvucD1HGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlVFgNadYacasV2/mrFdy5qhXb+CmV2/epFhq3J9VZ9abVGTQ
+        mFNjzZlSY86aUWPOmlBjzZVPX8iQTVzCi0hYu4hHVbmHRlS4h0ZUuIZFVLiHRFS5hkVUuohGVbuMSVnC
+        lE9ezZZPX9CaUGLVl1Fh1JZRYNWaUWTboFRl4qVWbeenVmzqrFVv7qNVZdMAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/BJ1UY3OrWW3i
+        rFdx5qpXceOmV27ep1ds3aFXadicVGbRmFNjzZhTY82aUGPNmVBhy5FMXcSMSVi7iEdUt4JCUrB/QE+q
+        ej1LonU7Sp50OkecdDpJnXg9SqF9QE2rhUNTuIVFVLuJR1jBk01dz5hPYdSWUGDUlFFf1ZlQY9qfVWbj
+        olRr5qdWbeyqVm3vn1VkmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQMDAwUEREXKxAUF0wQExZcEBMVaRETFXcQFBaH
+        EhUXjRIVF4wRFReEERUXdRMTFmcSEhVSExMYNAwZGRQAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAIRLVBukV2ivrFhu5qtXceWoVm/gpldu3qJWatqeVGbTmVJkzphSY82aUGLN
+        l1Bhy5BNXMKJR1a5hENTsXxATqZ0OkeZbjdEkmo2QY1nNT6KZjQ9iWY0PYlnND+MajZAkm83Q5d2PEih
+        gkFRtoRFVLyPSlrJlU5f05VPXtWTT1/WmFFi251TZOSeUmjmp1Rt7qRTZ+6JTFdXAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVFRUMEhYWRBAUFnwSFRiz
+        ERUY5hIVF/kSFRj/EhUY/xIWGP8SFRj/EhUY/xIVGP8TFRj/ExUY/xMVGP8TFhj/ExUY/xMWGP8UFRj/
+        FBYY/RQVGOwUFRnIFRUZmBUVG14YGBgpAAAABAAAAAAAAAAAAAAAAAAAAACWUmBHqFlr1KtXceapV3Hj
+        pldu3qRWbN2fVWfWm1Jlz5hSYsyYUmPNl1Bhy5BNXcKJRle4gUJRrXc9Sp5tOEOQZzQ/iGI0PYRfMDt9
+        XC85fFstOHpbLTh6XS45fV4xO4FhMzuFZTQ9jGw2QpZ2PEilgkJQu4dGVsOTTl7TlExd1ZFPXdeVTmHc
+        mlJk5YhGWudhMT/uLxce6igNGhMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAA8XFyESFhlwExcYuBIWGPUUGBv/FRkb/xMXGf8UGBv/Fhod/xMXGv8TFxn/ExcZ/xMXGv8TFhn/
+        ExYZ/xMWGf8TFhn/FBYZ/xQWGf8UFhn/FBYZ/xUWGf8VFhn/FRYZ/xYWGf8XFxr/GBca/xkYG/8cGRzq
+        HxkeqSUcH1kzJiYUnVVlfatZbeSrV3HmqFZv4KZWbN2iVmnanFNl0pdTY82YUmLMmVBhy5NOXcSIR1i5
+        gEJRrHU7SJppNkGMYzQ+g1swOnpYLDdzUyo0a1AoMmZLJS9lSyUvZUslL2VPKDJqUSg0cFgsNnlgMjuE
+        ZDQ+jm03RJx/QE62g0NSwJBMW9KRTFvWiUpY12o4RN1AIijnIxEV6RwNEu8ZDRCtAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxcXFhQZG3AUFxvMFBgb/hQYG/8VGRz/GR8i/xsgJP8ZHyL/
+        GR4i/xsgJP8cIiX/GR4i/xccH/8XHCD/Fhse/xUZHP8VGBv/FRga/xUYGv8VFxr/FRca/xUXGv8VFxr/
+        FRYZ/xYXGv8XFxr/GBca/xkXG/8aGBz/HRkd/yAaHv8mHSL/NiQq/4tNW/usV2/3q1hw7aVWbd+kV2zd
+        nlVn1plSZM6YUmLMmFFhzJRPYMeLSVi7gkNSrnY8SptpN0KKYDI8f1ouNnRSKTJpTSYwY0gkL1xEIyxW
+        QiEqVT4iKFJAISdTQiIoWEYjLl5KJi5jTycxbVcrNXteMTqHZzQ+lnk8SbB/Qk/AeD9M0lEpM9YoFRrX
+        HQ8T4BoOEOgWCw/rFQoM7xQIDlkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFRkZOxMYG6cUGBv3
+        Fxwf/xshJP8fJSn/JSwx/yw1Ov8lLTP/KzQ6/ykyOP8pMjn/KjM6/yYvNv8oMTf/JzA2/ycwNv8mLzT/
+        JS0y/yQrL/8iJyz/HyQo/xwfI/8ZHB//GBod/xcYG/8XGBv/GBgb/xkYG/8aGBz/Gxgc/x4aHf8hGx//
+        Jx0i/0csNP+bVGX/rFhx/6lYcf+mV27/olhr/JtUZ+qYUmLRmFJizJdPYcqOTFy/hURUsnk9S55qN0OL
+        YTI8flgtNnFOKDJlSCQsW0IfKFE3HSRFMxsfQDIZHT0rFR46KxUeOi0ZHT0yFx9BOhsiSkMhKlpHJi1k
+        TigxcVguNoRdMDmTUSkyrDMaIcEeDxPTGw4Q1xcMENgWDA3jEwkN5xIIC+8QCQviFQAVDAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAACFhodThUbHcYbISX/IScr/ys0Of8xO0H/MTo//zdCSP87R07/N0JJ/ztIUP86R07/
+        OkdO/zlFTf85Rk7/Mj5H/zM/Sf8vOkL/MTxD/zE8Q/8zPkX/MTxC/y85Pv8uNjv/KjE2/yguM/8lKy//
+        IiUp/x4gJP8cHCD/Gxod/xwZHf8fGh7/Ixwh/yofJP9eOEL/p1ls/6xYcv+nWG//pVhu/6BXav+aVWb/
+        mFRk/5lSY/2ST1/liEdXwH5AUKVsOUWPYzM9gFgtOHFNKTBjRCMsVjkcI0cyGSE9LRQZMycQFi0gExMn
+        HA4VJBwOFSQhDRQmIxEXKysTGDUtFB09NBsfSUEjKF5AIShqMxkfgBwPEZEZCw6sFgsOwhUKDdUUCQ3X
+        EgoL2hEIC+YQCArpDgcJ7w4ICJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBwcPxofI8okKzD/Ljg+/zlES/87R03/
+        P0tS/0BNVP9BT1f/Q1Nb/0NTW/9EVV3/Q1Rc/0NVXf9CU1v/QlNc/z5OWP89TVb/OktV/zlIU/84RlL/
+        OEdR/zlGTv86Rk7/OkVL/zlCSf82QEb/NDxC/zI6P/8wNjz/LTI3/youM/8nKC3/JyUp/yYgJf8vIij/
+        dkRQ/6tacP+qWXH/pVhv/6RYbf+eVmj/mFRl/5hTZP+XUmP/jk1d/4NGVv90Pkv8ZjhCzFkwOn5PKDJk
+        RSQqVDgeJUQvFxw2KREXKx8PFyAdCRMaGg0NEw8PDxAREREPDw8PEBgMDBUbCRIcGw0UJSMUGTIkEBg/
+        Hg8SVRMJDGgSCgx+EQgMkREKC68QCQrFEAkK1g8JCdcOCAreDwcI5w4GCOwMBwjuCwUFLgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        FR0dIyAoLKwuOD7+PEhP/zZBR/85Rkz/Q1FY/0dWXf9KWmP/SVli/0pbZP9KXWb/SV1n/0tdZv9JW2T/
+        Rlli/0ZZYv9GV1//QlVf/0RVX/9BU13/QVRe/0JUXv9CU1z/QVBZ/0FOVv89SE//P0pR/z9JUf89Rk3/
+        O0RK/zlBR/84PkT/NDg+/zQ2PP81Mjn/PjE4/41PXv+rWXH/qVlx/6VYb/+iWGv/nFVn/5dUZP+YU2T/
+        lFFh/4lKWv98Q1H/azxH/2A2Qf9UMDr/Risz8jkiKZIwGBw1IRQaJh4UFBkTExMNAAAABQAAAAEAAAAA
+        AAAAAAAAAAAAAAAAAAAAAxUAFQwUCgoZDQYNJw0ICDoQBglNDgcJZw4ICH0PCAiSDwgJsw8HCsoOBwnX
+        DgcJ2A0GCeINBgfoCwYH7wwFCLUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/BCQuM3gyPUP2QlBY/z1LUv87SE7/O0hP/0dXYP9NYGn/
+        TV9o/05ibP9QZG3/T2Ru/09lb/9NY23/TF9p/0ZaY/9EVl7/RFRd/0laY/9KXmf/SmBr/0lfav9KXmj/
+        SVxl/0lYYf9KWGH/SVdg/0pVXP9ET1b/RE5V/z5GS/9ASVD/P0ZN/z5FS/8+Q0r/QEBH/1NCS/+cV2j/
+        q1ly/6hZcf+lWG//oFdq/5lVZv+XVGT/mFNk/49PXv+ER1b/cz9M/2U5RP9YMz3/TC02/z8oL/8zIyn/
+        KB8k/x4aHskbFxs3AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARIAAA4PBwcg
+        CQQJNAoHB0gMBwdnDAYIfw0GCJYMBgi5DQcI0AsHCNgLBgjbDAUH5goGBusKBQfvCgMGSwAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsyOiM3REnG
+        RVVd/0pcZf9DU1v/O0hP/z9OVf9HV1//UmRu/1Rpc/9VanT/VGhy/1FpdP9RZ3H/S11m/0peaP9JXWb/
+        Rllh/0NVXP9GWmP/TmVw/09oc/9PZnL/T2Js/1Fia/9PXWb/TFpi/0tZYf9NWmP/TFhg/0lUW/9KVV3/
+        TFde/0VNU/9GTFL/R0xT/0VFTP9lTln/pVtu/6xac/+nWXD/pFlv/55Yav+ZVWb/mFRl/5ZSY/+LS1v/
+        fURS/2s8R/9eNkD/UTA6/0QqM/82Iyr/KiAl/yQfJP8fHiH/HB0g/xoaHvkWGBp7AAAAAgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQkJCRoKBQUyCgcHSAkEB2gLBQeCCwYInQsGB8ELBQjV
+        CgUI2AsFBt8KBQboCQYH7woGBscAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABATVVfRlRe805gav9KXmj/SV5n/0hcZf9JXGX/T2Jr/1Vocv9WbHf/
+        Vm56/1Zwe/9VcHz/U2x4/01ia/9KXGT/R1pj/0leZ/9HW2P/TWVv/1Juev9TbXn/Umx4/1Rrdv9VaXT/
+        U2Nt/1Vlb/9UZG7/VGRt/1Jhaf9SYGn/UF1m/09bZP9PWWL/TVZe/05VXf9RU1v/dlVg/6pdcv+rW3T/
+        plpx/6Rabv+dWGr/mFZn/5lWZ/+UU2T/iE1c/3hEUf9mO0b/WDM9/0krNf85JCv/LB4k/yIcIf8gHiP/
+        Hh8j/x0fI/8cHiL/HB4i/xobH/8XGBu4ExMdGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
+        CwALFwoFBTEKAwZLCQQHawkFB4gKBgeoCwYGxwkFB9cKBQfaCgQG5QkFBuoIBQfwCAUFWgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4VFQJR1hgmUpdZ/9LYGr/
+        R1tl/0BQWP9CUlr/SFpi/1Jmb/9ZcHr/WnB7/1lxfP9ZdID/WHR//1dyfv9SanX/TmVv/0xha/9MYmz/
+        Sl1m/05mcP9Ub3v/Vmx2/1Rmbv9WaXP/VWhy/1VpdP9YanT/V2dx/1Vkbf9VZG7/VWRt/1Ria/9UYWr/
+        VGBq/1ReZ/9QVl3/Vlhg/4RaZv+sXnT/qlx0/6Zacf+jWm7/m1hq/5hXZ/+ZV2j/kVRk/4VNXf90R1T/
+        ZkFM/1c5RP9GMDn/MyQr/yUcIf8cGB3/GRgc/xgYG/8YGBz/GRsf/xodIf8aHiH/Gx4i/xkcH/8XGRzm
+        ExcaTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAVCgUFMgkGBlEJBAZwCAUFkAkFB7QJBgfP
+        CgUH2QoEBt0IBQXoCAUH7ggEBs8AAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAP1VfGEhaYsVDVl//SF5o/0tibf9LX2j/Sl1l/1Zsd/9ZcXz/XHR//1t0f/9adH//
+        XHR//1t2gv9bdYD/V3J9/1Nrdv9UbXj/VnB8/1Vsd/9XcHv/WXSA/1x2gf9cbnf/W295/1txfP9cb3n/
+        XG54/1psdv9ZaXT/Wmp0/1locv9XZW7/WWdx/1lmcP9ZZG3/WmNs/11dZ/+RYG//rF11/6pcdP+mW3H/
+        oVtt/5tYaf+ZWGj/mFdo/45TY/+BTl3/cUlV/2REUP9XQUz/SDpD/zo0PP8tLjT/IyMo/xscIP8XFxv/
+        FhYa/xUWGv8UFBj/FRYa/xgbH/8XGh3/Fhkc/xcZHf8VFxv9FRcbeAAAAAEAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAsACxcEBAQ1CAUFWQgEBnoIBQaYCQUGwAkEBdYJBAXZCAQF4wgFBuoIBQbwCAUFWgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFJudSVOY2vaQVNb/0ZaY/9JX2n/
+        T2Ru/1Npc/9OY2z/V255/1dyff9dd4L/XHaC/1dyfv9cdID/WnSA/113g/9ZdH//V3J+/1l1gf9bdYD/
+        W3iF/1t4hP9beIT/XXWA/112gv9ddYD/XnR//1xzfv9dcX3/XnB7/15vef9ba3X/Wmhx/1lncP9aZ3H/
+        XGhy/15ncv9lZHD/nGR0/61edv+pXXT/pVxx/6Bbbf+ZWGn/mVhp/5dYaf+LU2P/fU5d/25KV/9iR1P/
+        V0dS/0pETf8/QEj/NjxD/y80PP8nLDP/ICMp/xobIP8VFhr/ExQZ/xITGP8RExf/ExUZ/xgcH/8VGBv/
+        ExUZ/xMVGP8TFBj+ExQYkgAAAAMAAAAAAAAAAAAAAAAAAAABCQkJGwgEBDwHBQViBwUFhAkEB6gIBQbK
+        CQQF2QkEBdwIBQXnBwUG7gcDBsgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAABQZHImRlpj40dbZP9RanX/TmRt/09kbv9UbXj/U2dx/01iav9Ua3T/W3iE/1p1gP9UbHf/
+        Vm96/1hyff9UanT/Vm54/1d0gP9ZeYb/XHmE/1x2gf9efIn/X32K/2N+iv9hd4L/X3WA/190gP9fdoH/
+        X3aB/2B1gP9fcXv/XGx1/19veP9da3P/XWpz/19rdv9hanX/a2h0/6Jldv+tXnf/p110/6Vccf+fW23/
+        mVlq/5pZav+VWGn/iVRk/3pRXv9sTFn/XkdU/1FHU/9JSVP/Q0lT/z9HT/85QUn/MDhB/ykwOf8jKTL/
+        HyQr/xkcIf8TFRr/EhMY/xETF/8QExf/EhQY/xUZHP8RFBf/ERMW/xEUF/8SFBj/ExYZoQAAAAQAAAAA
+        AAAAAAAAAAMHBwciBwMHRgcEB20HBQWQCAUFuAgEBtQIBAXZBwQF4wcFBusIBQbwBgMGTQAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUmZyKE5kbehPaHP/WHN+/1VteP9bcn3/
+        V3B6/1Rtd/9TaXP/U2t1/1p2gv9ceYX/XXuI/1t4hP9adoH/V3F8/1Vqc/9Va3T/W3eD/15+i/9ifYn/
+        YnmF/2B+i/9jeIP/X3qG/19/jf9jhJH/YX2K/2B7iP9geoX/YXWA/2J0fv9jdH7/YXF7/2Jwe/9jcHv/
+        ZW96/3Jqdv+nZXf/rV53/6dddP+lXXH/nltt/5laav+aWWr/klho/4dUY/94Ul//bVNf/2BQW/9STVj/
+        RkpW/0JLVv9CTVj/Qk5W/ztETv81Pkj/LzhC/yoyPP8lLDX/ICYu/xofJf8UFxv/ExYb/xATF/8QEhf/
+        Excb/xIVGv8QExf/DxIW/xASFf8RFBf/ERUXjwAAAAEAAAAAAAAABwUFBSwGBgZTBgQGeggEBp4HBQbH
+        CAQF2AgEBdwHBQXnBwUG7gYFBbkAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAFRtcypQa3fjT2p1/1l2gv9ceIT/YICN/2KAjv9igY//XnqG/1lzff9ad4L/W3R//1p1gP9ddoH/
+        XHiD/1x1gP9ZcHr/WXB5/1pxe/9cd4L/X3uG/2F9if9igI7/YoCN/2V8iP9ifIf/Y3yI/2F9iv9lgo//
+        Y32J/2J8iP9keIL/ZXeC/2N1f/9kdH//ZXR//2ZxfP93a3f/q2Z5/6xfeP+nXXT/pF1x/51bbf+ZWmr/
+        mVpr/5FYZ/+EVWT/d1Vh/2xVYf9jWWX/VVRf/0xUX/9IVF//RFBb/0NPW/9EUVv/QE1W/zhETv82QUr/
+        ND5H/y84Qf8mLjf/KjM5/x8lK/8UGB3/EhYb/xATGP8QExf/Exca/xEUGP8OEhb/DhEV/w4RFf8PERX+
+        EBIXeQAAAAAAAAAPBAQEOAUFBWIHBQWJCAUFsggEBtIIBAXZBwQF4wcFBesHBQbvCQQENwAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDWmEiTmdx5lNve/9dfIj/Yn+M/2ODkf9lgo//
+        ZIST/2SDkv9geob/Yn2J/2ODkf9jhJL/ZYKP/2F/jP9jf4z/X3uH/1tzff9ddX//XneB/2B5hP9jfor/
+        Y3+M/2N9if9lfYj/Z36J/2Z/iv9mfor/ZH6K/2WBjf9jgY//ZIKQ/2Z+i/9leIP/ZXiE/2Z2gf9oc37/
+        fm57/65me/+sX3j/p110/6NdcP+bW23/mVtr/5haav+OWGf/gVZk/3VWY/9rWGX/Y11o/1ldaf9OWmf/
+        Sldk/0hWY/9GVGH/RlRh/0ZVX/8+S1b/OkdS/zdDTf87Rk7/NkFJ/zA6Qv8tNz7/JzA2/xogKP8UGR//
+        ERUZ/xEVGv8QExj/Exgc/w4RFv8NEBT/DRAU/w4RFf8PERX/DxUVYQkJCRwHBwdIBgQGcwYEBpkHBQbF
+        CAUF2AgEBd0HBQXoBwQG7wYDBp0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        M0xMFE1oc9JTcX3/YYCN/2aCkP9lgY7/ZoKQ/2WHlv9mh5X/aIaU/2mGlP9ohJH/Z4KP/2eHlf9nhZP/
+        Z4SS/2aFkv9jfor/Yn+L/2J/i/9jfon/ZH2I/2V+if9mfon/Z4GM/2iCjv9of4v/aICM/2iCj/9pgIz/
+        aYGN/2d9iv9je4f/ZX6L/2h7hv9mfIj/an+M/4VygP+vaH3/rGB4/6ZedP+iXnH/m1tt/5lba/+XWmv/
+        jFhn/35XZf90WWX/altn/2BdaP9bYm3/WWdx/05bZv9GVGP/RlVj/0lZZv9HV2T/SFdj/z9MWP8/TFj/
+        PElU/ztHUv87R1D/OURM/zVAR/8sNz//Iyw1/xsjKv8UGyH/EBQZ/w8TGP8TFxv/EBQY/w4RFv8NEBT/
+        DREV/xATF/8QEhX4DRAQXwUFCFoHBQeEBwUHrwgGB9EIBQfaBwQF5AYFBuwGBQXmCQAJHAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/PwRLYGmzT2l0/197iP9ng5D/aYSS/2uIlv9ni5r/
+        ZomZ/2iJmP9piJf/aImY/2uIlf9ph5X/aoeU/2qIlv9rhpT/aoiW/2qHlf9mhJL/ZYCM/2Z/iv9ngIv/
+        aYGN/2mDkP9qhJH/a4KO/2mCjv9pg5D/a4SQ/22Gk/9qg5D/aX6L/2yDj/9tfor/a3mE/2t3gv+HcH7/
+        sGh+/6tgef+mXnX/oV5w/5tbbf+ZW2z/lVpr/4tZaP98WGb/clpn/2pfa/9iZG//X2p0/1lncP9aaHH/
+        VWVw/01caf9JWGb/SFdi/0hWYv9NXmn/Sltm/0NTXv8/T1r/PUxX/z5NVv8/TFT/O0dP/zNBSP8oND7/
+        Ii01/xojK/8UGyL/EBQa/w8TGP8QFBn/EBQY/w4SFv8OERX/DxIW/xAUF/8QEhXtCAoKfggGCJcHBgfE
+        CAUH2QgFBt4HBQXpBwUG8AYEBnYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        UGt2clJsd/9adYD/ZX2J/2uJl/9sjp3/aY2c/2uJl/9qjJv/aoua/2mMnP9ripn/bIiW/22Jl/9th5T/
+        bIeU/2uIlv9qiZj/aYqZ/2iJmP9oh5X/aISS/2mFk/9shJH/bIOQ/2qFk/9sg5D/a3+J/22CjP9vhpP/
+        boSR/22Cjv9tgIz/b4OQ/3CCjv9xf4v/j3KA/7Bpf/+rYXn/p191/6BdcP+aXG3/mlts/5Raa/+JWGj/
+        elpo/3Fdav9pYGv/YWh0/19teP9dcX3/XHF8/1psd/9XaHP/Vml1/1hrd/9UZXD/UmZx/09jbf9MYm3/
+        SV1o/0VYY/9BVGD/P1Jd/0FTXf8+T1j/OEhR/zA+SP8rN0D/ISw1/xojLP8XHST/ERYb/xIWG/8RFRn/
+        EBQY/w4SFv8OEhb/DxMW/w8SFf8ODxPkCAgIsggHCNIIBgjbBgUG5QcFB+0HBAbOAAAACAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF58jitWc3/yWHJ9/2F7h/9jgo//aYeV/2iLm/9qjZz/
+        ao6d/2qMnP9si5v/bIqY/22Kmf9viJb/b4mX/3CIlf9uh5T/b4eT/2uKmf9qipn/aYiX/2qFk/9qg5D/
+        aYaU/2uGlP9pgY//ZH2M/2uAjv9uhJH/cYeU/3CFkv9pfYv/aXyJ/2t9iv9zhZP/eYmX/5Z4iP+yaoH/
+        q2J5/6Zfdf+gXXD/mlxt/5pbbf+TWmv/h1lo/3lcaf9xXmz/Z2Vy/2Jue/9gcn3/X3R//150f/9cc3//
+        XG96/1xueP9ecXz/X3R//1pueP9SaXX/UWh0/05mcf9MY2//SmFs/0deaf9BV2P/QVZh/z9UXv87Tln/
+        NkdR/zNCS/8tOkL/ICs1/xskLf8YHyX/FBke/xIWG/8QFBj/EBMX/w8TFv8QExf/DhAU/w0QE/8NDhDp
+        CAcJ2gcGB+AHBgbqBwYH8AcDB0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVf38G
+        XH2MzVx8if9gfYn/ZIWT/2uGlP9uipn/a46d/22Mm/9sjZz/bY2d/2+Lmf9ujp3/bo2c/3GKmP9xiZb/
+        bYOO/3CIlf9vi5n/bI2b/2yMm/9si5r/aoST/2iCkf9ph5f/aoaW/2d9i/9ke4r/Y3uM/2mAj/9tgpD/
+        bICO/2V4h/9ic4P/YnKD/3WEk/+YeYn/s2yD/6tje/+mYHb/n15w/5lcbf+ZW23/kllq/4Raaf94W2j/
+        bWBu/2htev9ib3z/YXiE/2J2gv9gdYD/XnWB/15yff9cdoL/WnSA/15zfv9gd4L/Wm96/1VseP9Sa3f/
+        T2l1/05odP9MZ3L/SmZz/0Vdaf9AV2P/QFZi/zxQXP85TFf/N0lT/zFASv8oNT//IS43/x0nL/8aIij/
+        FRsf/xQZHP8QFRj/EBMX/xEVGP8PExb/DhAT/w4QE/8LCw3nBwYH5wcGB+4GBgafAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGWQoX1iiZn/XXqG/2aGlP9nhJL/bYya/22Onf9tj57/
+        bpCg/26Qn/9uj5//b46d/2+Lmf9xipj/coya/3OKl/9yiZb/cY2b/2+Onf9ujp3/bo6d/26NnP9tjJz/
+        bI6e/26QoP9rjp7/aoaV/2iBkP9jfI3/ZHuK/2mAj/9jdoT/ZHWE/2Z3h/9wf5D/mnqK/7JthP+sZHz/
+        pmB2/6Bfcf+aXm//mVxu/5BZav+DWmn/dl1q/25icP9naXb/X3aE/2R9iv9kfIj/YnV//2F2gP9id4L/
+        X3aB/1x3g/9dc3//W3F8/1lxfP9cc37/V3F8/1Zuef9Tbnr/UGx5/05qdv9Nanf/SmRw/0Zea/9EW2f/
+        Qllk/z1SXf86Tln/NEZQ/ys7Rv8pN0D/JjM7/yIsMv8bIyf/FRse/xQYHP8RFRj/ERUY/xEVGP8QExX/
+        DxMV/w4QE/sIBwjtBwYH4AoKChgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqlKIk
+        ZZGi9mSHlv9igI3/aYiW/2+Onf9wj5//cIyZ/3GQnv9tlqf/cI+f/3KNmv9wjpz/dI2a/3OOnf9yjpz/
+        dI2a/3SMmv9yjZv/bYeU/3GOnf9wjp3/cI6c/3COnP9vjJr/boeW/2qCkP9pgZH/a4SU/2V9j/9lfI3/
+        ZXyM/2B3if9ke4//eIud/518jf+zbYX/rGR8/6Zgdv+fX3H/ml5v/5pdb/+PWmv/gFdn/3RZZ/9tY3H/
+        Z2t4/2Z2gv9kfIn/ZH2K/2N+i/9leYT/YXiD/2B5hf9eeob/X3mF/192gv9deIT/XXWA/1xwe/9Yb3r/
+        VXJ+/1dzf/9RcHz/UG57/05tef9MaHT/SWRw/0dgbf9CWmb/PFJe/zpPW/84TVj/MkRQ/y4+SP8wPkb/
+        Kzg+/yQuM/8bIyb/Fhsf/xIXGv8RFRj/EhYY/xEVGP8SFRf/EBQV/wwOD/gHBwdgAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AWeXqbZhhpX/YoKQ/22RoP9tjZz/cJOj/3KXp/9yl6b/
+        b5eo/3GRoP9zkJ7/c4+d/3SNmv9zjJr/c5Cf/3OOnP9zjJn/c46b/3SKlv+DjpL/co+d/3KPnv90j53/
+        dJCe/3OPnf9zjJr/dIqY/3OKmf9vhZb/aoCR/2uAkf9xhJP/bX+P/3WHl/+gfY7/s2yF/6tlff+mYXf/
+        n19y/5leb/+ZXW7/j1ts/4FcbP90W2r/a2Fv/2dqd/9qeYT/aX6L/2h9if9mfor/Zn6L/2V7h/9kfIn/
+        YHqI/196hv9ffYr/XHmG/1p5hv9deYX/X3R+/1pvev9YdYL/W3mF/1NzgP9Tc4D/Tmx4/01reP9IZ3T/
+        Q19u/0Jbaf88U2H/PlVh/z1TXv86UFn/NEdR/zVGT/8yQUj/KjY7/yIrL/8ZICT/FRod/xEWGf8RFRn/
+        ERUY/xEVF/8SFRf/DxIU/Q8PFyEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsmaxE
+        ZJGi/2aMm/9ul6f/bpWl/2uQn/9wlqb/cpus/3GWp/9zkaD/cpSk/3WSof90kaD/c5Oi/3WSof9zkJ//
+        dY6c/3SLmP91j53/dY+d/3SQn/9zkZ//dJKh/3OQn/9zjp3/cYua/3GMm/9xh5X/b4SU/2h9jf9idon/
+        X3KF/2V0hP9ue4z/m3WG/7NshP+sZn3/pmF2/55ecf+ZXm//mFxu/41abP+AXGz/dmBv/2picf9hZ3b/
+        ZniG/2+DkP9leof/ZXyJ/2Z/jP9mgI3/ZX+M/2J7iP9ffYr/YHqH/2F6h/9ieob/XnWA/1x5hv9de4f/
+        XnuH/116hv9efov/VXaE/1R2g/9QcH3/Tm17/0hndf9BX2//QV1s/z5XZv9BWmb/P1di/z9WYP88UFr/
+        Ok1V/zhIUP8vPEP/KTQ5/yAnK/8WHB//EhYa/xEWGP8RFRj/ERUY/xIVGP8SFRf/DxITpgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf39/Ammcrc9pkqP/bJam/22Sov9pjZz/aYmX/2yOnf9wlqf/
+        cpWl/3KWpv90lKP/c5Oi/3OTo/91lKP/dZKh/3aPnP90jJn/do6a/3WQn/90kqH/c5Gg/26Nnv9ui5z/
+        b4uc/3CMnP9wiJj/cYeV/2p9i/9rf4//YnaI/2J0h/9gcIP/Ymx//5Rsfv+waIH/q2V+/6Vgdf+dXnD/
+        mFtt/5dbbP+KVWf/elVm/3Jgcf9sanv/ZHCC/1tvg/9hdYb/a4KR/2V7if9le4j/aoOR/2R/jP9lfov/
+        ZHyK/2F7if9ieYb/YoCO/2aCkP9lfYn/XHqH/1t9i/9ZfIr/XH6M/2ODkf9Xe4n/U3WC/1JzgP9Lann/
+        SWd2/0Vicf9EYnD/QFtr/0BaZ/9BWmb/Qllk/z9WYP8+Ulv/PE1W/zZFTP8uOkH/JzE2/x0jJ/8UGRz/
+        EhYZ/xIWGf8SFRj/ERYY/xMYGv8OEhT7DBISKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtoLNU
+        a5ut/22XqP9rlKX/a5Oj/26Onf9wkJ//bpGg/3WVpf91k6P/dJam/3SVpf91lKP/dpWk/3OVpv9zlKT/
+        d5Sj/3iQnf92k6L/dpOi/3WSof90kaD/b4uc/2uHmf9phJb/bIOU/3GImf9yh5b/bH+M/22Akf9jdon/
+        YXGF/2Bqfv+Sa3//sGiB/6pkfP+kX3T/nFtv/5habf+WWGv/iVRm/3hRYv9qUmT/XVVo/1Nccf9bcoj/
+        XHiP/2J4jP9Ya3v/XHB//191hP9me4b/Y3eD/2J6iP9ef47/X3yM/2B8i/9kgI7/Y3+M/2J+i/9ff43/
+        W3+N/1p+jf9Zfo3/Y4WU/1t/jf9Zeof/V3eE/1Jxf/9MaHj/TGl4/0tpd/9GZHL/QVtq/0Reav9FXWj/
+        Qllj/0BWYP8/U1z/OkpT/zJASP8sNz3/JCwx/xogI/8TGBv/Exca/xIWGf8TFxr/Exga/xAUF/8NEhOm
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW2gs8hqlqj/Z4yc/22Pnv9ul6n/cZmq/2+QoP9xlab/
+        cpen/3WYqP9zmqv/dpen/3iUo/92lKP/dpWk/3mSof92laX/eZKg/3eTov93kqD/d5Kg/3eQn/90jZz/
+        b4ma/2eAk/9lfJD/aX+R/2V6jP9keIv/YnWJ/2Fyhv9hboL/j2p+/69ngf+rZX7/pF91/5xcb/+XWmz/
+        lllr/4hTZf93UGH/aVFj/1tTZ/9RWG7/TmF5/1Jnfv9heIz/YnuP/1lwhP9ab4L/X3eI/22Jmf9le4n/
+        XXeH/1x1hf9dfY7/YoKR/2GCkf9egZD/XoGQ/12Bkf9bgZH/WoCQ/1qAkP9fhJP/YoSS/1t9iv9cfIn/
+        XHuI/05tfP9NbHr/S2p4/0lndv9GY3D/RmBt/0dhbP9FXWj/Qlpk/0JYYf8+UFn/NkdP/zA+Rf8sNjz/
+        Iisv/xcdIP8TGBv/EhcZ/xIWGf8SFxn/EhYX/w8TFfsRERcsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxobY/
+        b5+y/3CarP9vm63/b5Wl/3Cdrv9zmqv/cpSj/3CZqf9wlKT/c5mp/3Saqv91mKj/dpSj/3eWpv92l6f/
+        d5en/3iUo/95laT/eZKg/3eQn/94kJ7/eJCe/3iPnv91jJz/boWW/2Z8jv9nfY//ZXmL/2V4iv9gcof/
+        ZXOH/41sgP+vZ4D/rGd//6Vgdv+cXXD/mFps/5VZbP+IUmX/dU5g/2hPYv9bU2f/U1tv/1Fief9MX3b/
+        VGqB/2F5jv9ngJT/bYeZ/1pvgP9gdYT/a4ST/2SCkP9eeYr/W3aH/2B+jv9ihZX/X4SU/12Dk/9ehpb/
+        XIWW/1yElP9agpP/WoKS/1+FlP9lh5b/YIOS/1+Ajv9ff43/VHSD/01peP9LZnX/TGp4/0lkcf9LaHT/
+        SWVw/0dhbf9FXWf/RFxm/0JWX/88Tlb/NkZN/zE+Rf8pNDn/HyYr/xQZHP8TFxr/EhYZ/xIWGP8RFRj/
+        EBQW/w4TFKEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHGjta1voLL/cpqr/3Gcrf9zmqv/dJut/3CYqP9xj57/
+        cZOi/3WXp/92l6f/dpmp/3eZqf94man/eJin/3iYp/92laT/e5Sj/3qTof95kJ7/eJCf/3mRoP91jZ3/
+        b4eY/26Elv9rgpT/aX6Q/2h8jf9meIr/aHmN/2Z1if+MbID/sGmC/61mgP+nYnj/nl5x/5hcbv+WWWz/
+        iFNl/3ZPYP9nT2L/W1Jm/1Vecv9YbIL/VmuC/2R8kf9kfZP/YnuR/1Nrgf9edYn/XHKE/2J5if9ieov/
+        aoaV/2iElP9jgI//Y3yK/2ODkv9ihpb/X4aX/12Hl/9bhpf/W4SW/1uElf9cgpH/ZIaU/2SGlP9liZj/
+        YIOS/1p9i/9UdoT/VXWC/1JreP9SaXX/TWl2/01odP9KaHT/SGVx/0Vibf9FX2n/RFpj/0NWXv89TlX/
+        N0ZN/y88Qv8lLzT/GiAj/xMYG/8SFxn/EhYY/xIWGP8QFBb/DhIV9A4ODhIAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnoKkb
+        bqO3+XKgs/94mqr/dpmq/3ebq/9znK7/cY+e/3GPnf91l6j/eJmp/3eaqv93l6f/d5qr/3ebrP95man/
+        eJem/3uWpP96laT/epOh/3qRn/94kJ//do2d/3OKm/9wiJn/c4ma/3OJmv90iZj/coaX/26Bk/9ygZP/
+        jXOG/7Fqgv+uaIL/pmJ4/55ecf+ZXm//l1tu/4lVZv94UWL/aVFk/1pSZ/9QWW//VGd+/190iv91j6P/
+        eZSo/2uEmv9kfZP/VGuC/09mfP9Uan//XHSH/110hf9ieIb/boiX/22Jmf9jhJX/ZIaW/2OHl/9hiJn/
+        X4ma/12Imf9bhZf/XISU/1+ElP9kipn/YIWU/2CGlv9hhJP/WH2L/1V6if9Yeof/U3J+/09vfP9RbHj/
+        UGt3/0xqdv9JY27/R2Vx/0Vga/9EW2X/Q1hh/z9SW/86SlP/NEJJ/ys3PP8hKS7/FRod/xMXGv8RFhn/
+        ERYZ/xAUF/8PFBb/ERMVdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGyitXZxo7b/caG0/3idrf91n7D/dp6w/3KUo/9yj5z/
+        c5Gg/3WZqv94nKz/dpyt/3qZqP93na7/eJqr/3yYp/97laP/epKf/3uUov94jZf/eZCd/3qSof93jp7/
+        dYuc/3eOnv96kJ//eY6e/3uQn/98j5//fIub/5B7jP+ybIT/r2uD/6dke/+eXnH/mV1u/5hdb/+LWGn/
+        eVNj/2xVZv9fWGr/VFtu/1Nmfv9ec4j/eJOn/4Wktv+DobL/dI+i/3SPpP9geY//TWN8/0xje/9Xb4T/
+        XXWG/150hP9ieIb/Z4KQ/2eHl/9miJf/ZIeX/2KJmv9gipv/YIqb/12HmP9eh5j/YYaW/2SIl/9lg5D/
+        XoWV/1qAj/9Xfo3/VnyK/1Z6iP9acHz/Vmt2/1Jrd/9Pbnr/TW57/09pdf9IaHT/SWNu/0VcZv9EW2X/
+        QFVe/zxPV/82Rk7/MD1D/ygyN/8bIib/Exgb/xIXGf8SFxr/ERUY/xAUF/8PFRbWAAAAAQAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8B
+        b6S303Gjtv91n7H/dpyt/3Sfsf91nK3/cZGg/3WYp/90l6b/d5qq/3ebq/92mqr/eJur/3ubq/99mKf/
+        ep2t/3ucrP99maf/fZel/3yYp/99lqX/eZGh/3OKnP90i53/dIuc/3WKm/96j5//fJCg/36PoP+QgJH/
+        s26F/69rg/+qaH7/n19z/5leb/+YXW//jFhq/3tWZ/9uWGr/Yl1v/2Bsfv9leY3/Z32S/3WPo/9+mq7/
+        fJms/2+HmP9gd4r/WG+D/1JpgP9LYnv/UGd+/1NqgP9WcIT/WHKF/116jP9mhpf/aImY/2qIl/9ohpX/
+        ZIqa/2WOn/9nkaP/X4uc/1+ImP9ih5f/Y4mZ/2SImP9dhpb/WYKS/1eAkP9Xf47/UniI/1Zwff9Wa3f/
+        UnF+/05wfv9OcX7/S217/0llcP9IZnL/SGFs/0ZaY/9DV2D/PlJc/zhKU/80Q0v/LTk//yIqL/8VGx7/
+        Ehca/xIXGv8SFhn/ERUY/xEVF/8PFBkzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGyfsihvo7j/caK2/3Oitf95n6//dZ6w/3ebq/92m6v/
+        dZio/3aZqf92l6b/d5em/3mYpv95n7D/eaGx/32Yp/95nq//e5yt/3yZqf99maj/fZmo/36ZqP99lqX/
+        dYyd/3KIm/9ziJv/d4ud/3SHmP95i57/kYmb/7Jvhv+wbIX/q2qA/6Bgc/+aXnD/mV5v/41Zav98V2f/
+        cVxs/2lldv9eaH3/bIOY/3aOov9+mar/fpmq/3WPoP9uhpf/boWV/2h+j/9fd4v/V26D/1Bof/9Ua4H/
+        VGyC/1hyhv9cdoj/YH+R/2WFlf9riJb/aYmY/2eLm/9ljJz/e6Ky/4KpuP9ijZ//YIqb/1+Jmv9hipv/
+        Y4eW/16Glv9ahJT/WIKS/1Z+jv9Rdof/U3WE/1d2hP9Vd4P/U3F9/090gf9Rb3v/T257/0tlcP9JZnH/
+        SGFr/0leZ/9DWGH/O09Y/zdJUf8wP0b/JzI3/xohJf8TGBv/Ehga/xIXGf8RFhj/ERUY/xEVF4UAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        aJ6zd2ugtf9zpLf/dKS3/3SitP93n7D/epur/3WcrP94na7/d5mp/3eYp/94na3/fJ2t/3ihs/96obL/
+        fJ6u/3ufr/99nKz/f5mo/4CdrP+Cnq3/fpin/3mSo/9vhpn/boOX/3GGmf90iJv/d4ib/4+Mnf+ycoj/
+        sGyE/6xqgf+hYHT/ml5w/5ldcP+NWWv/fFZm/3FbbP9raHn/bHiJ/3OKnv9yi6H/e5aq/4Ccrv93kKH/
+        eZKk/3iRov9vh5j/a4KS/2iAkf9ddYn/Vm+E/1dvhP9Xcof/WnKF/152h/9geoz/aoST/2uJmf9njp7/
+        Z42e/2WOnv9okqP/apWm/2GNn/9gjJ7/X4ud/2GLnP9jjJ3/XYeY/1yDk/9ZgpL/V4CQ/1d8iv9XfIr/
+        VnuJ/1V3hP9Rd4X/UHWD/09xfv9NcH3/Tml1/0lodP9KYGr/S19o/0VZYv8+VF3/Ok1W/zRDS/8sOT//
+        Iiov/xQaHf8TGBv/Exgb/xIWGP8RFRj/EBMXzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABonLTDa6C2/3Gjt/90prn/daCz/3ihs/98nKv/
+        d56u/3eitP93n6//ep+v/3qgsf96orP/e6Gx/3ygsP98oLD/fpuq/3+aqf9/nq3/g6Cv/4WhsP99l6j/
+        a4KX/2J5kP9le5H/aX6U/3OFmf+EhJf/sXOJ/7Fshf+sa4H/omJ1/5lecP+ZXnD/jlps/31WZv9zXGz/
+        bGd4/257jv98laj/dY+k/3eTqP+AnrL/cIqe/22FmP96lKT/b4aV/2mBk/9nfpD/ZX2Q/196j/9jfZL/
+        XXSG/1x0hv9YdIn/XXmM/2aCk/9mhpj/aI2e/2iOoP9njp//Zo6f/2WOn/9jj6D/YY6g/2KPoP9jj6D/
+        YY2e/2OOn/9eiJn/XIWV/1uElP9agI//W3+N/1p6iP9Wfo3/WHuJ/1R3hP9ReIX/UnWC/05xfv9Mb3z/
+        S2t4/0xmcf9MZG3/Rl5o/0BVXv88UVr/OElQ/zE/Rf8pMjj/GSAk/xQZG/8TGBv/EhYZ/xEVF/8RFRf7
+        DBgYFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        YomcDWmds/ptorj/daa5/3ShtP94orT/ep6u/3ugsf95n6//eqCx/3uer/96oLH/fJ+v/3yisv99obL/
+        fKCx/36fr/9+man/gJ2t/4amtf+JqLf/gZ2v/3WOov9mfZP/YXeO/2N3jv9pe5L/c3eN/6xyh/+zcIn/
+        q2qC/6Njdv+aXnD/ml5x/5Fdbv+AWmr/dF5u/2pkdv9seIn/e5Kk/3yXq/95lKn/g6K0/3qYrP9lfZP/
+        boic/3KJmv90jJr/boeX/2uDlf9mf5H/Z4GV/2mClv9lgpb/aYOV/2R/kf9ifZD/aoiY/2eJmv9pjp//
+        aY+g/2iPn/9njp//Zo6f/2SPoP9jj6H/Y5Ci/2KPoP9lkaL/ZI+g/1+LnP9dh5j/XoaW/12BkP9ef43/
+        W32K/1p6h/9YdoP/VHyK/1J6iP9Rd4X/T3SC/01xfv9ObHj/Tmdy/05jbf9HX2n/RFli/z9UXv86TVX/
+        NERL/y05P/8hKi7/FRoe/xMYG/8SFxn/ERUY/xAUFv8QExZOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqn7FIZpeu/3Gmuv90qLv/dqS2/3mitP99oLD/
+        faKz/3qfsP97n7D/fJ6t/32erf9/oK7/gKKx/3+hsf+Bn67/f56v/3ydr/99na7/iam4/4Wktf93k6f/
+        cImf/2J4kP9hdo7/ZnmQ/293jf+lb4T/s2+I/69wiP+kZHj/ml1w/5pdcP+SXW//g1tr/3pmdv93dIX/
+        aHKF/2+Emf97lar/iqi6/4ektP+Jprb/dI6g/3KLnv9zjJ3/e5Sj/3SNnf9yjZ3/aYWY/2eAkv9mgJL/
+        YoGV/2qDlP9tiJj/bYeX/2mHmP9pi5z/ZYib/2aMnv9pkaL/aZCh/2mPoP9nj6D/Z5Cg/2WQof9jkKH/
+        YY+h/2WRov9nkqT/YIqa/1+LnP9ciJn/XYaW/1uElP9agpL/WYGR/1d/jv9VfYz/U3uK/1J5h/9QdIH/
+        T3OA/05wff9QanX/Ump0/01lb/9IW2T/QVNb/z1QWf84SFD/MD5E/ycxN/8aICT/FBgb/xIXGv8RFRj/
+        EBQW/w8UFocAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAGSUpn9qm7D/cqW4/3eitP92oLT/eKS2/3+erv99o7T/fJ+v/32isv99o7T/fqOz/4Kksv+BpbT/
+        gKS0/4Cis/99obL/faCy/4Wnt/+DpLX/epms/3WRpf9xiqD/aX+V/2t9lP9wfJH/pHSI/7Nvif+ydYz/
+        pmd8/5pecP+ZXW//klxt/4JXaP98Znb/fnuM/3+OoP92jaH/gJuu/4qpu/+SscH/iae2/5CuvP98lab/
+        eJGh/3yWpf98lqT/fJen/22Jm/9tipz/c42d/3CQof9sjZ//bY2e/2uNn/9wkKD/cI+e/2qNn/9ihpr/
+        ZIqd/2qSo/9pkqT/aJGj/2iQof9rk6P/Z5Ch/2WRo/9kkaP/ZJCh/2WPoP9gjJ7/YYyc/1+LnP9fiZr/
+        XoSU/1qElP9YgpL/V4CQ/1Z/jv9UfYz/U3qJ/1J3hf9RcX7/UHF+/1FseP9UbXj/T2dx/0hcZf9DVV3/
+        QFNc/zpMVP80Q0n/Kzc9/x8oLP8UGRz/Exca/xEWGP8QFBf/DhIVvAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZpSos2qVpv9zqLv/d6a5/3WhtP96obP/
+        faS1/36jtP9/oLD/fqS1/36ktf9/pbX/hae1/4Sot/+ApLX/gqS1/3+is/+Hqrr/hKm5/3+is/9+nq//
+        fJmq/3WNov93i57/dIKX/592i/+zb4n/sHKK/6psgv+bXnH/mV1w/5Rdb/+DVmf/clZn/3Zxgf+Glqf/
+        ka6//4qouv+Fo7f/kbLC/5e4xv+Mq7z/kK+9/3yVo/9/mKf/gJqp/4Cbqv95kqH/dY6e/3KOoP90k6P/
+        c5Sl/3GUpf9ukaP/bJCi/2+TpP9vlKX/bZKk/2iOof9oj6L/aZOk/2mUpv9olKX/aZKk/22Wp/9mkaP/
+        ZpOl/2qXqf9kkqT/YY+h/2COn/9gjJ3/ZpCh/2GMnf9diJn/XIaX/1mDlP9YgZL/V4CQ/1Z+jf9Weoj/
+        VXiF/1Byf/9Sc4D/Umx3/1dyff9QaHL/SmFr/0hZYv9CV2D/PU9X/zhHT/8tOkH/Iy0z/xYcH/8TFxr/
+        ERYY/xEVF/8PEhXqAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAABqnK/hbZmr/3Sqvf90qbz/cZ2y/3ihtP9+n7D/gaCw/4Cjs/9/prf/fqa3/4Gmtv+Gp7b/
+        iKu6/4Gis/+Gp7f/g6a2/4muvv+DqLj/f6Gy/32brf96laj/d46i/3KDmf+Xd4v/sm2G/7Fyif+tcYb/
+        nWBz/5lecP+VXnD/h1ts/3RWZv9qXW//dHyM/42ouf+hwc//kbHB/46uvv+ewM7/o8PQ/5a2xf+Lqbn/
+        f5mo/4KdrP+Dn67/iaa1/32Yp/+Go7L/iai3/4OltP94laX/dJOk/26Qov9vlKX/b5Wm/2+Vp/9ulKb/
+        apGk/2uUpv9qlaf/aJao/2eWqf9nlaj/apao/2iVp/9slab/d6Cw/22Yqf9ikKL/YY+g/2CNn/9lj6D/
+        ZI+g/16Jm/9ch5j/WoWW/1mDk/9XgZH/VoCP/1Z+jf9Veoj/VnJ+/1J0gP9Yb3n/VnB7/1Brd/9LX2j/
+        S15n/0NWX/8/Ulv/OEpS/zA/R/8rNjz/GSAk/xMYG/8SFxn/ERUY/xAUFv4KFBQZAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYomcDXGlufxxobP/dqm8/3aitP95oLL/
+        e6O1/36is/+Aprb/gaS0/3+ouf9/p7j/gqi4/4mruf+Jq7r/h6i4/4uvvf+Eqbr/kLPD/4KmuP9/n7H/
+        gJyu/3+Zq/95j6P/j3mN/7Juhv+vbIX/rW+F/6BkeP+ZXnD/l15x/4haa/91Vmb/altt/2Rnev+Bmav/
+        j6/B/6PD0f+cvcz/k7TD/6XG0/+tzdj/n8DN/5Gwv/+Cna3/g6Cv/4aisf+Rsb//krLA/5S0wv+Orrz/
+        jK69/4eot/93lab/bo+i/3GWpv9wlqj/cJao/2+Vp/9rk6X/bJao/2qYqv9omKv/Z5ir/2eXqv9ol6n/
+        aZeq/3CarP98pbX/d6Kz/2OSpP9ikKL/YY+g/2GOn/9kkKH/Xoqc/12Imf9bhpf/WYSV/1iCkv9YgZH/
+        Vn+O/1d8iv9VeIX/VnJ+/1hwev9Wcn3/UGx3/1Fkbv9KXmj/Rlpj/0FVXv88Tlb/NERL/y05P/8hKS7/
+        FBkc/xIWGf8RFRj/EBQW/xAUGD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAABvn68wcKO2/3Kitf93qrz/eaO0/3ymuP9/prf/gKe4/4Cktf+CpbX/gKi4/4Kmt/+Dqrr/
+        jbC+/5Gzwf+Jrr3/jbHA/4yxwP+UuMb/i6++/4OjtP+Dn7D/gZqs/4+Jm/+zcIf/r2yF/61vhf+jaHz/
+        mmBx/5hecP+LXG3/fF9v/3Jkdv9uc4X/bH6T/4qou/+NrcD/mLnJ/6DD0f+WuMj/p8jU/6zM1/+lxdH/
+        mrrI/4iktP+IpbT/h6Sz/5KywP+UtML/iKe1/3+drP+DpLP/haW0/4Ghsf9wkaP/cJSm/3CVp/9vlqf/
+        a5Kl/2iPo/9tl6n/apms/2iZrP9omaz/Z5ir/2eXqv9qmaz/c6Gz/4Svv/99qbn/apiq/2ORo/9kkaP/
+        aJSl/2mUpv9jj6D/Xoqc/1yImP9ahpb/WYSU/1iCkv9XgI//Wn2K/1Z4hv9XdoP/W3iE/1ZxfP9Sa3b/
+        UWRt/01faf9KW2T/Q1Zf/z9QWf83R07/LzxD/yUvNP8WHB7/EhYZ/xEVGP8QFBf/DxQXYwAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHWnuExsm63/c6a4/3aqvP96p7n/
+        e6m6/4Kmtv9/qbr/gKq6/4CouP+Aqrv/g6m5/4eruv+QtMH/k7bE/42ywf+PtcP/kLXD/5S4xv+Yusj/
+        h6W1/4Wgsf+OlKX/snSK/7Fuh/+tbYT/pmyA/5pgcv+aYHL/jV1v/3xba/96bn7/dnuN/36Tp/+Pr8H/
+        jq7A/5y+zf+cvs7/o8XT/5/Bz/+oyNT/o8PQ/6fI1P+iws7/jay6/4imtf+JqLf/iaq4/4usuv+IqLf/
+        h6e2/4Wjsv+GpbT/hKS0/4Kktf9ylaf/bZKl/2ySpf9ljKH/a5Om/22Yq/9qmq7/aZut/2iarf9omaz/
+        Z5ir/2marP9unrD/hbHA/3+ru/9nlqj/ZJOl/2uXqf9qlqj/aJSl/2aSo/9hjZ7/XYma/1uHl/9ahZX/
+        WYOT/1mBkP9beYX/WniE/1V4hv9ad4L/WXaB/1Jtef9SaXT/TGFr/0pdZ/9EWGH/QlNb/ztJUf8zP0X/
+        KTM5/xohJP8SFxr/ERUY/xAVF/8PExWCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAcaa1ZXKmuf94sMP/d6q9/3yktf98p7j/gKq7/3+rvP+CpbX/gqSz/4KouP+DrLz/
+        iq69/4yywf+HsMD/jrXD/5O4xv+Vucb/nLbB/5y8yf+JpLT/i5mp/7B4jP+zcIj/rm+G/6dsgP+bYXP/
+        m2Bz/5Fhc/+AXm7/emt6/4SLnP+Dmq3/gZ2x/4akuP+TtMX/ocLR/6LF0v+oydb/qMrW/6rL1/+mx9P/
+        p8jU/6fJ1P+QssH/h6i3/4epuP+Iqbj/iau6/4qtvP+Iqbn/hKSz/4amtf+FpbX/h6u7/3OXqv9skaT/
+        bJOn/2uTp/9tmav/bJut/2qcr/9pnK//aZuu/2qZq/9omKv/aJms/2eYq/9yobP/f6y8/2iXqv9llKb/
+        ZpSm/2mWqP9rl6n/Z5Ol/2GNnv9fi5z/XIiZ/1uGl/9ahJX/XYCP/117h/9Zf47/V3uI/1p3g/9Xc3//
+        VG14/1Jqdf9PZG7/TWFr/0dXX/9FVF3/P01U/zdDSf8sNzz/Hycr/xMYGv8RFRj/EBUX/w8UFZcAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByp7t4dau+/3iyxP95r8H/
+        fqe4/36qu/9/q73/gqm6/4Smtv+DqLn/gqq7/4Osvf+Erb3/hrDA/4ixwf+Ls8L/mLzK/5/Bzf+cucX/
+        mbbE/4ubqv+rfI//s3GJ/65wh/+qb4T/nGJ1/5lecP+QW23/gVtr/35vff+EiZn/jKO0/5y8zP+NrcD/
+        dZGn/3eUqv+Ttcb/sNHc/6vO2f+rzdn/qMrW/6vN2P+tztn/rM7Z/5e8yf+JrLv/h6m4/4aot/+Fp7f/
+        h6y7/4Ontv+CpbT/iKq4/4Wot/+Hrb3/d5yv/22Spv9ulqj/bZep/22brv9rnbD/ap2w/2qcr/9qm6//
+        aZuu/2iarf9omaz/aJms/3OitP98qbn/bJyu/2yarP9qmKr/aJan/2qXqP9nk6X/X42e/16LnP9diZr/
+        XIeY/1uGlv9agpL/WoCP/1p/jv9Ye4j/XX2J/1Z1gf9UbXn/Umt3/1Focv9MX2j/S11m/0dWXv9BT1f/
+        OkZN/zA6QP8iKi7/FBkb/xEVGP8QFBf/DxMVpwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAHCltZF3sMP/ebPF/3qvwv96sML/fK2//4Kqu/+Bq7z/gqy9/4Ctvv+BrL3/
+        gay+/4Ktvv+KtMP/jbXD/4qxwf+PtMP/lLfF/5a2xP+MpbX/poKU/7Rxiv+vcYj/q3GF/6Bpe/+aYHH/
+        k11u/4JZav91XGz/gYKS/4+ktP+Mqrz/mbrK/4Wluv9xj6f/dJWr/4Gkt/+dwc//psrW/6zP2v+mytb/
+        qMrW/6fK1f+rzdn/o8fT/5e7yP+QtML/jbHA/4+0wv+Ns8L/i7HA/4Wquv+Cp7f/ia++/5G4x/95oLH/
+        cJap/26VqP9xmq3/bpyv/2yesf9rnrH/ap2x/2qdsP9pm6//aZuu/2marf9pmq7/fau7/3+tvf94prf/
+        d6W2/3qmt/9rmKr/cJyt/2aTpf9jkKH/X4yd/16Km/9diZr/XIeX/12ElP9ffIr/WX6N/1l+jP9ef4z/
+        V3aC/1dyff9UanT/UmVv/1BibP9NXmf/Slpi/0RSWv89SlH/Mz5E/yYvM/8VGh3/ERUY/xAUFv8RFBWv
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcqe3oXiyxf96tMb/
+        erHE/3uwwv9/rsD/frDC/4Oqu/+Brb7/ga2//4Gtvv+Crb7/g66//463xv+NtcX/iK+//4uxwf+XuMf/
+        lLLB/56KnP+1c4v/sHGJ/61yh/+jbYH/mmFy/5dhc/+JX3D/eWBv/3Vvf/+SpbX/lLLC/4inuv+QssP/
+        hqi7/3iar/+Apbf/hKu7/461xP+OtcT/lbzK/6zO2v+mydX/pMjU/6PH0/+dws//l7zK/53Cz/+kyNT/
+        ncLP/5C4xv+JscD/f6a2/4atvf+LtMP/jLTE/3adsP90m63/c5ut/3Gcrv9wna//bZ6y/2yfsv9rnrH/
+        ap2x/2qcsP9pnK//aZuu/2mbrv+Br7//gq+//4ezwv+EsMD/fam5/3iltv90obL/bpqs/2eUpv9gjZ//
+        Xoud/16Km/9diJj/XYWW/12Ajv9ZgI//XIGP/2GBjv9ceIT/WHJ+/1Vrdv9SZW7/UGJq/1Bia/9MXWX/
+        RlVd/z9NVP82Qkj/KTM4/xcdH/8SFhj/EBQX/xAUF68AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABzq7ylebPG/3q0x/96ssX/fbLE/32zxf+CrL3/g62+/4Ouvv+Brr//
+        ga6//4Guv/+Brr//iLHC/421xP+LscH/ia6+/5a3xf+Zl6j/tXWM/7Fyiv+tcYf/pnGF/5tidP+XYHH/
+        il5u/3lebf9+eIf/g5Gj/6bD0P+00t3/p8jU/6LF0v+YvMv/gqi6/4Ssvf+JscH/ibLB/4Wvv/+Eqbn/
+        jLPB/57E0f+w0t3/ocXS/5q+zP+cws7/n8XS/5vCz/+NtsX/jLTD/4Cpuf+Gr7//ibLC/4Suv/+LtMT/
+        d6Cy/3Wdr/9znK7/cp2v/3Gdr/9umqz/bJ+z/2ufsv9rnrH/ap2x/2qcsP9pnK//aZuv/3Sktv94qLr/
+        eai5/3+svP99qbn/dqO0/3iktP9xna//ZZOk/2GPoP9fi5z/Xoma/12HmP9hg5H/X3+N/1x8iv9kg5H/
+        ZIGO/158iP9ZdYH/WHB7/1Zrdf9VZ3D/UmVu/0xdZv9HV1//QU9W/zhFS/8sNjv/GiAj/xIWGf8PExb/
+        DhQVsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHSsvKZ6tMf/
+        e7XI/3yzxv99tMf/f7DC/4Cxw/+AscP/gbDB/4KvwP+CrsD/gq6//4Kuv/+Drb7/hq2+/4etvf+Qs8L/
+        m6e4/7R5jv+ycor/rnKJ/6lyhv+dZ3n/mV9x/4tbbP94V2f/alpr/3F5iv+PrL3/sdHc/8Dd5v/D4Oj/
+        tNXf/6/R3P+oy9f/irLC/4avwP+KtMT/iLPD/4Svv/+Crb3/ha/A/4u0w/+kydX/rM/a/7jY4v+rz9r/
+        mcHO/4u1xP+DrLz/ibHB/4m0w/+HssL/hrHC/4iywv91n7H/dJ6x/3SesP9znrD/cZ6x/2+fsv9toLT/
+        bKCz/2ufsv9rnrL/ap2x/2qcsP9qnK//a52w/3uqu/9xobP/cJ+x/22cr/9qmav/aZeq/2uYqv9kkqT/
+        Y46f/2SFlP9iiZn/Xoma/16Hl/9fhJP/X36M/2GCkP9mhJH/X32J/1x4g/9YcX3/Vmx3/1Zpc/9RYmr/
+        TV1m/0paYv9DUln/OkdO/y85P/8dIyf/EhYZ/w8TFv8PExWzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdqu8onu1yP98tsj/fLXI/3y2yP+As8X/f7LE/4CyxP+CscL/
+        grDB/4KvwP+Cr8D/g66//4Ssvv+GrL3/h6u8/5auvf+xgJP/s3KL/69xiP+rcob/oWx+/5pfcv+OXG3/
+        fFpp/2xZaf9lZ3j/Zn2Q/3edsf+Fr8H/jLbG/5rC0P+ZwM//nMPQ/73b5P+31+H/lb7M/4u2xv+Pusn/
+        j7vK/5C8yv+Brr7/ga29/4WwwP+TvMr/o8nV/5/G0/+Wv83/krzK/5O8yv+GscH/iLPD/465yP+NuMf/
+        eKO2/3aesf91oLL/dKCy/3Kgsv9xoLP/b6G0/22htP9soLT/bKCz/2ufsv9rnrH/ap2w/2qdsP9voLP/
+        eKi5/3Ojtf9qmq3/Z5ir/2aWqf9nlqj/ZZSn/2OSpP9ljp//ZI+g/2CMnv9fiZr/XoiZ/1+ElP9ef47/
+        ZYOR/2WFkv9gf4v/W3aC/1hyff9Xbnn/V2t1/1RmcP9OXmj/S1tj/0VVXP87SVD/MTxB/yEoLP8SFxn/
+        DxMW/xATF6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0p7iX
+        e7bI/3y2yP97tcf/fbbI/322yP9+tcf/gLPF/4Oywv+DssP/g7HC/4Owwf+Erb7/ha2+/4esvf+JqLn/
+        qYSX/7V0jf+wdYz/rXSI/6Vzhf+bYXP/kl1v/4Faaf9wWmj/ZmR1/2R5i/9wlKj/faW4/3mluv96pLj/
+        gKm7/4Ksvv+QuMf/qc3Z/8Pg6P+hyNX/i7fG/5C8y/+Vwc//lMHP/4q4x/+CsMD/ga2+/4Wwwf+KtcX/
+        jLfG/53F0v+extL/krzL/4y3xv+KtcX/irfG/4ezxP90orT/dqK0/3WitP9yorX/caO2/2+jtv9uo7b/
+        baK1/22itf9sobT/bKCz/2ufsv9rnrH/a56x/3iouv98rLz/bZ6x/2iarP9nmKv/Z5iq/2aWqP9mlaj/
+        ZJOl/2aQof9ojZ3/YIyd/2CLnP9fiZr/YIWV/2WDkP9hgpD/XoCN/2B/i/9beIP/WnR//1hwe/9YbHb/
+        Vmly/1Bgav9MXGT/R1hf/z5MUv8zPkT/JS0x/xMXGv8QFBf/DhMWnQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHOmt4R7tsj/fLfJ/322yP99t8n/fbbI/4C0xf+Bs8X/
+        hLLD/4OyxP+FtMT/g7DB/4Svv/+Hrr//iKu8/5+Mnv+0dIz/sXWM/651iv+pd4r/nWZ3/5VfcP+FW2v/
+        c1po/2pkc/9lc4P/bpCk/3egtf98p7r/fKq8/4Cpu/+ArL3/gay9/4Wvv/+cxNH/u9vk/7jZ4/+u0t3/
+        sdTf/7XX4f+jzNj/msbU/5TAz/+FtMP/hrTE/4q3xv+MuMj/jLnI/4u4x/+Jtsb/hrLD/4e0xP+Gr77/
+        eaW3/3alt/93orP/dKK0/3GluP9wpbj/b6S3/2+kt/9uo7b/baK1/22htP9soLT/bJ+z/2yfsv9vorT/
+        gbHB/3enuf9rnK//aJqt/2qbrv9nmKv/ZZao/2SVp/9kk6X/ZZGi/2OPoP9jjJz/Y4eW/2GKmv9ig5L/
+        YIOS/16Bj/9jhJL/Xn2K/1x5hP9bdoL/WnF8/1lueP9WaXL/UWJr/01dZf9IWGD/QE5V/zVBR/8oMDX/
+        Exgb/xAUFv8PExWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        caKxbHqzxv99tsj/fbfJ/363yf9+t8n/hLDB/4KzxP+Fs8T/gbHE/4SvwP+Er8D/hq/B/4etvv+VmKn/
+        tXeO/7J0jP+vdYv/qneK/6Fuf/+YYHL/iVtr/3daaP9rYW//Z3KB/2+On/99pLb/gKW3/4Csvv+ArL3/
+        gKy+/4Ctvv+Brb7/gay9/4i0w/+w097/r9Pe/8jj6//M5u3/wd/n/5bC0f+Vw9H/k8DO/4e0xP+Mucj/
+        kb/N/5XC0P+Nu8r/gLHC/4Gyw/+Tvsz/kL3M/3qktv93prj/daa4/3mhs/9zpbf/caa5/3CluP9wpbj/
+        b6W4/2+kt/9uo7b/baK1/22htP9soLP/bJ+z/26htP96q7z/c6S2/2udsP9omq7/apuu/2eYq/9ml6n/
+        ZZWo/2SUpv9kk6T/ZJGj/2SLnP9kiZn/YYqa/2OFlf9ghJP/X4GQ/12Ajv9dfYr/XHmF/114g/9dc37/
+        WWx2/1dpc/9SZG3/Tl9n/0lZYf9BT1b/OUVL/ycwNP8VGRz/EBQX/w8TFYAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1p7hMe629/3+1xv9+t8r/frfJ/3+3yf+DssP/
+        gLTG/36ww/9/scP/gbPF/4Wvwf+Hq7z/j6S1/7J6j/+zdY3/sHaN/614jP+ldYf/mmFz/41dbv96W2n/
+        bF1r/2hwf/9sh5f/e6K0/4Crvf+Ep7j/gau9/3+uwP+Arr//gK6//36qvf+Aq73/gq/A/57G0/+fyNX/
+        u9zl/8Ti6v+/3uf/j8DP/4u8zP+XxdP/i7XE/4Wywv+GtcX/grHC/4m1xP+MvMz/kcHP/57J1v+FscH/
+        e6a3/3enuP95o7X/daa4/3Onuf9yp7n/cKa5/3Cluf9wpbj/b6S3/26jt/9to7b/baK1/22htP9soLP/
+        cKO2/3anuf9vobT/bZ+y/2mbrv9omq3/Z5ir/2aXqv9nl6r/ZpWn/2SUpv9nkKH/apCf/2SNnf9oi5v/
+        ZIqZ/2GFlf9ggpH/XoCO/159iv9deYX/XXR//11yff9ZbHf/WGt1/1Rlb/9QYWv/Sltj/0FQV/85RUz/
+        KjM4/xUZHf8RFRf/EBMWXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAHmpvCp7s8X/frLE/364yv9/uMr/f7bJ/4Owwv+BsML/e63C/4Gxw/+EscL/h62//46rvP+ugZT/
+        tHOM/7F2jf+ud4v/qHmL/55nef+RXm//gFxs/29bav9oann/aoKR/3ecrv+Aq7z/ga2+/4Guv/9/r8H/
+        gK/B/4CvwP+ArsD/fqy+/4CuwP+Arb//iLbG/4u6yv+Pvc3/utvk/7/f5/+Mvs7/g7fH/4O4yf+Mu8r/
+        ibPD/4q1xP+MuMf/n8jV/5nH1P+Nv83/f7LD/32qu/93q77/eqe5/3emuP90qLv/c6e6/3Knuv9xp7r/
+        cKa5/3Cluf9wpbj/b6S3/26jt/9uo7b/bqO2/3KmuP96q73/dqi6/2+htP9qnbH/aZyv/2iarf9nmaz/
+        aJmr/2eYqv9ol6r/ZpWn/2uWp/91nK3/bZeo/2eQoP9ji5v/YYaW/2KFlP9jhJP/YoGO/155hf9ddoH/
+        XXJ8/1tueP9ZbHb/VGZw/1Jkbf9LXWX/QVBY/ztHTv8qNDj/FRoc/xEVGP8OExg0AAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZn+ZCny1yPt8rL7/f7bJ/4C3yP9/tcj/
+        fbDD/4Kuwf+AsMP/g7LE/4awwv+Iqbv/pIia/7VzjP+xdIv/r3aK/6l4i/+jb4H/lF9w/4VbbP9zW2n/
+        aGNy/2d7iv9zlqj/gKm6/4Ksvv+BrL7/ga7A/4Cvwf+Ar8H/gLDC/4Cwwf+Ar8D/f6y+/3+uwP+DscL/
+        hLTF/4K0xf+r0Nv/t9vk/47B0P+Hu8v/ir7O/5LAzv+ZxNL/lsXT/5bC0P+OwM//h7vL/4Gxwv96rsD/
+        e7DC/4O0xP9+prf/daq8/3itvv90qLv/cqe7/3Kou/9xp7r/cKa5/3Cmuf9vpbj/caa5/3Wpu/91qbv/
+        eau9/3Ckt/9vorX/bJ+z/2qesf9qnK//aZuu/2iarf9snK//aJms/2iZq/9xnrD/eaOz/36mtv9plab/
+        ZI+g/2KJmP9liZn/aoyb/2KEkv9hf4z/YHqG/152gf9edH7/W295/1lrdv9VaHH/U2Zv/0xeZf9EU1v/
+        PElQ/ys0Of8VGhz/ERUY/A4OHBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAe7TF2360xv+Ar8D/grTG/3+ww/97rsP/fKvA/3+pvf+HrsD/iKa4/5aSpf+1dYz/
+        snSM/7B0iv+seYz/qHeJ/5lhc/+JW2z/d1po/2pebP9nc4H/b46e/36mt/+Cqrv/gKOy/4Ksvf+Crr//
+        gq/A/4Gvwf+BsMH/gLDC/4Cvwf+Crb7/gq6+/4Gxw/+Cr8D/gq/A/4y0xP+gytf/iL3N/42/zv+LvMz/
+        krnH/5nD0f+UwtD/j77N/4O4yP+GsMD/f6m6/3utv/+Ousn/jr7N/3qsvv97rsD/eKy+/3aqvP91qLr/
+        c6e6/3Oou/9xp7r/cae6/3SpvP93q77/dKi7/2+jt/9uorb/baG0/22htP9sn7P/a56y/2qdsP9pnK//
+        aZuu/2marf9pmaz/d6Kz/3+quv+Drbz/gKm5/2aTpf9ljp//ZYmZ/2SImP9khZT/YYKR/2F/i/9geob/
+        XnR+/11xfP9cb3n/WWt2/1dpc/9UZ3D/TF5n/0VUXP89SVD/KzQ5/xUZHP8RFBbfAAAAAQAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9tsepf7LD/4Gtvv+Ctcf/
+        hK6//3isw/93pb3/hqa5/4atv/+Sm6z/sneN/7Nyi/+wdYz/rXaK/6l6jP+ganz/jl1u/3taaf9tW2n/
+        Z2p4/2yEk/97n7D/g6y9/4antv+Qpa7/gqu9/4Otvv+Drr//gq/A/4Kvwf+Br8D/ga/A/4GvwP+Crr//
+        ga/A/4GvwP+Erb3/gLLD/4Syw/+Ww9H/kcDP/6jR3P+Yv83/kL/O/4a1xf+CrL3/gqi4/4Cquv+AscH/
+        hLLC/5K7yf+Ftsf/fK7A/32qu/99qLn/fa2+/3isvv91qLv/cqi7/3KpvP92rL7/eK2//3Oou/9xprn/
+        b6O3/26jtv9torX/bqK1/2ygs/9rn7L/a56x/2qdsP9qnK//aZuu/3eltv97prb/hrC//4u0wv+Bq7r/
+        aZWm/2aOn/9ljJz/ZomZ/2mGlP9igY//ZX6K/2F2gP9hdoD/X3R+/1xwev9ZbHb/Vmhy/1Rmb/9NXmf/
+        RVRb/zxIT/8rNDn/FBgb/xAUF7kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAH23xnZ+rr//ga/A/4O1xv+JscL/fK/E/36rwP+GrsD/iqm7/61+kv+0coz/
+        sHOL/7B5jf+sfI7/p3SG/5Nfb/+BWmn/cVto/2ZjcP9pe4n/d5en/4Souf+EqLn/gqS0/4Kouv+ErL3/
+        hK2+/4Suv/+Dr8D/g6+//4Ktvv+Crb7/gq6//4GvwP+Br8H/gq6//4Kuvv+AsMH/g6/A/5XAzv+axdL/
+        o8vX/6jP2/+JuMj/gqy9/4Gtvv+Es8P/f7HC/4O3yP+Brb3/i7LB/5W+zP+HuMj/gbTE/3uvwP98scP/
+        eK7A/3Srvf90qr3/fLHC/3+zxP96r8D/eKy+/3Oou/9wprn/b6S3/22itf9tobT/baG0/2ufsv9sn7L/
+        a56x/2qdsP9tnrH/gK6+/3mnuP+FsL//ibPB/4Gruv91n7D/apSk/2uSov9tkaH/bY2b/2iBjP9ogIv/
+        YnZ+/2F2gP9hdoD/XXB7/1lsd/9XaXP/U2Rt/01fZ/9EU1v/OkZN/ygxNv8TFxr/DxUXgAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdqu5SX+wwf+Frr7/
+        hbXF/4u2xv+GtMb/grHE/4Ouwv+ii53/tHOM/7F0i/+wd4v/rn6R/61+kP+aZXb/h1tr/3ZaaP9oXWr/
+        ZnGA/3GOnv+Bo7T/hae5/4Slt/+Gprj/h6m6/4asvP+Frr7/hK+//4Ouv/+Drb7/hK2+/4Wsvf+Erb3/
+        g66//4Kuv/+Br8D/ga/A/4KvwP+JtcX/hrLC/4ixwf+Yvcr/p8zY/4q1xP+BrLz/gaq7/4OzxP+Kusn/
+        irfH/4SwwP+Kucj/i7jH/4G1xv+Kusn/kLnI/4i5yP9/tMX/erDB/3uxwv99ssP/fbHD/36yw/93rL7/
+        eKy+/3Spu/9yp7n/bqO2/26itf9vo7b/bKCz/2yfsv9rnrH/a52w/3GitP9+rLz/f6y8/4Gtvf+Ks8L/
+        ibLA/4Gquf9xnK3/d56t/3mcq/9vj53/Z4CM/2h/iv9keYT/ZHmE/2F1f/9dcXv/Wm13/1dpc/9TZG3/
+        Tl5n/0ZVXf9ET1T/KDA0/xMYGv8SFhY4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABiiYkNgrbJ94azw/+IssL/irbH/4q4yf+Ks8X/j5Sq/7R1jf+yc4v/
+        sXeN/7F+kv+vgZT/pXOF/45eb/96Wmj/bFpo/2Vodv9ogJD/fJ6w/4Citv+FpLb/gaK1/4eouv+Iqrv/
+        hqu7/4Orvf+Drr//gq2//4GqvP+FrL3/hqy8/4WsvP+Erb3/g66+/4Kuv/+Drr//g6+//4awwP+Erb7/
+        g629/4mywv+Ks8P/gqy9/4CrvP+Bqbn/gaq6/3+xw/+Etsb/fq7A/3yuwP98r8H/gbLD/5DBz/+QwdD/
+        hLnJ/4G2x/+Ct8f/gbXG/36yw/9/tMT/frPE/3uvwf93rL7/dqq8/3CluP9vpLf/b6O2/22itf9tobT/
+        bKCz/2yfsv9tn7L/dqa3/3Kitf9+q7z/d6a2/32puf+BrLv/h7C+/3+ntv99pLP/d5uq/3GRn/9pg5D/
+        aH+K/2R6hf9jeYP/YHaB/1xzfv9bbnj/V2pz/1Nkbv9OXmf/R1Vd/z1KUP8lLDH/Ehca8hkZGQoAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/ucm6
+        hbfI/4qxwf+Ht8j/irjJ/4+qvP+weY//s3KL/7F1jP+weo7/sYSX/7CClf+WZXX/g2Fw/3NebP9lYG3/
+        ZXaF/3GQo/9/pLf/gKK2/4emt/+Gp7j/hqq7/4arvP+Fq7z/f6e7/4Grvv+Aqr3/f6a6/4asvP+Hq7v/
+        h6u7/4asvP+FrLz/hKy9/4WsvP+Gq7v/h6u7/4Wquv+Eqrr/g6u7/4Kru/+Bqrv/gaq7/4Gpuv9/qrv/
+        gK6//4Csvf9+qbv/ea/C/3ytv/+GtMT/irvK/4G3x/+Atsb/hLnJ/4e6yv+Ct8j/g7jI/4a6yf+EuMj/
+        g7bG/3esvv9zqLv/cKW4/3CluP9wpLf/baK1/2+jtv9xpLf/c6S3/3Kktv9yo7X/bZ6x/3imuP91pLX/
+        daK0/3youP+Aqrn/fKW1/3+ltf9uk6P/aIiX/2qGk/9ogIz/Y3yH/2J5g/9ddoH/WniE/1xwe/9YanT/
+        U2Vu/01eZ/9HVl7/PElP/yEoLP8SFhmoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIG5y26Ducr/irTE/4q0xf+Ktsf/qIaa/7RyjP+wc4v/
+        sHeL/65/kv+wgZT/oHCC/4phcf98ZHL/bGJw/2Vvff9wiZn/faCz/4SpvP+Eprj/gqK2/4Kkt/+Gq7z/
+        gqm8/4KpvP+AqLv/fqe7/4CpvP+Cqrz/h629/4mruv+Kq7r/iaq5/4iquf+Jqrr/iKi4/4mntv+Kqbj/
+        iKe2/4aot/+Eqbn/g6q6/4Kqu/+Cqrr/gKq7/4Gquv+Aqbr/gqi4/4Kpuv+Drr//h7bG/47Az/+Ovs3/
+        iLvL/360xf+Ctcb/hbnJ/4O3yP+Hu8v/i73N/4C0xf94rsD/dqu+/3SqvP9yp7r/caa5/2+kt/9uo7b/
+        bqK2/3epu/98rb7/d6i6/22fsv9snrH/caGz/3aktv9yoLL/fKi4/3ymtv91n6//cZip/2iOnv9miJf/
+        aIOQ/2V/i/9kfYn/Y3mE/150f/9bdYD/WXJ9/1hrdf9TZW//TV1n/0ZVXf86Rk3/HCQo/xMZHFoAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        f7a/HIO4yvyItsf/i7TG/5uXqP+1dI3/snOL/7B1i/+teo3/rH2Q/6x9kP+QYXL/fmFu/3Zndf9qbnv/
+        bYOS/3ybrP+Fqbv/h6y9/4epuv+ApLj/g6i7/4Kou/+BqLz/f6a6/36luf+BqLv/g6u9/4Ssvv+Jr7//
+        i6y8/4upuP+KqLf/iqi3/4qot/+Kp7b/iae2/4mntf+IprX/iKa2/4aouP+Eqbn/g6m6/4Kquv+Bqrr/
+        gKq7/4Couf9+q7z/fq2+/4O1xv+Hucr/j8HP/4a6yv+Jvcz/ksLQ/4q5yf9+scL/frTF/42/zv9+tMX/
+        fLHD/3arvf93q73/eKy+/3quwP9yp7r/cqa5/2+kt/9uo7b/dai6/4Cwwf+AsMD/c6S2/3GitP90pLb/
+        eae4/3WjtP95pbb/faa2/3Sdrf9rk6T/aI6e/2aJmP9mg5H/ZIGN/2R+iv9jeoT/YXaB/1lwe/9ccn3/
+        WGx2/1Nlb/9NXmf/RVVe/zVFTf8XHiL3ExMTDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg7jJxIe2yP+Rprj/s3eN/7NzjP+xdYz/
+        rniL/65/kv+te47/m21+/4Nfbv96ZnT/cG16/3SGlP96mar/ham5/4itvv+IrL3/iau8/4WqvP+Frb//
+        ha2//4Wtvv99orj/fqO4/4KpvP+Frb7/hq6//4uwwP+StMP/jq28/4yquf+Nq7r/i6m4/4qot/+KqLb/
+        iae2/4mmtf+JprX/iKa1/4aot/+Eqbn/g6m5/4Opuf+Bqrv/gKu8/3+svf+Bqrv/h7TF/429zP+Wvsz/
+        hq29/4q9zP+dytf/rNPe/5PD0v+Mvs7/hbjJ/4G2x/+Btsf/gLTF/36yw/94rL7/dqu9/3Gmuf9yprn/
+        b6S3/2+kt/91qLv/g7PD/4q3x/99rb7/dqa5/3yru/9/rLz/daO1/3WgsP94obH/c5qq/2qTpP9nj5//
+        Z4qZ/2eGlP9lgpD/ZH+L/2N8hv9hd4L/X3R//1twev9Ya3b/U2Zw/01eZ/9AU1v/Kzc8/xQaHa8AAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACDuMlpibPF/6t/kv+0cYv/sXSL/693i/+ufZH/sICT/6h8j/+IW2v/eV5r/3Blc/94g5D/
+        gp+u/42ywf+IsMH/ibDB/4muv/+IrL3/h62//4awwf+Erb//g6y+/4Cmuv94nbT/gKW5/4qxwf+Ms8P/
+        iq6+/5Ozwf+SssD/krG//5Cvvf+Prrz/kK69/4upuP+Jp7b/iae1/4mmtf+IprX/iKa1/4antv+Fp7f/
+        hai4/4Kpuf+Bq7z/f6y9/4GvwP+Br7//hrXF/4m2xv+Fs8P/i7zL/5HD0f+s1N//oc3Z/5vI1f+Iu8v/
+        ibvM/5TE0v+Husr/eq/B/3quwP92qrz/caa5/3Cluf9wpLj/cKW4/3aqu/+Kucj/i7nH/4CwwP+CscH/
+        g7HB/36svf99qrr/fae3/3qjs/9wlqb/apOj/2aPoP9mi5v/ZYiX/2SEkv9jgI7/YX6K/2B5hP9edYD/
+        XHF8/1hrdf9TZnD/TV5n/z9RWf8oMTb/FhkdTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH+vvxCbjZ/zs3GK/7Fxif+wdIr/
+        rXmN/6x9j/+rfI//mG5//3pYZv9vXWv/Z2Z0/36WpP+VuMb/kbjI/4y2xv+MtMX/i7LD/4euv/+Hr8H/
+        h7HC/4Wvwf+Hr8D/gae7/3uht/+Dqr3/hay+/4muv/+OsL//kbC+/5Kxv/+Prr3/lbTC/5Ozwf+Us8H/
+        jqy6/4qntv+Kp7X/h6Sy/4mmtf+IprT/iKW0/4iltP+HprX/hKi4/4Gqu/+BrL3/gK2+/4Ctvv+DscH/
+        jrrJ/4Kywv+Ft8f/ibzL/47Bz/+Jvc3/hrrK/47Az/+izdn/nsrX/4S5yf97sML/eq/B/3eqvP9yp7r/
+        caa5/3Knuv91qbv/h7fG/4y7yf+FtcX/j7vJ/5S+y/+Oucj/i7bE/4Wvvv+DrLv/f6Sz/2+Vpf9qlKT/
+        Z4+g/2WMnP9kiZj/Y4WU/2KCkP9hf4v/YHuG/113gv9ccXz/WGt1/1JmcP9KXmj/P05V/yAoK+QAMzMF
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAl1lnNq5qf/Kxb4j/r3KJ/611if+re43/rX2Q/6R9kf+DW2r/dFxp/2Vdav9ndIH/
+        haW0/6nL1/+Otsj/l7/O/5C5yf+Nt8f/iLLE/4izxP+ItMT/h7HC/4ixwv+Dq77/gqq9/4Otv/+Cq7//
+        jLLD/5Gywf+Ssb//lLTC/5Kxv/+Ssb//krLA/5Gvvf+Nqrn/iqe2/4qntv+Jp7b/iaa1/4mmtf+IprT/
+        iKW0/4iltP+Gprb/hKq6/4Otvf+Er7//hLDA/5fCz/+dx9T/ncfU/5zI1f+PwM//i77O/4i8zP+IvMz/
+        jb/O/53K1/+hzNj/ibzM/32yxP97sMH/e6/A/3WqvP9zqLr/e66//4K0xP+Pvcv/lsHP/4+8yv+bxND/
+        mcLO/5S9yv+Pucb/irTD/4Ktvf95o7P/bZeo/22UpP9pkqL/ZI2d/2OKmv9jhZT/YoKQ/2B/jP9ffIj/
+        XXiD/1xxe/9Xa3X/UGVw/0pbZP84Rk3/GCAlfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8/XwilXG7CrWB67a9xif+uc4j/
+        qXiM/6p5jP+meY3/lG1//3laZ/9tXm3/YWVy/2mCkf+Dqrv/rtHd/5rA0f+IssT/jbbH/4q0xf+ItMb/
+        h7TF/4e0xf+Is8T/ibLC/4ixwv+GsML/gKq//4Suwv+Mr77/kLPC/5W1xP+VtML/kK69/4+tvP+PrLv/
+        jqu6/42ruf+LqLf/iqe2/4qntv+Kp7X/iaa1/4mmtf+JprT/iKa1/4imtf+JrLz/ia+//5O7yf+YwM7/
+        rNDc/73d5f+y1uD/oczY/5fG1P+OwdD/frXG/3+1x/9/tsf/hbvK/5rJ1v+dytb/hrrK/3etv/93rb//
+        eKy//3esvv99scL/i7vK/5TBz/+axNH/mcPQ/53F0v+bw9D/lL7L/424xv+EsL//e6e4/3Kcrf9tkqL/
+        Z5Gi/2WQof9ljp//Y4qa/2SFlP9igpD/YYCN/2J/i/9geYT/XHJ9/1ZteP9QZnD/R1hh/yo4PPQVHx8Y
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAnFdoeqlac+aoXHTirW2E+ap2iv+oeYz/qXqO/6B8kP+AXm3/cVpo/2dhb/9qeYf/
+        cJGj/32ovP+ly9n/pMrY/4+4yv+Js8X/hrHD/4Ovw/+EscP/h7LE/4qzxP+KssL/ibDB/4Wvwf+Er8H/
+        ibTF/4y1xv+Rt8f/m7vJ/5Kxv/+Oq7r/jqu6/42quf+Mqbj/jKm3/4uot/+LqLf/iqe2/4qntv+Kp7b/
+        iqe2/4mmtf+JprX/iKa1/4iot/+Nr73/nsLP/6TI1f+v0t3/ttjh/5K9zP+VwtD/mMbU/3+2x/+Ducn/
+        grjJ/4e8zP+Pwc//oc3Z/53K1/+UxNH/e7DC/3Wrvf94rb//eq7A/4GzxP+SwM7/msXS/5jD0P+aw9D/
+        ncXS/5fBzv+Ousj/ibXE/32qu/9zoLH/a5mr/2yUpf9okaL/ZJGj/2SOn/9kiZn/ZIWU/2KCkf9ggI7/
+        YHyI/195hP9Zc3//VW56/09kbv8/U1z/Ii0yjQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBRYiyoW27iqlpz5aRbct2lY3bk
+        qHiL/6p3iv+kfI//lnqN/3JTYf9qXGr/XmNw/3aPn/+Hrb//f6vB/5jB0v+iydj/iLLH/4Kswv9+qL//
+        e6a+/4Gtwv+JtMX/i7PD/4qwwP+Kr8D/gqu+/4Wvwf+HscL/jLXG/5K2xv+UtML/lLPB/5uvuP+OrLv/
+        i6i4/4upuP+Lqbj/i6m4/4uot/+LqLf/iqe2/4uotv+Lqbj/j668/4upuP+Kp7b/iae2/4qpuP+jxND/
+        osbS/6zP2/+SvMr/ga6//4Cwwf9/s8T/ir7O/5vK1/+PwdD/kcPR/6DN2f+o0dz/ptDb/4/Az/+EuMj/
+        dqy+/3OpvP92q73/gbTE/5HAzv+dx9P/kr7N/4u5yP+Yws//nMPQ/5O9yv+Pucj/fqu7/3Kgsv9rmav/
+        apWm/2aVp/9kkqT/ZI2e/2SKmv9jhpX/YYOS/2CAjv9hfor/XHiD/1dzf/9TbXn/S2Fs/zRES/UTHR0a
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAABVVVUDolhptalYc+alWnLfo1tw3JxZa9CmcoT0qXqO/6B8kP+Hb3//aVNh/1xWZP9XZXT/
+        dZOl/5G5yf+Qus7/gKzD/5bA0f+DrcT/eqO8/36nwP97pL7/fKa9/4OswP+Ir8D/h6y+/4Oou/+Dqb3/
+        h7DC/4ixwv+IsMD/i7C//46tvP+Ssb//mK63/5Cuvf+Hpbb/i6i3/4ypuP+Lqbj/i6m4/4uot/+LqLf/
+        iqe2/4qntv+Orbv/lrXD/4yruf+Jp7b/iqm4/6HCz/+ix9P/mcDO/4axwf+Arr//fq6//32wwv+Atsf/
+        lcbU/53L2P+jztr/rNTf/6bQ3P+o0Nz/mcfU/3qwwv98sML/eK3A/3Oou/95rb//ksHO/5XBz/+Ht8f/
+        iLfG/4m3xv+dxNH/nMPP/4m0w/99q7v/cqGz/2qarP9ol6n/ZpSn/2aSo/9jjJz/Y4uc/2KHl/9hhJP/
+        YIGP/116iP9Zd4T/VnF9/09qdv9DWmX/KDU8kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJtUZmGpWW/mqFhx46RYb92fWGvV
+        mFdpzJ9hddmkfpH/mYSZ/3ljcv9iVGH/Vlpn/1lygv9pjaT/mcHR/5O+0P+ArMP/e6a//36lvf97o73/
+        f6a//3efu/9+p8D/fqe9/4Srvv9+o7j/fKC2/32iuP+ErL7/i7LC/4qwwP+Lr7//ja29/42ru/+KqLn/
+        iai5/4mmt/+Prbv/jKq5/4ypuP+OrLr/jKq4/4uot/+LqLf/iqe2/4qot/+Rsb//jq27/4qot/+Orr3/
+        mr7L/6PJ1f+Ru8r/ga6//3+uv/9+r8D/fa/B/3+0xf+PwdD/mcnW/5vJ1v+aydb/kMLQ/4u+zf+Gusr/
+        f7LE/3esv/93rL7/cqi7/3Kou/92qr3/eq2//4S0xP90prn/equ8/4e0xP+KtcX/g7DA/4Gtvf9zorT/
+        bZyu/2uZq/9mlaf/ZJKk/2OPof9ijJ3/YoiY/2GElP9fgI//WHWE/1Z0gf9QbHr/SmRw/zVJVO4VHx8Y
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACLRVwWp1pr16pYc+alWHDeoVhs2ppWac6ZV2nMlVVoxJp1iOaWjaD/a1po/1tWY/9RYG3/
+        ZIaX/2+csv+Assj/j73P/4m3yv+CrsT/bZOx/3GYtv92nrj/cpq2/3aeuv99pb3/gKe8/3mdtf92mrL/
+        ep61/4asvv+KscH/i7DA/4uuvv+Mrbz/iKe4/4mnuP+Jp7f/jKq5/4yquf+Lqbj/jKm4/46ruv+Mqrn/
+        i6m3/4uot/+KqLf/iKSz/4yquf+Lqbj/iaq5/5W4xf+Uucf/rtHc/424x/+Brr//f66//32vwP99sMH/
+        gLTF/4m8zP+UxdP/kMLR/4a7y/+Btsf/gbbH/32yxP99r8D/dqy+/3OqvP9yqLv/cqe7/3Gnuf9xprn/
+        dqm7/2+jtv9vo7b/b6K1/2+htP9woLP/caGy/2ucrv9rm63/Z5eq/2WVp/9kk6X/Y5Ci/2OMnf9hiZn/
+        YoaV/1p6iv9VdYP/UnB+/0xndP9FXWn/LDlAbgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKBXaJKqV3Hmp1lx4aVZcN6eV2rT
+        mFZmzJpVZ8qNUGG4gFJio4+MnvhiVWP/Ulln/1Fpd/9nkaP/eq7B/4S7zf+Jvs//i7vN/426zP9/qsP/
+        cZm3/32jvf92nbj/c5u2/3Katv9xmLT/dZmz/3SVr/9+n7X/iKy+/4asvv+Irr//iq29/4iouf+CoLP/
+        h6W2/4imt/+Hpbb/iaa3/4ypuP+Mqrn/jau5/4yquf+Lqbj/i6i3/4uot/+LqLf/i6m3/5Ozwf+Psb//
+        j7PC/5K3xv+mytb/ibPE/4Csvf9/rb7/fq/B/3+zw/+Dt8f/hLjI/4y9zf+QwdD/jL7N/4W5yv+Dt8j/
+        jL7N/4u9zP94rsD/dKq9/3OpvP9yqLv/cae6/3CluP9wpLf/b6K2/26itf9uobT/cKK0/3ChtP92pLb/
+        b5+x/2iZrP9nl6r/ZZWn/2STpf9jkKL/Y4yd/2GJmv9cgJD/V3iI/1R0hP9Qa3j/RmFv/zpTYMQAAAAC
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACSUF42qlpu5atZcuWmWHDeolls2ZlVZ86bVmfMlFJjwoRJWqluQEyGeW58pFtVYv9RXmr/
+        VXWD/26ZrP9/tsj/g73O/4i9zv+KvM7/i7vN/4i2yv91n7r/c5y4/3mhuv9ymbX/bJOx/2+Ws/9pj67/
+        b5Ov/3ibs/+Cp7v/gKe7/4OpvP+EqLr/h6a4/4qpuv+GpLb/h6W2/4mnuP+Mqrn/jaq5/42quf+Mqrn/
+        i6m4/4upt/+Lp7X/i6i2/4yquP+XtsP/jqy6/42vvv+RtML/jbLB/57C0P+Ms8T/fai8/4Ozw/+DtMT/
+        hbXG/4W2xv+Gt8f/hrfH/5TC0P+LvMz/i7zM/4i7y/+Gusr/hbnJ/32yw/96r8H/dqy+/3Oou/9xp7r/
+        caW5/3Ckt/9worT/bqK1/26gs/9tn7L/a56w/22esf9tna//aJms/2eXqf9llaf/ZJOl/2OQov9fipz/
+        XYOV/1V4i/9ZeYf/V3J+/0Zhcv8/WWvyPldjKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAqRZabeqV3LmqFhw4KRYbt2dV2nS
+        mVZmzJtUZ8qMTF23eEJRlmU7R3lUNUBbTk9cwFBhbf9hgZD/cJ2y/4C0yP+Eusz/hLjL/4e4y/+Qtsb/
+        iLXK/3qmwP91oLv/b5i1/2uSsf9qkrD/apKx/2qSsP9tlbL/cZi0/3efuP9/p7z/faS6/4SpvP+Gprj/
+        iqq8/4qpu/+Lqbn/jau7/46suv+Nq7r/j627/4upt/+LqLb/jKm4/4uot/+LqLf/hp+r/5SzwP+Prrz/
+        kbC+/4uru/+Krr//ibHD/4Wvwf+Fs8T/grDB/4CvwP+Ar8D/gbHC/4Gyw/+Ovcz/oMrX/4q7y/+Iu8v/
+        hLnJ/4W5yf+EuMn/gLXG/3qvwv93rb//c6m8/3Oou/9xprn/caS3/2+jtv9uorX/b5+z/22esf9rnrH/
+        apyv/2marf9omav/Z5ep/2WVp/9kkqX/ZI6g/1qDl/9SeY7/U3eK/1p2g/9NaHf/Plpu/0FhcmkAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACbVGNXqllv5qtZcuWmWHDeoVhr2JtVZ82bVGfNlFFiwoVIWKptPEmHXDRAa0guOE07Mz88
+        SWFs5G2Mm/98qLv/frTJ/3+1yf+FuMr/gbPH/4y3yf+Gssj/eqjC/2uXtv9slrX/ZY2u/2CHqv9kjK7/
+        a5Wz/22Ytf91obv/eqa9/36pv/9/qL3/f6W6/4OkuP+Gpbj/iKa4/4yruv+Nq7v/jq28/5S0wv+Prbz/
+        jqy7/5Kwvf+Mqbj/jKq4/4qntf+Lp7X/iqWx/5Cuuv+dvcn/jrC//4+1xv+HscT/jrjJ/5C4yP+Susn/
+        lb/N/5G+zP+Kucj/jr3M/6XO2v+gytj/jL3N/42/zv+Hu8v/ibzL/4m8y/+Lvcz/frLE/3itwP93rL7/
+        dqu+/3Wpu/9yprn/cKS3/2+jtv9uobT/bZ+y/2yesf9qnLD/aZuu/2iZq/9nl6r/ZpWn/2uVpv9vkqL/
+        XoSX/1l/kv9Ye4v/VHSE/0Bfdv9FY3asAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAB
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf0xMCqdaa86rV3Pmp1hx4KZZbt2dV2nS
+        m1VnzZtVZ8uNTV64ekFQmGY5RXxSLz1gPCgwPycfJyBIXWo8YoWT94SzxP+Cuc3/fbLI/4G2yv+Gt8r/
+        grLG/3ekv/9smbj/aJS1/3Gcuv9jjbD/YYqs/2aPr/9lkLH/bJm3/3Gduv9zn7r/eqa+/3ylvP94m7L/
+        eZ+3/4Snuv+Hqbv/jq69/46tvP+WtcP/kbC//5Cvvf+Mqbf/i6e2/4upuP+LqLf/iqa1/4upt/+ZuMX/
+        qsrV/6DD0P+Rt8f/hK7B/4Wrvv+PtMT/krvK/5K9zP+Su8r/ocnW/6nP2/+It8j/k8DP/5PB0P+Jusz/
+        i77N/4u+zf+Lvc3/iLvL/4W4yP+AtMX/fLHC/3ywwv99scL/eq6//3apvP9yprn/cKS2/26htf9uobT/
+        a56y/2yesP9pm67/aJms/2mYq/9mlaf/Yoyg/2WLnf9nipn/XH6P/1Z5if9GaH7/QmR7109vfxAAAAAA
+        AAAAACozMx4mKix+IycpwCMlJ+cjJij5JCcp/SMmJvUhJSbbISQltiMlJWYfHx8QAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACdVmZwrVpw56tacuWmWHDeoVhr2JtVZ86cVWjNllJjw4dIWK1wPEmKXzQ/cEsqNlQyIygz
+        JBgkFQAAAABhhZdjga/B/oq/0f98sMf/e7HI/3ipw/93pcD/dJ+7/3Ccuf9smbj/cJy7/26YuP9iiq3/
+        Zo+w/2eRsv9lj7H/ZY+w/3mkv/+Gscb/dJ64/3SduP+ErsL/krvL/461xf+NssH/kLC//5KywP+Us8H/
+        lrfE/4upuf+Jprb/iaW0/4uot/+Mqrn/jKu5/5u8yP+qzdj/ncTT/5C2x/+Iqrv/hqe5/4yvv/+Wvsz/
+        mMDO/5vE0v+gyNb/q9Dc/5C8zf95qL7/eqvA/4W4yf+Lvs7/ibzM/4G2x/97scP/fLHD/32xw/9+ssP/
+        frHD/36xwv+DtMT/grPD/4Cxwf98rL3/caS3/3Gjtf9tn7L/a52w/2qbrv9tnK7/apir/2OQpP9ijaD/
+        ao2e/2yJlv9gfoz/Tm+C/0Zof+5Kb4gpAAAAADc3Pik0ODu0OTw+/DM2N/86PT//NTg6/zM1N/8qLC7/
+        JScp/yMmJ/8hJCX/ISMk/yAjJPYfICKjHh4eMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhkNQE6labdmtWXPnqFhx4KdZbt2gV2rS
+        m1dozZ1VZ8yPTl66fUNSnmo5RYFVLzxlRCcuRy8dIysVFRUMAAAAAAAAAACBrsCOi77Q/4q/0v95scn/
+        c6bD/2+evf9plbX/cZy6/2yXt/91n73/cJm4/2aOr/9rlLT/bJe2/3OevP9znrv/fajB/5K9z/9+qsL/
+        cpy3/32pv/+Nucr/mMLQ/5nBz/+ews//ocHO/6LD0P+oydX/j66+/4mnuP+Kp7X/i6y6/4mvvv+Iqbb/
+        lLfE/57Azf+UtsX/haq7/4WnuP+CpLb/ham6/5e+zf+pztr/pczZ/6PL2P+Nucr/grDE/3SmvP92q8D/
+        f7XH/4i8zP9/tcb/e7HD/3qvwf99r8H/f7DB/4Cyw/+Dtsb/jrnI/426yf+Rvcv/j7vJ/4CwwP+CsMD/
+        eKi5/3ChtP9rnbD/bZ2v/2+drv9mlaj/Y5Ck/2ePof9ri5v/YX+P/1J2iv9KboX3T3WJSjMzMwU7P0OF
+        SU1P+E5RU/9LTU//W11e/2NmZ/9lZ2j/Wlxd/0xNT/9BQ0T/OTs8/ywuMP8mKCr/IyUn/yEjJP8fISP9
+        Gx4ghB8fHwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACfV2h9rlpx56tac+WoWXLfpFhs2J1Vac6eVWnOmlNlxopKW7J0PUyQYzVBeFIrOV05ICk+
+        JRYeIioqKgYAAAAAAAAAAFWqqgOJusmyiLzQ/4K1zP9nm73/ZJa6/2KStv9rmrr/cJy6/3Cbuf9hiq7/
+        aJCw/2+cuv9um7v/ibbN/4Oxyf99qsP/fanC/3WhvP90obv/favB/4W0x/+Pvs7/lcPS/6fP2/+nztr/
+        nMXT/463x/+EpbT/h6Wz/42zwf+TtsT/krLA/4upt/+Nq7n/jqy5/4mot/+Eprf/gJ+x/36luP+Crb7/
+        h7HC/5vE0f+lzNj/o8rX/36uwv92qr//eKzA/3auwf97scP/fLHC/3uvwP97rb//gbHC/4W0xP+Fs8P/
+        g7TE/5PAzv+Qvsz/j7zK/5G7yv+Mt8b/ibXE/4q1w/94p7n/bp+y/22esP90obL/aZer/2aVqP9jjqL/
+        Yoqd/1l8kP9UeIz/TXOJ/FR1jGRCS0sbTVJTxnN2d/+ChYb/fH5//21vcP9tb3D/dHZ3/3l7fP9+f4H/
+        b3Fy/2VmZ/9kZWf/VVdY/0ZISf82ODn/MjQ1/yEjJP8eICL/GhsbuRwcHAkAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0VcFqlbbd2uWXPnqFly4KhacN6iV2zU
+        nFdozZ9VaM2TUGG+hEZXp208R4dcMj5uSyo2VTMhJTYkGxscAAAAAwAAAAAAAAAAAAAAAHWcsA2Bs8e9
+        hbnO/3Wqxv9socH/ZZq8/2yevv9xo8D/d6bB/3Cdu/98qsT/fqzG/2qVtf+EsMj/d6fB/3mpwv98q8P/
+        fKzC/3urwv97rML/g7TH/4u7zP+fytf/rdPe/6fM2P+WwM7/i7TE/4motv+HprT/iaWy/46suv+bu8j/
+        lLPA/4+uvP+Lqrn/h6W1/4Smt/+EqLr/haW1/4Gsvf+Dr8D/iLPE/4+7y/+Qu8v/e6q+/3mvwv94rsL/
+        ea3A/3yvwf9/rL7/fKy+/4Oxwv+DsMH/gKy9/3+tvv+HtsX/l8LP/5bAzf+Wv8z/lL3K/423xf+JtML/
+        eqi5/3+qu/90obT/dqGz/2uZrP9llan/Yo+k/2KNof9XfZP/VHqP/011i/xVeJFmWV9mKIGGiOaTlZf/
+        jpGS/4+Rkv+Fh4j/ent8/4CBgv+LjY7/gIKD/4OEhf97fX7/c3V1/36Agf90dXb/Y2Rl/0tNTv8wMjP/
+        MjM0/yIkJv8dHyD/GBobuBwcHAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACiWGh/r1py565adeapWnLfplpt2p5Xac+eVmrOnlVpy45NX7h7QlGZajlFgVovPGZFJzFN
+        LhokMR8VFRgAAAABAAAAAAAAAAAAAAAAAAAAAH+jtg5+tsm9d67I/3Orxv9upsP/bKPB/22hv/9tnr3/
+        c6G9/3ikv/90nrv/c5y4/3ypwf9+rsT/eqzD/3qvxf+Bt8r/gLXI/4K2yf+Fucv/iLnK/5rE0f+31d7/
+        tdbg/5rBz/+Ps8T/jKy6/42ruv+Nrr3/kLHA/5KywP+Wt8X/nL3K/5i6yP+Lq7r/hai5/4Wru/+FpbX/
+        gaGy/3ymuv+HscP/ga3A/3emvP97rcD/equ+/3mpvP98rL7/hbPE/32tvv+EscL/gq6//4CrvP9+qLn/
+        ibTD/5jBzv+Vv8z/mMHO/4+4xv+Err7/gKy8/3mmuP+BrLz/h6++/36ouP9smq7/Z5er/2WSp/9mkqT/
+        XYOZ/1l/lP9MdIz8VXqRZoaTkxOusbThoaSm/6aoqf+jpab/kZOU/4aIif+DhYb/iYuM/4uMjf+Ehof/
+        g4WF/3x9fv+EhYb/fX9//3p7fP9sbW7/S0xM/0VHR/87PT7/MDIz/yEjJP8ZGxv/FhgYnQAAAAEAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhkNQE6tbbtyvWXXnq1lz4atbc9+kWWzW
+        nldqzqBWas6ZVGXEi0lcsXY/TJBmNkJ6VC47Y0IkLEUwGyAvIhcXFgAAAAEAAAAAAAAAAAAAAAAAAAAA
+        AAAAAG2RkQd7s8aseLDJ/3Srxv9rosH/Zpq9/2OTt/9rmbn/bJi4/3ahvf9rlrX/cp+7/3enwP93qMH/
+        e63D/3yxxv9/tsr/g7rM/4S6y/+Gt8n/jLnJ/7bX4v+nzdr/pcrX/4+1xf+NssL/ja6+/4qwwf+JsMH/
+        jbDA/5G4x/+fxNH/pcjV/5zBzv+KscH/iK6//4SqvP9+nKz/e6S3/4azxP97qbz/e6m9/36uwP+BrL7/
+        g62//4Ovwf+GscL/ga/A/4SwwP+Aq7v/f6i5/4Suvv+exdH/j7nH/5G6yP+Wvcr/irPB/4avv/+Drb3/
+        f6m6/3+nuf94orT/bJqu/2qYrP9ol6r/bJao/2OMoP9Wf5f/T3iQ/FV/mWIAAAABzc7OpMLFxv+5u7z/
+        r7Gy/6aoqf+eoKH/kJKT/4SFhv+Rk5T/l5iZ/5KTlP+Njo//hoeI/4mKi/94eXn/aGpr/19hYf9TVFT/
+        T1BR/0pLTP9MTU//Ozw9/x4gIf8YGhv/FxcXWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACgV2l0r1ty569bd+eqWnPfqFtw3KFXbNGfV2rOoFdqzZRQYr2HSFmpcjxJimQ2QXVTLThf
+        PSIqQi0cIS0iFxcWAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaZmQV3sciRfLXM/3iyyv9wp8T/
+        Z5y+/2aWuf9nlbf/d6TB/4Guxv9wnrz/b6C9/3Olv/96rMP/gbLG/4G0yP+Assb/grTH/32wxf+Hs8f/
+        sNTg/63T4P+32OP/m8LR/4mvwP+Hrb7/lLrK/5O6yf+NssL/nMHO/6nN2f+hx9T/m8PQ/4u3xv+IsMD/
+        hKq7/4OdrP9+qbz/fKy//3+itf+BqLn/fqi6/36svv9/rb7/ibbG/4Kuv/+Dr7//fqm6/36ouf9+qLn/
+        lr7M/5nBzv+Er7//hq+//421xP+Gr7//hK29/4Cpuv95orX/cZyw/26csP9tmq7/a5qt/2yYqv9jjqP/
+        XYSa/1N9lfBahppMAAAAAM/T00HQ0tP+wMLD/7q8vf+vsLL/o6Wm/6Kkpf+XmJn/iIqL/4iKi/+Iior/
+        k5WW/5eZmf+TlJX/kJKT/3x9fv9oamr/ZWZn/1NUVP9LS0z/UVJT/1JTVP9ERUf/Kiss/xscHv8XGRrd
+        FxcXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfz8/CKpbbdOwWnXorFx0461cdeCmWm7Y
+        oFdrz6BXas6fVmnLkk5guYJEVKBuPEiGYTM/cVMsN1w+IytBLRYhLR8VFRgAAAAEAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAD//wF7tcprfLXL+nqzy/94rcf/a6DA/2qbvP9sm7v/irbO/4680f9pnLz/
+        cKXB/3mtxP93qMH/eKS8/3qlvf92pL3/eKa//4mxxf+hyNf/s9fi/7na5f+gytf/kL7O/5K7y/+axNP/
+        stTe/6PJ1v+01uD/tdji/6jQ2/+ZxdP/iLbH/4Svv/98qb3/eaK4/3+svv+Cr8D/gaq7/4Cqu/+Aqbr/
+        fqm7/3+qvP+Err//gam6/4Cpuv9+qLj/fqe4/4Ouvv+exdH/mcDO/4KsvP9+prf/f6e4/36nuP97pLb/
+        dqCz/3Kesf9umq7/bZer/2eUqv9pl6r/ZpOo/2KLn/9bg5vfWIWgLgAAAAAAAAAA0tPUtszOz//CxMX/
+        t7m6/6yur/+bnJ7/oqOk/6Kkpf+OkJH/jY+P/4iJiv+PkJH/np+g/5eYmf+Vlpf/f4GB/2xtbv9kZWb/
+        VVVW/1dYWf9gYWH/WVlb/05PT/9AQUL/KSsr/xobG/8XFxd2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACdVWdZr1xy57Jcd+irW3Pfq1tz36VZbtWgWGvPoldsz51VaceQTF63fEFQmG87SIVfMT9t
+        Uyw3XD0iKkIvGh8wIxEaHRkZGQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/uck+
+        e7XL5X2zy/91q8b/bJ29/26cu/90ob7/hbXM/3SpxP91qsT/dqnC/3Kfuv93pr//eKa//3inv/96qMD/
+        grDF/5TC0/+v1OD/utvl/6vQ3f+v1OD/nsvZ/7vb5f+01uH/rtPf/67T3v/B3+j/ttfh/6DJ1v+Htcb/
+        g62+/3+muf9/pLf/gKe5/4Opuv+Aq7z/fqe6/4Kltf97nLD/gqi7/4euvv+BqLn/fqa3/3uktv99prj/
+        kLnH/53D0P+dw9D/j7fF/4mxv/+ErLz/d5+x/3WesP9zm67/c5ut/3eesP94na7/cZmr/2uXqf9okaP/
+        X4uis12GoRMAAAAAAAAAAMvLyxnT1db5ycvL/76/wf+2t7j/sLGy/6Kkpf+jpKX/paan/5ydnv+Njo//
+        hYeI/5WWlv+Zmpv/jI2O/4KDhP9oaWn/bW5u/1pbXP9bXF3/WFhZ/1tbXP9RUlP/UVFS/0NERP8xMjL/
+        HiAg/xYXGNwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKdabLqzXHbor1135a1bdeCoW2/b
+        olht0qFYbM+jV2vOnFRmxI9LXrN5QVCVbjtHhF4xPWxULjhePyEtRDQcITUkFR0jGQwZFCoAAAYAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhkZMwpYdH8ufLHDwoO4zf90psL/cKG//3apxP97r8f/
+        fbTK/321y/+Atcr/gLHG/4a1x/9/tcn/ebDH/3qwxv+EtMf/ibLE/5vC0v+42uT/rdPf/5jD0v+q0d3/
+        qM/b/6nN2v+extT/msDP/5rAz/+Rtsf/h7TG/4CuwP99prr/gKa5/36jtv+ApLb/f6e6/36kt/+BorP/
+        fp+x/4Oktv+OtMT/haq7/3+mt/98pLb/fKW3/4Cpuv+Susj/ncPP/6XI1P+fw8//jbPC/4Opuf99pLX/
+        eqGz/3mgsf+Cp7b/g6Wz/36erP90lqT/aZSm9l+NpnN/f38CAAAAAAAAAAAAAAAA2dnZWNPU1f/Gx8j/
+        v8DB/7m7u/+wsbL/n6Gi/5qbnf+en6H/nZ6f/5OUlP+EhYb/hoeI/3x9fv+AgIH/eHl6/2RlZv9lZmb/
+        Xl9f/2RlZv9ZWlr/X2Bg/1xdXf9gYGH/TE1N/z4/P/8zNDT/GBka/xMTE0AAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACUT18wsF5y6LFad+euXHbirlx14ahbb9mhV2zPollsz6RZbM6YUmbAjUtcsHtCUJVuOkiD
+        YDI+b1YsOWFHJS9LOB4mOykXHSsmFxchIhcXFhUVFQwqAAAGAAAABAAAAAQqACoGFxcXCyQYJBUmHiYh
+        NCQuMT8tOERPO0ZaeYydrIS1yfiBs8n/g7XK/4a5zP+Kucv/irzN/4G0yf97scj/gLHG/3msw/92qsP/
+        eKzD/4GvxP+Cr8P/i7fI/7HV4P+u097/m8TU/4e1yv+Issj/fqrA/4Gvw/99qsH/cZy3/3ygtf+ArcD/
+        gqy+/4Spu/+Eqrv/gqm7/4Oru/+ApLb/gaO0/4KgsP97m67/gKK0/4WouP+CpLT/f6O0/3+mtv9+p7f/
+        gam5/5K5x/+XvMn/m7/M/5i8yf+St8T/jbLA/4Opuf+Bp7f/ham3/4Gksv95nKz/cZen/2eUqsdbi6Mq
+        AAAAAAAAAAAAAAAAAAAAAAAAAADU1taLy8zN/8LExP+3ubr/sLKy/6aoqf+ur7D/rK2u/6eoqf+dnp//
+        hoeI/4SFhv9ucHD/Z2hp/2FhYv9cXV3/WFla/1hYWf9XWFj/Xl5f/11eXv9rbGz/aWpq/2BhYf9NTk7/
+        PD09/zM0NP8cHR3/ExUVdgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKZaa4eyXXTos1156atbdN+uXnTg
+        qFtv16FZbM+jWWzPpVpuzphSZb2PS1ywe0JQlXA7R4RiNEF0Vy47Y1AsNVZAIilDOR4nOi0WIS0pFBsl
+        JhcXISIZGR4iGRkeIBgYHykbGyUsGyEuNh8oOD8mMUhJLThaVDdAb2M+SYNvR1aZg2R0vpChs/CNu83/
+        irrM/4q1yP+Ktsj/ibPF/4Szxv+Ftcj/g7HE/4K1yP+EuMr/h7fI/4e0xf+FsMP/k7/Q/6fN2/+Wv9D/
+        garB/3ictf95obr/gKe8/3+nvP96oLf/gae6/4asvf+Iq7v/h6y8/4SsvP+Eq7v/g6m6/4Kltv+Ao7X/
+        f52w/36er/+BorP/gaO0/4Gjs/+Bpbb/f6S1/3+jtP+ApbX/jrTC/5G2xP+OtMH/mb3J/5K2xP+Msb//
+        i6+9/4apt/98n6//d5qp/2uQovBhj6ZuP39/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHR0663uLn/
+        tba3/6mqq/+kpab/oKGj/7S2tv+ur7D/p6io/5WWl/97fHz/bm5v/2RlZf9lZWb/WVpb/1pbW/9ZWlr/
+        VFVV/1ZXV/9hYmP/bGxt/31+fv92d3j/Xl9f/1JSUv9FRkb/Ozw8/yorLP8bGxuUAAAAAAAAAAAAAAAA
+        AAAAAAAAAAB/KlUGrF1v1bNdeemyXnfmrlx24Ktdc92mWnDVo1pu0KZYbM+lWW3NllFkvI9LXrB8QlGW
+        cj1JiGg2RHpcMD9pVi85YUsoMlFCISxFOSApPjQeJzozHCU2NBwhNTIbJTc2HSU9OyEsRUUoMlFNLTdg
+        VjI9cGI3Q4FsP0uUfEdXrItQYcSVWmzUll5x2peElOuSrb/8jrjK/4m3yv+Lucr/jLjJ/4q4yf+Kt8j/
+        ibfH/4yyw/+Itcb/gq7B/3efuP92nrj/f6nA/4Ksw/+AqMD/cZay/3aatf94nbb/gKa7/4Cmuv+Dqr3/
+        h66+/4esvf+Hqbn/h6q6/4Wpuf+EqLn/gKS2/36gs/+CobL/gJ6w/4Ger/+An7D/f5+x/3ucrv+AoLD/
+        gqCw/4Kisv+OsL7/kLG//4qsu/+ApLT/gKa2/4KouP+DprX/e52t/22Tpftli6GZWIWbFwAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzM7PvKiqqv+ipKX/oaKj/52en/+Njo//j5CR/52en/+oqan/
+        jY6O/3N0df9kZWb/X2Bg/11dXv9ZWVr/WFlZ/1dYWP9WV1f/WFla/2VlZv+TlJX/kpOT/4GCgv9oaWn/
+        WVpa/1BQUf9UVVb/MTIz/xwcHawAAAAAAAAAAAAAAAAAAAAAAAAAAJxWZUGzYHTps1x46LBdd+SxXXfi
+        q11w26Vbb9SkWm7Qpllu0KVabc2YUma9kUxgtH9DVJp1PkuLbzxIgmU1QnNbMT1nVS47YlItNVpLKjNU
+        RyYwT0QnMU5IJTJRTCkxV00qNV9ULjppWjI9dGM2QoNtPEiTekNSp4hKXL+SUmXPmFho2ZhYa9ucXG/h
+        oGB26aRifO6eg5boj7PD1Y22x/+Kucn/irnK/4q4yP+MtMT/irHC/4Kmuv96n7f/dJu1/3KWsf9ylK//
+        bpKv/3qfuP95nLX/gKW7/4Sqv/+DqLz/hqy+/4Srvf+Fq7z/h6u7/4int/+Fo7T/f52w/3yarv98mq7/
+        epit/3mYrf9zk6n/c5Op/3OUqv9ujKT/epep/3+brP+Bn7D/iqq5/4entv+EpbT/g6W2/36jtP99orP/
+        eJut/22PpfpmjqShXYyhJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC9vr6r
+        oKGi/6Okpf+cnZ7/kZKT/5WWl/+MjY7/k5SV/6Chov+AgYL/dXZ2/2trbP9lZWb/X2Bg/1paW/9ZWlr/
+        Wltb/19gYf9lZmf/gYKC/5iZmv+Vlpb/eHl6/25vb/9fYGD/XV1e/1pbXP9FRkb/HBwcqgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAplxtirRedOi0Xnrprlx44bJed+KqXXHapVtw06RabtCoW3DRp1tvzptSZ8CWT2G5
+        hkdYoXlAT5NzPkuHbTtHgGU2QnZfMkBuWjE9aFkvPWdYMTpoVzA8aVkvO2xdMj5zYzVBfWc4RYhvPUmV
+        e0NSp4ZJWbuRUWHMmFVn15lWaNqZV2rdn1pu5qJcc+unXHXvol5ywIpXZSNVqqoDkK69VY+ywMSHsMH+
+        hrHE/4Kuwv96pLz/bJOw/2qPrv9wk7D/b5Sx/26TsP9pkK//bZGu/26Srv9rkK3/c5m0/3qhuP+Bp7r/
+        hqy9/4apuv+Do7T/fpyw/32Zrf93k6r/dZCn/3SRqP9zj6b/ZoSf/2aGof9wj6j/e5uw/3uar/99m67/
+        f52v/3+fsP9+nq//fZ2u/3earf90ma3/b5Wr/2OIovFVepuSUnyeJQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALi4up+bnJ7/mZuc/5eZmv+UlZb/ra6v/6KjpP+XmJn/
+        lJWW/3+Agf93eHn/cXJy/2lqav9mZ2f/ZGRl/2tsbf9qa2z/bG1u/4qLjP+VlZb/mJma/4GCgv90dHX/
+        eHl6/2hoaf9sbW7/a2ts/1hYWf8oKSuSAAAAAAAAAAAAAAAAAAAAAAAAAAGqXG7LtV556bVfeumsW3Xf
+        sl534qxec9umW27SpFtv0albcNGnXHDPn1ZqxZZQYrqRS16vgENVm3lBTZF0PkuKbz1IhWw5R4FqOEZ/
+        aThEfmg4RH9pOESCaztGiW88SJB1Pk2agERTq4hKWryST2LKmlNm1ZtVaNmZV2fbnVhr4qJacOilWnPt
+        p1py75xZaoZtSEgHAAAAAAAAAAAAAAAAAAAAAISmtTR/n7WYeZq0722Tr/9li6z/aI+v/3KZtf92nrj/
+        aJCu/2SLq/9jian/X4Wn/2aMq/91nLX/fqW6/32ht/98nrP/fZuw/36br/92kqn/co6l/2qFn/9nhJ7/
+        b4ym/3OQqf92lq7/hae7/4Chtv95ma7/fJqt/32arP91kaX/b4qg/2uHnv9khp//ZYyl/V+FochVe5hr
+        RHeIDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        r7GxgZudnv+Vl5f/lJWW/5OUlf+oqar/q6yt/6ipqv+foKH/gYKD/35/f/92d3f/cnJz/3N0dP98fX7/
+        f4CA/3+AgP+BgoL/lpeX/5mamv+RkpL/dHV2/3t8fP+Li4z/eXp7/4KEhP93eHj/aGhp/ycpKW8AAAAA
+        AAAAAAAAAAAAAAAAi01cIbJfc+i3XXzqtl976K1bdt+wX3bhrV9026Zbb9KmXW/Sp1pv0KpbcNCkWm7L
+        mFNmvZZPYrqOSl2sgkVVnntBUZd5QE+Tdj9MkHU+TI91P02RdT9NlHlBTpuAQ1Olh0hYs41MXb+UUGLK
+        m1Ro1Z1VaNmbVmjanVdp3qJYbeakWXHqp1hz76VZbtiUU2JDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAABxjakJf6CzTnCRrKN2mLDueJuz/3aZs/93m7b/Z4ur/16Ao/9bfZ//Y4Sk/2mKp/9oiqf/
+        Z4im/26OqP9siqX/aIWh/2eDn/9ifpv/W3eV/197mf9mg5//a4ii/2qHof91kaf/eZSp/32Zq/97l6n/
+        eJOn/26KoP9khJ39XYCcx1h9m3ZLcJYiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoq6tVq6yt/5+gof+am5z/pKWm/6amp/+dnp//
+        pqan/6qrq/+YmZn/oaKj/5SVlv+AgIH/hYaH/4mKi/+Oj5D/hoeH/5OUlP+en6D/n6Ch/46Pj/+EhIX/
+        lpeY/5mam/+YmZr/mpub/4OEhf9bXFz/RERENAAAAAAAAAAAAAAAAAAAAACfWmlVs2F16bVdeum2X3vo
+        sF534LBfduGtX3Tbpltx06Vbb9GoXHDRrFty1KdccM+hV2vHmFJmvZdQY7uTTmG3jUpdr4hHWaiGRlin
+        iEhYqopKW6+MSly1kExevZNQYsWYVGXNn1Zq1Z9XatidVmjZnVZp3KNZbOSlWG/pplly7apacfCfWGqh
+        hkNQEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEhtbQdsi6JC
+        aIehi22NpsNujKb1ZIKh/2iGpP92lrD/e5yz/2B+nP9ifpz/ZIKf/199m/9ZeJf/VnOT/1Vxkf9TcJD/
+        V3OS/198l/9jf5r/aYSd/2yHn/9yjaP/cYui+GiFnM1kg52VXYGcVV90lBgAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAKqqqhibnZ34sbKy/6Wmp/+lpqf/q6us/52en/+xsrP/tre4/7y9vv+8vb3/uLm5/5eYmP+bm5z/
+        n6Ch/5ydn/+TlJX/qaqr/6anp/+XmJj/kZGS/5SVlv+trq//qKmq/66ur/+nqKj/mZqb/2hoaec/Pz8E
+        AAAAAAAAAAAAAAAAAAAAAKRaa4K3Ynfqtl176LZgeuewX3nhsl934q1fdNuqXHPWplxv0qddb9KpXHDS
+        q11x06dccM+kWWzKnFVnwphRZL6XUGS+llFkv5dRY8CWUGTBmFJmxZ1VaMuhV2rSo1hs1qBYa9ifWGrY
+        n1hr26JZbeKlWm/nqFpx66pYc++nWG/el1RkVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ/mQqGo7I1iKm2Y4iouIqFqLmo
+        dJKpv2F/mc5ceZfiWHWU3FFvj9dPa47XT2yN1lFujtVVco/HVXKPsFZyj5dZd5J4XnmUVGiFnCw/X38I
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIGBg6+en6D/m5yd/6Chov+xsrP/
+        sbGy/7i5uv+5ubr/wsPD/8PExP/BwcL/u7u8/7W1tv+rrKz/nZ6f/6Gio/+0tbX/m5yd/6KjpP+bnJ3/
+        pKSl/7KztP+tra7/rK2t/6Wmpv+lpqb/cXFxiQAAAAAAAAAAAAAAAAAAAAAAAAAAqF5vpbdgd+q1XXrp
+        tmB86LBeeOC0YXnkrWBz3Kxec9ikW2/RqF1x1Kddb9KqW3LUrVxz1KlbcdGnW2/Qplttz6NabM6jWWzO
+        pVlt0KdbbtSmWm7Wplpu16JZbNigWGvYoFhs26NZbuCnWnDnqFlx6atZc+2sWnHwolhpooVNWBcAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAfX2BOX9/gP55env/n6Ch/6mqq/+5u7v/uLm6/72+vv+5urr/w8PE/8LCw//Cw8T/
+        vL29/7O0tf+vsLD/t7i5/6Gio/+kpKX/sbGy/6Okpf+sra3/tre4/7i5uf+4uLn/ubm6/6urrPRNTU0X
+        AAAAAAAAAAAAAAAAAAAAAAAAAACrXnC6uGB36rZefOm4Yn3prlx437Vhe+WuYHTerl9026hdcdWmXG7S
+        p15x1adecdOpW3DTq1xx1atbctarW3LWqltx1qpbcNaoXG/Xpltv16NbbteiWW3YpFlt26dbb+CpXHLm
+        qVpy6apac+yuWnPwqFpv15ZUZU4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg4WFrHZ2d/+EhYb/
+        qqur/7Gys//ExcX/tLW1/7u8vf/Cw8T/v7/A/8XGxv/DxMT/w8TF/8LCw/+9vr7/sLGy/62ur/+1tbb/
+        srKz/8TFxv/IyMn/ycnJ/8vMzP/DxMT/srK0fwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKdcbsm5Ynjq
+        uF186rlifeuvXXfgtmF75LNhd+KvX3TdrV923KhdcdWlW2/Tp1xx1KdecdWpXnLWqF5y1qZccdalW3DW
+        plxv16Rcb9elWm/ZqFxx3apccOKrXXTmq1x06KxbdeuuWnbvrFpy7KFXaIl/SFsOAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAACao6MclJWV7nd4eP+YmZr/uLi5/6enqP+2t7f/xMTF/8XGx//Gx8f/
+        x8jI/8bGx//Gxsf/wMHB/8HBwv/AwcL/vL29/729vf/Cw8P/xcbH/8rLzP/S09P/1dbW/8/Pz9K/v78I
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAplttw7lieOq5XX7quWJ96rJfeuOyX3rjtmF85rBhduGvX3Td
+        r1913atddNqpXHPXpltx1qZab9WmWm/Vp1xv16hdcdqpXXLdql5y4K1ddOSvXXbnrV126K9cdeqxW3fv
+        sFx08KdabLWTT2AtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACpqa1L
+        mZqa/ZKTk/+6u7v/xcbG/8HCw//BwsL/u7y8/8rLy//Hx8j/u7y8/7u7vP/AwcH/xMXG/8PExf+4ubn/
+        wsPD/8fIyP/R0tL/1tfX/9vb3P/Z2dvq1NTUJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoXXCx
+        uGJ36rlffeu3YHzpuWJ+67BeeOC1YXzktmF95rJgeOOwX3XgrmB0365hdd+uYHXfrmB0365fdeCuX3Ph
+        rl915LFgduawXnforl526LBcd+qzXHjvslt276pbb86cVmZQAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2trZmxcbG/cTFxv/Ly8z/xsfI/8fHyP+6u7v/
+        uru8/8LDxP/ExcX/x8jI/8bGx//Cw8T/vL29/7/AwP/Cw8P/zs7P/9vb2//c3N3/39/f6NnZ2S8AAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKVbbYm1Y3XquWB767lgf+y5YX3rt2F+6K9eeeG0YHzk
+        tWB85rdie+e0YHvmtGB55bJgeOayYHjms2B657NfeuivXXjnsV556bNeeey1XXnvs1x376xccNmjWWpn
+        bUhIBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAADPz89GwsPE5Lm6u//Kysv/y8zM/83Oz//Ky8v/yMnJ/8fHyP/Fxcb/vr+//8DBwf/ExcX/
+        ycrK/9HR0v/Z2dn/3t7f/+Dg4MjZ2dkbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        nFZlQbRiduu5YnnruV9867lgf+y5YX3rumR/7LRfeuWxXnnjsF5547FeeeOwXXjksV155bFeeOazYHnp
+        tF9567ZffO61XHnvtF13761ectihWGttc0VFCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCwsIVy8vLmsbHyPvJycr/
+        yMjJ/8jJyf+5urr/wsLD/76+v//BwsL/w8PE/8/Q0P/U1dX/19fY/9vc3Pjd3d2B2traBwAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAACqV1vurdjd+u6Y3vsuWB+7LpegO24X33r
+        uGF97Lpife26Yn3tuGN+7LdgfO24YX7uuGB97rZee+62XXnvtGB376xeccaiWmpgcThUCQAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAycnPK7i4uJiys7Pqtba2/rCxsv+4ubr/u7y9/8PExP/Fxsb/
+        y8vL/s7Q0N/T09OGx8fHFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACRUF4jrV5w1bdjd+u5Y3nsumJ87Ltgfe27YH/uumB/7rlffe65X33uuGB877hgeu62YXbu
+        sV9z46lcbpiZVWY8AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAGvr68dxcXFQr6+wWfBwcF1u7u7bb6+vk+/v78gAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACTTmIaplxsm7Bidee1ZHXs
+        tWJ17LZid+22YXjttWF37bNhdu2tX3LSqV1wlqFaak9/P1UMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf0ZUEptUY0WkXW1dr19xY55XaFqgVmlBf0RYGgAAAAEAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAD///////////////////////////////////////AP//////////////////+AB///////
+        ///////////8AAP/////////////////8AAB/////////////////8AAAf////////////////8AAAH/
+        ///////////////8AAAB////////////////+AAAAP///////////////+AAAAH///////////////+A
+        AAAB////////////////AAAAAf///////////////AAAAAH///////////////gAAAAB////////////
+        ///wAAAAAf//////////+H//wAAAAAP/////////+AAAf4AAPgAD/////////4AAAAcAAf+AA///////
+        //wAAAAAAA//wAf////////gAAAAAAA//8AH////////gAAAAAAAf//AB////////gAAAAAAAf//4A//
+        //////gAAAAAAAB//+AP///////wAAAAAAAAP//gH///////wAAAAAAAAB//wB///////4AAAAAAAAAH
+        /8A///////4AAAAAAAAAA//AP//////8AAAAAAAAAAH/wH//////+AAAAAAAAAAAf4B///////AAAAAA
+        AAAAAD+A///////gAAAAAAAAAAAfgP//////wAAAAAAAAAAAHwH//////4AAAAAAAAAAAA8B//////8A
+        AAAAAAAAAAAGA//////+AAAAAAAAAAAAAgf//////gAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAD///
+        ///4AAAAAAAAAAAAAA//////+AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAP//////gAAAAAAAAAAAA
+        AD//////4AAAAAAAAAAAAAAf/////8AAAAAAAAAAAAAAH//////AAAAAAAAAAAAAAA//////gAAAAAAA
+        AAAAAAAP/////4AAAAAAAAAAAAAAB/////8AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAH/////wAA
+        AAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAP////+AAAAAAAAAAAAAAAB/////gAAAAAAAAAAAAAAAf//
+        //wAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAB/////AAAAAAAAAAAAAAAAP////wAAAAAAAAAAAAA
+        AAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAA
+        AAAAAAAA////+AAAAAAAAAAAAAAAAH////gAAAAAAAAAAAAAAAB////4AAAAAAAAAAAAAAAAf///8AAA
+        AAAAAAAAAAAAAH////AAAAAAAAAAAAAAAAB////wAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAAAH//
+        //AAAAAAAAAAAAAAAAB////wAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAAAH////gAAAAAAAAAAAAA
+        AAB////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAA
+        AAAAAAAA////+AAAAAAAAAAAAAAAAP////wAAAAAAAAAAAAAAAD////8AAAAAAAAAAAAAAAB/////AAA
+        AAAAAAAAAAAAAf////wAAAAAAAAAAAAAAAH////+AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAA///
+        //4AAAAAAAAAAAAAAAP/////AAAAAAAAAAAAAAAH/////wAAAAAAAAAAAAAAB/////8AAAAAAAAAAAAA
+        AA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////wAAAAAAAAAAAAAAB/////4AAAAAAAA
+        AAAAAAAf////+AAAAAAAAAAAAAAAP/////AAAAAAAAAAAAAAAH/////gAAAAAAAAAAAAAAB/////4AAA
+        AAAAAAAAAAAA/////8AYAAAAAAAAAAAAAf/////AHAAAAAAAAAAAAAH/////gD4AAAAAAAAAAAAD4D//
+        /4A/AAAAAAAAAAAABwAH//8APwAAAAAAAAAAAAwAAf//AH+AAAAAAAAAAAAYAAD//gB/wAAAAAAAAAAA
+        MAAAf/4Af+AAAAAAAAAAAGAAAD/8AP/wAAAAAAAAAADAAAA//AD/+AAAAAAAAAABwAAAH/gA//4AAAAA
+        AAAAA4AAAB/4AP//AAAAAAAAAAeAAAAP8AD//4AAAAAAAAAfgAAAD/AA///AAAAAAAAAPwAAAA/gAP//
+        gAAAAAAAAP8AAAAH4AD//gAAAAAAAAH/AAAAB+AAf/gAAAAAAAAH/wAAAAfAAD/gAcAAAAAAH/8AAAAH
+        wAAOAAPwAAAAAP//AAAAD8AAAAAP/gAAAAf//4AAAA/AAAAAH//AAAA///+AAAAPgAAAAH///gAP////
+        gAAAD4AAAAD//////////8AAAB+AAAAD///////////AAAA/gAAAB///////////4AAAP4AAAB//////
+        //////AAAH+AAAB////////////4AAD/gAAB/////////////AAB/8AAB/////////////4AA//AAB//
+        ////////////gA//4AB///////////////////AD////////////////////////////////////////
+        /////////////////////ygAAABAAAAAgAAAAAEAIAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ1SYSKoWWpbqVlrfqlba4OjWGhfiU5iDQAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZVWYPqFlqZ6xbb8CxWnHpsVly6bFac+qxWnTr
+        sVxw66paa8qNVGMSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJNQXROpWWx9r1tw3LBadOitWXLl
+        rVly5K1ZcuSsWXDkrVlx569YdOuxWXHspVdoeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkUhIB6hYa22vWnHa
+        rlly5atYceOoV27gqFls36ZYa96lWGvfqFht4qlYbuSqV2/msFdy7KdYaawAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        o1dnQKxYbsatWXHlq1lw4adXbN2iVmnXnVVm1JtUZdObU2TSnFRl1J5UZ9mjVmjgpldt5K1XceyoV2q0
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACWS1oRqFhrk6xZcOWpWXDhpVds255VZ9SbU2PPm1Jjz5tSYs+ZUmLPmlFh0ZlSY9OYUmHT
+        nlNm26VWbOWrVm7rp1hqoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAACiVGhCq1huz6tYcOKlWGvcnlRm05lSZM6YUWHMlE5fxo9KW8CLSFi+
+        jElZv49MWsWYT1/Ql1Bh1JlRY9ijVmrkqVZu7KRXZncAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhERGR4PFBQxEBQYPxIVFUYQFBg+
+        EBYWLg4OHBIAAAABAAAAAAAAAAAAAAAAAAAAAJFISAelV2mDqldw46ZXbt6gVmjVmVJkzpdPYcqOS1u+
+        gkJRrHc9Sp5vOESUbTdDk3M6R52BQU+zjUlZxZdPYNSXUWDYoFNn5adUbO6ZUGE8AAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHx8fCBQYG0oTFhqREhYZyxIWGfcTFhn/
+        ExYZ/xMWGP8TFhj/ExYY/xQWGP8UFhn/FRUY7RYWGb0aGBqGIxsfQY1NXCSpWGy5qVZu4qNVadmbUmXP
+        l1Bhyo1KWbx7QE6jajdCi14wOnpYLTZxVCs0b1gtNnZgMjuEbThCmYJDUr2RTFvUhkhW2mEyPuczGiHd
+        MwAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWGho5FhkcnxkdIPIeJSn/
+        ISgt/yEoLf8iKS7/ICcs/x4mKv8dIib/Gx8i/xgaHv8WGBv/Fxca/xgXG/8bGBz/IRsf/08wOf+iVGv8
+        plht8p5UZ9uYUmLMkUxcwXxBT6RnNUGFViw1bUglLlg8HihMORwjRzofJUpEIipZUCkyb18wO41eMDq3
+        PyEo1BwPEtwVCg7qEwoMjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoeIkMhKS3E
+        LDU6/zdCSP87SE7/PkxU/z9OVv8+TFX/OkhR/zVDTf80QUr/NkFJ/zQ9Q/8vNzz/KjA1/yQnK/8hICT/
+        Jh4j/2o9Sf+pWHD/pFht/5tVZv+UUWL+g0dV6Gs5RJ9UKzRqQiErTTEYHTQkDhUjHRMTGhsSEhwfExMo
+        LRQcPiwXHGEcDxKIFAsMuRMJC9YQCQvhDwcJ7Q8FCjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        IDExHzI8Q7E5RUv/PEpQ/0lZYv9MXmf/TGBq/0tfaP9GWWL/Rlhg/0ZaZP9FWWP/Rldg/0VUXP9DTlX/
+        P0lQ/z1FTP86QEb/PztC/4VMXP+oWXD/oFdq/5hUZf+QT17/d0FP/1w0P/9CKTH8KR0jpCIRGR4AAAAF
+        AAAAAAAAAAAAAAABEwATDQsFCy0OBQhZDQcJiQ4GCcIMBwnZDAYH5wwFCLgAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAQVJXXUVWX/FHWmP/RFVd/1Fkbv9VbHf/U2t2/01gav9JXWb/R1tk/05ncv9RaXX/
+        UmRu/1Fgaf9QXmf/Tlpj/01YYP9KUVj/VU5W/5hYa/+nWnH/nlhq/5dVZf+ITFv/ajtH/0wtNv8yIin/
+        Ix8k/x0eIf8ZGx/cGBgcNQAAAAAAAAAAAAAAAAAAAAEGBgYlCwUFWgoFBpQLBgfNCwUG3QkFBuwKBgZJ
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABVVVUGRFhgmUpfaf9HWmP/TmJs/1lvev9acn3/WnWA/1Vuev9RaXT/
+        UWdx/1Zwe/9Ya3X/WGx2/1lrdv9YaHL/VmVv/1Zkbv9XYWv/ZVtk/6Jccf+mW3H/nFhq/5ZWZ/+CTl3/
+        ZUNP/0g2P/8qJCr/Ghkd/xcXG/8XGRz/GRwg/xYZHPkUGRtwAAAAAAAAAAAAAAAABgYGJQcFBWUJBAen
+        CQQH1ggEBeUJBQbCAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMZmYKSV5nuEpfaP9PZW//UGVv/1dxfP9adH//
+        WHJ9/1hxfP9YdYH/W3aC/116h/9feYT/XnWB/151gP9ecn3/XW13/1tpcv9daXP/dGZz/6dfdf+kXHH/
+        m1lq/5RXaP98UF7/YEhU/0tHUf87QUn/LDI6/x8jKv8VFxv/EhMY/xMWGv8UFhr/EhQX/xMVF40AAAAB
+        AAAAAQUFBTAGBAZ5CQUFvwgEBdwHBQbsBwMHRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMZn8KT2lyvVdyfv9ceIT/
+        W3aC/1Zwev9bdoL/XHiE/1lzfv9XbXf/XXqG/2J9if9ifYn/YXyI/2OAjf9hfIj/Y3aB/2Nzfv9kcXz/
+        fmp4/6pgd/+jXHH/mlpr/5BXZ/94VGH/YlRg/0tQW/9DTln/QExV/zU/SP8tNT7/Iikx/xcbIP8QFBj/
+        EhUZ/xATF/8PEhX/DxMVggAAAAYHAwdGBgUGlQgEBtMHBAXkBwUFswAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzM2YF
+        T2p1tl57iP9kgY//ZYWT/2WCkP9lgY//ZYSS/2SCj/9ge4b/YHqF/2N9iP9lf4v/Z3+K/2eAjP9ngIz/
+        ZH+M/2Z8iP9neob/h299/6theP+iXXD/mVts/4xYZ/91WGX/Yl1o/1Neav9HVWP/R1Zj/0NRXP87SFP/
+        OkVO/zM9Rf8kLTT/FRsh/xAUGf8RFRn/DRAV/w4RFf8PERN1BwUHZggFBrcIBAXdBgUG6gUFBS4AAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAT2dyilt2gf9qiJX/aoqZ/2iKmf9qipn/a4iW/2uHlf9qiJb/aIiW/2eDj/9pg4//
+        aoSR/2uBjf9sg5D/bYSR/2yBjv9ufor/jHCA/6tief+hXXH/mVts/4lZaf9yXGn/Y2Zy/1xtd/9YaHP/
+        UWJv/05eaf9MYGr/RFZh/z9QW/8+TVb/MT9I/yItNf8VHCP/ERUZ/xAUGP8OEhb/EBMW+woKC6sIBwjT
+        BgUG5gcFBY8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXX2NP1p4g/xlgo//aouZ/2uNnP9tjJv/bYyb/3CJl/9vhpP/
+        bYqY/2uKmf9pg5L/aoaV/2Z+jP9pgI7/boSR/2Z5h/9tfoz/l3qL/6xke/+gXnH/mFts/4Zaaf9wYm//
+        Y257/2B0gP9edH//W3J9/190f/9XbXj/UGl0/0xlcP9GXmr/QFZh/zlMV/8yQUr/IS02/xkgJv8TFxv/
+        EBQX/w8TFv8NEBP6CQcJ4ggFB9oAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcY2pCWOMnNxkgo//bYua/2+Onf9ukaH/
+        cI6c/3KMmv9zjJr/coyZ/2+Mm/9vjp3/bo2c/2yKmf9qg5P/ZHyN/2R6iv9qfY7/l3iL/6xlfP+fX3L/
+        l1xt/4JZaP9uY3H/ZHWB/2R9iv9id4L/YHiE/152gv9cc3//WnF8/1VwfP9QbXn/TGl1/0ZfbP9AVmH/
+        OExX/y09SP8pNTz/HCQo/xMYG/8RFRj/ERQW/w0PEPgIBQhWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGWTpX5mi5r/
+        bZGg/3GXp/9xlqX/c5Kh/3SQnv9zkJ7/dI2a/3SOm/93j5v/c5Cf/3OOnP9yipn/boSU/2Z6jP9sfY3/
+        mXmM/6xmff+fX3L/llxu/4Jdbf9rYXD/aXeE/2d8if9mf4z/ZHyJ/197iP9fe4f/XHiE/112gv9beob/
+        VHWC/05tev9FY3H/P1ln/z9WYv86T1n/NkdP/yk0Ov8ZHyP/ERYZ/xEVGP8RFRf+DxQUMgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAG2dthVrmKjzbJSk/2yNnP9wkqL/c5Wl/3SUo/90lKT/dpKh/3aPnf91kqH/cY6f/2yImv9viJj/
+        boOR/2d7jP9gcIP/jmt//6pkfP+dXXD/lFlr/3lTZf9kX3H/XnKH/2J3iP9hd4X/Zn2K/2J9i/9ge4n/
+        ZICO/2F9iv9afYz/X4GP/1d6iP9ScX//SWd2/0Vjcf9BW2j/Qllk/z5SW/80Q0r/JS4z/xUaHf8SFhn/
+        Ehca/w8SFbMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABvoLKCbJan/2+Wp/9xlqb/cZan/3SZqv92lqX/dpal/3eVpP94k6L/
+        d5Gg/3ePnv9uhpf/Z32P/2R5i/9ic4f/i2uA/6tlff+dXXD/kldq/3dQYv9dVWj/T191/1pwhv9kfJD/
+        XXOD/2iCkf9cd4f/YIGQ/1+Ckv9eg5P/W4KS/1yDkv9gg5H/XX6L/09tfP9LaXf/SGRx/0dhbP9DWmT/
+        PU9X/zE+Rf8gKC3/Exgb/xIWGf8QFBf+DxQUMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtkbYHb6Gz6XSaq/90m6z/cZGg/3SXpv92mKj/
+        d5qq/3iYp/95laT/epKf/3iQn/9yiZr/cIaX/26Ck/9sfY//jG+E/6xmf/+fX3L/lFlr/3hRY/9bU2j/
+        WGl//2qDl/9lfpT/VWyC/1tyhf9je4v/aYWV/2OCkv9hh5f/XYeY/1uElf9hhpX/YoaV/12Aj/9VeIX/
+        Um16/09qdv9KZnL/RmFt/0NZYv87TFT/LTk//xkfIv8SFxn/ERUY/xATFp4AAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbKG3UnKhtP92nq//
+        c5io/3SUov93mqv/d5qq/3qbq/97man/fJWj/3uToP93j5//dYyc/3iOnv98j5//lH2P/69qgv+gYHP/
+        lVxu/3tWZ/9jXW//XW6C/3KMoP99mav/aIGV/1Nqgv9RaX//WnOF/2N+jv9oiJf/ZYiY/2ONnv9eiJn/
+        YoeX/2GFlf9YgJD/VXuK/1duef9Qb3v/TW16/0hlcf9GXGf/P1Nc/zRETP8kLjP/Exgb/xIWGf8PFBb1
+        ExMTDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAGygtadzo7b/dqCx/3ebq/92mqr/d5mo/3qdrv97nq7/e52u/36aqf9/mqn/do6g/3GGmf91iJv/
+        k4WY/7BshP+hYnb/ll1u/31Yaf9saHn/bICV/3yWqf95kqT/cYmZ/2d+j/9XboT/VW6D/1t0h/9kgJH/
+        aYqZ/2aMnf90nK3/YYye/2CKm/9giJj/WoOT/1V8jP9WeYf/VHWC/1Byf/9Na3f/SWRv/0dcZf87Tlf/
+        LjtC/xkfI/8TGBr/ERUY/xIVGFUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAFWqqgNqnrbvc6S3/3igsv96nq7/eaCx/3ugsP97obL/fKCw/3+bqv+Eo7L/
+        fpmq/2V8kv9ne5H/hXyR/7Buhv+jY3f/l15w/4Baa/9taHn/eI6h/3qWqv90j6T/couc/2+Glv9nf5L/
+        ZH+T/2J7jv9feo3/Z4aX/2mOn/9njp//ZI6g/2KPof9jj6D/YYyd/12Glv9cgI//WXyK/1Z5h/9SeIX/
+        TnF//01pdf9KYWv/QFVe/zZGTf8kLTL/FBkc/xEWGP8PFBeXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlmK0ybZ+0/3aktv97obL/fKGx/3yhsf9/obD/
+        gKOz/3+gsP9/oLH/gqO0/3OOo/9mepL/eniO/69wiP+lZnv/mF1v/4Rdbv97eYr/c4ib/4imuP+KqLf/
+        d5Ch/3qTov90jp//bIeZ/2mHmv9siZr/boub/2aKnP9njqD/aZGi/2iQof9lkKL/Y5Ci/2OOn/9fipv/
+        XYaW/1qCkv9Wf47/U3uJ/1F0gf9Qbnr/UWlz/0VYYP88Tlb/LTpA/xgeIv8SFhn/DxMX0AAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ5qrZXCgsv90o7f/
+        e6Gz/3+isv9+pbb/g6a2/4Omtv+CpbX/hqq6/36fsP95kqX/fYKW/61xif+pbIH/mF5w/4RZav9yaHn/
+        kau7/4yrvP+au8r/j66+/3+ZqP+Dn63/fJem/32cq/90lKX/bpGj/2+Upf9rkqP/apOl/2iVp/9qlaf/
+        aJOl/22Yqf9hj6H/Y46f/2CLnP9bhZb/WIGS/1Z+jP9UdoP/VHF8/1NteP9KXmf/QFNc/zNCSv8fKCz/
+        EhcZ/xAUFvkAACQHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAG+jtY50pbj/eaO1/36ktf+BpbX/gKe4/4eruv+Krbz/iq6+/4ywwP+BoLH/gpKl/6lxiP+rbIP/
+        m2By/4ldbv9wYnT/d4qd/5a2x/+au8r/qcrW/5y8yf+ForH/jKu5/5Gxvv+Hp7b/gaGx/3CSpP9wlqf/
+        a5Kl/2uXqv9omaz/Z5eq/22brf99qLj/ZJOl/2OQov9kj6H/XIiZ/1mElP9XgJD/V3qI/1h0gP9Tbnr/
+        TmFr/0VYYf86SlL/KDM5/xMYG/8RFRf/EhIYKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABwobOsdqq9/3unuP+Aqbr/gae3/4Kquv+LsL7/jbPC/5K3xf+Zucb/
+        iKCx/6l8kf+tboT/nWN2/45fcP99cID/fpGl/46tv/+fwc//pcbT/6fI0/+mx9P/i6u6/4ipuP+Jq7r/
+        hqa1/4WltP98n7D/bJKl/2qTpv9rmq3/aZuu/2iYq/9qmq3/faq6/2aVp/9plqj/aJSl/1+LnP9bhpf/
+        WoKS/1p7iP9YeIX/VnF8/1BmcP9IW2T/QE9X/zA7Qf8YHiH/ERUX/w4SFUYAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdKq9wnmxw/98rL3/gau7/4Kquv+CrL3/
+        ha+//4uzwv+Wusj/lrPB/6SDlv+vcYj/oGd5/49cbf99anr/i5+v/5KyxP90kqn/mLvK/6rN2P+oy9b/
+        q83Y/5e6yP+Krrz/iq++/4Wquf+Gqrn/gqi5/26VqP9umq3/a52x/2qcsP9pm67/aZqt/3upuf9yoLL/
+        bput/2mWqP9gjZ7/XYma/1uFlf9bf43/W32K/1Zyfv9SaXP/TV9o/0VUXP82Qkj/HCMm/xEVF/8PFRVV
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHauwNF6s8X/
+        fbHD/4Gtvv+Brr7/ga2//4exwv+LssL/kLPD/6CSpP+xcon/pG2A/5Vgcf9+ZXX/jJqq/528zP+Ut8f/
+        gKW3/4mxwP+LssH/n8PQ/6bK1f+av83/n8TR/5G5x/+DrLz/h7DA/4Gquv90nK7/cZ2v/22esf9rnrH/
+        apyw/2mbrv98qrv/ga6+/3qmt/9zn7D/ZJGi/16Km/9ehpb/XH+N/2GCj/9bd4L/VWt1/1Jkbf9JWWL/
+        O0lP/yIpLf8RFRf/ERQXWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAB4ssPSfLXH/36zxf+AssP/grDB/4KvwP+Drb7/hqy9/5yis/+ydIv/qXGF/5hgcv97WWn/
+        am5//4+yw/+qzdn/psrX/6nM2P+MtsX/irbF/4axwf+NtsX/psvX/57F0v+NtsX/iLLC/4q1xf97pbf/
+        dJ+x/3Kfsf9uoLP/bKCz/2uesf9qnLD/c6S2/2+fsv9pmav/aJap/2SQov9jipr/XoiZ/1+BkP9kg5H/
+        XnqG/1hvev9VZ3D/TFxl/z9OVf8oMDX/ERUY/xEUF1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAd7DCxny2yP99tsj/gLTF/4Oyw/+EscL/ha6//46jtP+xeI//
+        rXWK/5xmeP+DW2v/aWV1/26Po/97p7r/fqi7/4awwP+x097/pcrX/6PK1/+Xw9H/h7TE/4i0xP+Qu8r/
+        kbzK/4m1xP+EsMD/dqO1/3Ojtf9wpLf/bqO2/22htP9soLP/bJ+y/3urvP9qnK7/aJmr/2WVqP9lkqP/
+        ZI2d/2GJmv9ihJL/YIKQ/117h/9ac37/V2t1/05faP9DUln/LTc8/xEWGP8NFBRLAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHmsvq5+tsj/frfJ/4KzxP+BscT/
+        g7DC/4mrvP+sf5X/sHaM/6Nvgf+KXW3/bWJx/2+Km/+Ap7j/gKy+/4Ctv/+ArL3/lr/N/7TX4f/E4en/
+        kcDP/4+7yv+KuMf/i7nI/4i4yP+Svcz/eaa3/3ektv9yprn/cKW5/2+kt/9uo7b/baG0/26htP90prj/
+        apyv/2iZrP9mlqn/ZZSm/2aPoP9ki5v/YoaV/1+Bj/9de4f/XXV//1hrdf9RYmv/RVVc/zE7Qf8SFxr/
+        DRIXNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB7ssSM
+        frPF/3+3yf+BsML/gLDD/4auv/+lip7/sXWM/6h2if+SYHH/cl1s/2t/j/9+p7n/ga2//4Cvwf+Ar8H/
+        f62//4Kwwv+IuMj/t9nj/4m8zP+LvMz/kLzL/5TAz/+LvMz/fK/A/3yrvf92qbv/c6i6/3Gnuv9wpbn/
+        b6W4/3KmuP91qLr/cKO1/2qdsP9omq3/aZms/2qZq/91n6//aJOk/2OJmf9khpX/YH2J/110f/9abXf/
+        VGZv/0dXX/8zPkT/Exca/g4OHBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAfrXHYX+xwv+CssT/eqvB/4Sqvf+ZkqX/s3SM/614i/+caHn/eltp/2lwfv97n7H/
+        hqa0/4Ksvv+Cr8D/gbDB/4GuwP+Br8D/gq6//4y5yP+PwM//l8HP/5G+zf+Gs8P/ga29/4i1xf+CtMX/
+        e6u8/3irvf9zqLv/c6i7/3aqvf9wpbj/baK1/22gtP9rnrH/apyv/2ydsP9+qLj/hK28/2aRov9lipn/
+        ZISS/2J7h/9fdH7/W254/1Vncf9JWWH/ND5E/xIXGeYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHq0xDCBr8D/h7TF/4Gww/+NpLf/sXaN/7B4jf+mdYf/
+        hFxr/2ljcf91kKD/hKe4/4SnuP+Frb3/g66//4Ouvv+Drb7/gq/A/4Kuv/+EscH/j7rJ/6LJ1f+FscH/
+        gq/A/4W2xv+GssH/irnI/4a1xf9/s8T/d63A/32yw/96rsD/dKm7/2+kt/9uorX/bJ+y/2uesf93prj/
+        gKy8/4exv/90nq//cpen/2qHlP9mfIb/YneB/1tvef9VZ3D/SVlh/zQ+Q/8RFxmtAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVqqoDgrXG7Im0xf+Ls8X/
+        qn2U/7F2jP+wgpX/k2Z2/29dav9pfIz/f6G1/4Wltv+Hqrv/g6q8/4Gsvv+Dqrz/hqy8/4Wtvf+Erb7/
+        hq29/4SsvP+Gr7//gau8/4Gpuv+BsMH/fK2//3+xwv+Lvcz/grfI/4O3yP+Btsb/gLTF/3aqvf9vpbj/
+        bqO2/26itf9vorT/caK1/3mnuP98qLj/gaq5/3ierf9riZb/Zn2J/2F4gv9bcn3/VWdx/0paYv8wOj//
+        ExUaaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAIO5yqGKtMX/oJKm/7Fzi/+ue47/o3SG/39jcv9qcX7/e5ut/4Wpu/+Cpbj/g6m8/4Cnu/+Aqbz/
+        hq29/4qruv+Jqbj/iai4/4mntv+Ip7b/hKm5/4Kquv+Bqrr/gKm6/4Guv/+LvMz/ibzL/4e5yf+Btcb/
+        h7vL/3qwwf92q73/dKm7/3Ckt/9yprj/fa2+/2+hs/91pLb/d6S1/3iisv9rkqL/ZoaU/2R/i/9hd4L/
+        W3J9/1Zocv9JWWL/KTQ5/RMdHRoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAACEt8hLk6O2/7N0jP+veI3/rX6Q/4hhcf90b3z/f5yr/4etvv+JrL3/
+        hq2//4Stv/99orf/hKu9/4qwwP+SssD/j628/42ruv+Kp7b/iaa1/4emtf+FqLj/g6m5/3+svf+Cr8D/
+        jLrJ/4i2xv+izdn/l8bT/4a5yf+Husr/e6/A/3Sou/9wpbj/c6e5/4m3xv99rb7/f629/3mltf91na3/
+        aJGi/2aImP9kgY//YXqG/11yff9VaXP/R1hg/yIqML8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjWN/Eqx1jPmvc4n/rHuO/5pwgv9wW2n/
+        dIWT/5e8y/+Qucj/irLD/4eyw/+HsMH/gKe7/4Osvv+NscD/krHA/5Kxv/+TssD/jKm4/4mmtf+JprX/
+        iKW0/4amtv+Cq7z/gq6//5G9y/+Qvs3/jL/O/4i8zP+WxtP/k8PR/3uwwv92q73/dKm7/4O0xP+Ou8r/
+        lsDN/4+5x/+Fr77/dZ2t/2qSo/9ki5v/Y4OS/2B9iv9ddH//VGhz/0NTW/8cJShZAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRaboqrZ3/y
+        qneK/6Z6jv9/YG//aGd1/3aZq/+kytj/i7XG/4eyxP+Gs8T/ibPD/4ewwf+Er8L/jrPD/5a1w/+Prbv/
+        jau6/4ypuP+Kp7b/iqe1/4mmtf+IprX/iq28/5vBz/+z1uD/n8jV/4/B0P+At8j/h7vL/53K1/+Dt8f/
+        d6y//3yvwf+TwM7/mcPQ/5vE0P+Oucf/fKi5/22XqP9mkaL/ZIyc/2OEkv9hf4z/XXaB/1JpdP82Rk7g
+        KioqBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAJxUZjmoWXHjo11w26d3ifyYeIv/aFZk/2h6iv+Ks8b/lL3Q/4Krwv99pr//gq3B/4mvwP+Fq77/
+        hrDC/4yzw/+SscD/lK66/4qot/+Lqbj/i6i3/4uot/+Nq7n/jqy7/4mot/+ixdH/l7/N/4Cvv/+Ctsf/
+        l8fV/6DM2f+n0Nz/irzL/3etv/95rb//lcLQ/4u5yP+XwM7/krvJ/3imt/9ql6r/ZpOl/2SMnP9ihZT/
+        X36M/1h1gf9MZHD/Lj1EaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAH9VVQamWG7BpVhw3ptXac+dbH/ghXOF/1lZZv9liJz/j7zO/4KuxP92nbj/
+        eJ+6/3ykvf9/pLr/e561/4iuwP+Lr7//i6u7/4mnuP+Mqrn/jKm4/42ruf+LqLf/iqe2/46su/+Nrr3/
+        oMTR/4i0xP9+rsD/frLD/5HD0f+TxNL/h7vL/4Czxf92q77/cqi7/3Spu/93qrz/eKm7/3uqu/90o7T/
+        apqs/2WUpv9jjp//YYeW/1l5iP9Rbnv/PlVg1yoqKgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkWGhrqFhx459Ya9aZVGbJgUxao3Bod+dSZXP/
+        c6O2/4a9zv+Lu83/e6a//3ifuv9xmbX/cJay/3aZsv+Eqr3/h6u9/4emuP+Hpbb/iae4/42quf+Mqrn/
+        i6i3/4upt/+Rr73/j7LA/5m9y/+Er8D/gbHB/4O1xv+Hucn/j7/O/4e6yv+Iu8v/eK7A/3SpvP9xprn/
+        cKO2/26htP9uoLP/cJ+y/2eYq/9llKb/Yo6f/1yBk/9XdoT/RmJx/DtVYTwAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWUWgWqVhw2qRYbt2aVWfO
+        kE9gu2s9SYBLP0tpWnSB+Hqrv/+DuMv/ibbI/4Gtxf9vmbf/Zo6u/2iRsf9wmrX/e6W8/4Cmu/+Gprn/
+        iqm6/46su/+Qrr3/jqu5/4ypuP+KpbP/j626/5KywP+KscP/irXG/4q2xv+Htsb/kL7N/5bD0v+IvMv/
+        h7rK/4G1xv92rL7/dKm7/3Ckt/9uobX/bJ6x/2qbrv9nmKr/ZpSn/2OKnP9Weo3/T2x9/0FdcYUAAAAA
+        AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        p1ltjKpZceKgWGrVmlRnyoFFVKJaMz9oMCQqKl9/jmaEt8n/fbLI/36uxf9ynrv/bZm4/2WOsP9mkLD/
+        apW0/3umv/93n7f/hazA/4yvwP+SscD/k7LA/4uot/+LqLf/i6m4/6LDz/+Yvcz/hqq9/5G3xv+Wv83/
+        pczZ/4m3yP+HuMn/ir7N/4S4yP9/tMX/fbHC/36xwv97rb7/c6W4/26gs/9qnK//apms/2OQo/9pi5r/
+        WHmK/0Vnfbs2SEgONjk7dDAyNM8sLzD3JSgq/CEkJuQgIiSbHCEhNQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAm1RjJKtZceOnWG/dnFdoz5RRYsBwPEmKSis0UiofHxgAAAAAh7jKkYO4zv9rnb7/
+        ape4/3Cbuv9okLH/bZm4/3ypw/+CrsX/dqK8/4OxxP+VwdD/o8jV/53C0P+JqLf/ja+9/4ytu/+TtMH/
+        iay8/4Gktv+JscL/pMvX/5S/z/95q8D/ebDD/4C0xf98sMH/gbLC/4a3x/+Ou8r/j7vJ/4Wywv90pLb/
+        bp6w/2mXqv9kjqH/Xn+R/09yiNVNWmFMY2Zp32BjZP9oamv/bm9w/1haW/9ISUv/MTM1/yUnKP4cHR+R
+        AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKhabparWXPjo1ht151VaM2KSVutZDdCd0EmLkIkEhIO
+        AAAAAFWqqgOCtsmic6nF/2ugv/9wosD/dqO//3SfvP99q8P/eqzD/36xxv+BtMf/k8HQ/7DS3f+Tusn/
+        iqm4/42suv+WtsP/lLTC/4eouP+Fp7j/gKi6/4izxf9/rsH/eazA/36vwf9/rr//gq+//4Ktvv+Tvsz/
+        lb7L/4mzwv9/q7z/fqi5/22brv9lkqb/XIOY/092jteMmqJgl5mb+ZSWmP+ChIX/iImK/4OEhf98fX7/
+        enx8/1laW/85Ojv/JCYn/xcZG5cAAAAAAAAAAAAAAAAAAAAAAAAAAJ1SaSKuWnPkqlty36FXa9GcVGfH
+        gERSnV4zP2w6Hyg5FRUVDAAAAAAAAAAAf39/AnixyJB1rcf/aJy9/2mXuP92or7/cqG9/3ipwv9/s8f/
+        grfJ/4a0x/+v09//osbU/4uvv/+PtcX/krfG/6PI1P+Tu8n/hq29/36hs/9/qr3/fqq8/4Csvv+FscL/
+        gq6+/3+puf+UvMr/i7TD/421xP+Erb3/eqS2/3CcsP9qmKv/ZI2h/1R9lM6Ioa4pxsnL6LS2t/+ipKX/
+        jY6P/46Qkf+SlJX/jY6P/3Fyc/9bXFz/TU5P/0dISv8fICH/FhkZUAAAAAAAAAAAAAAAAAAAAACpWm2H
+        rlp25KhacNuhV2vPl1JkwHc/TZFaLzxmNh8kOB4PHhEAAAAAAAAAAAAAAAAAAAAAe7bLaXqyyfluocD/
+        dqPA/3ytx/91qcP/dqS9/3imvv9/rML/ps7b/6/U3/+cxtX/r9Le/63R3f+11+L/kr7N/4Crvf9+prn/
+        gqu8/4Couf9/pbj/g6u8/36nuP+Drb3/nMPQ/4auvv9+prf/dqCy/3Kcr/9vmKv/aJWn/1+Jnqlci6IL
+        0tTUcsXHyP+ytLX/oKKj/5yen/+Ki4z/l5iZ/4+Qkf9wcXL/XFxd/1pbXP9SU1T/Nzg5/xoaG9QAAAAB
+        AAAAAAAAAACUVWoMr1tz3K5cduKmWW7Volhsz5VPYbp0P0yMWS87ZzsfK0AmFx4hGRkZCgAAAAMAAAAD
+        Hx8fCCofKhhkeYhjfarA6Xutxv+Ctcr/grfL/4Cyx/96r8X/frDF/4y3yP+x1eD/mcPT/5a+z/+NuMr/
+        hqzB/4Kvwf+BqLr/gae5/4Clt/9/n7H/hqm6/4Gmt/9+pbf/ibHA/53Czv+Vusj/hKq6/36ktf+Ao7L/
+        c5io8WSPpmUA//8BAAAAANHS0ri/wcL/sLGy/6Wmp/+goaL/iImK/3Z3eP9tbm//Xl9g/15fX/9gYWH/
+        YWJj/0VGRv8nJyj/EBYWLgAAAAAAAAAAqVtsWbNdd+isXHTfpVpv06VZbM+UTmC2dj5NjmEyQG5MKzRT
+        OR4nOi0cIS0qGB4qNB8kMUEkL0ZTLzxlaz9MjIdWZ7yTkqPtjLTG/oq3yP+Itsj/hrXH/4i2x/+BrMD/
+        jLXJ/4avxf92m7X/fqS6/4Cmuv+HrL3/hqu7/4Spuv+Ao7X/gJ6w/4Ghsv9/obL/gKKz/4iruv+OssD/
+        i6++/4esuv97na3+bZOlqGSRoxwAAAAAAAAAAAAAAAC9vb7aqKqr/5ydnv+jpaX/nJ2e/3Bxcf9hYmL/
+        WVpa/1dXWP9dXl7/hISF/29wcf9QUVH/Ozs8/xkcHFAAAAAAAAAAAK5dcqeyXXnlrV513qVbbtKnW27P
+        llBkun1CUZZuOkh/XDI9a1UtO19RLDhbUyw5Yl0yPnNsO0iNgEZWsJRTZNCbWGreoV1y6aFsgK6Ns8SL
+        i7TF8Iezxf98o7r/cpez/3CUsP9vlbH/dZmz/32juv+Eq73/hai5/4Kgsv96l6z/d5Wq/26Npf90lKv/
+        eJar/3+dr/+Do7P/fZ+x/3OZrPtpjqasZY6jMgAAAAAAAAAAAAAAAAAAAAAAAAAAqKmr0pydnv+am5z/
+        lpeY/42Ojv9yc3P/ZWVm/2BhYv9kZWX/gYKD/5KSk/91dXb/ZGVl/1hZWv8jIyNPAAAAAI1UVAmzXXbi
+        sV145K5fdt6mXG7SqVpv0JxVacKOS12sekFPlHI+S4pvPEmHcDxKjHpBUJyGSVm0lVJjzZtWaNqfV2zj
+        pFpw559YbG5/f38CAAAAAImcsA18nrVkbJGtvHGXsftzmbT/Y4io/2GEpf9xla//dJWu/3SRqf9siKL/
+        Y3+b/22KpP92laz/fJqu/3uXqv9uiqD/YoOdz2KHo3pSe5QfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAKanp7WZmpv/oaKj/6amp/+YmZr/iouM/3p7fP+FhYb/hoeI/5ucnf+Ghof/jY6P/4uMjf9vcHH/
+        MTExKQAAAACgWWw2tV956bJfeeSvX3bepltx06hdcNKnW2/Om1RowZROYbmPTF+zkU1fuJZRZMScVGjQ
+        n1dq2KBXbOCmWXHqplhvxJ5UZS0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjjZsSa4qlU2yJpI12l667
+        dJKr2WB+m+tYdpbsUm6Q61VxkOZceJTRZoGbs2+LoYtohZxYXnqXGwAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAACRk5NwpKWm/6ipqv+ur6//u7y9/76/v/+oqar/oaKj/6Slpv+fn6D/
+        mZqa/62urv+pqqv/ioqK2wAAAAEAAAAAqlxxWLZfeem0YHvksWF44apcc9anXnHTql1x06pbcdOnW2/S
+        plpv06VabtakWW3YpVlu3qhacOerWnHnpVdseH9VVQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf39/Dnx9feqenp//uru7/7m6u//BwsP/
+        wsLD/7q7u/+xsrP/ra6v/7Gys//AwMH/wMDB/6mpqWIAAAAAAAAAAKdcbmO4X3vqtGB85rVhe+SvYHbe
+        q15y2KhccdamXHDWp1xw16ddcNupXXLgrVxz561bdeyqWnGvoVdkJgAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcnJxV
+        jo6P/re4uf+/wMD/xMXF/8TExf/AwcH/wsPE/729vv/Iycn/1NTU/9XV1bh/f38CAAAAAAAAAACmW29O
+        uGF567lgfuuyX3rjtWB65bJgeOOxYXbisV93469ed+WwXnfosl537K9cdMekV2xJAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAMLCxWrDw8T4yMnK/8PExP/Gxsb/xMXF/8HBwv/Hx8j/2NjY/97e3rPU1NQM
+        AAAAAAAAAAAAAAAAllppEbNidd+5YX3suWF/7LZffOi1X3zotGB66bVfeuu1X3rur1x1wahcblNVVVUD
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAysrKLMTExK++vr/6ubm6/7/AwP/Jycr/
+        09PT2dvb22T///8CAAAAAAAAAAAAAAAAAAAAAAAAAAClXWxEsmF01rdhee25YHrttmB57bNfd9GwX3OL
+        o1tpNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        tra2B8LCwiq7wMA5v7+/HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJkzZgWhV2kp
+        qFxsL5tNYxcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        /////////3/////////wH////////8Af////////AA////////wAD///////8AAP///////gAB//////
+        /4AAH////4ADAPAf///8AAAD+B////AAAA/4P///wAAAB/g///+AAAAD+H///gAAAAH4f//8AAAAAHj/
+        //gAAAAAMP//8AAAAAAx///gAAAAAAH//+AAAAAAA///wAAAAAAH///AAAAAAAf//4AAAAAAA///AAAA
+        AAAD//8AAAAAAAH//wAAAAAAAf/+AAAAAAAB//4AAAAAAAD//gAAAAAAAP/+AAAAAAAA//wAAAAAAAD/
+        /AAAAAAAAP/8AAAAAAAA//wAAAAAAAD//AAAAAAAAP/8AAAAAAAA//wAAAAAAAD//AAAAAAAAP/+AAAA
+        AAAA//4AAAAAAAD//gAAAAAAAf/+AAAAAAAB//8AAAAAAAH//wAAAAAAA//+AAAAAAAD//4AAAAAAAf/
+        /AAAAAAAB//8AAAAAAAP//ggAAAAAA//8HAAAAAAGD/wcAAAAAAgD+D4AAAAAEAH4PwAAAAAgAfA/wAA
+        AAGAA8D/gAAABwADwP8AAAAPAAOA/AAAAD8AA4AAPgAB/wADgAB/wA//gAOAAf////+AB4AD/////8AH
+        gA//////4A+AP//////wP8D///////////////////8oAAAAMAAAAGAAAAABACAAAAAAAABIAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoVdkJqpbbGqtW26W
+        rFttmqZYaF9/f38CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf39/Aqlba06tWXC2
+        sFtz6K9acuevWXLnsFpz6rFaceymWGhrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoWmlB
+        rVlwv61aceWrWW/iqFhs36ZYbN+nWGzhqFhu5K1YceupWWy3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        nFhiGqtYbp+tWXDkp1hu3qFXadieVGXTm1Nk0ppTZNOdU2XWpVdq4apWb+iqV2zBAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAGnV2taq1hw2KdYbt6gVGjVm1Jjz5hRYcyVTV/IlE1fyZlPYNCYUWHUnVNl26hWbOioV2um
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFBQUGRISGCoTExg0EBYWLRQUFBkAAAAC
+        AAAAAAAAAAAAAAAAm1RjEqhYbZ+oWG/hoFVo1plRY86TTF3EhUZTsXg9TKF0PEmdez5Mp4hHVb6VTl/T
+        mVFi2qRUa+qhVGZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGhoxExcZgRQYG8MUGBz1Exca/xMXGf8TFhn/
+        FBYZ/xQWGf8VFRn0GBcZxx4ZHYx4QVBZqVduy6RXbNuaU2TQkk5ew39CT6ZoNUCGWS43clEoMmpUKzRw
+        XzA6g3g9SaqKSVjQaDhE3TwfJ+wfExMoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqKioGGR4kYyIpLtEoMDX/MDpA/zE8Q/8vOUD/
+        LDY9/ys0Ov8oLzT/IiYq/x0fI/8bGh3/IBsf/184Q/+mV27/n1Vp+pVQYeGERlSxZzZAgkwpMV06HyNB
+        LRkeMi0UGTM1HCNHQyIpbjoeJKAfDxPRFAsM4REJCr4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC82PUszPUPaPElQ/0hXYP9KXGb/
+        SVxl/0VXYP9FV2H/QlVg/0JSW/9BTVT/PUZN/zlARv85Nz7/e0dW/6ZYbv+bVWf/j05e/3A+S/9MLTfv
+        LR4lfCgNGhMqAAAGAAAAAxwAAAkSDAwqDwcKYg8HCaQOBwnWDQYH6AsFCFsAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzTEwKRlhgnEZYYf9HWWH/
+        VGhz/1Vuef9NYmz/SVxl/01kbv9SaXT/U2Vv/1Fgaf9QXWX/TVhg/1NRWf+SV2n/pFlv/5lWZ/+GTFv/
+        XjdC/zgkK/8iHSL/HB4h/xkbH6kRESIPAAAAAAAAAAAJCQkcCgUHZQsFB7ULBQbdCQQH1AAAAAYAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5iaxpGWmPO
+        TGJs/1Blb/9adH//WnN+/1l0f/9WcX3/WXN//1xzff9ccXv/XG54/1ppcv9ZZ3D/ZmNu/55ecv+iWm7/
+        l1do/35PXf9bRVD/OzhA/yIjKf8WFxv/FBUZ/xcZHf8TFhncFBQUJQAAAAAICAgfCAQGeQgFBssIBAXl
+        BwUFZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        VGd6G1Bqc9pZc37/WHF8/1dwe/9bdoL/WHF8/1lyff9gfIj/YX2J/2J9iv9he4f/YnR//2Jxe/9ybHj/
+        pGB2/6Bbbv+UWGn/eVVi/1lQW/9ETVj/PUdR/y43QP8hJy//FBgc/xEUGf8QExf/DxIW5RAQGB8EBAQ1
+        CAQGnQgEBdsHBQbMAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAABLWmkRVHB71mSBjv9lhpT/ZoOR/2aFk/9mg5H/Yn2J/2J8h/9mgIz/aICL/2iBjf9mgI3/
+        Z3qG/3p0gv+nYnj/n1xv/5FZaf91WWb/X2Bq/0xaZv9GVWL/Q1Jd/ztIUv82QUn/Iyw0/xMYHv8RFBn/
+        DREV/w8SFtcHBwlpBwYGxAYFBeYGAwZLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABVcHyqY3+L/2qMm/9qi5r/bIqZ/22Hlf9siJb/aYiX/2mEkv9pgo//
+        bIKP/22DkP9tgI3/hXuK/6hjef+dXW//jVpq/3Jgbf9hbXj/XXF9/1pteP9WanX/TWNv/0ZaZv9AU13/
+        NERO/yItNv8VGyH/EBUZ/w8TFv8NDhDkCAYI3QcEB6sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGWNn1higpD/bIuZ/26Qn/9vjpz/cY2b/3KKl/9vjJr/
+        bo2c/22Lmv9pg5L/Zn2N/2V5if+Eeoz/qmZ8/51ecP+KWmr/b2Rx/2N4hf9ieIP/X3eD/1x0gP9acXz/
+        U256/01qdv9GX2v/PVNe/zFCTf8mMzv/GR8j/xEVGf8QExb/CgsN6gcHByEAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc6K5C2aOoOVrj57/cZam/3GUpP90kZ//
+        dI+d/3SNm/91j5z/c4+e/3KMmv9tg5L/ZXiK/4V5i/+qZ33/nF1w/4hcbf9rY3P/aHmH/2Z9iv9kfYr/
+        YHuI/196hv9ceIT/W3qH/1Fyf/9HZXP/QFln/z5VYP84SlL/KTM5/xUaHf8RFRj/ERMW6RUVFQwAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbJywdWyUpP9ukqL/
+        cpWk/3WXp/92laT/d5Oi/3eSof90j5//a4SW/2uBkv9ld4r/eWyB/6hke/+aW27/glNl/15Wav9ZboT/
+        X3WH/2R7iv9geon/YX+O/2GBj/9bgI//XoKR/1p7iP9PbXv/SGVz/0Vfa/9BWGH/NkVN/yMrMP8TGBr/
+        EhYZ/w8TFXYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/f78E
+        cJ+y4nOaq/9ylaX/dJen/3eYqP94mKj/eZWk/3iRn/91jJz/b4WX/2t+kP98c4f/qWZ9/5tdcP+CU2X/
+        XVRp/15xhv9jfJL/WnGG/2F3iP9mgpH/YoOT/1+Hl/9bhZb/YYWU/2CEk/9Vd4X/UGt3/0xodP9GYWz/
+        QVVe/zNBSP8bISX/EhYZ/w8UF+QAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAABspLVJdKCy/3Wdrv90lKT/d5qp/3mcrP97mqn/fJak/3qTof91i5z/d4yc/4qHmP+sa4L/
+        nF9x/4ZZav9mYHP/ZnqO/3qVqP9qg5X/UmmA/1dvg/9hfY7/aIiX/2ePn/9hi5z/YoiX/1yDk/9VfIv/
+        VW98/09wff9LZ3P/Rl1n/ztOVv8pNDr/Exgb/xEWGP8QExdNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABroLaac6O2/3ier/93na7/eZ2t/3qhsf99nKz/gZ6t/3eQov9qgJX/
+        goWY/61vhf+eYHP/iFpr/3BrfP90i6D/eJOm/3SMnf9pgJL/XnaL/1t0iP9jf5D/aI2d/2iQof9jj6H/
+        YY2e/12Hl/9Zf4//V3uJ/1J2hP9Ob3z/S2Vw/0NYYv80REv/GyIm/xIXGv8QFReZAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrnrLddqO2/3yhsf97oLD/f6Gx/3+hsf9/n7D/
+        gaGy/2yEmv9xeI//qnCI/59hdf+MXW7/d3OF/3uTpv+Jprf/dY6g/3iRof9shpj/aIWY/2uImv9oiZv/
+        aI+g/2iQof9mkKL/ZJCi/2CLnP9dhZX/WoCP/1R8i/9RdYL/UWx4/0pfaf88Tlb/KDM5/xMYG/8PFBbV
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHGbqRJvn7L+dqK2/3+isv9/pbb/
+        hKi3/4Smtv+Fqbr/fp2u/3qJnf+ncon/o2d7/41bbf9yaHn/k7DA/5S0w/+VtcP/gJqq/4Sgr/+CobD/
+        dZWm/2+Tpf9sk6X/apSm/2iVp/9qlaf/bJip/2GOn/9ijZ7/WoWW/1eAkP9VeIX/VXF9/05mcf9DVl//
+        MkBH/xgeIf8RFRf8HBwcCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG+itDd0prj/
+        fKa3/4CnuP+Bp7j/i6++/42xwP+RtcP/hZ+w/6V5jv+man7/kl5w/3hsff+AmKv/m7zM/6LD0P+jxND/
+        iKa1/42uvP+FpbT/gaGx/3GVqP9qkqX/a5ms/2iZrP9rm63/e6e3/2WTpf9nk6T/XYma/1mDlP9Ze4n/
+        WXaC/1FpdP9IW2T/OkpR/yAoLP8RFRj/EREXKwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAHSnu094r8H/fqq7/4Kpuv+Cq7v/h7DA/5C2xf+YtsP/o4OX/6pug/+VXnD/gXCA/4+puv98m7D/
+        n8HP/6nL1/+qzNf/kbXD/4qtvP+Hq7r/h6u6/3Wbrf9umKv/a52w/2mbrv9omq3/eKa3/26crf9plqj/
+        X4yd/1yHl/9bf43/WnqH/1RteP9OYGn/Q1FY/ykyN/8RFRj/EBQUPgAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAHWsvV16s8b/frHC/4Guv/+Brr//h7HC/4uwwP+ilqj/rnKI/5pjdf9+ZHT/
+        mq+9/6DBz/+Irb7/ibHB/5C3xv+ixtP/ocXS/5i/zf+Grr7/iLHB/3igsv9yna//bZ6x/2qesf9pnK//
+        eqm6/3uouf9ynrD/Y4+g/16Jmf9egI//YYCO/1lyff9TZW7/SFhg/zE8Qv8SFhn/DxMXQgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHasvVp7tcj/frXH/4Gyw/+DsMH/ha2+/5aesP+xdYv/
+        oGl7/39ca/9odYf/gaq9/5C4yP+u0Nv/k73M/5G9y/+FscH/lL3L/5W+zP+LtsX/hrLC/3Whs/9xobT/
+        bqG1/2ygs/9rnrH/daa3/2marP9mlqj/ZZCh/2CLnP9ghJP/YoKP/1t1gf9WanT/S1xk/zdESv8VGh3/
+        EBQUPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHSrvUZ9tcf/f7bI/4Kyw/+DscP/
+        jKa4/7B5kP+ncoX/iF1t/2tvfv97oLL/f6y9/4Csvv+Vvcz/udrj/6vR3P+Qvcz/irjH/4m4x/+Ousn/
+        eqa3/3Wkt/9wprn/b6S3/22htf9tobT/dKW3/2mbrv9ml6n/ZJOl/2WMnP9jh5b/X4CO/114g/9ZbHf/
+        T2Bp/zxJUP8XHSD/EREXLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHixxiR9s8X/
+        f7XH/3+uwf+HrL7/q4CW/612i/+TYnP/bmVz/3eaq/+Brb7/gK/B/4CuwP+Cr8H/jrrK/6DL2P+Ku8v/
+        kr7N/4++zf9/sMH/fa2+/3WpvP9yp7r/cKa5/3Kmuf9zprn/bqG0/2mcr/9pmaz/b52u/3GbrP9kipr/
+        Y4WT/194hP9abnj/UmVu/z9NVP8YHiH8GRkZCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAFWqqgN+scLzg7LE/4Cqvv+hi5//sHaM/6Btf/91XWv/cYiY/4Wot/+Dqrv/g6/A/4Kuv/+Br8D/
+        gq+//4u5yP+ex9T/iLTE/4KvwP+Hs8P/hbXF/32uv/91qr3/ea7A/3Spu/9vo7b/baC0/2uesf9wobP/
+        g629/3mjs/9pj5//Z4SR/2J3gf9ccHr/U2Vv/0BNVP8XHiDZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAACCtMS8ibXG/5Oesv+ydYz/rX2Q/4Rfbv9ocYD/gKGz/4WnuP+Fq7z/
+        gay+/4WsvP+Erb3/g66+/4auvv+KssH/gqy8/4GvwP+AsMH/hLXF/4e6yv+Btsf/gLXG/3qvwP9xprn/
+        bqK1/26htP9yo7X/eqi5/4Ksu/95n6//aoaT/2R6hP9cc33/VGVv/0FPVv8XHCCXAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEucluja/A/696kf+ueo7/mG1+/3Jsef96mKn/
+        ham7/4Oou/+Ap7v/gaq8/4quvf+Kqbj/iqi3/4mntv+FqLj/gqq6/4Cquv+Crr7/jLzL/4y9zP+Gucn/
+        hLjJ/3muwP90qbz/b6S3/3qsvf91pbf/dqW2/3mktP9tlKT/ZoWT/2N8h/9cc37/VGZw/zpIUP8VHCBH
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEt8EZpYWa/a92jP+oeoz/
+        d15s/4KYp/+Ls8P/iK/A/4avwf9/prr/hq2//4+wv/+RsL7/kK69/4mmtf+IprX/hqa2/4Kquv+Arr//
+        ibbF/42+zf+VxdP/ksLR/4K2xv92qr3/cqa5/4S0xP+Jt8b/hrLB/3yltf9qkqL/ZYmY/2J/jP9ddYD/
+        U2Zw/zRAR+UAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClWm9V
+        rWqC9qp5jP+MaXn/aGt6/5S4yP+PuMn/h7PF/4izxP+HsMH/ha/B/5O1xP+Rr73/jqy6/4uot/+Kp7X/
+        iaa1/4iouP+Tusj/rNHc/5jF0/+Ducn/jsDP/5HBz/94rb//f7LC/5bCz/+aw9D/jbfG/3Whsv9pkqL/
+        ZIqa/2KBj/9ed4L/UGVw/y08QnsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAKFQaxOnWXHToWB03qN8j/9tWmn/cIma/423y/+Fr8X/fae//4WuwP+Dqbz/iLDC/4+xwP+Srbv/
+        i6i4/4ypuP+LqLf/jay6/4uquP+cvsv/j7nI/36wwf+SxNL/oc3Z/5jG1P95rsD/e6/B/428yv+Pu8n/
+        jrjG/3CfsP9mlKb/Y4ub/2GCkP9YdYL/RFtm7SIzMw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAKZYbZCjWW/cmVZoyYtzhN1YXGn/cp+y/4q6zP95orz/d565/3ifuP94m7P/
+        h62//4qrvP+Iprf/i6i4/42quf+Lqbf/i6i3/42tvP+bv8z/hbHB/3+xwv+KvMz/i77N/4S4yP95rsD/
+        cqi7/3Kmuf9vorX/cKG0/2ycr/9llKf/Y42e/1x+jv9Oa3n/PFJeaQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1ZrMqlZcOKdV2nSjk1etWFATXNXa3jne67C/4W4y/+FsMX/
+        b5i2/2iPr/9vmLT/faa8/4Omuf+JqLn/jqy7/46su/+Mqbf/jKi2/5Gwvv+NssP/iLPE/4i2xv+Lusr/
+        ksHQ/4e7y/+Btcb/dqu9/3Kmuf9vorX/bJ6x/2marf9mlaf/YIia/1Z2hv9DYHK5AH9/AgAAAAAAAAAB
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqFlwsaVYbtuaVGfKeEFPlEUrMkZad4c+
+        g7fJ+H2wx/9zoLz/bpm5/2WOr/9rlrX/fqnB/3ujuv+PtMT/lLTC/5Kxv/+LqLf/ja27/6DE0f+Hq73/
+        krnI/53G0/+Ousv/hrjJ/4W6yv9/s8T/frLD/4Gywv94qbv/b6Gz/2ubrv9lkaX/ZYeX/01vguA+TFQ5
+        Oz5Aozk9P+4uMDL9IyYo4yEjI48dHR0aAAAAAAAAAAAAAAAAAAAAAAAAAACmWGtFq1ly46BYa9OUT2K9
+        ZDdCdzghJy0AAAAAhrfLWXitxv1omrv/cJ27/3Gcuv98qcP/favD/3uqwf+Qv87/p83Z/42wv/+Mrbv/
+        krG+/4uquf+Cprf/h7HC/5bAz/95q7//e6/C/36vwP+Br8D/j7zL/5K8yv+GssH/dqS2/2uZrP9hi5//
+        VHiO6XB+hn9/gYL0d3l6/31/gP9zdXb/Y2Rl/zk7PP8gIiPqFhwcLQAAAAAAAAAAAAAAAAAAAACrWnC3
+        qFlx3Z9Was6HR1moWi88ZS0WHiIAAAAAAAAAAHmwx1h0q8f4aZy8/3KevP90or7/eqzE/4G2yf+Ht8n/
+        sNPe/5G2xv+NssL/lrrI/5zAzv+Grb3/gKa3/32ou/9+rL7/g7DB/4Gsvf+MtcT/j7jH/4exwP98prj/
+        cZ6x/2iUqP9XgZbjkqeyV7q8vfmkpqf/i4yN/4+Qkf+Ki4z/cHFy/1FSU/9CQ0T/Gx0f3RwcHAkAAAAA
+        AAAAAKNbaDiuXHTlp1pv155Wacl+QlOZVC44Xi4aISYAAAACAAAAAAAAAAB9tcs7ebDI5m6evv98rcf/
+        d6rD/3qpwP9+rMP/qM7b/6TM2f+s0dz/rtHd/6DI1v+Bq77/f6e5/4Gouf+Bp7n/gqq7/3+ouf+awc7/
+        iLC//3qitP92nrH/cJiq/2OOo8NYf5wa0NLTn7u9vv+jpKX/mpuc/4yNjv+Njo//amts/1paW/9XWFj/
+        NTY2/xcZGW0AAAAAAAAAAK1bcZauXHbipVlt055UacZ8QVCUWi88ZTofKDkjGhodKBoaEy8cJRs/KDI4
+        ZFFed4aarueIuMv/hbbJ/4Gyxv+Bssb/jLfJ/5zF1P+AqcD/f6i9/4CovP+Eqrv/g6i5/4Cgsv+BorT/
+        gaS1/4Gnt/+Vusf/kbbD/4SpuP95nK30bJWodlWqqgMAAAAAxMXF2a6vsP+pqqv/mJma/3Jzc/9gYWH/
+        WFla/2RlZf9sbW3/RkdH/yIkJLEAAAAAjVRUCbJddd+tXHTfpFtv0Z9WacaCRFScaDdEeFUtO19LKjNU
+        USw1W10yQHN3QlCekFFiyZxab+Gdeo7MjbbFtoi0xf6Cqr//c5mz/3KYtP92mrT/fqS6/4WqvP+Eo7X/
+        fJqu/3aVqv92lav/epms/4Khsv+Co7T/dZut9XCVqJNnjaAbAAAAAAAAAAAAAAAApqmq35ucnf+Wl5j/
+        iYqL/2lpav9fYGD/ZGVl/4uMjP96e3z/YWJi/z4/P70AAAAAqVxsQrVdeeeuXnXfpVtv0aZabsySTmCz
+        f0NSmHY+TY55P06VhEZXqpNPYcebVmnao1lv56NZbpGLXFwLAAAAAHyctydvk66CcZWw02qNq/5jhaX/
+        bpCr/3CPqP9ohaD/YX6a/26Mpf96l6z/dJGl9WaGnbhhh6JmWniWEQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        o6WmwZ2en/+mp6j/n6Ch/4mKi/+JiYr/j5CQ/5WVlv+QkZH/kJGR/2BiYpYAAAAArV5zcbZeeuewX3fg
+        qFxx1KldcNKlWW3NnlVqx55WacmgV2nQolls2aVYb+OoWXHUolhqSAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAH+WrRZ9nrNHdZasZlp5lnNRbY9wVXCOa115lVJphZsuZmaZBQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAi4uLapiZmv+1trb/vb2+/76/v/+ur7D/qaqq/6OjpP+zs7T/sbKz/319fTsAAAAA
+        rV5xhLdgfOmzX3nirV9026lcctanXHDVqFxw16ddcNupXHLjrFx06KhacIqjW20OAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf39/BomJi8+xsrP/vr+//8XGx//BwsL/vr/A/7/AwP/Q0NH/
+        z8/RogAAAAAAAAAArV9xbrlgfOu2YXvntGB55LFgeeOxX3jjsV5457FeeOuvW3Snp1dpKQAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALy8vBvExcXEx8jJ/8TFxf/ExcX/
+        xMTF/9LS0//d3d2f2traBwAAAAAAAAAAo1tlGbVhdda5YX3suGF97LZge+y1YHnhsF10k6ZYbi4AAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/f38C
+        v7+/ULW1tpG9vr6qyMrKjdPT0zsAAAAAAAAAAAAAAAAAAAAAAAAAAJtUYxKtYXNUrmFxXKxfcDuRSG0H
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////+fAAD/////
+        /A8AAP/////wBwAA/////8AHAAD/////gAcAAP////4ADwAA///ABA4PAAD//wAAPw8AAP/8AAB/HwAA
+        //AAAB8fAAD/4AAADz8AAP/AAAAGPwAA/4AAAAJ/AAD/AAAAAH8AAP8AAAAA/wAA/gAAAAD/AAD+AAAA
+        AP8AAPwAAAAAfwAA/AAAAAB/AAD4AAAAAD8AAPgAAAAAPwAA+AAAAAA/AAD4AAAAAD8AAPgAAAAAPwAA
+        +AAAAAA/AAD4AAAAAD8AAPgAAAAAPwAA+AAAAAA/AAD4AAAAAD8AAPgAAAAAPwAA/AAAAAB/AAD8AAAA
+        AH8AAPwAAAAA/wAA+AAAAAD/AADwAAAAAf8AAPEAAAAB/wAA4YAAAAIPAADjwAAABAcAAMPgAAAIAwAA
+        w/AAABADAACD+AAAcAEAAIPgAADwAQAAgAOAB/ABAACAD///+AMAAAAf///4AwAAgH////wHAACB////
+        /x8AAP///////wAAKAAAACAAAABAAAAAAQAgAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqVWYerFpxc65Zb6uuWm+up1dpOgAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACnV2kdrFlvlKxacOKqWW7iqllu4q1ZcOetWW2/
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/P38EqVhsbqlYb9qiV2rYnVNl0ppSZNGaUmTV
+        pFZq4alXbssAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAABDBkZFA8XFyESEhIbAAAABQAAAAAAAAAApVppIqlXbbWiVmrYl1BiyotIV7d/Qk+q
+        hEVUtZVOXs+dUmbepVRqowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAABISJA4WGx5mHCElthofJPAZHiL/Fxse/xUYGv8WFxn6HBgc0HA/TZikVmzamlJjzYVFVKxlMj99
+        TycvYE4nLmJhMTqGbDhFx0UlLeImExhcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAB8fPwgyPUN9NkFI8ENSWv9EVF3/QVFa/z1NV/88SE//NT1D/zAwNv9vQE7/oVdr/45OXf9hN0Hh
+        OCMoXiwWFhckEhIOHwwTKBgND3MQCAvKDQYJ2xUAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAABGWV8oR1lj001gaf9Xbnn/UWlz/05kbf9UanT/VWZw/1Ngaf9VWWL/jVdp/55Ya/+CTFv/
+        SjE6/yIcIf8ZGx/2FhgaaAAAAAANAAATCAYGfgoEB9kKBAZ+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAATmZwNFFqde1UbHb/WnWA/1hxe/9ceIT/YHuH/2B5hf9gcn3/Z2t2/5pgdP+aWmv/
+        elRh/05LVv83P0j/ISYt/xMWGv8SFRj/DxMVhAgICB8HBAaoCAQF2A4AABIAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAE1qcSRdeYbtZ4eV/2iFk/9ohZP/ZICM/2eAjf9pgY3/aYGO/3J5hv+fZHj/
+        l1ts/3Zcav9aZG//S1to/0RTXv86SFH/Iy01/xIWHP8OEhb/DA4RoAgGB9MHBARqAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAB/f38CYICOxmuKmP9tjp3/cIuZ/2+KmP9sipn/aYST/2h/jf91e4v/
+        o2h9/5Rbbf9yZXP/YnaB/151gP9bcXz/UGt2/0Zfa/85TFb/JDA4/xQaHf8QExb+CgkKwgAAAAQAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGiWqWJrj57/cZWl/3SSov91j57/dI+d/3CMm/9tg5L/
+        cHSH/6Noff+QWmz/a2R1/2V4h/9kfYr/YXyJ/116h/9Zeoj/TGp4/0Fbaf88UFr/JzE2/xIXGv8QFBe4
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/f38CcJuu2nGWpv90mKj/d5en/3mUov92jp7/
+        bYOU/3B2if+gZXz/j1hq/2JYbP9edIr/XHOH/2R+jv9hg5P/XISV/2CEk/9YeYf/TWl2/0ZhbP87TFT/
+        HiYq/xEWGP8OExM0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG+gtD50oLP/dZio/3ibq/97nKz/
+        fZel/3WMnf9/i5z/pW2D/5Jcbv9uZ3n/cYmc/2+Imv9UbIL/X3mL/2eKmf9lj6D/YYiY/1d+jv9Uc3//
+        TWx4/0VcZv8wP0b/FBkc/xEUFpUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAap60iXeitP97oLD/
+        faGx/36fr/9+m63/a3qR/6Jwh/+VX3H/d3GC/4Gcr/92j6H/boeY/2eDlf9mhZf/aI+g/2WPof9ijp//
+        XYWV/1h+jP9RdoT/Tmhz/z5QWf8fKCz/EBUX2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwobS8
+        eqO1/4Cltf+Gqbj/iKu7/36Zq/+gdIr/mWJ0/3drff+TssL/nLzJ/4WhsP+Eo7H/dZan/22Upf9plqj/
+        apep/2yYqv9ijqD/WoWV/1Z7iv9VcHv/R1tk/y06QP8SFhn+FRUVDAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAHSrvNt+qbr/gqm6/4qxwP+Wt8X/oYSY/55leP+Fdob/hKG0/6HE0f+oytX/ja+9/4iquf+Cpbb/
+        bZWo/2qcr/9pmq3/dKKz/2qXqP9eipv/W4CP/1h2gv9OYmz/O0hP/xUbHf8NExMnAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAeLLD6H+xwv+Crr//h6/A/6CXqf+lbID/fmN0/5m1xP+ZvMv/irTD/5a9y/+fxdL/
+        irPC/4Otvf9znrD/bJ+y/2qdsP94p7j/b52v/2KNnv9ehJP/X36K/1Vpc/9EU1v/GyEk/xERFywAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAB6ssXcf7XH/4Oxw/+Sn7H/rHWJ/4ZgcP9yiZv/fqq8/5O7yv+w097/
+        j73L/4u4x/+Nucn/eqe4/3Glt/9uo7b/bKCz/3GitP9nl6r/ZZCi/2KHl/9efov/WW96/0paYv8gKCz/
+        Dw8XIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH2yxLt/scT/iae5/616kP+UZnf/cHuK/4Kquv+Br8H/
+        ga/A/5O+zf+Ovs3/j7vK/4Szw/98rb7/dKi7/3Knuv9xpbj/bJ+z/2qbrv94o7T/ZY6e/2KBjv9ccXv/
+        Tl9o/yMrMPgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgLHCh4ezxP+mg5n/pnWI/3FmdP9/n7H/
+        haq7/4Otvv+Erb3/hK+//4+3xv+Crb7/grHC/4a3x/9/tMX/frLE/3Knuv9uobT/caK0/3+ru/94n6//
+        aIKO/150fv9QYGn/Ji4yxQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBucs7nJer/695jv+Hann/
+        e5Wl/4WqvP+BqLv/hay+/42tu/+Kqbj/h6e2/4Kpuf+Brb3/irrJ/5DAz/+Et8j/dqu9/3GluP98rb3/
+        eae3/3CYqf9lhJH/X3aA/09hav8lLzR1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKNbbyescof6
+        m3GD/3F4h/+Wvcz/h7LE/4avwP+JsMH/krG//46suv+JprX/iKa1/4qywf+dxtP/ibzM/5PD0v97r8H/
+        grPE/5bBzv+Hs8H/bZam/2OHl/9feYX/SVtl9x8fKhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAB
+        plhur6FmeeJ3Z3b/eZyu/4OtxP99pr7/gqe7/4mwwf+PrLv/i6m4/4upt/+Nqrn/lrjF/4e0xP+KvMz/
+        mMfU/36yw/99sMH/hLPD/36rvP9olqj/YomZ/1l2hP9BVmKRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAKdXbFejWG3ZiExdqlxldNJ+scT/hLHG/2+Ytf9wlrL/gai8/4emuP+Nq7r/jKq4/42ruP+RtMT/
+        hrPD/4i4yP+Nvs3/grbH/3SpvP9vo7b/bZ6x/2aWqP9ehZf/TWl54ERVZg8AAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAACpVHEJqVlxy5tVaMtrO0d5TltnKoO1yuNxoL3/apW1/26auP96pb7/irPF/5m7yf+Lqrj/
+        k7PA/4quv/+VvMv/j7vM/4O2yP+As8T/hLXF/4CwwP9voLL/Z5Sn/1t9j/VTY259UFNU0EVHSfwxMzPf
+        ISQkcQAAAAEAAAAAAAAAAKpZb2enWnDakU5huFQuOVgqACoGf7bIKnGoxONunr3/dqS//3yuxf+HuMr/
+        pcnW/4yuvv+Yusj/ia6+/4GqvP9+rL//ga/A/4awwP+Qucf/gqy8/3Gesf9eiJ7zjaCrkqGjpP2Ji4z/
+        h4mK/2hpav88Pj//Gx0degAAAACqVVUDrlx0yqVZbdOISVqmTig1USIRIg8AAAABaZalInWju9F8rcb/
+        e67E/3ysw/+ly9n/nsbV/53D0v+GsMH/gKe5/4Glt/+Ap7j/krnH/4euvv96obL/bJWo1WCHni3HycnK
+        qqus/5OVlv+Cg4T/YmNj/1tcXf8wMTL0FRUVDKtbb0CwXXXjpVtt0YlIWaVfMkBrSSYwSU0rMkxoOkd6
+        ilJivZeGm+GJtcbehLDD/3yju/94nrf/gKa7/4Wouf99nrH/eZis/36esP+FqLf/faGz6XSXqnZtkbYH
+        AAAAAKmrrOqcnZ7/g4SE/2BgYf9mZ2j/fn+A/1JSU/8fHx8osl51grBfduGnXG/SnFRov4ZHV6OFR1ik
+        kE9gvp1VadykWG6vo1ttHKqqqgNxlLFIcJWwmGeJqNFvjqnxY4Cd9WB8mO1ykafPco6jnGOFnlJff58I
+        AAAAAAAAAAAAAAAAnp6fyaeoqf+nqKj/kpOU/5mamv+Wl5j/iouM9jMzMwqyXnektGB55KtectipXHHU
+        qFtw1qhccd2pWnLYqFlxYf8AAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAACEhIRTp6ip/7/Awf/AwcH/t7i5/8PExP/CwsSHAAAAALNgdoq3YXzp
+        tGB75rJgeOayXnjfrlx1gqlUcRIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADExMRkxMTF6sDBwv/IyMn12trahv///wMAAAAA
+        pVppEbRgdXy1X3iIsl11V5xidQ0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/f38CwcHBGba2tgcAAAAA
+        AAAAAAAAAAD////n////A////gP///gD//ABx//AA+f/AAHv/gAAT/wAAB/4AAAf+AAAH/AAAB/wAAAP
+        4AAAD+AAAA/gAAAP4AAAD+AAAA/gAAAP4AAAD/AAAB/wAAAf4AAAH+AAAD/MAABHzgAAA48AAQGPAAcB
+        AHAfAQH//4ED///D3////ygAAAAYAAAAMAAAAAEAIAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAClWWYUrVpwca1ZcLOvWm+0oFRnGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkUhtB6tYbnGqWW3Wo1Zp2aFWadqoV23m
+        qlZsXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQkBxUVFRgPDx4R
+        AAAAAAAAAACoVm4sp1Ztup1SZtGNSlu7iEZVtZROXs2hU2fiplRrRQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAHR0nGiMrL4AmLjLQISgs/B4kKP8aHCD/GRgb7m4+S7mfVGnhiklXsWQzPnJJJixQ
+        TygwalcsNrszGiHaGRkZCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVVQNBUlp5Q1Jb9k1ha/9JXWb/
+        S19p/0lXX/9GTFP/ekxb/5hUZv9lOkX/LSEn2hgYHTQAAAADCwcHQwsGB8MLBQeHAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAASG1tB1FocrBTanT/WnR//1p1gP9eeIT/X3N+/2Jrdv+SX3H/klho/15MWP8yNz//
+        GBsg/xIVGfYRFBRKBQUFWwgEBdYJCQkaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWnSBpGeHlv9phpT/
+        Z4SS/2aAjf9qgY7/cH2L/5pleP+MXGz/ZWZx/1Fhbf9EVmH/M0FK/xcdI/8OEhX1CQkKuwYEBncAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAABmj55Sa42b/3CRoP9zjZv/cY6c/22Hlv9teov/nWl9/4deb/9odIL/
+        YXqG/1x2gv9TcX7/Qlxp/zNFTv8aISX/DhEU9AAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wFvmqvV
+        cZWl/3aXp/94k6H/cYma/256jf+ZZXr/f1Zo/15sgf9fdoj/YoCP/16Dk/9egpD/T217/0Zga/8zQkn/
+        FBkc/xEUF1gAAAAAAAAAAAAAAAAAAAAAAAAAAGuhtzl1oLH/d5qq/3udrf98lqX/doeZ/6Bwhf+GX3H/
+        bn6S/3CJm/9YcYb/ZYSU/2WOn/9fh5j/V3mI/05vfP9EWmT/Iy0y/xAWF7kAAAAAAAAAAAAAAAAAAAAA
+        AAAAAG2fsnt6orT/f6Sz/4KktP95k6b/mXCH/4tgcv+Gmqv/haGx/3qWpv9ujp//aZCi/2iTpP9kkKL/
+        XYaW/1R6if9QaXT/NkZN/xIYG/QAAAACAAAAAAAAAAAAAAAAAAAAAHWpvKF/qLn/hay8/5K1w/+egpb/
+        k2V3/4GSpf+hw9H/mrvI/4mquf98n7D/a5ir/2marf9xn7D/Y4+h/1qBkP9Wcn3/RVVe/xshJf8TExMa
+        AAAAAAAAAAAAAAAAAAAAAHiyxa2AscP/hK/A/52Wqf+aZnn/gI2d/5q+zP+PuMf/l7/M/4+4x/9/qbr/
+        b5+y/2uesf91pLb/aJWm/1+Glv9deof/T2Fq/yQsMP8PFxcgAAAAAAAAAAAAAAAAAAAAAHyyxZqAs8X/
+        kKGz/6Vxhf92c4L/f6q8/4ayw/+lzNj/jbzL/4m4yP94qLr/cKa5/3Ckt/9tn7L/aZiq/2eOnv9ffYr/
+        VWhx/ys0Of4SEhIOAAAAAAAAAAAAAAAAAAAAAIGxw2yIrL7/rH2S/4Bmdv9/nq//g6y9/4Otvv+FscH/
+        jLbF/4Owwf+DtMX/fLHC/3Oou/9toLP/eKa3/3efr/9mf4r/WGt1/y86PtsAAAAAAAAAAAAAAAAAAAAA
+        AAAAAH+7yiKjiJ3+mXCB/36Uo/+GrL3/gqm8/42uvf+Lqbj/hqi3/4GsvP+Lu8r/jb7N/3muv/94qrz/
+        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
+</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/DefaultSorter.cs b/ObservatoryCore/UI/DefaultSorter.cs
new file mode 100644
index 0000000..040859d
--- /dev/null
+++ b/ObservatoryCore/UI/DefaultSorter.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Observatory.UI
+{
+    internal class DefaultSorter : IComparer
+    {
+        /// <summary>
+        /// Specifies the column to be sorted
+        /// </summary>
+        private int ColumnToSort;
+        /// <summary>
+        /// Specifies the order in which to sort (i.e. 'Ascending').
+        /// </summary>
+        private SortOrder OrderOfSort;
+        /// <summary>
+        /// Case insensitive comparer object
+        /// </summary>
+        private CaseInsensitiveComparer ObjectCompare;
+
+        /// <summary>
+        /// Class constructor.  Initializes various elements
+        /// </summary>
+        public DefaultSorter()
+        {
+            // Initialize the column to '0'
+            ColumnToSort = 0;
+
+            // Initialize the sort order to 'none'
+            OrderOfSort = SortOrder.None;
+
+            // Initialize the CaseInsensitiveComparer object
+            ObjectCompare = new CaseInsensitiveComparer();
+        }
+
+        /// <summary>
+        /// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
+        /// </summary>
+        /// <param name="x">First object to be compared</param>
+        /// <param name="y">Second object to be compared</param>
+        /// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
+        public int Compare(object? x, object? y)
+        {
+            int compareResult;
+
+            ListViewItem? listviewX = (ListViewItem?)x;
+            ListViewItem? listviewY = (ListViewItem?)y;
+                                    
+            // Compare the two items
+            compareResult = ObjectCompare.Compare(listviewX?.SubItems[ColumnToSort].Text, listviewY?.SubItems[ColumnToSort].Text);
+
+            // Calculate correct return value based on object comparison
+            if (OrderOfSort == SortOrder.Ascending)
+            {
+                // Ascending sort is selected, return normal result of compare operation
+                return compareResult;
+            }
+            else if (OrderOfSort == SortOrder.Descending)
+            {
+                // Descending sort is selected, return negative result of compare operation
+                return (-compareResult);
+            }
+            else
+            {
+                // Return '0' to indicate they are equal
+                return 0;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
+        /// </summary>
+        public int SortColumn
+        {
+            set
+            {
+                ColumnToSort = value;
+            }
+            get
+            {
+                return ColumnToSort;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
+        /// </summary>
+        public SortOrder Order
+        {
+            set
+            {
+                OrderOfSort = value;
+            }
+            get
+            {
+                return OrderOfSort;
+            }
+        }
+    }
+}
diff --git a/ObservatoryCore/UI/MainApplication.axaml b/ObservatoryCore/UI/MainApplication.axaml
deleted file mode 100644
index f5a24df..0000000
--- a/ObservatoryCore/UI/MainApplication.axaml
+++ /dev/null
@@ -1,15 +0,0 @@
-<Application xmlns="https://github.com/avaloniaui"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:dialog="clr-namespace:Egorozh.ColorPicker.Dialog;assembly=Egorozh.ColorPicker.Avalonia.Dialog"
-             xmlns:local="clr-namespace:Observatory.UI"
-             x:Class="Observatory.UI.MainApplication">
-  <Application.DataTemplates>
-    <local:ViewLocator/>
-  </Application.DataTemplates>
-  <Application.Styles>
-    <FluentTheme Mode="Dark"/>
-    <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
-    <StyleInclude Source="avares://Egorozh.ColorPicker.Avalonia.Dialog/Themes/Default.axaml" />
-    <dialog:FluentColorPickerTheme Mode="Dark" />
-  </Application.Styles>
-</Application>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/MainApplication.axaml.cs b/ObservatoryCore/UI/MainApplication.axaml.cs
deleted file mode 100644
index 0564983..0000000
--- a/ObservatoryCore/UI/MainApplication.axaml.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using Avalonia;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Markup.Xaml;
-using Observatory.UI.ViewModels;
-
-namespace Observatory.UI
-{
-    public class MainApplication : Application
-    {
-        public override void Initialize()
-        {
-            AvaloniaXamlLoader.Load(this);
-        }
-
-        public override void OnFrameworkInitializationCompleted()
-        {
-            if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
-            {
-                var pluginManager = PluginManagement.PluginManager.GetInstance;
-                desktop.MainWindow = new Views.MainWindow()
-                {
-                    DataContext = new MainWindowViewModel(pluginManager)
-                };
-
-                desktop.MainWindow.Closing += (o, e) =>
-                {
-                    pluginManager.Shutdown();
-                };
-            }
-
-            base.OnFrameworkInitializationCompleted();
-        }
-    }
-}
diff --git a/ObservatoryCore/UI/Models/BasicUIModel.cs b/ObservatoryCore/UI/Models/BasicUIModel.cs
deleted file mode 100644
index 143ba37..0000000
--- a/ObservatoryCore/UI/Models/BasicUIModel.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Observatory.UI.Models
-{
-    public class BasicUIModel
-    {
-        public string Time { get; set; }
-        public string Description { get; set; }
-    }
-}
diff --git a/ObservatoryCore/UI/Models/CoreModel.cs b/ObservatoryCore/UI/Models/CoreModel.cs
deleted file mode 100644
index bfbdc5e..0000000
--- a/ObservatoryCore/UI/Models/CoreModel.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Avalonia.Controls;
-using Observatory.UI.ViewModels;
-
-namespace Observatory.UI.Models
-{
-    public class CoreModel
-    {
-        public string Name { get; set; }
-        public ViewModelBase UI { get; set; }
-        
-    }
-}
diff --git a/ObservatoryCore/UI/Models/NotificationModel.cs b/ObservatoryCore/UI/Models/NotificationModel.cs
deleted file mode 100644
index 4f9a05b..0000000
--- a/ObservatoryCore/UI/Models/NotificationModel.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Observatory.UI.Models
-{
-    public class NotificationModel
-    {
-        public string Title { get; set; }
-        public string Detail { get; set; }
-        public string Colour { get; set; }
-        public int Timeout { get; set; }
-        public double XPos { get; set; }
-        public double YPos { get; set; }
-    }
-}
diff --git a/ObservatoryCore/UI/NotificationForm.Designer.cs b/ObservatoryCore/UI/NotificationForm.Designer.cs
new file mode 100644
index 0000000..012e455
--- /dev/null
+++ b/ObservatoryCore/UI/NotificationForm.Designer.cs
@@ -0,0 +1,39 @@
+namespace Observatory.UI
+{
+    partial class NotificationForm
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(800, 450);
+            this.Text = "NotificationForm";
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/ObservatoryCore/UI/NotificationForm.cs b/ObservatoryCore/UI/NotificationForm.cs
new file mode 100644
index 0000000..26c5ef2
--- /dev/null
+++ b/ObservatoryCore/UI/NotificationForm.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Observatory.UI
+{
+    public partial class NotificationForm : Form
+    {
+        public NotificationForm()
+        {
+            InitializeComponent();
+        }
+
+        public Guid Guid;
+    }
+}
diff --git a/ObservatoryCore/UI/NotificationForm.resx b/ObservatoryCore/UI/NotificationForm.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/ObservatoryCore/UI/NotificationForm.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/PluginHelper.cs b/ObservatoryCore/UI/PluginHelper.cs
new file mode 100644
index 0000000..ceee265
--- /dev/null
+++ b/ObservatoryCore/UI/PluginHelper.cs
@@ -0,0 +1,126 @@
+using Observatory.Framework.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography.X509Certificates;
+using System.Speech.Synthesis;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Observatory.UI
+{
+    internal class PluginHelper
+    {
+        internal static List<string> CreatePluginTabs(MenuStrip menu, IEnumerable<(IObservatoryWorker plugin, PluginManagement.PluginManager.PluginStatus signed)> plugins, Dictionary<object, Panel> uiPanels)
+        {
+            List<string> pluginList = new List<string>();
+            foreach (var plugin in plugins)
+            {
+                AddPlugin(menu, plugin.plugin, plugin.signed, uiPanels);
+                pluginList.Add(plugin.plugin.ShortName);
+            }
+            return pluginList;
+        }
+
+        internal static List<string> CreatePluginTabs(MenuStrip menu, IEnumerable<(IObservatoryNotifier plugin, PluginManagement.PluginManager.PluginStatus signed)> plugins, Dictionary<object, Panel> uiPanels)
+        {
+            List<string> pluginList = new List<string>();
+            foreach (var plugin in plugins)
+            {
+                AddPlugin(menu, plugin.plugin, plugin.signed, uiPanels);
+                pluginList.Add(plugin.plugin.ShortName);
+            }
+            return pluginList;
+        }
+
+        private static void AddPlugin(MenuStrip menu, IObservatoryPlugin plugin, PluginManagement.PluginManager.PluginStatus signed, Dictionary<object, Panel> uiPanels)
+        {
+            var newItem = new ToolStripMenuItem()
+            {
+                Text = plugin.ShortName,
+                BackColor = menu.Items[0].BackColor,
+                ForeColor = menu.Items[0].ForeColor,
+                Font = menu.Items[0].Font,
+                TextAlign = menu.Items[0].TextAlign
+            };
+            menu.Items.Add(newItem);
+
+            if (plugin.PluginUI.PluginUIType == Framework.PluginUI.UIType.Basic)
+                uiPanels.Add(newItem, CreateBasicUI(plugin));
+        }
+
+        private static Panel CreateBasicUI(IObservatoryPlugin plugin)
+        {
+            Panel panel = new();
+            var columnSorter = new DefaultSorter();
+            ListView listView = new()
+            {
+                View = View.Details,
+                Location = new Point(0, 0),
+                Size = panel.Size,
+                Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Top,
+                BackColor = Color.FromArgb(64, 64, 64),
+                ForeColor = Color.LightGray,
+                GridLines = true,
+                ListViewItemSorter = columnSorter
+            };
+
+            foreach (var property in plugin.PluginUI.DataGrid.First().GetType().GetProperties())
+            {
+                listView.Columns.Add(property.Name);
+            }
+
+            listView.ColumnClick += (sender, e) =>
+            {
+                if (e.Column == columnSorter.SortColumn)
+                {
+                    // Reverse the current sort direction for this column.
+                    if (columnSorter.Order == SortOrder.Ascending)
+                    {
+                        columnSorter.Order = SortOrder.Descending;
+                    }
+                    else
+                    {
+                        columnSorter.Order = SortOrder.Ascending;
+                    }
+                }
+                else
+                {
+                    // Set the column number that is to be sorted; default to ascending.
+                    columnSorter.SortColumn = e.Column;
+                    columnSorter.Order = SortOrder.Ascending;
+                }
+                listView.Sort();
+            };
+
+            panel.Controls.Add(listView);
+            
+            plugin.PluginUI.DataGrid.CollectionChanged += (sender, e) =>
+            {
+                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add &&
+                e.NewItems != null)
+                {
+                    foreach (var newItem in e.NewItems)
+                    {
+                        ListViewItem newListItem = new();
+                        foreach (var property in newItem.GetType().GetProperties())
+                        {
+                            newListItem.SubItems.Add(property.GetValue(newItem)?.ToString());
+                        }
+                        newListItem.SubItems.RemoveAt(0);
+                        listView.Items.Add(newListItem);
+                    }
+                }
+            };
+            
+            return panel;
+        }
+
+        internal static Panel CreatePluginSettings(IObservatoryPlugin plugin)
+        {
+            Panel panel = new Panel();
+
+            return panel;
+        }
+    }
+}
diff --git a/ObservatoryCore/UI/SettingsPanel.cs b/ObservatoryCore/UI/SettingsPanel.cs
new file mode 100644
index 0000000..36bc925
--- /dev/null
+++ b/ObservatoryCore/UI/SettingsPanel.cs
@@ -0,0 +1,96 @@
+using Observatory.Framework;
+using Observatory.Framework.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Observatory.UI
+{
+    internal class SettingsPanel : Panel
+    {
+        public Label Header;
+        private IObservatoryPlugin _plugin;
+        private Action<Control, CoreForm.AdjustmentDirection> _adjustPanelsBelow;
+
+        internal SettingsPanel(IObservatoryPlugin plugin, Action<Control, CoreForm.AdjustmentDirection> adjustPanelsBelow) : base()
+        {
+            Header = CreateHeader(plugin.Name);
+            _plugin = plugin;
+            _adjustPanelsBelow = adjustPanelsBelow;
+
+            // Filtered to only settings without SettingIgnore attribute
+            var settings = PluginManagement.PluginManager.GetSettingDisplayNames(plugin).Where(s => !Attribute.IsDefined(s.Key, typeof (SettingIgnore)));
+            CreateControls(settings);
+
+        }
+
+        private void CreateControls(IEnumerable<KeyValuePair<PropertyInfo, string>> settings)
+        {
+            int controlRow = 0;
+            bool nextColumn = true;
+
+            // Handle bool (checkbox) settings first and keep them grouped together
+            foreach (var setting in settings.Where(s => s.Key.PropertyType == typeof(bool)))
+            {
+                CheckBox checkBox = new()
+                {
+                    Text = setting.Value,
+                    Checked = (bool?)setting.Key.GetValue(_plugin.Settings) ?? false
+                };
+
+                checkBox.CheckedChanged += (object? _, EventArgs _) =>
+                {
+                    setting.Key.SetValue(_plugin.Settings, checkBox.Checked);
+                    PluginManagement.PluginManager.GetInstance.SaveSettings(_plugin, _plugin.Settings);
+                };
+
+                checkBox.Location = new Point(nextColumn ? 10 : 130, 3 + controlRow * 29);
+                controlRow += nextColumn ? 0 : 1;
+                nextColumn = !nextColumn;
+
+                Controls.Add(checkBox);
+            }
+
+            // Then the rest
+            foreach (var setting in settings.Where(s => s.Key.PropertyType != typeof(bool)))
+            {
+                
+            }
+        }
+
+        private Label CreateHeader(string pluginName)
+        {
+            var headerLabel = new Label()
+            {
+                Text = "❯ " + pluginName,
+                BorderStyle = BorderStyle.FixedSingle,
+                ForeColor = Color.White
+            };
+
+            headerLabel.Click += HeaderLabel_Click;
+
+            return headerLabel;
+        }
+
+        private void HeaderLabel_Click(object? _, EventArgs e)
+        {
+            this.Parent?.SuspendLayout();
+            if (Header.Text[0] == '❯')
+            {
+                Header.Text = Header.Text.Replace('❯', '⌵');
+                this.Visible = true;
+                _adjustPanelsBelow.Invoke(this, CoreForm.AdjustmentDirection.Down);
+            }
+            else
+            {
+                Header.Text = Header.Text.Replace('⌵', '❯');
+                this.Visible = false;
+                _adjustPanelsBelow.Invoke(this, CoreForm.AdjustmentDirection.Up);
+            }
+            this.Parent?.ResumeLayout();
+        }
+    }
+}
diff --git a/ObservatoryCore/UI/TabTemplateSelector.cs b/ObservatoryCore/UI/TabTemplateSelector.cs
deleted file mode 100644
index a9dc4ca..0000000
--- a/ObservatoryCore/UI/TabTemplateSelector.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Controls.Templates;
-using Avalonia.Metadata;
-using Observatory.UI.Views;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Observatory.UI
-{
-    public class TabTemplateSelector : IDataTemplate
-    {
-        public bool SupportsRecycling => false;
-
-        [Content]
-        public Dictionary<string, IDataTemplate> Templates { get; } = new Dictionary<string, IDataTemplate>();
-
-
-        public IControl Build(object param)
-        {
-            return new BasicUIView(); //Templates[param].Build(param);
-        }
-
-        public bool Match(object data)
-        {
-            return data is BasicUIView;
-        }
-    }
-}
diff --git a/ObservatoryCore/UI/UIHelper.cs b/ObservatoryCore/UI/UIHelper.cs
new file mode 100644
index 0000000..116b4d1
--- /dev/null
+++ b/ObservatoryCore/UI/UIHelper.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Observatory.UI
+{
+    internal class UIHelper
+    {
+    }
+}
diff --git a/ObservatoryCore/UI/ViewLocator.cs b/ObservatoryCore/UI/ViewLocator.cs
deleted file mode 100644
index 1b76b96..0000000
--- a/ObservatoryCore/UI/ViewLocator.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Controls.Templates;
-using Observatory.UI.ViewModels;
-using System;
-
-namespace Observatory.UI
-{
-    public class ViewLocator : IDataTemplate
-    {
-        public bool SupportsRecycling => false;
-
-        public IControl Build(object data)
-        {
-            var name = data.GetType().FullName!.Replace("ViewModel", "View");
-            var type = Type.GetType(name);
-
-            if (type != null)
-            {
-                return (Control)Activator.CreateInstance(type)!;
-            }
-            else
-            {
-                return new TextBlock { Text = "Not Found: " + name };
-            }
-        }
-
-        public bool Match(object data)
-        {
-            return data is ViewModelBase;
-        }
-    }
-}
diff --git a/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs b/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
deleted file mode 100644
index e7f472f..0000000
--- a/ObservatoryCore/UI/ViewModels/BasicUIViewModel.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Data;
-using System.Threading.Tasks;
-using System.Collections.ObjectModel;
-using Observatory.UI.Models;
-using ReactiveUI;
-using System.Reactive.Linq;
-using Observatory.Framework;
-using System.Collections.Specialized;
-
-namespace Observatory.UI.ViewModels
-{
-    public class BasicUIViewModel : ViewModelBase
-    {
-        private ObservableCollection<string> _headers;
-        private ObservableCollection<string> _formats;
-        private ObservableCollection<ObservableCollection<object>> _items;
-
-        public System.Collections.IList SelectedItems { get; set; }        
-
-        
-        public ObservableCollection<string> Headers
-        {
-            get => _headers;
-            set
-            {
-                _headers = value;
-                _headers.CollectionChanged += (o, e) => this.RaisePropertyChanged(nameof(Headers));
-                this.RaisePropertyChanged(nameof(Headers));
-            }
-        }
-
-        public ObservableCollection<string> Formats
-        {
-            get => _formats;
-            set
-            {
-                _formats = value;
-                _formats.CollectionChanged += (o, e) => this.RaisePropertyChanged(nameof(Formats));
-                this.RaisePropertyChanged(nameof(Formats));
-            }
-        }
-
-        public ObservableCollection<ObservableCollection<object>> Items
-        {
-            get => _items;
-            set
-            {
-                void raiseItemChanged(object o, NotifyCollectionChangedEventArgs e) { this.RaisePropertyChanged(nameof(Items)); }
-
-                _items = value;
-                _items.CollectionChanged += raiseItemChanged;
-                this.RaisePropertyChanged(nameof(Items));
-                foreach (var itemColumn in value)
-                {
-                    itemColumn.CollectionChanged += raiseItemChanged;
-                }
-            }
-        }
-
-        public BasicUIViewModel(BasicGrid basicGrid)
-        {
-            Headers = basicGrid.Headers;
-            Formats = basicGrid.Formats;
-            Items = basicGrid.Items;
-        }
-
-        private PluginUI.UIType _uiType;
-
-        public PluginUI.UIType UIType
-        {
-            get => _uiType;
-            set
-            {
-                _uiType = value;
-                this.RaisePropertyChanged(nameof(UIType));
-            }
-        }
-    }
-}
diff --git a/ObservatoryCore/UI/ViewModels/CoreViewModel.cs b/ObservatoryCore/UI/ViewModels/CoreViewModel.cs
deleted file mode 100644
index bccdc54..0000000
--- a/ObservatoryCore/UI/ViewModels/CoreViewModel.cs
+++ /dev/null
@@ -1,310 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Data;
-using System.Diagnostics;
-using System.Linq;
-using System.Net.Http;
-using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
-using Observatory.Framework.Interfaces;
-using Observatory.UI.Models;
-using ReactiveUI;
-
-namespace Observatory.UI.ViewModels
-{
-    public class CoreViewModel : ViewModelBase
-    {
-        private readonly ObservableCollection<IObservatoryNotifier> notifiers;
-        private readonly ObservableCollection<IObservatoryWorker> workers;
-        private readonly ObservableCollection<CoreModel> tabs;
-        private string toggleButtonText;
-        private bool _UpdateAvailable;
-        
-        public CoreViewModel(IEnumerable<(IObservatoryWorker plugin, PluginManagement.PluginManager.PluginStatus signed)> workers, IEnumerable<(IObservatoryNotifier plugin, PluginManagement.PluginManager.PluginStatus signed)> notifiers)
-        {
-            _UpdateAvailable = CheckUpdate();
-            
-            this.notifiers = new ObservableCollection<IObservatoryNotifier>(notifiers.Select(p => p.plugin));
-            this.workers = new ObservableCollection<IObservatoryWorker>(workers.Select(p => p.plugin));
-            ToggleButtonText = "Start Monitor";
-            tabs = new ObservableCollection<CoreModel>();
-            
-            foreach(var worker in workers.Select(p => p.plugin))
-            {
-                if (worker.PluginUI.PluginUIType == Framework.PluginUI.UIType.Basic)
-                {
-                    CoreModel coreModel = new();
-                    coreModel.Name = worker.ShortName;
-                    coreModel.UI = new BasicUIViewModel(worker.PluginUI.BasicGrid)
-                    {
-                        UIType = worker.PluginUI.PluginUIType
-                    };
-                    
-                    tabs.Add(coreModel);
-                }
-            }
-
-            foreach(var notifier in notifiers.Select(p => p.plugin))
-            {
-                Panel notifierPanel = new();
-                TextBlock notifierTextBlock = new();
-                notifierTextBlock.Text = notifier.Name;
-                notifierPanel.Children.Add(notifierTextBlock);
-                //tabs.Add(new CoreModel() { Name = notifier.ShortName, UI = (ViewModelBase)notifier.UI });
-            }
-
-            
-            tabs.Add(new CoreModel() { Name = "Core", UI = new BasicUIViewModel(new Framework.BasicGrid()) { UIType = Framework.PluginUI.UIType.Core } });
-
-            if (Properties.Core.Default.StartMonitor)
-                ToggleMonitor();
-            
-            if (Properties.Core.Default.StartReadAll)
-                ReadAll();
-
-        }
-
-        public static void ReadAll()
-        {
-            LogMonitor.GetInstance.ReadAllJournals();
-        }
-
-        public void ToggleMonitor()
-        {
-            var logMonitor = LogMonitor.GetInstance;
-
-            if (logMonitor.IsMonitoring())
-            {
-                logMonitor.Stop();
-                ToggleButtonText = "Start Monitor";
-            }
-            else
-            {
-                logMonitor.Start();
-                ToggleButtonText = "Stop Monitor";
-            }
-        }
-
-        public static void OpenGithub()
-        {
-            ProcessStartInfo githubOpen = new("https://github.com/Xjph/ObservatoryCore");
-            githubOpen.UseShellExecute = true;
-            Process.Start(githubOpen);
-        }
-
-        public static void OpenDonate()
-        {
-            ProcessStartInfo donateOpen = new("https://paypal.me/eliteobservatory");
-            donateOpen.UseShellExecute = true;
-            Process.Start(donateOpen);
-        }
-
-        public static void GetUpdate()
-        {
-            ProcessStartInfo githubOpen = new("https://github.com/Xjph/ObservatoryCore/releases");
-            githubOpen.UseShellExecute = true;
-            Process.Start(githubOpen);
-        }
-
-        public async void ExportGrid()
-        {
-            try
-            {
-                var exportFolder = Properties.Core.Default.ExportFolder;
-
-                if (string.IsNullOrEmpty(exportFolder))
-                {
-                    exportFolder = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
-                }
-
-                OpenFolderDialog openFolderDialog = new()
-                {
-                    Directory = exportFolder
-                };
-
-                var application = (IClassicDesktopStyleApplicationLifetime)Avalonia.Application.Current.ApplicationLifetime;
-
-                var selectedFolder = await openFolderDialog.ShowAsync(application.MainWindow);
-
-                if (!string.IsNullOrEmpty(selectedFolder))
-                {
-                    Properties.Core.Default.ExportFolder = selectedFolder;
-                    Properties.Core.Default.Save();
-                    exportFolder = selectedFolder;
-
-                    foreach (var tab in tabs.Where(t => t.Name != "Core"))
-                    {
-                        var ui = (BasicUIViewModel)tab.UI;
-                        List<object> selectedData;
-                        bool specificallySelected = ui.SelectedItems?.Count > 1;
-
-                        if (specificallySelected)
-                        {
-                            selectedData = new();
-
-                            foreach (var item in ui.SelectedItems)
-                                selectedData.Add(item);
-                        }
-                        else
-                        {
-                            selectedData = new(); // TODO: Make this work in new UI
-                        }
-
-                        var columns = selectedData[0].GetType().GetProperties();
-                        Dictionary<string, int> colSize = new();
-                        Dictionary<string, List<string>> colContent = new();
-
-                        foreach (var column in columns)
-                        {
-                            colSize.Add(column.Name, 0);
-                            colContent.Add(column.Name, new());
-                        }
-
-                        foreach (var line in selectedData)
-                        {
-                            var lineType = line.GetType(); // some plugins have different line types, so don't move this out of loop
-                            foreach (var column in colContent)
-                            {
-                                var cellValue = lineType.GetProperty(column.Key)?.GetValue(line)?.ToString() ?? string.Empty;
-                                column.Value.Add(cellValue);
-                                if (colSize[column.Key] < cellValue.Length)
-                                    colSize[column.Key] = cellValue.Length;
-                            }
-                        }
-
-                        System.Text.StringBuilder exportData = new();
-
-
-                        foreach (var colTitle in colContent.Keys)
-                        {
-                            if (colSize[colTitle] < colTitle.Length)
-                                colSize[colTitle] = colTitle.Length;
-
-                            exportData.Append(colTitle.PadRight(colSize[colTitle]) + "  ");
-                        }
-                        exportData.AppendLine();
-
-                        for (int i = 0; i < colContent.First().Value.Count; i++)
-                        {
-                            foreach (var column in colContent)
-                            {
-                                if (column.Value[i].Length > 0 && !char.IsNumber(column.Value[i][0]) && column.Value[i].Count(char.IsLetter) / (float)column.Value[i].Length > 0.25)
-                                    exportData.Append(column.Value[i].PadRight(colSize[column.Key]) + "  ");
-                                else
-                                    exportData.Append(column.Value[i].PadLeft(colSize[column.Key]) + "  ");
-                            }
-                            exportData.AppendLine();
-                        }
-
-                        string exportPath = $"{exportFolder}{System.IO.Path.DirectorySeparatorChar}Observatory Export - {DateTime.UtcNow:yyyyMMdd-HHmmss} - {tab.Name}.txt";
-
-                        System.IO.File.WriteAllText(exportPath, exportData.ToString());
-                    }
-                }
-            }
-            catch (Exception e)
-            {
-                ObservatoryCore.LogError(e, "while exporting data");
-                ErrorReporter.ShowErrorPopup("Error encountered!",
-                    new List<(string, string)> { ("An error occurred while exporting; output may be missing or incomplete." + Environment.NewLine +
-                    "Please check the error log (found in your Documents folder) for more details and visit our discord to report it.", e.Message) });
-            }
-        }
-
-        public void ClearGrid()
-        {
-            foreach (var tab in tabs.Where(t => t.Name != "Core"))
-            {
-                var ui = (BasicUIViewModel)tab.UI;
-
-                ui.Items.Clear();
-
-                // For some reason UIType's change event will properly
-                // redraw the grid, not BasicUIGrid's.
-                ui.RaisePropertyChanged(nameof(ui.UIType));
-            }
-        }
-
-        public string ToggleButtonText
-        {
-            get => toggleButtonText;
-            set
-            {
-                if (toggleButtonText != value)
-                {
-                    toggleButtonText = value;
-                    this.RaisePropertyChanged(nameof(ToggleButtonText));
-                }
-            }
-        }
-
-        public ObservableCollection<IObservatoryWorker> Workers
-        {
-            get { return workers; }
-        }
-
-        public ObservableCollection<IObservatoryNotifier> Notifiers
-        {
-            get { return notifiers; }
-        }
-
-        public ObservableCollection<CoreModel> Tabs
-        {
-            get { return tabs; }
-        }
-
-        private static bool CheckUpdate()
-        {
-            try
-            {
-                string releasesResponse;
-
-                var request = new HttpRequestMessage
-                {
-                    Method = HttpMethod.Get,
-                    RequestUri = new Uri("https://api.github.com/repos/xjph/ObservatoryCore/releases"),
-                    Headers = { { "User-Agent", "Xjph/ObservatoryCore" } }
-                };
-
-                releasesResponse = HttpClient.SendRequest(request).Content.ReadAsStringAsync().Result;
-
-                if (!string.IsNullOrEmpty(releasesResponse))
-                {
-                    var releases = System.Text.Json.JsonDocument.Parse(releasesResponse).RootElement.EnumerateArray();
-
-                    foreach (var release in releases)
-                    {
-                        var tag = release.GetProperty("tag_name").ToString();
-                        var verstrings = tag[1..].Split('.');
-                        var ver = verstrings.Select(verString => { _ = int.TryParse(verString, out int ver); return ver; }).ToArray();
-                        if (ver.Length == 4)
-                        {
-                            Version version = new(ver[0], ver[1], ver[2], ver[3]);
-                            if (version > System.Reflection.Assembly.GetEntryAssembly().GetName().Version)
-                            {
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-            catch
-            {
-                return false;
-            }
-
-            return false;
-        }
-
-        private bool UpdateAvailable
-        {
-            get => _UpdateAvailable;
-            set
-            {
-                this.RaiseAndSetIfChanged(ref _UpdateAvailable, value);
-            }
-        }
-
-    }
-}
diff --git a/ObservatoryCore/UI/ViewModels/MainWindowViewModel.cs b/ObservatoryCore/UI/ViewModels/MainWindowViewModel.cs
deleted file mode 100644
index 89ccdd9..0000000
--- a/ObservatoryCore/UI/ViewModels/MainWindowViewModel.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Observatory.UI.ViewModels
-{
-    public class MainWindowViewModel : ViewModelBase
-    {
-        public MainWindowViewModel(PluginManagement.PluginManager pluginManager)
-        {
-            core = new CoreViewModel(pluginManager.workerPlugins, pluginManager.notifyPlugins);
-
-            if (pluginManager.errorList.Any())
-                ErrorReporter.ShowErrorPopup("Plugin Load Error", pluginManager.errorList);
-        }
-
-        public CoreViewModel core { get; }
-    }
-}
diff --git a/ObservatoryCore/UI/ViewModels/NotificationViewModel.cs b/ObservatoryCore/UI/ViewModels/NotificationViewModel.cs
deleted file mode 100644
index f2aa0da..0000000
--- a/ObservatoryCore/UI/ViewModels/NotificationViewModel.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Observatory.Framework;
-
-namespace Observatory.UI.ViewModels
-{
-    public class NotificationViewModel : ViewModelBase
-    {
-        public NotificationViewModel(NotificationArgs notificationArgs)
-        {
-
-            Notification = new()
-            {
-                Title = notificationArgs.Title,
-                Detail = notificationArgs.Detail,
-                Timeout = notificationArgs.Timeout,
-                XPos = notificationArgs.XPos,
-                YPos = notificationArgs.YPos,
-                Colour = Avalonia.Media.Color.FromUInt32(Properties.Core.Default.NativeNotifyColour).ToString()
-            };
-            
-        }
-
-        public Models.NotificationModel Notification { get; set; }
-    }
-}
diff --git a/ObservatoryCore/UI/ViewModels/ViewModelBase.cs b/ObservatoryCore/UI/ViewModels/ViewModelBase.cs
deleted file mode 100644
index 3d2314a..0000000
--- a/ObservatoryCore/UI/ViewModels/ViewModelBase.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using ReactiveUI;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Observatory.UI.ViewModels
-{
-    public class ViewModelBase : ReactiveObject
-    {
-    }
-}
diff --git a/ObservatoryCore/UI/Views/BasicUIView.axaml b/ObservatoryCore/UI/Views/BasicUIView.axaml
deleted file mode 100644
index e97c7d1..0000000
--- a/ObservatoryCore/UI/Views/BasicUIView.axaml
+++ /dev/null
@@ -1,10 +0,0 @@
-<UserControl xmlns="https://github.com/avaloniaui"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
-             x:Class="Observatory.UI.Views.BasicUIView">
-  <Panel Name="UIPanel">
-
-  </Panel>
-</UserControl>
diff --git a/ObservatoryCore/UI/Views/BasicUIView.axaml.cs b/ObservatoryCore/UI/Views/BasicUIView.axaml.cs
deleted file mode 100644
index 403b61d..0000000
--- a/ObservatoryCore/UI/Views/BasicUIView.axaml.cs
+++ /dev/null
@@ -1,1259 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Data;
-using Avalonia.Markup.Xaml;
-using System.Text.RegularExpressions;
-using Observatory.Framework;
-using Observatory.Framework.Interfaces;
-using System.Linq;
-using Avalonia.Interactivity;
-using Avalonia.VisualTree;
-using System;
-using System.Collections.ObjectModel;
-using System.Collections.Generic;
-using Avalonia.Media;
-using Avalonia.Controls.ApplicationLifetimes;
-using System.Runtime.InteropServices;
-using System.IO;
-using Avalonia.Platform.Storage;
-
-namespace Observatory.UI.Views
-{
-    public class BasicUIView : UserControl
-    {
-        private DataGrid dataGrid;
-        private NativeNotification.NativePopup nativePopup;
-
-        public BasicUIView()
-        {
-            InitializeComponent();
-            nativePopup = new();
-
-            this.DetachedFromVisualTree += (o, e) =>
-            {
-                nativePopup.CloseAll();
-            };
-        }
-
-        private void InitializeComponent()
-        {
-            AvaloniaXamlLoader.Load(this);
-        }
-
-        public static readonly DirectProperty<BasicUIView, PluginUI.UIType> UITypeProperty =
-            AvaloniaProperty.RegisterDirect<BasicUIView, PluginUI.UIType>(
-                nameof(UIType),
-                o => o.UIType,
-                (o, v) => o.UIType = v,
-                PluginUI.UIType.None,
-                BindingMode.OneWay
-            );
-
-        public PluginUI.UIType UIType 
-        { 
-            get
-            {
-                return _uitype;
-            }
-            set
-            {
-                _uitype = value;
-                UITypeChange();
-            }
-        }
-
-        private PluginUI.UIType _uitype;
-        
-
-        private void ColumnGeneration(object sender, DataGridAutoGeneratingColumnEventArgs e)
-        {
-            e.Column.Header = SplitCamelCase(e.PropertyName);
-            e.Column.CanUserReorder = true;
-            e.Column.CanUserResize = true;
-            e.Column.CanUserSort = true;
-        }
-
-        private void UITypeChange()
-        {
-            var uiPanel = this.Find<Panel>("UIPanel");
-            dataGrid = null;
-
-            switch (UIType)
-            {
-                case PluginUI.UIType.None:
-                    break;
-                case PluginUI.UIType.Basic:
-                    dataGrid = new()
-                    {
-                        [!DataGrid.ItemsProperty] = new Binding("Items"),
-                        SelectionMode = DataGridSelectionMode.Extended,
-                        GridLinesVisibility = DataGridGridLinesVisibility.Vertical,
-                        IsReadOnly = true
-                    };
-                    dataGrid.AutoGeneratingColumn += ColumnGeneration;
-                    dataGrid.DataContextChanged += OnDataContextSet;
-                    dataGrid.SelectionChanged += OnSelectionChanged;
-                    uiPanel.Children.Clear();
-                    uiPanel.Children.Add(dataGrid);
-                    break;
-                case PluginUI.UIType.Avalonia:
-                    //TODO: Implement plugins with full Avalonia UI.
-                    throw new NotImplementedException();
-                case PluginUI.UIType.Core:
-                    uiPanel.Children.Clear();
-                    ScrollViewer scrollViewer = new();
-                    scrollViewer.Content = GenerateCoreUI();
-                    uiPanel.Children.Add(scrollViewer);
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
-        {
-            ((Observatory.UI.ViewModels.BasicUIViewModel)dataGrid.DataContext).SelectedItems = dataGrid.SelectedItems;
-
-        }
-
-        private void OnDataContextSet(object sender, EventArgs e)
-        {
-            if (UIType != PluginUI.UIType.Basic || !(sender is DataGrid)) return;
-            dataGrid = (DataGrid)sender;
-            if (dataGrid.DataContext != null)
-            {
-                var dataContext = ((ViewModels.BasicUIViewModel)dataGrid.DataContext).BasicUIGrid;
-                dataContext.CollectionChanged += ScrollToLast;
-            }
-        }
-
-        private void ScrollToLast(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
-        {
-            // Only trigger on adds.
-            if (e.Action != System.Collections.Specialized.NotifyCollectionChangedAction.Add || UIType != PluginUI.UIType.Basic || dataGrid == null || !(sender is ObservableCollection<object>))
-                return;
-            var dataContext = (ObservableCollection<object>)sender;
-            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-            {
-                dataGrid.ScrollIntoView(dataContext[dataContext.Count - 1], null);
-            });
-        }
-
-        private Grid GenerateCoreUI()
-        {
-            Grid corePanel = new();
-
-            ColumnDefinitions columns = new()
-            {
-                new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Auto) },
-                new ColumnDefinition() { Width = new GridLength(300) },
-                new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Auto) }
-            };
-            corePanel.ColumnDefinitions = columns;
-
-            SettingGridManager gridManager = new(corePanel);
-
-            var pluginManager = PluginManagement.PluginManager.GetInstance;
-
-            #region Native Settings
-
-            #region Plugin List
-            DataGrid pluginList = new() { Margin = new Thickness(0, 20, 0, 0) };
-
-            pluginList.Columns.Add(new DataGridTextColumn()
-            {
-                Header = "Plugin",
-                Binding = new Binding("Name")
-            });
-
-            pluginList.Columns.Add(new DataGridTextColumn()
-            {
-                Header = "Types",
-                Binding = new Binding("TypesString")
-            });
-
-            pluginList.Columns.Add(new DataGridTextColumn()
-            {
-                Header = "Version",
-                Binding = new Binding("Version")
-            });
-
-            pluginList.Columns.Add(new DataGridTextColumn()
-            {
-                Header = "Status",
-                Binding = new Binding("Status")
-            });
-
-            Dictionary<IObservatoryPlugin, PluginView> uniquePlugins = new();
-            foreach (var (plugin, signed) in pluginManager.workerPlugins)
-            {
-                if (!uniquePlugins.ContainsKey(plugin))
-                {
-                    uniquePlugins.Add(plugin,
-                        new PluginView() { Name = plugin.Name, Types = new() { "Worker" }, Version = plugin.Version, Status = GetStatusText(signed) });
-                }
-            }
-
-            foreach (var (plugin, signed) in pluginManager.notifyPlugins)
-            {
-                if (!uniquePlugins.ContainsKey(plugin))
-                {
-                    uniquePlugins.Add(plugin,
-                        new PluginView() { Name = plugin.Name, Types = new() { "Notifier" }, Version = plugin.Version, Status = GetStatusText(signed) });
-                }
-                else
-                {
-                    uniquePlugins[plugin].Types.Add("Notifier");
-                }
-            }
-
-            pluginList.Items = uniquePlugins.Values;
-            gridManager.AddSetting(pluginList);
-
-            Button pluginFolderButton = new()
-            {
-                Content = "Open Plugin Folder",
-                Height = 30,
-                Width = 150,
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center,
-                Margin = new Thickness(0, 0, 0, 20)
-            };
-
-            pluginFolderButton.Click += (object sender, RoutedEventArgs e) =>
-            {
-                string pluginDir = AppDomain.CurrentDomain.BaseDirectory + "plugins";
-                
-                if (!Directory.Exists(pluginDir))
-                {
-                    Directory.CreateDirectory(pluginDir);
-                }
-
-                var fileExplorerInfo = new System.Diagnostics.ProcessStartInfo() { FileName = pluginDir, UseShellExecute = true };
-                System.Diagnostics.Process.Start(fileExplorerInfo);
-            };
-
-            gridManager.AddSetting(pluginFolderButton);
-
-            #endregion
-
-            #region Popup Notification settings
-
-            Expander notificationExpander = new()
-            {
-                Header = "Popup Notifications",
-                DataContext = Properties.Core.Default,
-                Margin = new Thickness(0, 0)
-            };
-
-            Grid notificationGrid = new() { Margin = new Thickness(10, 10) };
-
-            notificationGrid.ColumnDefinitions = new()
-            {
-                new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Star) },
-                new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) },
-                new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) }
-            };
-
-            notificationGrid.RowDefinitions = new();
-
-            SettingGridManager notificationGridManager = new(notificationGrid);
-
-            TextBlock nativeNotifyLabel = new() { Text = "Enabled" };
-
-            CheckBox nativeNotifyCheckbox = new() { IsChecked = Properties.Core.Default.NativeNotify, Content = nativeNotifyLabel };
-
-            nativeNotifyCheckbox.Checked += (object sender, RoutedEventArgs e) =>
-            {
-                Properties.Core.Default.NativeNotify = true;
-                Properties.Core.Default.Save();
-            };
-
-            nativeNotifyCheckbox.Unchecked += (object sender, RoutedEventArgs e) =>
-            {
-                Properties.Core.Default.NativeNotify = false;
-                Properties.Core.Default.Save();
-            };
-            
-            Button notifyTestButton = new()
-            { 
-                Content = "Test",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right
-            };
-
-            notifyTestButton.Click += (object sender, RoutedEventArgs e) =>
-            {
-                Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-                {
-                    var notificationArgs = new NotificationArgs()
-                    {
-                        Title = "Test Notification",
-                        Detail = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras suscipit hendrerit libero ac scelerisque."
-                    };
-                    
-                    nativePopup.InvokeNativeNotification(notificationArgs);
-                });
-            };
-
-            TextBlock notifyFontLabel = new() 
-            { 
-                Text = "Font: ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-            ComboBox notifyFontDropDown = new()
-            {
-                MinWidth = 200
-            };
-
-            notifyFontDropDown.Items = new System.Drawing.Text.InstalledFontCollection().Families.Select(font => font.Name);
-
-            if (Properties.Core.Default.NativeNotifyFont.Length > 0)
-            {
-                notifyFontDropDown.SelectedItem = Properties.Core.Default.NativeNotifyFont;
-            }
-
-            notifyFontDropDown.SelectionChanged += (object sender, SelectionChangedEventArgs e) =>
-            {
-                var comboBox = (ComboBox)sender;
-                Properties.Core.Default.NativeNotifyFont = comboBox.SelectedItem.ToString();
-                Properties.Core.Default.Save();
-            };
-            
-            TextBlock monitorLabel = new()
-            {
-                Text = "Display: ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-            ComboBox monitorDropDown = new()
-            { 
-                MinWidth = 200
-            };
-
-            List<string> displays = new();
-            displays.Add("Primary");
-
-            var application = (IClassicDesktopStyleApplicationLifetime)Application.Current.ApplicationLifetime;
-            var screens = application.MainWindow.Screens.All;
-            
-            if (screens.Count > 1)
-                for (int i = 0; i < screens.Count; i++)
-                {
-                    displays.Add((i + 1).ToString());
-                }
-
-            monitorDropDown.Items = displays;
-
-            if (Properties.Core.Default.NativeNotifyScreen == -1)
-            {
-                monitorDropDown.SelectedItem = "Primary";
-            }
-            else
-            {
-                monitorDropDown.SelectedItem = (Properties.Core.Default.NativeNotifyScreen).ToString();
-            }
-
-            monitorDropDown.SelectionChanged += (object sender, SelectionChangedEventArgs e) =>
-            {
-                
-                var comboBox = (ComboBox)sender;
-                string selectedItem = comboBox.SelectedItem.ToString();
-                int selectedScreen = selectedItem == "Primary" ? -1 : Int32.Parse(selectedItem);
-                
-                Properties.Core.Default.NativeNotifyScreen = selectedScreen;
-                Properties.Core.Default.Save();
-            };
-
-            TextBlock cornerLabel = new()
-            {
-                Text = "Corner: ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-            ComboBox cornerDropDown = new()
-            {
-                MinWidth = 200
-            };
-
-            List<string> corners = new()
-            {
-                "Bottom-Right",
-                "Bottom-Left",
-                "Top-Right",
-                "Top-Left"
-            };
-
-            cornerDropDown.Items = corners;
-
-            cornerDropDown.SelectedItem = corners[Properties.Core.Default.NativeNotifyCorner];
-
-            cornerDropDown.SelectionChanged += (object sender, SelectionChangedEventArgs e) =>
-            {
-                var comboBox = (ComboBox)sender;
-                Properties.Core.Default.NativeNotifyCorner = comboBox.SelectedIndex;
-                Properties.Core.Default.Save();
-            };
-
-            TextBlock colourLabel = new()
-            {
-                Text = "Colour: ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-
-            BrushConverter brushConverter = new();
-
-            Egorozh.ColorPicker.Dialog.ColorPickerButton colourPickerButton = new()
-            {
-                Width = 25,
-                Height = 25,
-                Color = Color.FromUInt32(Properties.Core.Default.NativeNotifyColour),
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left
-                
-            };
-
-            colourPickerButton.PropertyChanged += (object sender, AvaloniaPropertyChangedEventArgs e) =>
-            {
-                if (e.Property.Name == "Color")
-                {
-                    Properties.Core.Default.NativeNotifyColour = ((Color)e.NewValue).ToUint32();
-                    Properties.Core.Default.Save();
-                }
-            };
-
-            TextBlock scaleLabel = new()
-            {
-                Text = "Scale (%): ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-
-            NumericUpDown scaleSpinner = new() 
-            { 
-                Value = Properties.Core.Default.NativeNotifyScale, 
-                AllowSpin = true,
-                Minimum = 1,
-                Maximum = 1000,
-                Increment = 1,
-                Width = 200,
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left
-            };
-
-            scaleSpinner.ValueChanged += (object sender, NumericUpDownValueChangedEventArgs e) =>
-            {
-                Properties.Core.Default.NativeNotifyScale = Convert.ToInt32(e.NewValue);
-                Properties.Core.Default.Save();
-            };
-
-            TextBlock timeoutLabel = new()
-            {
-                Text = "Duration (ms): ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-
-            NumericUpDown timeoutSpinner = new()
-            {
-                Value = Properties.Core.Default.NativeNotifyTimeout,
-                AllowSpin = true,
-                Minimum = 1,
-                Maximum = 3600000,
-                Increment = 1,
-                Width = 200,
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left
-            };
-
-            timeoutSpinner.ValueChanged += (object sender, NumericUpDownValueChangedEventArgs e) =>
-            {
-                Properties.Core.Default.NativeNotifyTimeout = Convert.ToInt32(e.NewValue);
-                Properties.Core.Default.Save();
-            };
-
-            notificationGridManager.AddSettingWithLabel(monitorLabel, monitorDropDown);
-            notificationGridManager.AddSettingWithLabel(cornerLabel, cornerDropDown);
-            notificationGridManager.AddSettingWithLabel(notifyFontLabel, notifyFontDropDown);
-            notificationGridManager.AddSettingWithLabel(scaleLabel, scaleSpinner);
-            notificationGridManager.AddSettingWithLabel(timeoutLabel, timeoutSpinner);
-            notificationGridManager.AddSettingWithLabel(colourLabel, colourPickerButton);
-            notificationGridManager.AddSettingSameLine(notifyTestButton);
-            notificationGridManager.AddSetting(nativeNotifyCheckbox);
-
-            notificationExpander.Content = notificationGrid;
-            
-            gridManager.AddSetting(notificationExpander);
-
-            #endregion
-
-            #region Voice Notification Settings
-
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
-            {
-
-                Expander voiceExpander = new()
-                {
-                    Header = "Voice Notifications",
-                    DataContext = Properties.Core.Default,
-                    Margin = new Thickness(0, 0)
-                };
-
-                Grid voiceGrid = new() { Margin = new Thickness(10, 10) };
-                SettingGridManager voiceGridManager = new(voiceGrid);
-
-                voiceGrid.ColumnDefinitions = new()
-                {
-                    new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Star) },
-                    new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) },
-                    new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) }
-                };
-
-                TextBlock voiceLabel = new() { Text = "Enabled" };
-
-                CheckBox voiceCheckbox = new() { IsChecked = Properties.Core.Default.VoiceNotify, Content = voiceLabel };
-
-                voiceCheckbox.Checked += (object sender, RoutedEventArgs e) =>
-                {
-                    Properties.Core.Default.VoiceNotify = true;
-                    Properties.Core.Default.Save();
-                };
-
-                voiceCheckbox.Unchecked += (object sender, RoutedEventArgs e) =>
-                {
-                    Properties.Core.Default.VoiceNotify = false;
-                    Properties.Core.Default.Save();
-                };
-
-                Button voiceTestButton = new()
-                {
-                    Content = "Test",
-                    HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right
-                };
-
-                voiceTestButton.Click += (object sender, RoutedEventArgs e) =>
-                {
-                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Properties.Core.Default.VoiceSelected.Length > 0)
-                    {
-                        List<string> harvardSentences = new() 
-                        {
-                            "Oak is strong and also gives shade.",
-                            "Cats and dogs each hate the other.",
-                            "The pipe began to rust while new.",
-                            "Open the crate but don't break the glass.",
-                            "Add the sum to the product of these three.",
-                            "Thieves who rob friends deserve jail.",
-                            "The ripe taste of cheese improves with age.",
-                            "Act on these orders with great speed.",
-                            "The hog crawled under the high fence.",
-                            "Move the vat over the hot fire."
-                        };
-
-                        NotificationArgs args = new()
-                        {
-                            Title = "Speech Synthesis Test",
-                            TitleSsml = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name=\"\">Speech Synthesis Test</voice></speak>",
-                            Detail = harvardSentences.OrderBy(s => new Random().NextDouble()).First()
-                        };
-                        
-                        new NativeNotification.NativeVoice().EnqueueAndAnnounce(args);
-
-                    }
-                };
-
-                TextBlock voiceSelectionLabel = new()
-                {
-                    Text = "Voice: ",
-                    HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                    VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-                };
-                ComboBox voiceSelectionDropDown = new()
-                {
-                    MinWidth = 200
-                };
-
-                var voices = new System.Speech.Synthesis.SpeechSynthesizer().GetInstalledVoices();
-                voiceSelectionDropDown.Items = voices.Select(v => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? v.VoiceInfo.Name : string.Empty);
-
-                if (Properties.Core.Default.VoiceSelected.Length > 0)
-                {
-                    voiceSelectionDropDown.SelectedItem = Properties.Core.Default.VoiceSelected;
-                }
-
-                voiceSelectionDropDown.SelectionChanged += (object sender, SelectionChangedEventArgs e) =>
-                {
-                    var comboBox = (ComboBox)sender;
-                    Properties.Core.Default.VoiceSelected = comboBox.SelectedItem.ToString();
-                    Properties.Core.Default.Save();
-                };
-
-                TextBlock voiceVolumeLabel = new()
-                {
-                    Text = "Volume: ",
-                    HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                    VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-                };
-
-                Slider voiceVolume = new()
-                {
-                    Value = Properties.Core.Default.VoiceVolume,
-                    Height = 40,
-                    Width = 300,
-                    Minimum = 0,
-                    Maximum = 100,
-                    Padding = new Thickness(0,0,0,20),
-                    VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-                };
-                
-                voiceVolume.PropertyChanged += (object sender, AvaloniaPropertyChangedEventArgs e) =>
-                {
-                    if (e.Property == Slider.ValueProperty)
-                    {
-                        Properties.Core.Default.VoiceVolume = Convert.ToInt32(e.NewValue);
-                        Properties.Core.Default.Save();
-                    }
-                };
-
-                TextBlock voiceRateLabel = new()
-                {
-                    Text = "Speed: ",
-                    HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                    VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-                };
-
-                Slider voiceRate = new()
-                {
-                    Value = Properties.Core.Default.VoiceRate,
-                    Height = 40,
-                    Width = 300,
-                    Minimum = -10,
-                    Maximum = 10,
-                    Padding = new Thickness(0, 0, 0, 20),
-                    VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-                };
-
-                voiceRate.PropertyChanged += (object sender, AvaloniaPropertyChangedEventArgs e) =>
-                {
-                    if (e.Property == Slider.ValueProperty)
-                    {
-                        Properties.Core.Default.VoiceRate = Convert.ToInt32(e.NewValue);
-                        Properties.Core.Default.Save();
-                    }
-                };
-
-                voiceGridManager.AddSettingWithLabel(voiceVolumeLabel, voiceVolume);
-                voiceGridManager.AddSettingWithLabel(voiceRateLabel, voiceRate);
-                voiceGridManager.AddSettingWithLabel(voiceSelectionLabel, voiceSelectionDropDown);
-                voiceGridManager.AddSetting(voiceCheckbox);
-                voiceGridManager.AddSettingSameLine(voiceTestButton);
-                
-                voiceExpander.Content = voiceGrid;
-
-                gridManager.AddSetting(voiceExpander);
-            }
-            #endregion
-
-            #region Export options
-
-            Expander exportExpander = new()
-            {
-                Header = "Export Options",
-                DataContext = Properties.Core.Default,
-                Margin = new Thickness(0, 0)
-            };
-
-            Grid exportGrid = new() { Margin = new Thickness(10, 10) };
-            SettingGridManager exportGridManager = new(exportGrid);
-
-            exportGrid.ColumnDefinitions = new()
-            {
-                new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Star) },
-                new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) },
-                new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) }
-            };
-
-            TextBlock exportStyleLabel = new()
-            {
-                Text = "Export style: ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-            ComboBox exportStyleDropDown = new()
-            {
-                MinWidth = 200
-            };
-
-            exportStyleDropDown.Items = new List<string>() {
-                    "Fixed width",
-                    "Tab separated",
-                };
-
-            if (Properties.Core.Default.ExportStyle.Length > 0)
-            {
-                exportStyleDropDown.SelectedItem = Properties.Core.Default.ExportStyle;
-            }
-
-            exportStyleDropDown.SelectionChanged += (object sender, SelectionChangedEventArgs e) =>
-            {
-                var comboBox = (ComboBox)sender;
-                Properties.Core.Default.ExportStyle = comboBox.SelectedItem.ToString();
-                Properties.Core.Default.Save();
-            };
-
-            TextBlock exportPathLabel = new()
-            {
-                Text = "Export Path: ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-
-            TextBox exportPath = new()
-            {
-                Text = Properties.Core.Default.ExportFolder
-            };
-
-            Button exportBrowse = new()
-            {
-                Content = "Browse",
-                Height = 30,
-                Width = 100,
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center
-            };
-
-            exportBrowse.Click += (object source, RoutedEventArgs e) =>
-            {
-                OpenFolderDialog openFolderDialog = new()
-                {
-                    Directory = exportPath.Text
-                };
-                var browseTask = openFolderDialog.ShowAsync((Window)((Button)source).GetVisualRoot());
-                browseTask.ContinueWith((task) =>
-                {
-                    string path = task.Result;
-                    if (path != string.Empty)
-                    {
-                        Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => { exportPath.Text = path; });
-                        Properties.Core.Default.ExportFolder = path;
-                        Properties.Core.Default.Save();
-                    }
-                });
-            };
-
-            exportPath.LostFocus += (object sender, RoutedEventArgs e) =>
-            {
-                if (System.IO.Directory.Exists(exportPath.Text))
-                {
-                    Properties.Core.Default.ExportFolder = exportPath.Text;
-                    Properties.Core.Default.Save();
-                }
-            };
-
-            exportGridManager.AddSettingWithLabel(exportStyleLabel, exportStyleDropDown);
-            exportGridManager.AddSettingWithLabel(exportPathLabel, exportPath);
-            exportGridManager.AddSetting(exportBrowse);
-
-            exportExpander.Content = exportGrid;
-
-            gridManager.AddSetting(exportExpander);
-            #endregion
-
-            #region System Context Priming setting
-
-            TextBlock primeSystemContextLabel = new() { Text = "Try re-load current system information when starting monitor" };
-            CheckBox primeSystemContexCheckbox = new() { IsChecked = Properties.Core.Default.TryPrimeSystemContextOnStartMonitor, Content = primeSystemContextLabel };
-
-            primeSystemContexCheckbox.Checked += (object sender, RoutedEventArgs e) =>
-            {
-                Properties.Core.Default.TryPrimeSystemContextOnStartMonitor = true;
-                Properties.Core.Default.Save();
-            };
-
-            primeSystemContexCheckbox.Unchecked += (object sender, RoutedEventArgs e) =>
-            {
-                Properties.Core.Default.TryPrimeSystemContextOnStartMonitor = false;
-                Properties.Core.Default.Save();
-            };
-
-            #endregion
-
-            #region Actions On Launch
-
-            TextBlock startMonitorLabel = new() { Text = "Start monitor on Observatory launch" };
-            CheckBox startMonitorCheckbox = new() { IsChecked = Properties.Core.Default.StartMonitor, Content = startMonitorLabel };
-
-            startMonitorCheckbox.Checked += (object sender, RoutedEventArgs e) =>
-            {
-                Properties.Core.Default.StartMonitor = true;
-                Properties.Core.Default.Save();
-            };
-
-            startMonitorCheckbox.Unchecked += (object sender, RoutedEventArgs e) =>
-            {
-                Properties.Core.Default.StartMonitor = false;
-                Properties.Core.Default.Save();
-            };
-
-            TextBlock startReadAllLabel = new() { Text = "Read All on Observatory launch" };
-            CheckBox startReadAllCheckbox = new() { IsChecked = Properties.Core.Default.StartReadAll, Content = startReadAllLabel };
-
-            startReadAllCheckbox.Checked += (object sender, RoutedEventArgs e) =>
-            {
-                Properties.Core.Default.StartReadAll = true;
-                Properties.Core.Default.Save();
-            };
-
-            startReadAllCheckbox.Unchecked += (object sender, RoutedEventArgs e) =>
-            {
-                Properties.Core.Default.StartReadAll = false;
-                Properties.Core.Default.Save();
-            };
-
-            #endregion
-
-            #endregion
-
-            #region Journal Location
-            TextBlock journalPathLabel = new()
-            {
-                Text = "Journal Path: ",
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
-            };
-
-            TextBox journalPath = new()
-            {
-                Text = Properties.Core.Default.JournalFolder
-            };
-
-            Button journalBrowse = new()
-            {
-                Content = "Browse",
-                Height = 30,
-                Width = 100,
-                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
-                HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center
-            };
-            
-            journalBrowse.Click += (object source, RoutedEventArgs e) => 
-            {
-                OpenFolderDialog openFolderDialog = new()
-                {
-                    Directory = journalPath.Text
-                };
-                var browseTask = openFolderDialog.ShowAsync((Window)((Button)source).GetVisualRoot());
-                browseTask.ContinueWith((task) => 
-                {
-                    string path = task.Result;
-                    if (path != string.Empty)
-                    {
-                        Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => { journalPath.Text = path; });
-                        Properties.Core.Default.JournalFolder = path;
-                        Properties.Core.Default.Save();
-                    }
-                });
-            };
-
-            journalPath.LostFocus += (object sender, RoutedEventArgs e) =>
-            {
-                if (System.IO.Directory.Exists(journalPath.Text))
-                {
-                    Properties.Core.Default.JournalFolder = journalPath.Text;
-                    Properties.Core.Default.Save();
-                }
-            };
-
-
-            #endregion
-
-            
-
-            #region Plugin Settings
-
-            foreach(var plugin in uniquePlugins.Keys)
-            {
-                GeneratePluginSettingUI(corePanel, plugin);
-            }
-
-            #endregion
-
-            gridManager.AddSetting(primeSystemContexCheckbox);
-            gridManager.AddSetting(startMonitorCheckbox);
-            gridManager.AddSetting(startReadAllCheckbox);
-            gridManager.AddSettingWithLabel(journalPathLabel, journalPath);
-            gridManager.AddSetting(journalBrowse);
-
-            return corePanel;
-        }
-
-        private void GeneratePluginSettingUI(Grid gridPanel, IObservatoryPlugin plugin)
-        {
-            var displayedSettings = PluginManagement.PluginManager.GetSettingDisplayNames(plugin.Settings);
-
-            if (displayedSettings.Count > 0)
-            {
-                Expander expander = new()
-                {
-                    Header = plugin.Name,
-                    DataContext = plugin.Settings,
-                    Margin = new Thickness(0, 0)
-                };
-
-                Grid settingsGrid = new() { Margin = new Thickness(10,10) };
-                ColumnDefinitions settingColumns = new()
-                {
-                    new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) },
-                    new ColumnDefinition() { Width = new GridLength(3, GridUnitType.Star) },
-                    new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }
-                };
-                settingsGrid.ColumnDefinitions = settingColumns;
-                expander.Content = settingsGrid;
-
-                int nextRow = gridPanel.RowDefinitions.Count;
-                gridPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(0, GridUnitType.Auto) });
-                gridPanel.AddControl(expander, nextRow, 0, 3);
-
-                var nonIgnoredSettings = displayedSettings.Where(s => !Attribute.IsDefined(s.Key, typeof(SettingIgnore)));
-
-                foreach (var setting in nonIgnoredSettings)
-                {
-                    if (setting.Key.PropertyType != typeof(bool) || settingsGrid.Children.Count % 2 == 0)
-                    {
-                        settingsGrid.RowDefinitions.Add(new RowDefinition()
-                        {
-                            Height = new GridLength(setting.Key.PropertyType != typeof(bool) ? 40 : 25),
-                        });
-                    }
-
-                    TextBlock label = new() { Text = setting.Value, VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center };
-
-                    switch (setting.Key.GetValue(plugin.Settings))
-                    {
-                        case bool boolSetting:
-                            CheckBox checkBox = new() { IsChecked = boolSetting, Content = label };
-
-                            checkBox.Checked += (object sender, RoutedEventArgs e) =>
-                            {
-                                setting.Key.SetValue(plugin.Settings, true);
-                                PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                            };
-
-                            checkBox.Unchecked += (object sender, RoutedEventArgs e) =>
-                            {
-                                setting.Key.SetValue(plugin.Settings, false);
-                                PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                            };
-
-                            settingsGrid.AddControl(checkBox, settingsGrid.RowDefinitions.Count - 1, settingsGrid.Children.Count % 2 == 0 ? 0 : 1);
-
-                            break;
-                        case string stringSetting:
-                            TextBox textBox = new() { Text = stringSetting };
-                            settingsGrid.AddControl(label, settingsGrid.RowDefinitions.Count - 1, 0);
-                            settingsGrid.AddControl(textBox, settingsGrid.RowDefinitions.Count - 1, 1);
-
-                            textBox.LostFocus += (object sender, RoutedEventArgs e) =>
-                            {
-                                setting.Key.SetValue(plugin.Settings, ((TextBox)sender).Text);
-                                PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                            };
-
-                            break;
-                        case int intSetting:
-                            // We have two options for integer values:
-                            // 1) A slider (explicit by way of the SettingIntegerUseSlider attribute and bounded to 0..100 by default)
-                            // 2) A numeric up/down (default otherwise, and is unbounded by default).
-                            // Bounds for both can be set via the SettingNumericBounds attribute, only the up/down uses Increment.
-                            Control intControl;
-                            SettingNumericBounds bounds = (SettingNumericBounds)System.Attribute.GetCustomAttribute(setting.Key, typeof(SettingNumericBounds));
-                            if (System.Attribute.IsDefined(setting.Key, typeof(SettingNumericUseSlider)))
-                            {
-                                // TODO: Suss the contents of this block into a function to share with non-integral numeric types as well?
-                                Slider slider = new()
-                                {
-                                    Value = intSetting,
-                                    Height = 40,
-                                    Width = 300,
-                                };
-                                if (bounds != null)
-                                {
-                                    slider.Minimum = bounds.Minimum;
-                                    slider.Maximum = bounds.Maximum;
-                                };
-                                slider.PropertyChanged += (object sender, AvaloniaPropertyChangedEventArgs e) =>
-                                {
-                                    if (e.Property == Slider.ValueProperty)
-                                    {
-                                        setting.Key.SetValue(plugin.Settings, Convert.ToInt32(e.NewValue));
-                                        PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                                    }
-                                };
-                                intControl = slider;
-                            }
-                            else // Use a Numeric Up/Down
-                            {
-                                NumericUpDown numericUpDown = new() { Value = intSetting, AllowSpin = true };
-                                if (bounds != null)
-                                {
-                                    numericUpDown.Minimum = (decimal)bounds.Minimum;
-                                    numericUpDown.Maximum = (decimal)bounds.Maximum;
-                                    numericUpDown.Increment = (decimal)bounds.Increment;
-                                }
-                                numericUpDown.ValueChanged += (object sender, NumericUpDownValueChangedEventArgs e) =>
-                                {
-                                    setting.Key.SetValue(plugin.Settings, Convert.ToInt32(e.NewValue));
-                                    PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                                };
-                                intControl = numericUpDown;
-                            }
-
-                            settingsGrid.AddControl(label, settingsGrid.RowDefinitions.Count - 1, 0);
-                            settingsGrid.AddControl(intControl, settingsGrid.RowDefinitions.Count - 1, 1);
-                            break;
-                        case FileInfo fileSetting:
-                            label.Text += ": ";
-
-                            TextBox settingPath = new()
-                            {
-                                Text = fileSetting.FullName,
-                                Width = 300,
-                                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right
-                            };
-
-                            Button settingBrowse = new()
-                            {
-                                Content = "Browse",
-                                Height = 30,
-                                Width = 100,
-                                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left,
-                                HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center
-                            };
-
-                            settingBrowse.Click += (object source, RoutedEventArgs e) =>
-                            {
-                                var currentFolder = new Avalonia.Platform.Storage.FileIO.BclStorageFolder(fileSetting.DirectoryName);
-                                var fileOptions = new FilePickerOpenOptions()
-                                {
-                                    AllowMultiple = false,
-                                    SuggestedStartLocation = currentFolder
-                                };
-
-                                var browseTask = ((Window)settingBrowse.FindAncestorOfType<Window>()).StorageProvider.OpenFilePickerAsync(fileOptions);
-                                
-                                //OpenFileDialog openFileDialog = new()
-                                //{
-                                //    Directory = fileSetting.DirectoryName,
-                                //    AllowMultiple = false
-                                //};
-                                
-                                // = openFileDialog.ShowAsync((Window)((Button)source).GetVisualRoot());
-                                
-                                browseTask.ContinueWith((task) => 
-                                {
-                                    if (task.Result?.Count() > 0)
-                                    {
-                                        if (browseTask.Result[0].TryGetUri(out Uri path))
-                                        {
-                                            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => { settingPath.Text = path.AbsolutePath; });
-                                            setting.Key.SetValue(plugin.Settings, new FileInfo(path.AbsolutePath));
-                                            PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                                        }
-                                    }
-                                });
-                                
-                            };
-
-                            settingPath.LostFocus += (object sender, RoutedEventArgs e) =>
-                            {
-                                if (settingPath.Text.Trim() != string.Empty)
-                                {
-                                    string fullPath;
-
-                                    try
-                                    {
-                                        fullPath = Path.GetFullPath(settingPath.Text);
-                                    }
-                                    catch
-                                    {
-                                        fullPath = string.Empty;
-                                    }
-
-                                    setting.Key.SetValue(plugin.Settings, new FileInfo(fullPath));
-                                    PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                                }
-                            };
-
-                            StackPanel stackPanel = new() { Orientation = Avalonia.Layout.Orientation.Horizontal };
-                            stackPanel.Children.Add(label);
-                            stackPanel.Children.Add(settingPath);
-
-                            settingsGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(32) });
-                            settingsGrid.AddControl(stackPanel, settingsGrid.RowDefinitions.Count - 1, 0, 2);
-                            settingsGrid.AddControl(settingBrowse, settingsGrid.RowDefinitions.Count - 1, 2);
-
-                            break;
-                        case Action action:
-                            Button actionButton = new()
-                            {
-                                Content = label.Text,
-                                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left
-                            };
-
-                            actionButton.Click += (object sender, RoutedEventArgs e) =>
-                            {
-                                action.Invoke();
-
-                                //Possible for the action to have changed a setting, save just in case.
-                                PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                            };
-
-                            settingsGrid.AddControl(actionButton, settingsGrid.RowDefinitions.Count - 1, 0);
-
-                            break;
-                        case Dictionary<string, object> dictSetting:
-
-                            var backingValueName = (SettingBackingValue)Attribute.GetCustomAttribute(setting.Key, typeof(SettingBackingValue));
-
-                            var backingValue = from s in displayedSettings
-                                               where s.Value == backingValueName.BackingProperty
-                                               select s.Key;
-
-                            if (backingValue.Count() != 1)
-                                throw new($"{plugin.ShortName}: Dictionary settings must have exactly one backing value.");
-
-                            label.Text += ": ";
-
-                            ComboBox selectionDropDown = new()
-                            {
-                                MinWidth = 200
-                            };
-
-                            selectionDropDown.Items = from s in dictSetting
-                                                      orderby s.Key
-                                                      select s.Key;
-
-                            string currentSelection = backingValue.First().GetValue(plugin.Settings)?.ToString();
-
-                            if (currentSelection?.Length > 0)
-                            {
-                                selectionDropDown.SelectedItem = currentSelection;
-                            }
-
-                            selectionDropDown.SelectionChanged += (object sender, SelectionChangedEventArgs e) =>
-                            {
-                                var comboBox = (ComboBox)sender;
-                                backingValue.First().SetValue(plugin.Settings, comboBox.SelectedItem.ToString());
-                                PluginManagement.PluginManager.GetInstance.SaveSettings(plugin, plugin.Settings);
-                            };
-
-                            settingsGrid.AddControl(label, settingsGrid.RowDefinitions.Count - 1, 0);
-                            settingsGrid.AddControl(selectionDropDown, settingsGrid.RowDefinitions.Count - 1, 1);
-
-                            break;
-                    }
-                }
-            }
-        }
-
-        private string GetStatusText(PluginManagement.PluginManager.PluginStatus status)
-        {
-            string statusText;
-
-            switch (status)
-            {
-                case PluginManagement.PluginManager.PluginStatus.Signed:
-                    statusText = "Signed";
-                    break;
-                case PluginManagement.PluginManager.PluginStatus.Unsigned:
-                    statusText = "Unsigned";
-                    break;
-                case PluginManagement.PluginManager.PluginStatus.InvalidSignature:
-                    statusText = "Signature Invalid";
-                    break;
-                case PluginManagement.PluginManager.PluginStatus.InvalidPlugin:
-                    statusText = "No Interface";
-                    break;
-                case PluginManagement.PluginManager.PluginStatus.InvalidLibrary:
-                    statusText = "Invalid Library";
-                    break;
-                default:
-                    statusText = "Unknown";
-                    break;
-            }
-
-            return statusText;
-        }
-
-        //From https://stackoverflow.com/questions/5796383/insert-spaces-between-words-on-a-camel-cased-token
-        private static string SplitCamelCase(string str)
-        {
-            return Regex.Replace(
-                Regex.Replace(
-                    str,
-                    @"(\P{Ll})(\P{Ll}\p{Ll})",
-                    "$1 $2"
-                ),
-                @"(\p{Ll})(\P{Ll})",
-                "$1 $2"
-            );
-        }
-    }
-
-    internal class PluginView
-    {
-        public string Name { get; set; }
-        public HashSet<string> Types { get; set; }
-        public string TypesString
-        {
-            get => string.Join(", ", Types);
-            set { }
-        }
-        public string Version { get; set; }
-        public string Status { get; set; }
-    }
-
-    internal static class GridExtention
-    {
-        public static void AddControl(this Grid grid, Control control, int row, int column, int span = 1)
-        {
-            grid.Children.Add(control);
-            Grid.SetColumnSpan(control, span);
-            Grid.SetColumn(control, column);
-            Grid.SetRow(control, row);
-        }
-    }
-
-    internal class SettingGridManager
-    {
-        private Grid settingPanel;
-
-        public SettingGridManager(Grid settingPanel)
-        {
-            this.settingPanel = settingPanel;
-        }
-
-        public int NewRow()
-        {
-            settingPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(0, GridUnitType.Auto) });
-            
-            return settingPanel.RowDefinitions.Count - 1;
-        }
-
-        public void AddSetting(Control control)
-        {
-            int rowIndex = NewRow();
-            settingPanel.AddControl(control, rowIndex, 0, 2);
-        }
-
-        public void AddSettingSameLine(Control control)
-        {
-            int rowIndex = settingPanel.RowDefinitions.Count - 1;
-            settingPanel.AddControl(control, rowIndex, 0, 2);
-        }
-
-        public void AddSettingWithLabel(Control label, Control control)
-        {
-            int rowIndex = NewRow();
-            settingPanel.AddControl(label, rowIndex, 0);
-            settingPanel.AddControl(control, rowIndex, 1, 2);
-        }
-    }
-}
diff --git a/ObservatoryCore/UI/Views/CoreView.axaml b/ObservatoryCore/UI/Views/CoreView.axaml
deleted file mode 100644
index acab29c..0000000
--- a/ObservatoryCore/UI/Views/CoreView.axaml
+++ /dev/null
@@ -1,108 +0,0 @@
-<UserControl xmlns="https://github.com/avaloniaui"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-             xmlns:vw="clr-namespace:Observatory.UI.Views"
-             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
-             x:Class="Observatory.UI.Views.CoreView">
-  <UserControl.Styles>
-    <Style Selector="Button.Hyperlink">
-      <Setter Property="Background" Value="Transparent"/>
-      <Setter Property="BorderThickness" Value="0,0,0,1"/>
-      <Setter Property="BorderBrush" Value="White"/>
-      <Setter Property="Padding" Value="0"/>
-      <Setter Property="FontSize" Value="10"/>
-    </Style>
-  </UserControl.Styles>
-  <Grid RowDefinitions="30,*,Auto">
-    <TextBlock Grid.Row="0" VerticalAlignment="Center" Padding="10,0,0,0" Name="Title">
-      Elite Observatory - v0
-    </TextBlock>
-    <TabControl Name="CoreTabs"
-      Grid.Row="1" Grid.Column="1"
-      VerticalAlignment="Stretch"
-      TabStripPlacement="Left"
-      Items="{Binding Tabs}"
-      BorderBrush="Black"
-      BorderThickness="1">
-      <TabControl.ItemTemplate>
-        <DataTemplate>
-          <TabItem>
-            <TabItem.Header>
-              <TextBlock Text="{Binding Name}"/>
-            </TabItem.Header>
-          </TabItem>
-        </DataTemplate>
-      </TabControl.ItemTemplate>
-      <TabControl.ContentTemplate>
-        <DataTemplate>
-          <vw:BasicUIView DataContext="{Binding UI}" UIType="{Binding UIType}"/>
-        </DataTemplate>
-      </TabControl.ContentTemplate>
-    </TabControl>
-    <Grid RowDefinitions="Auto,Auto" Grid.Row="2">
-      <StackPanel Grid.Column="1" Height="50" VerticalAlignment="Bottom" Orientation="Vertical" HorizontalAlignment="Left">
-        <Button 
-          Classes="Hyperlink" 
-          Name="github" 
-          Margin="10,0,0,5" 
-          Command="{Binding OpenGithub}" 
-          FontSize="15" 
-          Cursor="Hand">
-          github
-        </Button>
-        <Button 
-          Classes="Hyperlink" 
-          Name="Donate" 
-          Margin="10,0,0,0" 
-          Command="{Binding OpenDonate}" 
-          FontSize="15" 
-          Cursor="Hand">
-          Donate
-        </Button>
-      </StackPanel>
-      <WrapPanel Grid.Column="2" Height="50" VerticalAlignment="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
-        <Button 
-          Classes="Hyperlink" 
-          Name="update" 
-          Margin="0,0,10,0" 
-          FontSize="15" 
-          Command="{Binding GetUpdate}"
-          IsVisible="{Binding UpdateAvailable}"
-          IsEnabled="{Binding UpdateAvailable}"
-          Cursor="Hand">
-          Update Available
-        </Button>
-		<Button
-		  Name="export"
-		  Margin="10"
-		  FontSize="15"
-		  Command="{Binding ExportGrid}"
-		  Content="Export">
-		  Export
-		</Button>
-		<Button
-		  Name="clear"
-		  Margin="10"
-		  FontSize="15"
-		  Command="{Binding ClearGrid}"
-		  Content="Clear">
-		  Clear
-		</Button>
-        <Button 
-          Name="ToggleMonitor" 
-          Margin="10" 
-          Command="{Binding ToggleMonitor}" 
-          Content="{Binding ToggleButtonText}">
-          Start Monitor
-        </Button>
-        <Button 
-          Name="ReadAll" 
-          Margin="10" 
-          Command="{Binding ReadAll}">
-          Read All
-        </Button>
-      </WrapPanel>
-    </Grid>
-  </Grid>
-</UserControl>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/Views/CoreView.axaml.cs b/ObservatoryCore/UI/Views/CoreView.axaml.cs
deleted file mode 100644
index d0ffe44..0000000
--- a/ObservatoryCore/UI/Views/CoreView.axaml.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
-using System.Linq;
-
-namespace Observatory.UI.Views
-{
-    public class CoreView : UserControl
-    {
-        public CoreView()
-        {
-            
-            InitializeComponent();
-
-            var titleBlock = this.Find<TextBlock>("Title");
-            titleBlock.Text = "Elite Observatory Core - v" + System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
-
-        }
-
-        private void InitializeComponent()
-        {
-            AvaloniaXamlLoader.Load(this);
-        }
-    }
-}
diff --git a/ObservatoryCore/UI/Views/MainWindow.axaml b/ObservatoryCore/UI/Views/MainWindow.axaml
deleted file mode 100644
index 5bd6e5c..0000000
--- a/ObservatoryCore/UI/Views/MainWindow.axaml
+++ /dev/null
@@ -1,12 +0,0 @@
-<Window xmlns="https://github.com/avaloniaui"
-        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-        xmlns:views="clr-namespace:Observatory.UI.Views"
-        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
-        x:Class="Observatory.UI.Views.MainWindow"
-        Title="Elite Observatory"
-        ExtendClientAreaToDecorationsHint="True"
-        Content="{Binding core}"
-        Icon="/Assets/EOCIcon-Presized.ico">
-</Window> 
\ No newline at end of file
diff --git a/ObservatoryCore/UI/Views/MainWindow.axaml.cs b/ObservatoryCore/UI/Views/MainWindow.axaml.cs
deleted file mode 100644
index 76fcd37..0000000
--- a/ObservatoryCore/UI/Views/MainWindow.axaml.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
-
-
-namespace Observatory.UI.Views
-{
-    public class MainWindow : Window
-    {
-        public MainWindow()
-        {
-            InitializeComponent();
-#if DEBUG
-            this.AttachDevTools();
-#endif
-            Height = Properties.Core.Default.MainWindowSize.Height;
-            Width = Properties.Core.Default.MainWindowSize.Width;
-            
-            var savedPosition = new System.Drawing.Point(Properties.Core.Default.MainWindowPosition.X, Properties.Core.Default.MainWindowPosition.Y);
-            if (PointWithinDesktopWorkingArea(savedPosition))
-                Position = new PixelPoint(Properties.Core.Default.MainWindowPosition.X, Properties.Core.Default.MainWindowPosition.Y);
-            
-            Closing += (object sender, System.ComponentModel.CancelEventArgs e) =>
-            {
-                var size = new System.Drawing.Size((int)System.Math.Round(Width), (int)System.Math.Round(Height));
-                Properties.Core.Default.MainWindowSize = size;
-                
-                var position = new System.Drawing.Point(Position.X, Position.Y);
-                if (PointWithinDesktopWorkingArea(position))
-                    Properties.Core.Default.MainWindowPosition = position;
-
-                Properties.Core.Default.Save();
-            };
-        }
-
-        private bool PointWithinDesktopWorkingArea(System.Drawing.Point position)
-        {
-            bool inBounds = false;
-            
-            foreach (var screen in Screens.All)
-            {
-                if (screen.WorkingArea.TopLeft.X <= position.X
-                    && screen.WorkingArea.TopLeft.Y <= position.Y
-                    && screen.WorkingArea.BottomRight.X > position.X
-                    && screen.WorkingArea.BottomRight.Y > position.Y)
-                {
-                    inBounds = true;
-                    break;
-                }
-            }
-            
-            return inBounds;
-        }
-
-        private void InitializeComponent()
-        {
-            AvaloniaXamlLoader.Load(this);
-        }
-    }
-}
diff --git a/ObservatoryCore/UI/Views/NotificationView.axaml b/ObservatoryCore/UI/Views/NotificationView.axaml
deleted file mode 100644
index 2de1240..0000000
--- a/ObservatoryCore/UI/Views/NotificationView.axaml
+++ /dev/null
@@ -1,41 +0,0 @@
-<Window xmlns="https://github.com/avaloniaui"
-        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-        mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="150"
-        x:Class="Observatory.UI.Views.NotificationView"
-        ExtendClientAreaToDecorationsHint="True"
-        ExtendClientAreaChromeHints="NoChrome"
-        ExtendClientAreaTitleBarHeightHint="-1"
-        Title="Notification"
-        Width="400" Height="150"
-        Topmost="True"
-        TransparencyLevelHint="AcrylicBlur"
-        Background="Transparent"
-        Focusable="False">
-  <Panel DataContext="{Binding Notification}">
-    <Border Name="TextBorder" BorderBrush="{Binding Colour}" BorderThickness="4">
-      <StackPanel Name="TextPanel" Width="400">
-        <TextBlock
-          Name="Title"
-          Padding="10"
-          FontWeight="Normal"
-          FontSize="30"
-          Foreground="{Binding Colour}"
-          Text="{Binding Title}">
-          Title
-        </TextBlock>
-        <TextBlock
-          Name="Detail"
-          Padding="20,0"
-          FontWeight="Normal"
-          FontSize="20"
-          TextWrapping="Wrap"
-          Foreground="{Binding Colour}"
-          Text="{Binding Detail}">
-          Detail
-        </TextBlock>
-      </StackPanel>
-    </Border>
-  </Panel>
-</Window>
diff --git a/ObservatoryCore/UI/Views/NotificationView.axaml.cs b/ObservatoryCore/UI/Views/NotificationView.axaml.cs
deleted file mode 100644
index 653cc87..0000000
--- a/ObservatoryCore/UI/Views/NotificationView.axaml.cs
+++ /dev/null
@@ -1,267 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Layout;
-using Avalonia.Markup.Xaml;
-using Observatory.UI.ViewModels;
-using System;
-using System.Reflection;
-using System.Timers;
-using System.Runtime.InteropServices;
-
-namespace Observatory.UI.Views
-{
-    public partial class NotificationView : Window
-    {
-        private readonly double scale;
-        private readonly System.Timers.Timer timer;
-        private readonly Guid guid;
-        private bool defaultPosition = true;
-        private PixelPoint originalPosition;
-
-        public NotificationView() : this(default)
-        { }
-
-        public NotificationView(Guid guid)
-        {
-            this.guid = guid;
-            InitializeComponent();
-            SystemDecorations = SystemDecorations.None;
-            ShowActivated = false;
-            ShowInTaskbar = false;
-            MakeClickThrough(); //Platform specific, currently windows and Linux (X11) only.
-
-            this.DataContextChanged += NotificationView_DataContextChanged;
-            scale = Properties.Core.Default.NativeNotifyScale / 100.0;
-
-            AdjustText();
-
-            AdjustPanel();
-
-            AdjustPosition();
-
-            timer = new();
-            timer.Elapsed += CloseNotification;
-            timer.Interval = Properties.Core.Default.NativeNotifyTimeout;
-            timer.Start();
-
-#if DEBUG
-            this.AttachDevTools();
-#endif
-        }
-
-        public Guid Guid { get => guid; }
-
-        public void AdjustOffset(bool increase)
-        {
-            if (defaultPosition)
-            {
-                if (increase || Position != originalPosition)
-                {
-                    var corner = Properties.Core.Default.NativeNotifyCorner;
-
-                    if ((corner >= 2 && increase) || (corner <= 1 && !increase))
-                    {
-                        Position += new PixelPoint(0, Convert.ToInt32(Height));
-                    }
-                    else
-                    {
-                        Position -= new PixelPoint(0, Convert.ToInt32(Height));
-                    }
-
-                }
-            }
-        }
-
-        public override void Show()
-        {
-            base.Show();
-
-            // Refresh the position when the window is opened (required
-            // on Linux to show the notification in the right position)
-            if (DataContext is NotificationViewModel nvm)
-            {
-                AdjustPosition(nvm.Notification.XPos / 100, nvm.Notification.YPos / 100);
-            }
-        }
-
-        private void NotificationView_DataContextChanged(object sender, EventArgs e)
-        {
-            var notification = ((NotificationViewModel)DataContext).Notification;
-
-            AdjustText();
-
-            AdjustPanel();
-
-            AdjustPosition(notification.XPos / 100, notification.YPos / 100);
-
-            if (notification.Timeout > 0)
-            {
-                timer.Stop();
-                timer.Interval = notification.Timeout;
-                timer.Start();
-            }
-            else if (notification.Timeout == 0)
-            {
-                timer.Stop();
-            }
-        }
-
-        private void AdjustText()
-        {
-            string font = Properties.Core.Default.NativeNotifyFont;
-            var titleText = this.Find<TextBlock>("Title");
-            var detailText = this.Find<TextBlock>("Detail");
-
-            if (font.Length > 0)
-            {
-                var fontFamily = new Avalonia.Media.FontFamily(font);
-
-                titleText.FontFamily = fontFamily;
-                detailText.FontFamily = fontFamily;
-            }
-
-            titleText.FontSize *= scale;
-            detailText.FontSize *= scale;
-        }
-
-        private void AdjustPanel()
-        {
-            var textPanel = this.Find<StackPanel>("TextPanel");
-            Width *= scale;
-            Height *= scale;
-            textPanel.Width *= scale;
-            textPanel.Height *= scale;
-
-            var textBorder = this.Find<Border>("TextBorder");
-            textBorder.BorderThickness *= scale;
-        }
-
-        private void AdjustPosition(double xOverride = -1.0, double yOverride = -1.0)
-        {
-            PixelRect screenBounds;
-            int screen = Properties.Core.Default.NativeNotifyScreen;
-            int corner = Properties.Core.Default.NativeNotifyCorner;
-
-            if (screen == -1 || screen > Screens.All.Count)
-                if (Screens.All.Count == 1)
-                    screenBounds = Screens.All[0].Bounds;
-                else
-                    screenBounds = Screens.Primary.Bounds;
-            else
-                screenBounds = Screens.All[screen - 1].Bounds;
-
-            double displayScale = LayoutHelper.GetLayoutScale(this);
-            double scaleWidth = Width * displayScale;
-            double scaleHeight = Height * displayScale;
-
-            if (xOverride >= 0 && yOverride >= 0)
-            {
-                defaultPosition = false;
-                Position = screenBounds.TopLeft + new PixelPoint(Convert.ToInt32(screenBounds.Width * xOverride), Convert.ToInt32(screenBounds.Height * yOverride));
-            }
-            else
-            {
-                defaultPosition = true;
-                switch (corner)
-                {
-                    default:
-                    case 0:
-                        Position = screenBounds.BottomRight - new PixelPoint(Convert.ToInt32(scaleWidth) + 50, Convert.ToInt32(scaleHeight) + 50);
-                        break;
-                    case 1:
-                        Position = screenBounds.BottomLeft - new PixelPoint(-50, Convert.ToInt32(scaleHeight) + 50);
-                        break;
-                    case 2:
-                        Position = screenBounds.TopRight - new PixelPoint(Convert.ToInt32(scaleWidth) + 50, -50);
-                        break;
-                    case 3:
-                        Position = screenBounds.TopLeft + new PixelPoint(50, 50);
-                        break;
-                }
-                originalPosition = Position;
-            }
-        }
-
-        private void CloseNotification(object sender, System.Timers.ElapsedEventArgs e)
-        {
-            Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-            {
-                Close();
-            });
-        }
-
-        private void InitializeComponent()
-        {
-            AvaloniaXamlLoader.Load(this);
-        }
-
-        private void MakeClickThrough()
-        {
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
-            {
-                var style = GetWindowLong(this.PlatformImpl.Handle.Handle, GWL_EXSTYLE);
-
-                //PlatformImpl not part of formal Avalonia API and may not be available in future versions.
-                SetWindowLong(this.PlatformImpl.Handle.Handle, GWL_EXSTYLE, style | WS_EX_LAYERED | WS_EX_TRANSPARENT);
-                SetLayeredWindowAttributes(this.PlatformImpl.Handle.Handle, 0, 255, LWA_ALPHA);
-            } 
-            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
-            {
-                // X11 stuff is not part of official API, we'll have to deal with reflection
-                // This solution currently only supports the X11 window system which is used on most systems
-                var type = this.PlatformImpl.GetType();
-                if (type.FullName is not "Avalonia.X11.X11Window") return;
-                
-                // Get the pointer to the X11 window
-                var handlePropInfo = type.GetField("_handle", BindingFlags.NonPublic | BindingFlags.Instance);
-                var handle = handlePropInfo?.GetValue(this.PlatformImpl);
-                // Get the X11Info instance
-                var x11PropInfo = type.GetField("_x11", BindingFlags.NonPublic | BindingFlags.Instance);
-                var x11Info = x11PropInfo?.GetValue(this.PlatformImpl);
-                // Get the pointer to the X11 display
-                var displayPropInfo = x11Info?.GetType().GetProperty("Display");
-                var display = displayPropInfo?.GetValue(x11Info);
-
-                if (display == null || handle == null) return;
-                try
-                {
-                    // Create a very tiny region
-                    var region = XFixesCreateRegion((IntPtr)display, IntPtr.Zero, 0);
-                    // Set the input shape of the window to our region
-                    XFixesSetWindowShapeRegion((IntPtr)display, (IntPtr)handle, ShapeInput, 0, 0, region);
-                    // Cleanup
-                    XFixesDestroyRegion((IntPtr)display, region);
-                }
-                catch
-                {
-                    // libXfixes is not installed for some reason
-                }
-            }
-        }
-
-        [DllImport("user32.dll", SetLastError = true)]
-        static extern uint GetWindowLong(IntPtr hWnd, int nIndex);
-        [DllImport("user32.dll", SetLastError = true)]
-        static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
-        [DllImport("user32.dll")]
-        static extern uint SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
-        [DllImport("user32.dll")]
-        static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
-
-        internal const int GWL_EXSTYLE = -20;
-        internal const int WS_EX_LAYERED = 0x80000;
-        internal const int LWA_ALPHA = 0x2;
-        internal const int WS_EX_TRANSPARENT = 0x00000020;
-        
-        [DllImport("libXfixes.so")]
-        static extern IntPtr XFixesCreateRegion(IntPtr dpy, IntPtr rectangles, int nrectangles);
-
-        [DllImport("libXfixes.so")]
-        static extern IntPtr XFixesSetWindowShapeRegion(IntPtr dpy, IntPtr win, int shape_kind, int x_off, int y_off, IntPtr region);
-
-        [DllImport("libXfixes.so")]
-        static extern IntPtr XFixesDestroyRegion(IntPtr dpy, IntPtr region);
-        
-        internal const int ShapeInput = 2;
-    }
-}
diff --git a/ObservatoryCore/ErrorReporter.cs b/ObservatoryCore/Utils/ErrorReporter.cs
similarity index 56%
rename from ObservatoryCore/ErrorReporter.cs
rename to ObservatoryCore/Utils/ErrorReporter.cs
index 756f81a..3cb8412 100644
--- a/ObservatoryCore/ErrorReporter.cs
+++ b/ObservatoryCore/Utils/ErrorReporter.cs
@@ -4,7 +4,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
-namespace Observatory
+namespace Observatory.Utils
 {
     public static class ErrorReporter
     {
@@ -18,20 +18,7 @@ namespace Observatory
             displayMessage.AppendLine();
             displayMessage.Append("Full error details logged to ObservatoryErrorLog file in your documents folder.");
 
-            if (Avalonia.Application.Current.ApplicationLifetime is Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktop)
-            {
-                Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
-                {
-                    var errorMessage = MessageBox.Avalonia.MessageBoxManager
-                    .GetMessageBoxStandardWindow(new MessageBox.Avalonia.DTO.MessageBoxStandardParams
-                    {
-                        ContentTitle = title,
-                        ContentMessage = displayMessage.ToString(),
-                        Topmost = true
-                    });
-                    errorMessage.Show();
-                });
-            }
+            //TODO: Winform error popup
 
             // Log entirety of errors out to file.
             var timestamp = DateTime.Now.ToString("G");
@@ -43,8 +30,8 @@ namespace Observatory
                 errorLog.AppendLine();
             }
 
-            var docPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
-            System.IO.File.AppendAllText(docPath + System.IO.Path.DirectorySeparatorChar + "ObservatoryErrorLog.txt", errorLog.ToString());
+            var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            File.AppendAllText(docPath + Path.DirectorySeparatorChar + "ObservatoryErrorLog.txt", errorLog.ToString());
 
             errorList.Clear();
         }
diff --git a/ObservatoryCore/UI/HttpClient.cs b/ObservatoryCore/Utils/HttpClient.cs
similarity index 85%
rename from ObservatoryCore/UI/HttpClient.cs
rename to ObservatoryCore/Utils/HttpClient.cs
index 9e51e79..42f69a0 100644
--- a/ObservatoryCore/UI/HttpClient.cs
+++ b/ObservatoryCore/Utils/HttpClient.cs
@@ -1,7 +1,7 @@
 using System;
 using System.Net.Http;
 
-namespace Observatory
+namespace Observatory.Utils
 {
     public sealed class HttpClient
     {
@@ -28,7 +28,7 @@ namespace Observatory
             return lazy.Value.SendAsync(request).Result;
         }
 
-        public static System.Threading.Tasks.Task<HttpResponseMessage> SendRequestAsync(HttpRequestMessage request)
+        public static Task<HttpResponseMessage> SendRequestAsync(HttpRequestMessage request)
         {
             return lazy.Value.SendAsync(request);
         }
diff --git a/ObservatoryCore/JournalReader.cs b/ObservatoryCore/Utils/JournalReader.cs
similarity index 98%
rename from ObservatoryCore/JournalReader.cs
rename to ObservatoryCore/Utils/JournalReader.cs
index 6f600ad..72c73fe 100644
--- a/ObservatoryCore/JournalReader.cs
+++ b/ObservatoryCore/Utils/JournalReader.cs
@@ -6,7 +6,7 @@ using System.Text.Json;
 using System.Linq;
 using System.Reflection;
 
-namespace Observatory
+namespace Observatory.Utils
 {
     public class JournalReader
     {
@@ -26,7 +26,7 @@ namespace Observatory
                     while ((eventType == string.Empty || timestamp == string.Empty) && reader.Read())
                     {
                         if (reader.TokenType == JsonTokenType.PropertyName)
-                        { 
+                        {
                             if (reader.GetString() == "event")
                             {
                                 reader.Read();
@@ -58,7 +58,7 @@ namespace Observatory
                 }
 
                 deserialized = (TJournal)Convert.ChangeType(invalidJson, typeof(TJournal));
-                
+
             }
             //Journal potentially had invalid JSON for a brief period in 2017, check for it and remove.
             //TODO: Check if this gets handled by InvalidJson now.
diff --git a/ObservatoryCore/LogMonitor.cs b/ObservatoryCore/Utils/LogMonitor.cs
similarity index 95%
rename from ObservatoryCore/LogMonitor.cs
rename to ObservatoryCore/Utils/LogMonitor.cs
index c1cc760..2fe2383 100644
--- a/ObservatoryCore/LogMonitor.cs
+++ b/ObservatoryCore/Utils/LogMonitor.cs
@@ -8,7 +8,7 @@ using System.Text.RegularExpressions;
 using Observatory.Framework;
 using Observatory.Framework.Files;
 
-namespace Observatory
+namespace Observatory.Utils
 {
     class LogMonitor
     {
@@ -120,12 +120,12 @@ namespace Observatory
 
             DirectoryInfo logDirectory = GetJournalFolder(Properties.Core.Default.JournalFolder);
             var files = GetJournalFilesOrdered(logDirectory);
-            
+
             // Read at most the last two files (in case we were launched after the game and the latest
             // journal is mostly empty) but keeping only the lines since the last FSDJump.
-            List<String> lastSystemLines = new();
-            List<String> lastFileLines = new();
-            string lastLoadGame = String.Empty;
+            List<string> lastSystemLines = new();
+            List<string> lastFileLines = new();
+            string lastLoadGame = string.Empty;
             bool sawFSDJump = false;
             foreach (var file in files.Skip(Math.Max(files.Count() - 2, 0)))
             {
@@ -133,7 +133,7 @@ namespace Observatory
                 foreach (var line in lines)
                 {
                     var eventType = JournalUtilities.GetEventType(line);
-                    if (eventType.Equals("FSDJump") || (eventType.Equals("CarrierJump") && line.Contains("\"Docked\":true")))
+                    if (eventType.Equals("FSDJump") || eventType.Equals("CarrierJump") && line.Contains("\"Docked\":true"))
                     {
                         // Reset, start collecting again.
                         lastSystemLines.Clear();
@@ -162,7 +162,7 @@ namespace Observatory
             {
                 // If we saw a LoadGame, insert it as well. This ensures odyssey biologicials are properly
                 // counted/presented.
-                if (!String.IsNullOrEmpty(lastLoadGame))
+                if (!string.IsNullOrEmpty(lastLoadGame))
                 {
                     lastSystemLines.Insert(0, lastLoadGame);
                 }
@@ -193,14 +193,14 @@ namespace Observatory
         private Dictionary<string, int> currentLine;
         private LogMonitorState currentState = LogMonitorState.Idle; // Change via #SetLogMonitorState
         private bool firstStartMonitor = true;
-        private string[] EventsWithAncillaryFile = new string[] 
-        { 
-            "Cargo", 
-            "NavRoute", 
-            "Market", 
-            "Outfitting", 
-            "Shipyard", 
-            "Backpack", 
+        private string[] EventsWithAncillaryFile = new string[]
+        {
+            "Cargo",
+            "NavRoute",
+            "Market",
+            "Outfitting",
+            "Shipyard",
+            "Backpack",
             "FCMaterials",
             "ModuleInfo",
             "ShipLocker"
@@ -218,7 +218,7 @@ namespace Observatory
             {
                 PreviousState = oldState,
                 NewState = newState
-            });;
+            }); ;
 
             System.Diagnostics.Debug.WriteLine("LogMonitor State change: {0} -> {1}", oldState, newState);
         }
@@ -267,7 +267,7 @@ namespace Observatory
             else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
             {
                 string defaultJournalPath = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
-                    ? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) 
+                    ? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
                     + "/.steam/debian-installation/steamapps/compatdata/359320/pfx/drive_c/users/steamuser/Saved Games/Frontier Developments/Elite Dangerous"
                     : GetSavedGamesPath() + @"\Frontier Developments\Elite Dangerous";
 
@@ -290,7 +290,7 @@ namespace Observatory
             return logDirectory;
         }
 
-        private List<(Exception ex, string file, string line)> ProcessLines(List<String> lines, string file)
+        private List<(Exception ex, string file, string line)> ProcessLines(List<string> lines, string file)
         {
             var readErrors = new List<(Exception ex, string file, string line)>();
             foreach (var line in lines)
@@ -309,7 +309,7 @@ namespace Observatory
 
         private JournalEventArgs DeserializeToEventArgs(string eventType, string line)
         {
-            
+
             var eventClass = journalTypes[eventType];
             MethodInfo journalRead = typeof(JournalReader).GetMethod(nameof(JournalReader.ObservatoryDeserializer));
             MethodInfo journalGeneric = journalRead.MakeGenericMethod(eventClass);
@@ -326,7 +326,7 @@ namespace Observatory
             }
 
             var journalEvent = DeserializeToEventArgs(eventType, line);
-            
+
             JournalEntry?.Invoke(this, journalEvent);
 
             // Files are only valid if realtime, otherwise they will be stale or empty.
@@ -345,16 +345,16 @@ namespace Observatory
             // I have no idea what order Elite writes these files or if they're already written
             // by the time the journal updates.
             // Brief sleep to ensure the content is updated before we read it.
-            
+
             // Some files are still locked by another process after 50ms.
             // Retry every 50ms for 0.5 seconds before giving up.
 
             string fileContent = null;
             int retryCount = 0;
-            
+
             while (fileContent == null && retryCount < 10)
             {
-                System.Threading.Thread.Sleep(50);
+                Thread.Sleep(50);
                 try
                 {
                     using var fileStream = File.Open(journalWatcher.Path + Path.DirectorySeparatorChar + filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
@@ -389,7 +389,7 @@ namespace Observatory
                 });
 
                 ErrorReporter.ShowErrorPopup($"Journal Read Error{(readErrors.Count > 1 ? "s" : "")}", errorList.ToList());
-                
+
             }
         }
 
@@ -462,8 +462,8 @@ namespace Observatory
         {
             var journalFolder = GetJournalFolder();
 
-            await System.Threading.Tasks.Task.Run(() => 
-            { 
+            await Task.Run(() =>
+            {
                 while (IsMonitoring())
                 {
                     var journals = GetJournalFilesOrdered(journalFolder);
@@ -475,7 +475,7 @@ namespace Observatory
                         using FileStream stream = fileToPoke.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                         stream.Close();
                     }
-                    System.Threading.Thread.Sleep(250);
+                    Thread.Sleep(250);
                 }
             });
         }
diff --git a/ObservatoryFramework/BasicGrid.cs b/ObservatoryFramework/BasicGrid.cs
deleted file mode 100644
index b36105e..0000000
--- a/ObservatoryFramework/BasicGrid.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Observatory.Framework
-{
-    public class BasicGrid
-    {
-        public BasicGrid()
-        {
-            Headers = new();
-            Formats = new();
-            Items = new();
-        }
-
-        public readonly ObservableCollection<string> Headers;
-        public readonly ObservableCollection<string> Formats;
-        public readonly ObservableCollection<ObservableCollection<object>> Items;
-    }
-}
diff --git a/ObservatoryFramework/Interfaces.cs b/ObservatoryFramework/Interfaces.cs
index 52ad4b2..3f7e0e3 100644
--- a/ObservatoryFramework/Interfaces.cs
+++ b/ObservatoryFramework/Interfaces.cs
@@ -135,7 +135,7 @@ namespace Observatory.Framework.Interfaces
         /// <param name="notificationEventArgs">NotificationArgs object specifying notification content and behaviour.</param>
         /// <returns>Guid associated with the notification during its lifetime. Used as an argument with CancelNotification and UpdateNotification.</returns>
         public Guid SendNotification(NotificationArgs notificationEventArgs);
-        
+
         /// <summary>
         /// Cancel or close an active notification.
         /// </summary>
@@ -154,7 +154,14 @@ namespace Observatory.Framework.Interfaces
         /// </summary>
         /// <param name="worker">Reference to the calling plugin's worker interface.</param>
         /// <param name="item">Grid item to be added. Object type should match original template item used to create the grid.</param>
-        public void AddGridItem(IObservatoryWorker worker, List<object> item);
+        public void AddGridItem(IObservatoryWorker worker, object item);
+
+        /// <summary>
+        /// Add multiple items to the bottom of the basic UI grid.
+        /// </summary>
+        /// <param name="worker">Reference to the calling plugin's worker interface.</param>
+        /// <param name="items">Grid items to be added. Object types should match original template item used to create the grid.</param>
+        public void AddGridItems(IObservatoryWorker worker, IEnumerable<object> items);
 
         /// <summary>
         /// Add multiple items to the bottom of the basic UI grid.
@@ -167,7 +174,8 @@ namespace Observatory.Framework.Interfaces
         /// Clears basic UI grid, removing all items.
         /// </summary>
         /// <param name="worker">Reference to the calling plugin's worker interface.</param>
-        public void ClearGrid(IObservatoryWorker worker);
+        /// <param name="templateItem">Template item used to re-initialise the grid.</param>
+        public void ClearGrid(IObservatoryWorker worker, object templateItem);
 
         /// <summary>
         /// Requests current Elite Dangerous status.json content.
@@ -185,7 +193,7 @@ namespace Observatory.Framework.Interfaces
         /// or pass it along to its collaborators.
         /// </summary>
         /// <param name="plugin">The calling plugin</param>
-        public Action<Exception, String> GetPluginErrorLogger (IObservatoryPlugin plugin);
+        public Action<Exception, String> GetPluginErrorLogger(IObservatoryPlugin plugin);
 
         /// <summary>
         /// Perform an action on the current Avalonia UI thread.
diff --git a/ObservatoryFramework/ObservatoryFramework.xml b/ObservatoryFramework/ObservatoryFramework.xml
index 1c9f796..a046077 100644
--- a/ObservatoryFramework/ObservatoryFramework.xml
+++ b/ObservatoryFramework/ObservatoryFramework.xml
@@ -1439,18 +1439,26 @@
             <param name="notificationId">Guid of notification to be updated.</param>
             <param name="notificationEventArgs">NotificationArgs object specifying updated notification content and behaviour.</param>
         </member>
-        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.AddGridItem(Observatory.Framework.Interfaces.IObservatoryWorker,System.Collections.Generic.List{System.Object})">
+        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.AddGridItem(Observatory.Framework.Interfaces.IObservatoryWorker,System.Object)">
             <summary>
             Add an item to the bottom of the basic UI grid.
             </summary>
             <param name="worker">Reference to the calling plugin's worker interface.</param>
             <param name="item">Grid item to be added. Object type should match original template item used to create the grid.</param>
         </member>
-        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.ClearGrid(Observatory.Framework.Interfaces.IObservatoryWorker)">
+        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.AddGridItems(Observatory.Framework.Interfaces.IObservatoryWorker,System.Collections.Generic.IEnumerable{System.Object})">
+            <summary>
+            Add multiple items to the bottom of the basic UI grid.
+            </summary>
+            <param name="worker">Reference to the calling plugin's worker interface.</param>
+            <param name="items">Grid items to be added. Object types should match original template item used to create the grid.</param>
+        </member>
+        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.ClearGrid(Observatory.Framework.Interfaces.IObservatoryWorker,System.Object)">
             <summary>
             Clears basic UI grid, removing all items.
             </summary>
             <param name="worker">Reference to the calling plugin's worker interface.</param>
+            <param name="templateItem">Template item used to re-initialise the grid.</param>
         </member>
         <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.GetStatus">
             <summary>
@@ -1512,12 +1520,13 @@
             <para>(Untested/not implemented)</para>
             </summary>
         </member>
-        <member name="F:Observatory.Framework.PluginUI.BasicGrid">
+        <member name="F:Observatory.Framework.PluginUI.DataGrid">
             <summary>
-            <para>>Two-dimensional collection of items to display in UI grid for UIType.Basic</para>
+            <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
+            <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
             </summary>
         </member>
-        <member name="M:Observatory.Framework.PluginUI.#ctor(Observatory.Framework.BasicGrid)">
+        <member name="M:Observatory.Framework.PluginUI.#ctor(System.Collections.ObjectModel.ObservableCollection{System.Object})">
             <summary>
             Instantiate PluginUI of UIType.Basic.
             </summary>
@@ -1546,12 +1555,12 @@
         </member>
         <member name="F:Observatory.Framework.PluginUI.UIType.Basic">
             <summary>
-            Simple DataGrid, to which items can be added or removed.
+            Simple listview, to which items can be added or removed.
             </summary>
         </member>
-        <member name="F:Observatory.Framework.PluginUI.UIType.Avalonia">
+        <member name="F:Observatory.Framework.PluginUI.UIType.Panel">
             <summary>
-            AvaloniaUI control which is placed in plugin tab.
+            Panel control which is placed in plugin tab.
             </summary>
         </member>
         <member name="F:Observatory.Framework.PluginUI.UIType.Core">
diff --git a/ObservatoryFramework/PluginUI.cs b/ObservatoryFramework/PluginUI.cs
index d0a3403..0e73312 100644
--- a/ObservatoryFramework/PluginUI.cs
+++ b/ObservatoryFramework/PluginUI.cs
@@ -23,9 +23,10 @@ namespace Observatory.Framework
         public object UI;
 
         /// <summary>
-        /// <para>>Two-dimensional collection of items to display in UI grid for UIType.Basic</para>
+        /// <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
+        /// <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
         /// </summary>
-        public BasicGrid BasicGrid;
+        public ObservableCollection<object> DataGrid;
 
         /// <summary>
         /// Instantiate PluginUI of UIType.Basic.
@@ -34,10 +35,10 @@ namespace Observatory.Framework
         /// <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
         /// <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
         /// </param>
-        public PluginUI(BasicGrid basicGrid)
+        public PluginUI(ObservableCollection<object> DataGrid)
         {
             PluginUIType = UIType.Basic;
-            BasicGrid = basicGrid;
+            this.DataGrid = DataGrid;
         }
 
         /// <summary>
@@ -62,13 +63,13 @@ namespace Observatory.Framework
             /// </summary>
             None = 0,
             /// <summary>
-            /// Simple DataGrid, to which items can be added or removed.
+            /// Simple listview, to which items can be added or removed.
             /// </summary>
             Basic = 1,
             /// <summary>
-            /// AvaloniaUI control which is placed in plugin tab.
+            /// Panel control which is placed in plugin tab.
             /// </summary>
-            Avalonia = 2,
+            Panel = 2,
             /// <summary>
             /// UI used by Observatory Core settings tab.<br/>
             /// Not intended for use by plugins.

From 86cd7fe3e46fa638cc8208235e8807926a0edfc2 Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Fri, 7 Jul 2023 08:36:27 -0230
Subject: [PATCH 05/18] WIP: observatory UI overhaul

---
 .vscode/launch.json                           |   4 +-
 .../ObservatoryBotanist.csproj                |   1 +
 .../NativeNotification/NativePopup.cs         |  31 +-
 ObservatoryCore/ObservatoryCore.cs            |   7 +-
 ObservatoryCore/ObservatoryCore.csproj        |   5 +-
 .../PluginManagement/PluginCore.cs            |  18 +-
 .../PluginManagement/PluginManager.cs         |  63 ++--
 ObservatoryCore/UI/CoreForm.Designer.cs       |   2 +
 ObservatoryCore/UI/CoreForm.Plugins.cs        | 109 ++++++
 ObservatoryCore/UI/CoreForm.Settings.cs       | 111 +++++++
 ObservatoryCore/UI/CoreForm.cs                | 217 ++----------
 ObservatoryCore/UI/DefaultSorter.cs           |  64 +++-
 ObservatoryCore/UI/DwmHelper.cs               | 310 +++++++++++++++++
 .../UI/NotificationForm.Designer.cs           |  52 ++-
 ObservatoryCore/UI/NotificationForm.cs        | 204 +++++++++++-
 ObservatoryCore/UI/NotificationForm.resx      |  62 +---
 ObservatoryCore/UI/PluginHelper.cs            |  87 +++--
 ObservatoryCore/UI/SettingsPanel.cs           | 312 ++++++++++++++++--
 ObservatoryCore/Utils/LogMonitor.cs           |   2 +-
 ObservatoryCore/Utils/SettingsManager.cs      |  67 ++++
 ObservatoryDev/ObservatoryDev.sln             |  15 +-
 ObservatoryExplorer/DefaultCriteria.cs        |   4 +
 .../ObservatoryExplorer.csproj                |   9 +-
 ObservatoryFramework/Interfaces.cs            |  36 +-
 .../ObservatoryFramework.csproj               |   5 +
 ObservatoryFramework/ObservatoryFramework.xml |  28 +-
 ObservatoryFramework/PluginUI.cs              |   8 +-
 ObservatoryHerald/ObservatoryHerald.csproj    |   1 +
 28 files changed, 1448 insertions(+), 386 deletions(-)
 create mode 100644 ObservatoryCore/UI/CoreForm.Plugins.cs
 create mode 100644 ObservatoryCore/UI/CoreForm.Settings.cs
 create mode 100644 ObservatoryCore/UI/DwmHelper.cs
 create mode 100644 ObservatoryCore/Utils/SettingsManager.cs

diff --git a/.vscode/launch.json b/.vscode/launch.json
index ebce6d8..9926df6 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -5,12 +5,12 @@
             // Use IntelliSense to find out which attributes exist for C# debugging
             // Use hover for the description of the existing attributes
             // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
-            "name": ".NET Core Launch (console)",
+            "name": ".NET Core Launch (debug)",
             "type": "coreclr",
             "request": "launch",
             "preLaunchTask": "build",
             // If you have changed target frameworks, make sure to update the program path.
-            "program": "${workspaceFolder}/ObservatoryCore/bin/Debug/net5.0/ObservatoryCore.dll",
+            "program": "${workspaceFolder}/ObservatoryCore/bin/debug/net6.0-windows/ObservatoryCore.exe",
             "args": [],
             "cwd": "${workspaceFolder}/ObservatoryCore",
             // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
diff --git a/ObservatoryBotanist/ObservatoryBotanist.csproj b/ObservatoryBotanist/ObservatoryBotanist.csproj
index e89d165..b7dcb13 100644
--- a/ObservatoryBotanist/ObservatoryBotanist.csproj
+++ b/ObservatoryBotanist/ObservatoryBotanist.csproj
@@ -5,6 +5,7 @@
 	<ImplicitUsings>enable</ImplicitUsings>
     <SignAssembly>false</SignAssembly>
     <AssemblyOriginatorKeyFile>ObservatoryKey.snk</AssemblyOriginatorKeyFile>
+    <Configurations>Debug;Release;Portable</Configurations>
   </PropertyGroup>
 
   <PropertyGroup>
diff --git a/ObservatoryCore/NativeNotification/NativePopup.cs b/ObservatoryCore/NativeNotification/NativePopup.cs
index 2f4aed7..eff794e 100644
--- a/ObservatoryCore/NativeNotification/NativePopup.cs
+++ b/ObservatoryCore/NativeNotification/NativePopup.cs
@@ -15,25 +15,29 @@ namespace Observatory.NativeNotification
         public Guid InvokeNativeNotification(NotificationArgs notificationArgs)
         {
             var notificationGuid = Guid.NewGuid();
-            var notification = new NotificationForm()
+            Application.OpenForms[0].Invoke(() =>
             {
-                Guid = notificationGuid
-            };
-            notification.Show();
-            notifications.Add(notificationGuid, notification);
-            
-            //TODO: Implement winform notification
+                var notification = new NotificationForm(notificationGuid, notificationArgs);
 
+                notification.FormClosed += NotifyWindow_Closed;
+
+                notifications.Add(notificationGuid, notification);
+                notification.Show();
+            });
+            
             return notificationGuid;
         }
 
-        private void NotifyWindow_Closed(object sender, EventArgs e)
+        private void NotifyWindow_Closed(object? sender, EventArgs e)
         {
-            var currentNotification = (NotificationForm)sender;
-
-            if (notifications.ContainsKey(currentNotification.Guid))
+            if (sender != null)
             {
-                notifications.Remove(currentNotification.Guid);
+                var currentNotification = (NotificationForm)sender;
+
+                if (notifications.ContainsKey(currentNotification.Guid))
+                {
+                    notifications.Remove(currentNotification.Guid);
+                }
             }
         }
 
@@ -49,8 +53,7 @@ namespace Observatory.NativeNotification
         {
             if (notifications.ContainsKey(guid))
             {
-                //TODO: Update notification content
-                // notifications[guid].DataContext = new NotificationViewModel(notificationArgs);
+                notifications[guid].Update(notificationArgs);
             }
         }
 
diff --git a/ObservatoryCore/ObservatoryCore.cs b/ObservatoryCore/ObservatoryCore.cs
index f3f69cf..4abc1fc 100644
--- a/ObservatoryCore/ObservatoryCore.cs
+++ b/ObservatoryCore/ObservatoryCore.cs
@@ -1,4 +1,5 @@
 using Observatory.PluginManagement;
+using Observatory.Utils;
 using System.Reflection.PortableExecutable;
 
 namespace Observatory
@@ -11,6 +12,8 @@ namespace Observatory
         [STAThread]
         static void Main(string[] args)
         {
+            SettingsManager.Load();
+
             if (args.Length > 0 && File.Exists(args[0]))
             {
                 var fileInfo = new FileInfo(args[0]);
@@ -27,14 +30,14 @@ namespace Observatory
                 {
                     try
                     {
-                        Properties.Core.Default.Upgrade();
+                        // Properties.Core.Default.Upgrade();
                     }
                     catch 
                     {
                         // Silently ignore properties upgrade failure.
                     }
                     Properties.Core.Default.CoreVersion = version;
-                    Properties.Core.Default.Save();
+                    SettingsManager.Save();
                 }
 
                 
diff --git a/ObservatoryCore/ObservatoryCore.csproj b/ObservatoryCore/ObservatoryCore.csproj
index ae449bf..6bd0e88 100644
--- a/ObservatoryCore/ObservatoryCore.csproj
+++ b/ObservatoryCore/ObservatoryCore.csproj
@@ -7,6 +7,7 @@
 	<UseWindowsForms>true</UseWindowsForms>
 	<ImplicitUsings>enable</ImplicitUsings>
 	<RootNamespace>Observatory</RootNamespace>
+	<Configurations>Debug;Release;Portable</Configurations>
 	</PropertyGroup>
 
     <PropertyGroup>
@@ -59,9 +60,9 @@
 	</ItemGroup>
 
 	<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
-		<Exec Condition=" '$(OS)' == 'Windows_NT'" Command="if not exist &quot;$(ProjectDir)..\ObservatoryFramework\bin\Release\net5.0\ObservatoryFramework.dll&quot; dotnet build &quot;$(ProjectDir)..\ObservatoryFramework\ObservatoryFramework.csproj&quot; -c Release" />
+		<Exec Condition=" '$(OS)' == 'Windows_NT'" Command="if not exist &quot;$(ProjectDir)..\ObservatoryFramework\bin\Release\net6.0\ObservatoryFramework.dll&quot; dotnet build &quot;$(ProjectDir)..\ObservatoryFramework\ObservatoryFramework.csproj&quot; -c Release" />
 		<Exec Condition=" '$(OS)' == 'Windows_NT'" Command="if not exist &quot;$(OutDir)plugins\ObservatoryExplorer.dll&quot; dotnet build &quot;$(ProjectDir)..\ObservatoryExplorer\ObservatoryExplorer.csproj&quot; -c $(ConfigurationName)" />
-		<Exec Condition=" '$(OS)' != 'Windows_NT'" Command="[ ! -e &quot;$(ProjectDir)../ObservatoryFramework/bin/Release/net5.0/ObservatoryFramework.dll&quot; ] &amp;&amp; dotnet build &quot;$(ProjectDir)../ObservatoryFramework/ObservatoryFramework.csproj&quot; -c Release || echo No build necessary" />
+		<Exec Condition=" '$(OS)' != 'Windows_NT'" Command="[ ! -e &quot;$(ProjectDir)../ObservatoryFramework/bin/Release/net6.0/ObservatoryFramework.dll&quot; ] &amp;&amp; dotnet build &quot;$(ProjectDir)../ObservatoryFramework/ObservatoryFramework.csproj&quot; -c Release || echo No build necessary" />
 		<Exec Condition=" '$(OS)' != 'Windows_NT'" Command="[ ! -e &quot;$(ProjectDir)$(OutDir)plugins/ObservatoryExplorer.dll&quot; ] &amp;&amp; dotnet build &quot;$(ProjectDir)../ObservatoryExplorer/ObservatoryExplorer.csproj&quot; -c $(ConfigurationName) || echo No build necessary" />
 	</Target>
 	
diff --git a/ObservatoryCore/PluginManagement/PluginCore.cs b/ObservatoryCore/PluginManagement/PluginCore.cs
index 6e696bb..97773c2 100644
--- a/ObservatoryCore/PluginManagement/PluginCore.cs
+++ b/ObservatoryCore/PluginManagement/PluginCore.cs
@@ -105,17 +105,22 @@ namespace Observatory.PluginManagement
 
         public void AddGridItems(IObservatoryWorker worker, IEnumerable<object> items)
         {
-            //TODO: Add to winform list
+            //TODO: Use better bulk handling here.
+            foreach (var item in items)
+            {
+                worker.PluginUI.DataGrid.Add(item);
+            }
         }
 
         public void ClearGrid(IObservatoryWorker worker, object templateItem)
         {
-            //TODO: Clear winform list
+            worker.PluginUI.DataGrid.Clear();
         }
 
         public void ExecuteOnUIThread(Action action)
         {
-            //TODO: Execute action
+            if (Application.OpenForms.Count > 0)
+                Application.OpenForms[0].Invoke(action);
         }
 
         public System.Net.Http.HttpClient HttpClient
@@ -140,7 +145,7 @@ namespace Observatory.PluginManagement
             get
             {
                 var context = new System.Diagnostics.StackFrame(1).GetMethod();
-
+#if DEBUG || RELEASE
                 string folderLocation = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
                     + $"{Path.DirectorySeparatorChar}ObservatoryCore{Path.DirectorySeparatorChar}{context?.DeclaringType?.Assembly.GetName().Name}{Path.DirectorySeparatorChar}";
 
@@ -148,6 +153,11 @@ namespace Observatory.PluginManagement
                     Directory.CreateDirectory(folderLocation);
 
                 return folderLocation;
+#elif PORTABLE
+                string? observatoryLocation = System.Diagnostics.Process.GetCurrentProcess()?.MainModule?.FileName;
+                var obsDir = new FileInfo(observatoryLocation ?? String.Empty).DirectoryName;
+                return $"{obsDir}{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}{context?.DeclaringType?.Assembly.GetName().Name}-Data{Path.DirectorySeparatorChar}";
+#endif
             }
         }
 
diff --git a/ObservatoryCore/PluginManagement/PluginManager.cs b/ObservatoryCore/PluginManagement/PluginManager.cs
index 59cfa73..2df6441 100644
--- a/ObservatoryCore/PluginManagement/PluginManager.cs
+++ b/ObservatoryCore/PluginManagement/PluginManager.cs
@@ -30,7 +30,7 @@ namespace Observatory.PluginManagement
         }
 
 
-        public readonly List<(string error, string detail)> errorList;
+        public readonly List<(string error, string? detail)> errorList;
         public readonly List<Panel> pluginPanels;
         public readonly List<DataTable> pluginTables;
         public readonly List<(IObservatoryWorker plugin, PluginStatus signed)> workerPlugins;
@@ -181,21 +181,22 @@ namespace Observatory.PluginManagement
             });
 
             Properties.Core.Default.PluginSettings = newSettings;
-            Properties.Core.Default.Save();
+            SettingsManager.Save();
         }
 
-        private static List<(string, string)> LoadPlugins(out List<(IObservatoryWorker plugin, PluginStatus signed)> observatoryWorkers, out List<(IObservatoryNotifier plugin, PluginStatus signed)> observatoryNotifiers)
+        private static List<(string, string?)> LoadPlugins(out List<(IObservatoryWorker plugin, PluginStatus signed)> observatoryWorkers, out List<(IObservatoryNotifier plugin, PluginStatus signed)> observatoryNotifiers)
         {
             observatoryWorkers = new();
             observatoryNotifiers = new();
-            var errorList = new List<(string, string)>();
+            var errorList = new List<(string, string?)>();
 
             string pluginPath = $"{AppDomain.CurrentDomain.BaseDirectory}{Path.DirectorySeparatorChar}plugins";
-
-            string ownExe = System.Reflection.Assembly.GetExecutingAssembly().Location;
+            
+            string? ownExe = System.Diagnostics.Process.GetCurrentProcess()?.MainModule?.FileName;
             FileSignatureInfo ownSig;
 
-            using (var stream = File.OpenRead(ownExe))
+            // This will throw if ownExe is null, but that's an error condition regardless.
+            using (var stream = File.OpenRead(ownExe ?? String.Empty)) 
                 ownSig = FileSignatureInfo.GetFromFileStream(stream);
             
 
@@ -259,7 +260,7 @@ namespace Observatory.PluginManagement
                                     if (response == DialogResult.OK)
                                     {
                                         Properties.Core.Default.UnsignedAllowed.Add(pluginHash);
-                                        Properties.Core.Default.Save();
+                                        SettingsManager.Save();
                                     }
                                     else
                                     {
@@ -322,16 +323,16 @@ namespace Observatory.PluginManagement
 
             System.Runtime.Loader.AssemblyLoadContext.Default.Resolving += (context, name) => {
             
-                if (name.Name.EndsWith("resources"))
+                if ((name?.Name?.EndsWith("resources")).GetValueOrDefault(false))
                 {
                     return null;
                 }
 
                 // Importing Observatory.Framework in the Explorer Lua scripts causes an attempt to reload
                 // the assembly, just hand it back the one we already have.
-                if (name.Name.StartsWith("Observatory.Framework") || name.Name == "ObservatoryFramework")
+                if ((name?.Name?.StartsWith("Observatory.Framework")).GetValueOrDefault(false) || name?.Name == "ObservatoryFramework")
                 {
-                    return context.Assemblies.Where(a => a.FullName.Contains("ObservatoryFramework")).First();
+                    return context.Assemblies.Where(a => (a.FullName?.Contains("ObservatoryFramework")).GetValueOrDefault(false)).First();
                 }
 
                 var foundDlls = Directory.GetFileSystemEntries(new FileInfo($"{AppDomain.CurrentDomain.BaseDirectory}{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}deps").FullName, name.Name + ".dll", SearchOption.TopDirectoryOnly);
@@ -340,7 +341,7 @@ namespace Observatory.PluginManagement
                     return context.LoadFromAssemblyPath(foundDlls[0]);
                 }
 
-                if (name.Name != recursionGuard)
+                if (name.Name != recursionGuard && name.Name != null)
                 {
                     recursionGuard = name.Name;
                     return context.LoadFromAssemblyName(name);
@@ -361,37 +362,43 @@ namespace Observatory.PluginManagement
             }
             catch (ReflectionTypeLoadException ex)
             {
-                types = ex.Types.Where(t => t != null).ToArray();
+                types = ex.Types.OfType<Type>().ToArray();
             }
             catch
             {
                 types = Array.Empty<Type>();
             }
 
-            var workerTypes = types.Where(t => t.IsAssignableTo(typeof(IObservatoryWorker)));
-            foreach (var worker in workerTypes)
+            IEnumerable<Type> workerTypes = types.Where(t => t.IsAssignableTo(typeof(IObservatoryWorker)));
+            foreach (Type worker in workerTypes)
             {
-                ConstructorInfo constructor = worker.GetConstructor(Array.Empty<Type>());
-                object instance = constructor.Invoke(Array.Empty<object>());
-                workers.Add((instance as IObservatoryWorker, pluginStatus));
-                if (instance is IObservatoryNotifier)
+                ConstructorInfo? constructor = worker.GetConstructor(Array.Empty<Type>());
+                if (constructor != null)
                 {
-                    // This is also a notifier; add to the notifier list as well, so the work and notifier are
-                    // the same instance and can share state.
-                    notifiers.Add((instance as IObservatoryNotifier, pluginStatus));
+                    object instance = constructor.Invoke(Array.Empty<object>());
+                    workers.Add(((instance as IObservatoryWorker)!, pluginStatus));
+                    if (instance is IObservatoryNotifier)
+                    {
+                        // This is also a notifier; add to the notifier list as well, so the work and notifier are
+                        // the same instance and can share state.
+                        notifiers.Add(((instance as IObservatoryNotifier)!, pluginStatus));
+                    }
+                    pluginCount++;
                 }
-                pluginCount++;
             }
 
             // Filter out items which are also workers as we've already created them above.
             var notifyTypes = types.Where(t =>
                     t.IsAssignableTo(typeof(IObservatoryNotifier)) && !t.IsAssignableTo(typeof(IObservatoryWorker)));
-            foreach (var notifier in notifyTypes)
+            foreach (Type notifier in notifyTypes)
             {
-                ConstructorInfo constructor = notifier.GetConstructor(Array.Empty<Type>());
-                object instance = constructor.Invoke(Array.Empty<object>());
-                notifiers.Add((instance as IObservatoryNotifier, PluginStatus.Signed));
-                pluginCount++;
+                ConstructorInfo? constructor = notifier.GetConstructor(Array.Empty<Type>());
+                if (constructor != null)
+                {
+                    object instance = constructor.Invoke(Array.Empty<object>());
+                    notifiers.Add(((instance as IObservatoryNotifier)!, PluginStatus.Signed));
+                    pluginCount++;
+                }
             }
 
             if (pluginCount == 0)
diff --git a/ObservatoryCore/UI/CoreForm.Designer.cs b/ObservatoryCore/UI/CoreForm.Designer.cs
index 785e87f..5258cbf 100644
--- a/ObservatoryCore/UI/CoreForm.Designer.cs
+++ b/ObservatoryCore/UI/CoreForm.Designer.cs
@@ -360,6 +360,7 @@
             this.TestButton.TabIndex = 12;
             this.TestButton.Text = "Test";
             this.TestButton.UseVisualStyleBackColor = false;
+            this.TestButton.Click += new System.EventHandler(this.TestButton_Click);
             // 
             // ColourButton
             // 
@@ -569,6 +570,7 @@
             this.ToggleMonitorButton.TabIndex = 3;
             this.ToggleMonitorButton.Text = "Start Monitor";
             this.ToggleMonitorButton.UseVisualStyleBackColor = false;
+            this.ToggleMonitorButton.Click += new System.EventHandler(this.ToggleMonitorButton_Click);
             // 
             // ClearButton
             // 
diff --git a/ObservatoryCore/UI/CoreForm.Plugins.cs b/ObservatoryCore/UI/CoreForm.Plugins.cs
new file mode 100644
index 0000000..6b76cfa
--- /dev/null
+++ b/ObservatoryCore/UI/CoreForm.Plugins.cs
@@ -0,0 +1,109 @@
+using Observatory.PluginManagement;
+using Observatory.Framework.Interfaces;
+
+namespace Observatory.UI
+{
+    partial class CoreForm
+    {
+
+        private void PopulatePluginList()
+        {
+            List<IObservatoryPlugin> uniquePlugins = new();
+                        
+            foreach (var (plugin, signed) in PluginManager.GetInstance.workerPlugins)
+            {
+                if (!uniquePlugins.Contains(plugin))
+                {
+                    uniquePlugins.Add(plugin);
+                    ListViewItem item = new ListViewItem(new[] { plugin.Name, "Worker", plugin.Version, PluginStatusString(signed) });
+                    PluginList.Items.Add(item);
+                }
+            }
+
+            foreach (var (plugin, signed) in PluginManager.GetInstance.notifyPlugins)
+            {
+                if (!uniquePlugins.Contains(plugin))
+                {
+                    uniquePlugins.Add(plugin);
+                    ListViewItem item = new ListViewItem(new[] { plugin.Name, "Notifier", plugin.Version, PluginStatusString(signed) });
+                    PluginList.Items.Add(item);
+                }
+            }
+        }
+
+        private static string PluginStatusString(PluginManager.PluginStatus status)
+        {
+            switch (status)
+            {
+                case PluginManager.PluginStatus.Signed:
+                    return "Signed";
+                    
+                case PluginManager.PluginStatus.Unsigned:
+                    return "Unsigned";
+                    
+                case PluginManager.PluginStatus.InvalidSignature:
+                    return "Invalid Signature";
+                    
+                case PluginManager.PluginStatus.InvalidPlugin:
+                    return "Invalid Plugin";
+                    
+                case PluginManager.PluginStatus.InvalidLibrary:
+                    return "Invalid File";
+                    
+                case PluginManager.PluginStatus.NoCert:
+                    return "Unsigned Observatory (Debug build)";
+                    
+                case PluginManager.PluginStatus.SigCheckDisabled:
+                    return "Signature Checks Disabled";
+                    
+                default:
+                    return string.Empty;
+            }
+        }
+
+        private void CreatePluginTabs()
+        {
+            var uiPlugins = PluginManager.GetInstance.workerPlugins.Where(p => p.plugin.PluginUI.PluginUIType != Framework.PluginUI.UIType.None);
+
+            PluginHelper.CreatePluginTabs(CoreMenu, uiPlugins, uiPanels);
+
+            foreach(ToolStripMenuItem item in CoreMenu.Items)
+            {
+                pluginList.Add(item.Text, item);
+            }
+        }
+
+        private void CreatePluginSettings()
+        {
+            foreach (var plugin in PluginManager.GetInstance.workerPlugins)
+            {
+                var pluginSettingsPanel = new SettingsPanel(plugin.plugin, AdjustPanelsBelow);
+                AddSettingsPanel(pluginSettingsPanel);
+            }
+            foreach (var plugin in PluginManager.GetInstance.notifyPlugins)
+            {
+                var pluginSettingsPanel = new SettingsPanel(plugin.plugin, AdjustPanelsBelow);
+                AddSettingsPanel(pluginSettingsPanel);
+            }
+        }
+
+        private void AddSettingsPanel(SettingsPanel panel)
+        {
+            int lowestPoint = 0;
+            foreach (Control control in CorePanel.Controls)
+            {
+                if (control.Location.Y + control.Height > lowestPoint)
+                    lowestPoint = control.Location.Y + control.Height;
+            }
+            DuplicateControlVisuals(PopupNotificationLabel, panel.Header);
+            panel.Header.TextAlign = PopupNotificationLabel.TextAlign;
+            panel.Header.Location = new Point(PopupNotificationLabel.Location.X, lowestPoint);
+
+            DuplicateControlVisuals(PopupSettingsPanel, panel, false);
+            panel.Location = new Point(PopupSettingsPanel.Location.X, lowestPoint + panel.Header.Height);
+            panel.Visible = false;
+            CorePanel.Controls.Add(panel.Header);
+            CorePanel.Controls.Add(panel);
+        }
+    }
+}
\ No newline at end of file
diff --git a/ObservatoryCore/UI/CoreForm.Settings.cs b/ObservatoryCore/UI/CoreForm.Settings.cs
new file mode 100644
index 0000000..180877e
--- /dev/null
+++ b/ObservatoryCore/UI/CoreForm.Settings.cs
@@ -0,0 +1,111 @@
+using Observatory.Utils;
+
+namespace Observatory.UI
+{
+    partial class CoreForm
+    {
+        private void ColourButton_Click(object _, EventArgs e)
+        {
+            var selectionResult = PopupColour.ShowDialog();
+            if (selectionResult == DialogResult.OK)
+            {
+                ColourButton.BackColor = PopupColour.Color;
+                Properties.Core.Default.NativeNotifyColour = (uint)PopupColour.Color.ToArgb();
+                SettingsManager.Save();
+            }
+        }
+
+        private void PopupCheckbox_CheckedChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotify = PopupCheckbox.Checked;
+            SettingsManager.Save();
+        }
+
+        private void DurationSpinner_ValueChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyTimeout = (int)DurationSpinner.Value;
+            SettingsManager.Save();
+        }
+
+        private void ScaleSpinner_ValueChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyScale = (int)ScaleSpinner.Value;
+            SettingsManager.Save();
+        }
+
+        private void FontDropdown_SelectedIndexChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyFont = FontDropdown.SelectedItem.ToString();
+            SettingsManager.Save();
+        }
+
+        private void CornerDropdown_SelectedIndexChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyCorner = CornerDropdown.SelectedIndex;
+            SettingsManager.Save();
+        }
+
+        private void DisplayDropdown_SelectedIndexChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.NativeNotifyScreen = DisplayDropdown.SelectedIndex - 1;
+            SettingsManager.Save();
+        }
+
+        private void VoiceVolumeSlider_Scroll(object _, EventArgs e)
+        {
+            Properties.Core.Default.VoiceVolume = VoiceVolumeSlider.Value;
+            SettingsManager.Save();
+        }
+
+        private void VoiceSpeedSlider_Scroll(object _, EventArgs e)
+        {
+            Properties.Core.Default.VoiceRate = VoiceSpeedSlider.Value;
+            SettingsManager.Save();
+        }
+
+        private void VoiceCheckbox_CheckedChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.VoiceNotify = VoiceCheckbox.Checked;
+            SettingsManager.Save();
+        }
+
+        private void VoiceDropdown_SelectedIndexChanged(object _, EventArgs e)
+        {
+            Properties.Core.Default.VoiceSelected = VoiceDropdown.SelectedItem.ToString();
+            SettingsManager.Save();
+        }
+
+        private void PopulateDropdownOptions()
+        {
+            var fonts = new System.Drawing.Text.InstalledFontCollection().Families;
+            FontDropdown.Items.AddRange(fonts.Select(f => f.Name).ToArray());
+
+            DisplayDropdown.Items.Add("Primary");
+            if (Screen.AllScreens.Length > 1)
+                for (int i = 0; i < Screen.AllScreens.Length; i++)
+                    DisplayDropdown.Items.Add((i + 1).ToString());
+
+            var voices = new System.Speech.Synthesis.SpeechSynthesizer().GetInstalledVoices();
+            foreach (var voice in voices.Select(v => v.VoiceInfo.Name))
+                VoiceDropdown.Items.Add(voice);
+            
+        }
+
+        private void PopulateNativeSettings()
+        {
+            var settings = Properties.Core.Default;
+
+            DisplayDropdown.SelectedIndex = settings.NativeNotifyScreen + 1;
+            CornerDropdown.SelectedIndex = settings.NativeNotifyCorner;
+            FontDropdown.SelectedItem = settings.NativeNotifyFont;
+            ScaleSpinner.Value = settings.NativeNotifyScale;
+            DurationSpinner.Value = settings.NativeNotifyTimeout;
+            ColourButton.BackColor = Color.FromArgb((int)settings.NativeNotifyColour);
+            PopupCheckbox.Checked = settings.NativeNotify;
+            VoiceVolumeSlider.Value = settings.VoiceVolume;
+            VoiceSpeedSlider.Value = settings.VoiceRate;
+            VoiceDropdown.SelectedItem = settings.VoiceSelected;
+            VoiceCheckbox.Checked = settings.VoiceNotify;
+        }
+    }
+}
\ No newline at end of file
diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
index e3da322..03aefe9 100644
--- a/ObservatoryCore/UI/CoreForm.cs
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -1,6 +1,9 @@
-using Observatory.Framework.Interfaces;
+using Observatory.Framework;
+using Observatory.Framework.Interfaces;
 using Observatory.PluginManagement;
 using Observatory.Utils;
+using System.Text;
+using System.Windows.Forms;
 
 namespace Observatory.UI
 {
@@ -37,40 +40,6 @@ namespace Observatory.UI
             AdjustPanelsBelow(PopupSettingsPanel, AdjustmentDirection.Up);
         }
 
-        private void PopulateDropdownOptions()
-        {
-            var fonts = new System.Drawing.Text.InstalledFontCollection().Families;
-            FontDropdown.Items.AddRange(fonts.Select(f => f.Name).ToArray());
-
-            DisplayDropdown.Items.Add("Primary");
-            if (Screen.AllScreens.Length > 1)
-                for (int i = 0; i < Screen.AllScreens.Length; i++)
-                    DisplayDropdown.Items.Add((i + 1).ToString());
-
-            var voices = new System.Speech.Synthesis.SpeechSynthesizer().GetInstalledVoices();
-            foreach (var voice in voices.Select(v => v.VoiceInfo.Name))
-                VoiceDropdown.Items.Add(voice);
-            
-        }
-
-        private void PopulateNativeSettings()
-        {
-            var settings = Properties.Core.Default;
-
-            DisplayDropdown.SelectedIndex = settings.NativeNotifyScreen + 1;
-            CornerDropdown.SelectedIndex = settings.NativeNotifyCorner;
-            FontDropdown.SelectedItem = settings.NativeNotifyFont;
-            ScaleSpinner.Value = settings.NativeNotifyScale;
-            DurationSpinner.Value = settings.NativeNotifyTimeout;
-            ColourButton.BackColor = Color.FromArgb((int)settings.NativeNotifyColour);
-            PopupCheckbox.Checked = settings.NativeNotify;
-            VoiceVolumeSlider.Value = settings.VoiceVolume;
-            VoiceSpeedSlider.Value = settings.VoiceRate;
-            VoiceDropdown.SelectedItem = settings.VoiceSelected;
-            VoiceCheckbox.Checked = settings.VoiceNotify;
-        }
-
-
         private void CoreMenu_SizeChanged(object? sender, EventArgs e)
         {
             CorePanel.Location = new Point(12 + CoreMenu.Width, 12);
@@ -80,95 +49,27 @@ namespace Observatory.UI
 
         private Dictionary<string, ToolStripMenuItem> pluginList;
 
-        private void CreatePluginTabs()
+        private static void DuplicateControlVisuals(Control source, Control target, bool applyHeight = true)
         {
-            var uiPlugins = PluginManager.GetInstance.workerPlugins.Where(p => p.plugin.PluginUI.PluginUIType != Framework.PluginUI.UIType.None);
-
-            PluginHelper.CreatePluginTabs(CoreMenu, uiPlugins, uiPanels);
-
-            foreach(ToolStripMenuItem item in CoreMenu.Items)
-            {
-                pluginList.Add(item.Text, item);
-            }
+            if (applyHeight) target.Height = source.Height;
+            target.Width = source.Width;
+            target.Font = source.Font;
+            target.ForeColor = source.ForeColor;
+            target.BackColor = source.BackColor;
+            target.Anchor = source.Anchor;
         }
 
-        private void CreatePluginSettings()
+        private void ToggleMonitorButton_Click(object sender, EventArgs e)
         {
-            foreach (var plugin in PluginManager.GetInstance.workerPlugins)
+            if ((LogMonitor.GetInstance.CurrentState & Framework.LogMonitorState.Realtime) == Framework.LogMonitorState.Realtime)
             {
-                var pluginSettingsPanel = new SettingsPanel(plugin.plugin, AdjustPanelsBelow);
-                AddSettingsPanel(pluginSettingsPanel);
+                LogMonitor.GetInstance.Stop();
+                ToggleMonitorButton.Text = "Start Monitor";
             }
-            foreach (var plugin in PluginManager.GetInstance.notifyPlugins)
+            else
             {
-                var pluginSettingsPanel = new SettingsPanel(plugin.plugin, AdjustPanelsBelow);
-                AddSettingsPanel(pluginSettingsPanel);
-            }
-        }
-
-        private void AddSettingsPanel(SettingsPanel panel)
-        {
-            int lowestPoint = 0;
-            foreach (Control control in CorePanel.Controls)
-            {
-                if (control.Location.Y + control.Height > lowestPoint)
-                    lowestPoint = control.Location.Y + control.Height;
-            }
-            panel.Header.Location = new Point(PopupNotificationLabel.Location.X, lowestPoint);
-            panel.Header.Width = PopupNotificationLabel.Width;
-            panel.Header.Font = PopupNotificationLabel.Font;
-            panel.Header.ForeColor = PopupNotificationLabel.ForeColor;
-            panel.Header.BackColor = PopupNotificationLabel.BackColor;
-            panel.Header.TextAlign = PopupNotificationLabel.TextAlign;
-            panel.Location = new Point(PopupNotificationLabel.Location.X, lowestPoint + panel.Header.Height);
-            panel.Width = PopupSettingsPanel.Width;
-            CorePanel.Controls.Add(panel.Header);
-            CorePanel.Controls.Add(panel);
-        }
-
-        private void PopulatePluginList()
-        {
-            List<IObservatoryPlugin> uniquePlugins = new();
-
-            
-            foreach (var (plugin, signed) in PluginManager.GetInstance.workerPlugins)
-            {
-                if (!uniquePlugins.Contains(plugin))
-                {
-                    uniquePlugins.Add(plugin);
-                    ListViewItem item = new ListViewItem(new[] { plugin.Name, "Worker", plugin.Version, PluginStatusString(signed) });
-                    PluginList.Items.Add(item);
-                }
-            }
-        }
-
-        private static string PluginStatusString(PluginManager.PluginStatus status)
-        {
-            switch (status)
-            {
-                case PluginManager.PluginStatus.Signed:
-                    return "Signed";
-                    
-                case PluginManager.PluginStatus.Unsigned:
-                    return "Unsigned";
-                    
-                case PluginManager.PluginStatus.InvalidSignature:
-                    return "Invalid Signature";
-                    
-                case PluginManager.PluginStatus.InvalidPlugin:
-                    return "Invalid Plugin";
-                    
-                case PluginManager.PluginStatus.InvalidLibrary:
-                    return "Invalid File";
-                    
-                case PluginManager.PluginStatus.NoCert:
-                    return "Unsigned Observatory (Debug build)";
-                    
-                case PluginManager.PluginStatus.SigCheckDisabled:
-                    return "Signature Checks Disabled";
-                    
-                default:
-                    return string.Empty;
+                LogMonitor.GetInstance.Start();
+                ToggleMonitorButton.Text = "Stop Monitor";
             }
         }
 
@@ -337,82 +238,16 @@ namespace Observatory.UI
             Up, Down
         }
 
-        #region Settings Changes
-
-        private void ColourButton_Click(object _, EventArgs e)
+        private void TestButton_Click(object sender, EventArgs e)
         {
-            var selectionResult = PopupColour.ShowDialog();
-            if (selectionResult == DialogResult.OK)
+            NotificationArgs args = new()
             {
-                ColourButton.BackColor = PopupColour.Color;
-                Properties.Core.Default.NativeNotifyColour = (uint)PopupColour.Color.ToArgb();
-                Properties.Core.Default.Save();
-            }
+                Title = "Test Notification",
+                Detail = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec at elit maximus, ornare dui nec, accumsan velit. Vestibulum fringilla elit."
+            };
+            var testNotify = new NotificationForm(new Guid(), args);
+            testNotify.Show();
+
         }
-
-        private void PopupCheckbox_CheckedChanged(object _, EventArgs e)
-        {
-            Properties.Core.Default.NativeNotify = PopupCheckbox.Checked;
-            Properties.Core.Default.Save();
-        }
-
-        private void DurationSpinner_ValueChanged(object _, EventArgs e)
-        {
-            Properties.Core.Default.NativeNotifyTimeout = (int)DurationSpinner.Value;
-            Properties.Core.Default.Save();
-        }
-
-        private void ScaleSpinner_ValueChanged(object _, EventArgs e)
-        {
-            Properties.Core.Default.NativeNotifyScale = (int)ScaleSpinner.Value;
-            Properties.Core.Default.Save();
-        }
-
-        private void FontDropdown_SelectedIndexChanged(object _, EventArgs e)
-        {
-            Properties.Core.Default.NativeNotifyFont = FontDropdown.SelectedItem.ToString();
-            Properties.Core.Default.Save();
-        }
-
-        private void CornerDropdown_SelectedIndexChanged(object _, EventArgs e)
-        {
-            Properties.Core.Default.NativeNotifyCorner = CornerDropdown.SelectedIndex;
-            Properties.Core.Default.Save();
-        }
-
-        private void DisplayDropdown_SelectedIndexChanged(object _, EventArgs e)
-        {
-            Properties.Core.Default.NativeNotifyScreen = DisplayDropdown.SelectedIndex - 1;
-            Properties.Core.Default.Save();
-        }
-
-        private void VoiceVolumeSlider_Scroll(object _, EventArgs e)
-        {
-            Properties.Core.Default.VoiceVolume = VoiceVolumeSlider.Value;
-            Properties.Core.Default.Save();
-        }
-
-        private void VoiceSpeedSlider_Scroll(object _, EventArgs e)
-        {
-            Properties.Core.Default.VoiceRate = VoiceSpeedSlider.Value;
-            Properties.Core.Default.Save();
-        }
-
-        private void VoiceCheckbox_CheckedChanged(object _, EventArgs e)
-        {
-            Properties.Core.Default.VoiceNotify = VoiceCheckbox.Checked;
-            Properties.Core.Default.Save();
-        }
-
-        private void VoiceDropdown_SelectedIndexChanged(object _, EventArgs e)
-        {
-            Properties.Core.Default.VoiceSelected = VoiceDropdown.SelectedItem.ToString();
-            Properties.Core.Default.Save();
-        }
-
-
-        #endregion
-
-
     }
 }
\ No newline at end of file
diff --git a/ObservatoryCore/UI/DefaultSorter.cs b/ObservatoryCore/UI/DefaultSorter.cs
index 040859d..be77f8a 100644
--- a/ObservatoryCore/UI/DefaultSorter.cs
+++ b/ObservatoryCore/UI/DefaultSorter.cs
@@ -3,10 +3,11 @@ using System.Collections;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Observatory.Framework.Interfaces;
 
 namespace Observatory.UI
 {
-    internal class DefaultSorter : IComparer
+    internal class DefaultSorter : IObservatoryComparer
     {
         /// <summary>
         /// Specifies the column to be sorted
@@ -15,7 +16,7 @@ namespace Observatory.UI
         /// <summary>
         /// Specifies the order in which to sort (i.e. 'Ascending').
         /// </summary>
-        private SortOrder OrderOfSort;
+        private int OrderOfSort;
         /// <summary>
         /// Case insensitive comparer object
         /// </summary>
@@ -30,7 +31,7 @@ namespace Observatory.UI
             ColumnToSort = 0;
 
             // Initialize the sort order to 'none'
-            OrderOfSort = SortOrder.None;
+            OrderOfSort = 0;
 
             // Initialize the CaseInsensitiveComparer object
             ObjectCompare = new CaseInsensitiveComparer();
@@ -49,25 +50,68 @@ namespace Observatory.UI
             ListViewItem? listviewX = (ListViewItem?)x;
             ListViewItem? listviewY = (ListViewItem?)y;
                                     
+            if (OrderOfSort == 0)
+                return 0;
+
             // Compare the two items
-            compareResult = ObjectCompare.Compare(listviewX?.SubItems[ColumnToSort].Text, listviewY?.SubItems[ColumnToSort].Text);
+            compareResult = NaturalCompare(listviewX?.SubItems[ColumnToSort].Text, listviewY?.SubItems[ColumnToSort].Text);
 
             // Calculate correct return value based on object comparison
-            if (OrderOfSort == SortOrder.Ascending)
+            if (OrderOfSort == 1)
             {
                 // Ascending sort is selected, return normal result of compare operation
                 return compareResult;
             }
-            else if (OrderOfSort == SortOrder.Descending)
+            else 
             {
                 // Descending sort is selected, return negative result of compare operation
                 return (-compareResult);
             }
-            else
+        }
+
+        private static int NaturalCompare(string? x, string? y)
+        {
+            for (int i = 0; i <= x?.Length && i <= y?.Length; i++)
             {
-                // Return '0' to indicate they are equal
-                return 0;
+                // If we've reached the end of the string without finding a difference
+                // the longer string is "greater".
+                if (i == x.Length || i == y.Length)
+                    return x.Length > y.Length ? 1 : y.Length > x.Length ? -1 : 0;
+
+                // We've found a number in the same place in both strings.
+                if (Char.IsDigit(x[i]) && Char.IsDigit(y[i]))
+                {
+                    // Walk ahead and get the full numbers.
+                    string xNum = new(x[i..].TakeWhile(c => Char.IsDigit(c)).ToArray());
+                    string yNum = new(y[i..].TakeWhile(c => Char.IsDigit(c)).ToArray());
+
+                    // Pad with zeroes to equal lengths.
+                    int numLength = Math.Max(xNum.Length, yNum.Length);
+                    string xNumPadded = xNum.PadLeft(numLength, '0');
+                    string yNumPadded = yNum.PadLeft(numLength, '0');
+
+                    // Now that they're the same length a direct compare works.
+                    int result = xNumPadded.CompareTo(yNumPadded);
+                    if (result != 0)
+                    {
+                        return result;
+                    }
+                    else
+                    {
+                        // The numbers are identical, skip them and keep moving.
+                        i += numLength - 1;
+                    }
+                }
+                // Check if we have unequal letters.
+                else if (x[i] != y[i])
+                {
+                    // Straight compare and return.
+                    return x[i] > y[i] ? 1 : -1;
+                }
             }
+
+            // If we somehow make it here, return equal result.
+            return 0;
         }
 
         /// <summary>
@@ -88,7 +132,7 @@ namespace Observatory.UI
         /// <summary>
         /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
         /// </summary>
-        public SortOrder Order
+        public int Order
         {
             set
             {
diff --git a/ObservatoryCore/UI/DwmHelper.cs b/ObservatoryCore/UI/DwmHelper.cs
new file mode 100644
index 0000000..5724088
--- /dev/null
+++ b/ObservatoryCore/UI/DwmHelper.cs
@@ -0,0 +1,310 @@
+// Source: https://stackoverflow.com/questions/51578104/how-to-create-a-semi-transparent-or-blurred-backcolor-in-a-windows-form
+
+using System.Runtime.InteropServices;
+using System.Security;
+
+[SuppressUnmanagedCodeSecurity]
+public class DwmHelper
+{
+    public const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
+
+    public struct MARGINS
+    {
+        public int leftWidth;
+        public int rightWidth;
+        public int topHeight;
+        public int bottomHeight;
+
+        public MARGINS(int LeftWidth, int RightWidth, int TopHeight, int BottomHeight)
+        {
+            leftWidth = LeftWidth;
+            rightWidth = RightWidth;
+            topHeight = TopHeight;
+            bottomHeight = BottomHeight;
+        }
+
+        public void NoMargins()
+        {
+            leftWidth = 0;
+            rightWidth = 0;
+            topHeight = 0;
+            bottomHeight = 0;
+        }
+
+        public void SheetOfGlass()
+        {
+            leftWidth = -1;
+            rightWidth = -1;
+            topHeight = -1;
+            bottomHeight = -1;
+        }
+    }
+
+    [Flags]
+    public enum DWM_BB
+    {
+        Enable = 1,
+        BlurRegion = 2,
+        TransitionOnMaximized = 4
+    }
+
+    // https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
+    public enum DWMWINDOWATTRIBUTE : uint
+    {
+        NCRenderingEnabled = 1,       //Get atttribute
+        NCRenderingPolicy,            //Enable or disable non-client rendering
+        TransitionsForceDisabled,
+        AllowNCPaint,
+        CaptionButtonBounds,          //Get atttribute
+        NonClientRtlLayout,
+        ForceIconicRepresentation,
+        Flip3DPolicy,
+        ExtendedFrameBounds,          //Get atttribute
+        HasIconicBitmap,
+        DisallowPeek,
+        ExcludedFromPeek,
+        Cloak,
+        Cloaked,                      //Get atttribute. Returns a DWMCLOACKEDREASON
+        FreezeRepresentation,
+        PassiveUpdateMode,
+        UseHostBackDropBrush,
+        AccentPolicy = 19,            // Win 10 (undocumented)
+        ImmersiveDarkMode = 20,       // Win 11 22000
+        WindowCornerPreference = 33,  // Win 11 22000
+        BorderColor,                  // Win 11 22000
+        CaptionColor,                 // Win 11 22000
+        TextColor,                    // Win 11 22000
+        VisibleFrameBorderThickness,  // Win 11 22000
+        SystemBackdropType            // Win 11 22621
+    }
+
+    public enum DWMCLOACKEDREASON : uint
+    {
+        DWM_CLOAKED_APP = 0x0000001,       //cloaked by its owner application.
+        DWM_CLOAKED_SHELL = 0x0000002,     //cloaked by the Shell.
+        DWM_CLOAKED_INHERITED = 0x0000004  //inherited from its owner window.
+    }
+
+    public enum DWMNCRENDERINGPOLICY : uint
+    {
+        UseWindowStyle, // Enable/disable non-client rendering based on window style
+        Disabled,       // Disabled non-client rendering; window style is ignored
+        Enabled,        // Enabled non-client rendering; window style is ignored
+    };
+
+    public enum DWMACCENTSTATE
+    {
+        ACCENT_DISABLED = 0,
+        ACCENT_ENABLE_GRADIENT = 1,
+        ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
+        ACCENT_ENABLE_BLURBEHIND = 3,
+        ACCENT_INVALID_STATE = 4
+    }
+
+    [Flags]
+    public enum CompositionAction : uint
+    {
+        DWM_EC_DISABLECOMPOSITION = 0,
+        DWM_EC_ENABLECOMPOSITION = 1
+    }
+
+    // Values designating how Flip3D treats a given window.
+    enum DWMFLIP3DWINDOWPOLICY : uint
+    {
+        Default,        // Hide or include the window in Flip3D based on window style and visibility.
+        ExcludeBelow,   // Display the window under Flip3D and disabled.
+        ExcludeAbove,   // Display the window above Flip3D and enabled.
+    };
+
+    public enum ThumbProperties_dwFlags : uint
+    {
+        RectDestination = 0x00000001,
+        RectSource = 0x00000002,
+        Opacity = 0x00000004,
+        Visible = 0x00000008,
+        SourceClientAreaOnly = 0x00000010
+    }
+
+
+    [StructLayout(LayoutKind.Sequential)]
+    public struct AccentPolicy
+    {
+        public DWMACCENTSTATE AccentState;
+        public int AccentFlags;
+        public int GradientColor;
+        public int AnimationId;
+
+        public AccentPolicy(DWMACCENTSTATE accentState, int accentFlags, int gradientColor, int animationId)
+        {
+            AccentState = accentState;
+            AccentFlags = accentFlags;
+            GradientColor = gradientColor;
+            AnimationId = animationId;
+        }
+    }
+
+    [StructLayout(LayoutKind.Sequential)]
+    public struct DWM_BLURBEHIND
+    {
+        public DWM_BB dwFlags;
+        public int fEnable;
+        public IntPtr hRgnBlur;
+        public int fTransitionOnMaximized;
+
+        public DWM_BLURBEHIND(bool enabled)
+        {
+            dwFlags = DWM_BB.Enable;
+            fEnable = (enabled) ? 1 : 0;
+            hRgnBlur = IntPtr.Zero;
+            fTransitionOnMaximized = 0;
+        }
+
+        public Region Region => Region.FromHrgn(hRgnBlur);
+
+        public bool TransitionOnMaximized
+        {
+            get => fTransitionOnMaximized > 0;
+            set
+            {
+                fTransitionOnMaximized = (value) ? 1 : 0;
+                dwFlags |= DWM_BB.TransitionOnMaximized;
+            }
+        }
+
+        public void SetRegion(Graphics graphics, Region region)
+        {
+            hRgnBlur = region.GetHrgn(graphics);
+            dwFlags |= DWM_BB.BlurRegion;
+        }
+    }
+
+    [StructLayout(LayoutKind.Sequential)]
+    public struct WinCompositionAttrData
+    {
+        public DWMWINDOWATTRIBUTE Attribute;
+        public IntPtr Data;  //Will point to an AccentPolicy struct, where Attribute will be DWMWINDOWATTRIBUTE.AccentPolicy
+        public int SizeOfData;
+
+        public WinCompositionAttrData(DWMWINDOWATTRIBUTE attribute, IntPtr data, int sizeOfData)
+        {
+            Attribute = attribute;
+            Data = data;
+            SizeOfData = sizeOfData;
+        }
+    }
+
+    private static int GetBlurBehindPolicyAccentFlags()
+    {
+        int drawLeftBorder = 20;
+        int drawTopBorder = 40;
+        int drawRightBorder = 80;
+        int drawBottomBorder = 100;
+        return (drawLeftBorder | drawTopBorder | drawRightBorder | drawBottomBorder);
+    }
+
+    //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969508(v=vs.85).aspx
+    [DllImport("dwmapi.dll")]
+    internal static extern int DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);
+
+    [DllImport("dwmapi.dll", PreserveSig = false)]
+    public static extern void DwmEnableComposition(CompositionAction uCompositionAction);
+
+    //https://msdn.microsoft.com/it-it/library/windows/desktop/aa969512(v=vs.85).aspx
+    [DllImport("dwmapi.dll")]
+    internal static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
+
+    //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969515(v=vs.85).aspx
+    [DllImport("dwmapi.dll")]
+    internal static extern int DwmGetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);
+
+    //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969524(v=vs.85).aspx
+    [DllImport("dwmapi.dll")]
+    internal static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);
+
+    [DllImport("User32.dll", SetLastError = true)]
+    internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WinCompositionAttrData data);
+
+    [DllImport("dwmapi.dll")]
+    internal static extern int DwmIsCompositionEnabled(ref int pfEnabled);
+
+    public static bool IsCompositionEnabled()
+    {
+        int pfEnabled = 0;
+        int result = DwmIsCompositionEnabled(ref pfEnabled);
+        return (pfEnabled == 1) ? true : false;
+    }
+
+    public static bool IsNonClientRenderingEnabled(IntPtr hWnd)
+    {
+        int gwaEnabled = 0;
+        int result = DwmGetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingEnabled, ref gwaEnabled, sizeof(int));
+        return gwaEnabled == 1;
+    }
+
+    public static bool WindowSetAttribute(IntPtr hWnd, DWMWINDOWATTRIBUTE attribute, int attributeValue)
+    {
+        int result = DwmSetWindowAttribute(hWnd, attribute, ref attributeValue, sizeof(int));
+        return (result == 0);
+    }
+
+    public static void Windows10EnableBlurBehind(IntPtr hWnd)
+    {
+        DWMNCRENDERINGPOLICY policy = DWMNCRENDERINGPOLICY.Enabled;
+        WindowSetAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);
+
+        AccentPolicy accPolicy = new AccentPolicy()
+        {
+            AccentState = DWMACCENTSTATE.ACCENT_ENABLE_BLURBEHIND,
+        };
+
+        int accentSize = Marshal.SizeOf(accPolicy);
+        IntPtr accentPtr = Marshal.AllocHGlobal(accentSize);
+        Marshal.StructureToPtr(accPolicy, accentPtr, false);
+        var data = new WinCompositionAttrData(DWMWINDOWATTRIBUTE.AccentPolicy, accentPtr, accentSize);
+
+        SetWindowCompositionAttribute(hWnd, ref data);
+        Marshal.FreeHGlobal(accentPtr);
+    }
+
+    public static bool WindowEnableBlurBehind(IntPtr hWnd)
+    {
+        DWMNCRENDERINGPOLICY policy = DWMNCRENDERINGPOLICY.Enabled;
+        WindowSetAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);
+
+        DWM_BLURBEHIND dwm_BB = new DWM_BLURBEHIND(true);
+        int result = DwmEnableBlurBehindWindow(hWnd, ref dwm_BB);
+        return result == 0;
+    }
+
+    public static bool WindowExtendIntoClientArea(IntPtr hWnd, MARGINS margins)
+    {
+        // Extend frame on the bottom of client area
+        int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);
+        return result == 0;
+    }
+
+    public static bool WindowBorderlessDropShadow(IntPtr hWnd, int shadowSize)
+    {
+        MARGINS margins = new MARGINS(0, shadowSize, 0, shadowSize);
+        int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);
+        return result == 0;
+    }
+
+    public static bool WindowSheetOfGlass(IntPtr hWnd)
+    {
+        MARGINS margins = new MARGINS();
+
+        //Margins set to All:-1 - Sheet Of Glass effect
+        margins.SheetOfGlass();
+        int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);
+        return result == 0;
+    }
+
+    public static bool WindowDisableRendering(IntPtr hWnd)
+    {
+        int ncrp = (int)DWMNCRENDERINGPOLICY.Disabled;
+        // Disable non-client area rendering on the window.
+        int result = DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, ref ncrp, sizeof(int));
+        return result == 0;
+    }
+}
\ No newline at end of file
diff --git a/ObservatoryCore/UI/NotificationForm.Designer.cs b/ObservatoryCore/UI/NotificationForm.Designer.cs
index 012e455..444350b 100644
--- a/ObservatoryCore/UI/NotificationForm.Designer.cs
+++ b/ObservatoryCore/UI/NotificationForm.Designer.cs
@@ -28,12 +28,60 @@
         /// </summary>
         private void InitializeComponent()
         {
-            this.components = new System.ComponentModel.Container();
+            this.Title = new System.Windows.Forms.Label();
+            this.Body = new System.Windows.Forms.Label();
+            this.SuspendLayout();
+            // 
+            // Title
+            // 
+            this.Title.Font = new System.Drawing.Font("Segoe UI", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+            this.Title.ForeColor = System.Drawing.Color.OrangeRed;
+            this.Title.Location = new System.Drawing.Point(5, 5);
+            this.Title.MaximumSize = new System.Drawing.Size(355, 0);
+            this.Title.Name = "Title";
+            this.Title.Size = new System.Drawing.Size(338, 45);
+            this.Title.TabIndex = 0;
+            this.Title.Text = "Title";
+            // 
+            // Body
+            // 
+            this.Body.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.Body.AutoSize = true;
+            this.Body.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+            this.Body.ForeColor = System.Drawing.Color.OrangeRed;
+            this.Body.Location = new System.Drawing.Point(12, 45);
+            this.Body.MaximumSize = new System.Drawing.Size(320, 85);
+            this.Body.Name = "Body";
+            this.Body.Size = new System.Drawing.Size(51, 31);
+            this.Body.TabIndex = 1;
+            this.Body.Text = "Body";
+            this.Body.UseCompatibleTextRendering = true;
+            // 
+            // NotificationForm
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(800, 450);
+            this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
+            this.ClientSize = new System.Drawing.Size(355, 145);
+            this.ControlBox = false;
+            this.Controls.Add(this.Body);
+            this.Controls.Add(this.Title);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
+            this.Name = "NotificationForm";
+            this.ShowIcon = false;
+            this.ShowInTaskbar = false;
             this.Text = "NotificationForm";
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
         }
 
         #endregion
+
+        private Label Title;
+        private Label Body;
     }
 }
\ No newline at end of file
diff --git a/ObservatoryCore/UI/NotificationForm.cs b/ObservatoryCore/UI/NotificationForm.cs
index 26c5ef2..dee4e2e 100644
--- a/ObservatoryCore/UI/NotificationForm.cs
+++ b/ObservatoryCore/UI/NotificationForm.cs
@@ -1,9 +1,12 @@
-using System;
+using Observatory.Framework;
+using Observatory.Framework.Files.Journal;
+using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Data;
 using System.Drawing;
 using System.Linq;
+using System.Runtime.InteropServices;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows.Forms;
@@ -12,11 +15,206 @@ namespace Observatory.UI
 {
     public partial class NotificationForm : Form
     {
-        public NotificationForm()
+        private Color _color;
+        private readonly Guid _guid;
+        private readonly System.Timers.Timer _timer;
+        private bool _defaultPosition = true;
+        private Point _originalLocation;
+
+        protected override bool ShowWithoutActivation => true;
+        protected override CreateParams CreateParams
+        { 
+            get
+            {
+                CreateParams cp = base.CreateParams;
+                cp.ExStyle |= 0x00000008; // WS_EX_TOPMOST
+                return cp;
+            }
+        }
+          
+        public NotificationForm(Guid guid, NotificationArgs args)
         {
+            _guid = guid;
+            _color = Color.FromArgb((int)Properties.Core.Default.NativeNotifyColour);
             InitializeComponent();
+
+            Title.Paint += DrawText;
+            Body.Paint += DrawText;
+
+            if (System.Environment.OSVersion.Version.Major >= 6 && DwmHelper.IsCompositionEnabled())
+            {
+                if (Environment.OSVersion.Version.Major > 6)
+                {
+                    DwmHelper.Windows10EnableBlurBehind(Handle);
+                }
+                else
+                {
+                    DwmHelper.WindowEnableBlurBehind(Handle);
+                }
+
+                // For some reason this causes the window to become all white on my own
+                // PC. Looks very similar to strange system-specific all-white behaviour
+                // of Avalonia.
+                // DwmHelper.WindowBorderlessDropShadow(Handle, 2);
+            }
+
+
+            Title.ForeColor = _color;
+            Title.Text = args.Title;
+            Title.Font = new Font(Properties.Core.Default.NativeNotifyFont, 24);
+            Body.ForeColor = _color;
+            Body.Text = args.Detail;
+            Body.Font = new Font(Properties.Core.Default.NativeNotifyFont, 14);
+            this.Paint += DrawBorder;
+
+            AdjustPosition(args.XPos / 100, args.YPos / 100);
+
+            _timer = new();
+            _timer.Elapsed += CloseNotification;
+            if (args.Timeout != 0)
+            {
+                _timer.Interval = args.Timeout == -1 ? Properties.Core.Default.NativeNotifyTimeout : args.Timeout;
+                _timer.Start();
+            }
         }
 
-        public Guid Guid;
+        public void Update(NotificationArgs notificationArgs)
+        {
+            Title.Text = notificationArgs.Title;
+            Body.Text = notificationArgs.Detail;
+        }
+
+        private void AdjustPosition(double x = -1.0, double y = -1.0)
+        {
+            int screen = Properties.Core.Default.NativeNotifyScreen;
+            int corner = Properties.Core.Default.NativeNotifyCorner;
+            Rectangle screenBounds;
+
+
+            if (screen == -1 || screen > Screen.AllScreens.Length)
+                if (Screen.AllScreens.Length == 1)
+                    screenBounds = Screen.GetBounds(this);
+                else
+                    screenBounds = Screen.PrimaryScreen.Bounds;
+            else
+                screenBounds = Screen.AllScreens[screen - 1].Bounds;
+
+            if (x >= 0 && y >= 0)
+            {
+                _defaultPosition = false;
+                int xLocation = Convert.ToInt32(screenBounds.Width * x);
+                int yLocation = Convert.ToInt32(screenBounds.Height * x);
+                Location = Point.Add(screenBounds.Location, new Size(xLocation, yLocation));
+            }
+            else
+            {
+                _defaultPosition = true;
+                switch (corner)
+                {
+                    default:
+                    case 0:
+                        Location = Point.Add(
+                            new Point(screenBounds.Right, screenBounds.Bottom),
+                            new Size(-(Width+50), -(Height+50)));
+                        break;
+                    case 1:
+                        Location = Point.Add(
+                            new Point(screenBounds.Left, screenBounds.Bottom),
+                            new Size(50, -(Height + 50)));
+                        break;
+                    case 2:
+                        Location = Point.Add(
+                            new Point(screenBounds.Right, screenBounds.Top),
+                            new Size(-(Width + 50), 50));
+                        break;
+                    case 3:
+                        Location = Point.Add(
+                            new Point(screenBounds.Left, screenBounds.Top),
+                            new Size(50, 00));
+                        break;
+                }
+                _originalLocation = new Point(Location.X, Location.Y);
+            }
+        }
+
+        private void DrawBorder(object? sender, PaintEventArgs e)
+        {
+            using (Pen pen = new Pen(_color))
+            {
+                pen.Width = 6;
+                e.Graphics.DrawLine(pen, 0, 0, Width, 0);
+                e.Graphics.DrawLine(pen, 0, 0, 0, Height);
+                e.Graphics.DrawLine(pen, 0, Height, Width, Height);
+                e.Graphics.DrawLine(pen, Width, 0, Width, Height);
+            }
+        }
+
+        protected override void WndProc(ref Message m)
+        {
+            
+            switch (m.Msg)
+            {
+                case DwmHelper.WM_DWMCOMPOSITIONCHANGED:
+                    if (System.Environment.OSVersion.Version.Major >= 6 && DwmHelper.IsCompositionEnabled())
+                    {
+                        var policy = DwmHelper.DWMNCRENDERINGPOLICY.Enabled;
+                        DwmHelper.WindowSetAttribute(Handle, DwmHelper.DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);
+                        DwmHelper.WindowBorderlessDropShadow(Handle, 2);
+                        m.Result = IntPtr.Zero;
+                    }
+                    break;
+                case 0x0084:
+                    m.Result = (IntPtr)(-1);
+                    return;
+                default:
+                    break;
+            }
+            base.WndProc(ref m);
+        }
+
+        private void DrawText(object? sender, PaintEventArgs e)
+        {
+            if (sender != null)
+            {
+                var label = (Label)sender;
+                e.Graphics.Clear(Color.Transparent);
+                using (var sf = new StringFormat())
+                using (var brush = new SolidBrush(label.ForeColor))
+                {
+                    sf.Alignment = sf.LineAlignment = StringAlignment.Near;
+                    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
+                    e.Graphics.DrawString(label.Text, label.Font, brush, label.ClientRectangle, sf);
+                }
+            }
+        }
+
+        public Guid Guid { get => _guid; }
+
+        private void AdjustText()
+        {
+
+        }
+
+        private void CloseNotification(object? sender, System.Timers.ElapsedEventArgs e)
+        {
+            try
+            {
+                Close();
+            }
+            catch
+            {
+                try
+                {
+                    this.Invoke(() => Close());
+                }
+                catch
+                {
+                    throw new Exception("blah");
+                }
+            }
+            
+            _timer.Stop();
+            _timer.Dispose();
+        }
     }
 }
diff --git a/ObservatoryCore/UI/NotificationForm.resx b/ObservatoryCore/UI/NotificationForm.resx
index 1af7de1..f298a7b 100644
--- a/ObservatoryCore/UI/NotificationForm.resx
+++ b/ObservatoryCore/UI/NotificationForm.resx
@@ -1,64 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
+<root>
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
     <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
diff --git a/ObservatoryCore/UI/PluginHelper.cs b/ObservatoryCore/UI/PluginHelper.cs
index ceee265..cb0fc56 100644
--- a/ObservatoryCore/UI/PluginHelper.cs
+++ b/ObservatoryCore/UI/PluginHelper.cs
@@ -1,11 +1,7 @@
 using Observatory.Framework.Interfaces;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Cryptography.X509Certificates;
-using System.Speech.Synthesis;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections;
+using Observatory.PluginManagement;
+using Observatory.Utils;
 
 namespace Observatory.UI
 {
@@ -47,12 +43,20 @@ namespace Observatory.UI
 
             if (plugin.PluginUI.PluginUIType == Framework.PluginUI.UIType.Basic)
                 uiPanels.Add(newItem, CreateBasicUI(plugin));
+            else if (plugin.PluginUI.PluginUIType == Framework.PluginUI.UIType.Panel)
+                uiPanels.Add(newItem, (Panel)plugin.PluginUI.UI);
         }
 
         private static Panel CreateBasicUI(IObservatoryPlugin plugin)
         {
             Panel panel = new();
-            var columnSorter = new DefaultSorter();
+
+            IObservatoryComparer columnSorter;
+            if (plugin.ColumnSorter != null)
+                columnSorter = plugin.ColumnSorter;
+            else
+                columnSorter = new DefaultSorter();
+
             ListView listView = new()
             {
                 View = View.Details,
@@ -62,7 +66,8 @@ namespace Observatory.UI
                 BackColor = Color.FromArgb(64, 64, 64),
                 ForeColor = Color.LightGray,
                 GridLines = true,
-                ListViewItemSorter = columnSorter
+                ListViewItemSorter = columnSorter,
+                Font = new Font(new FontFamily("Segoe UI"), 10, FontStyle.Regular)
             };
 
             foreach (var property in plugin.PluginUI.DataGrid.First().GetType().GetProperties())
@@ -75,20 +80,20 @@ namespace Observatory.UI
                 if (e.Column == columnSorter.SortColumn)
                 {
                     // Reverse the current sort direction for this column.
-                    if (columnSorter.Order == SortOrder.Ascending)
+                    if (columnSorter.Order == 1)
                     {
-                        columnSorter.Order = SortOrder.Descending;
+                        columnSorter.Order = -1;
                     }
                     else
                     {
-                        columnSorter.Order = SortOrder.Ascending;
+                        columnSorter.Order = 1;
                     }
                 }
                 else
                 {
                     // Set the column number that is to be sorted; default to ascending.
                     columnSorter.SortColumn = e.Column;
-                    columnSorter.Order = SortOrder.Ascending;
+                    columnSorter.Order = 1;
                 }
                 listView.Sort();
             };
@@ -97,20 +102,58 @@ namespace Observatory.UI
             
             plugin.PluginUI.DataGrid.CollectionChanged += (sender, e) =>
             {
-                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add &&
-                e.NewItems != null)
+                listView.Invoke(() =>
                 {
-                    foreach (var newItem in e.NewItems)
+                    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add &&
+                e.NewItems != null)
                     {
-                        ListViewItem newListItem = new();
-                        foreach (var property in newItem.GetType().GetProperties())
+                        foreach (var newItem in e.NewItems)
                         {
-                            newListItem.SubItems.Add(property.GetValue(newItem)?.ToString());
+                            ListViewItem newListItem = new();
+                            foreach (var property in newItem.GetType().GetProperties())
+                            {
+                                newListItem.SubItems.Add(property.GetValue(newItem)?.ToString());
+                            }
+                            newListItem.SubItems.RemoveAt(0);
+                            listView.Items.Add(newListItem);
                         }
-                        newListItem.SubItems.RemoveAt(0);
-                        listView.Items.Add(newListItem);
                     }
-                }
+
+                    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove &&
+                    e.OldItems != null)
+                    {
+                        foreach (var oldItem in e.OldItems)
+                        {
+                            ListViewItem oldListItem = new();
+                            foreach (var property in oldItem.GetType().GetProperties())
+                            {
+                                oldListItem.SubItems.Add(property.GetValue(oldItem)?.ToString());
+                            }
+                            oldListItem.SubItems.RemoveAt(0);
+
+                            var itemToRemove = listView.Items.Cast<ListViewItem>().Where(i => i.SubItems.Cast<string>().SequenceEqual(oldListItem.SubItems.Cast<string>())).First();
+                            if (itemToRemove != null)
+                            {
+                                listView.Items.Remove(itemToRemove);
+                            }
+                        }
+                    }
+
+                    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
+                    {
+                        listView.Items.Clear();
+                        foreach (var item in plugin.PluginUI.DataGrid)
+                        {
+                            ListViewItem listItem = new();
+                            foreach (var property in item.GetType().GetProperties())
+                            {
+                                listItem.SubItems.Add(property.GetValue(item)?.ToString());
+                            }
+                            listItem.SubItems.RemoveAt(0);
+                            listView.Items.Add(listItem);
+                        }
+                    }
+                });
             };
             
             return panel;
diff --git a/ObservatoryCore/UI/SettingsPanel.cs b/ObservatoryCore/UI/SettingsPanel.cs
index 36bc925..3c9da92 100644
--- a/ObservatoryCore/UI/SettingsPanel.cs
+++ b/ObservatoryCore/UI/SettingsPanel.cs
@@ -2,10 +2,12 @@
 using Observatory.Framework.Interfaces;
 using System;
 using System.Collections.Generic;
+using System.Data.Common;
 using System.Linq;
 using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
+using System.Windows.Forms.VisualStyles;
 
 namespace Observatory.UI
 {
@@ -22,7 +24,7 @@ namespace Observatory.UI
             _adjustPanelsBelow = adjustPanelsBelow;
 
             // Filtered to only settings without SettingIgnore attribute
-            var settings = PluginManagement.PluginManager.GetSettingDisplayNames(plugin).Where(s => !Attribute.IsDefined(s.Key, typeof (SettingIgnore)));
+            var settings = PluginManagement.PluginManager.GetSettingDisplayNames(plugin.Settings).Where(s => !Attribute.IsDefined(s.Key, typeof (SettingIgnore)));
             CreateControls(settings);
 
         }
@@ -30,35 +32,300 @@ namespace Observatory.UI
         private void CreateControls(IEnumerable<KeyValuePair<PropertyInfo, string>> settings)
         {
             int controlRow = 0;
-            bool nextColumn = true;
+            bool recentHalfCol = false;
 
-            // Handle bool (checkbox) settings first and keep them grouped together
-            foreach (var setting in settings.Where(s => s.Key.PropertyType == typeof(bool)))
+            foreach (var setting in settings)
             {
-                CheckBox checkBox = new()
+                // Reset the column tracking for checkboxes if this isn't a checkbox
+                if (setting.Key.PropertyType.Name != "Boolean" && setting.Key.PropertyType.Name != "Button")
+                    recentHalfCol = false;
+
+                switch (setting.Key.GetValue(_plugin.Settings))
                 {
-                    Text = setting.Value,
-                    Checked = (bool?)setting.Key.GetValue(_plugin.Settings) ?? false
-                };
+                    case bool:
+                        var checkBox = CreateBoolSetting(setting);
+                        controlRow += recentHalfCol ? 0 : 1;
+                        checkBox.Location = GetSettingPosition(controlRow, recentHalfCol);
 
-                checkBox.CheckedChanged += (object? _, EventArgs _) =>
-                {
-                    setting.Key.SetValue(_plugin.Settings, checkBox.Checked);
-                    PluginManagement.PluginManager.GetInstance.SaveSettings(_plugin, _plugin.Settings);
-                };
+                        recentHalfCol = !recentHalfCol;
 
-                checkBox.Location = new Point(nextColumn ? 10 : 130, 3 + controlRow * 29);
-                controlRow += nextColumn ? 0 : 1;
-                nextColumn = !nextColumn;
+                        Controls.Add(checkBox);
+                        break;
+                    case string:
+                        var stringLabel = CreateSettingLabel(setting.Value);
+                        var textBox = CreateStringSetting(setting.Key);
+                        controlRow++;
+                        stringLabel.Location = GetSettingPosition(controlRow);
+                        textBox.Location = GetSettingPosition(controlRow, true);
+                        
+                        Controls.Add(stringLabel);
+                        Controls.Add(textBox);
 
-                Controls.Add(checkBox);
+                        break;
+                    case FileInfo:
+                        var fileLabel = CreateSettingLabel(setting.Value);
+                        var pathTextBox = CreateFilePathSetting(setting.Key);
+                        var pathButton = CreateFileBrowseSetting(setting.Key, pathTextBox);
+
+                        controlRow++;
+
+                        fileLabel.Location = GetSettingPosition(controlRow);
+                        pathTextBox.Location = GetSettingPosition(controlRow, true);
+                        pathButton.Location = GetSettingPosition(++controlRow, true);
+
+                        Controls.Add(fileLabel);
+                        Controls.Add(pathTextBox);
+                        Controls.Add(pathButton);
+
+                        break;
+                    case int:
+                        // We have two options for integer values:
+                        // 1) A slider (explicit by way of the SettingIntegerUseSlider attribute and bounded to 0..100 by default)
+                        // 2) A numeric up/down (default otherwise, and is unbounded by default).
+                        // Bounds for both can be set via the SettingNumericBounds attribute, only the up/down uses Increment.
+                        var intLabel = CreateSettingLabel(setting.Value);
+                        Control intControl;
+                        controlRow++;
+                        if (System.Attribute.IsDefined(setting.Key, typeof(SettingNumericUseSlider)))
+                        {
+                            intControl = CreateSettingTrackbar(setting.Key);
+                        }
+                        else
+                        {
+                            intControl = CreateSettingNumericUpDown(setting.Key);
+                        }
+                        intLabel.Location = GetSettingPosition(controlRow);
+                        intControl.Location = GetSettingPosition(controlRow, true);
+
+                        Controls.Add(intLabel);
+                        Controls.Add(intControl);
+                        break;
+                    case Action action:
+                        var button = CreateSettingButton(setting.Value, action);
+
+                        controlRow += recentHalfCol ? 0 : 1;
+                        button.Location = GetSettingPosition(controlRow, recentHalfCol);
+                        recentHalfCol = !recentHalfCol;
+
+                        Controls.Add(button);
+                        break;
+                    case Dictionary<string, object> dictSetting:
+                        var dictLabel = CreateSettingLabel(setting.Value);
+                        var dropdown = CreateSettingDropdown(setting.Key, dictSetting);
+                        controlRow++;
+
+                        dictLabel.Location = GetSettingPosition(controlRow);
+                        dropdown.Location = GetSettingPosition(controlRow, true);
+                        Controls.Add(dictLabel);
+                        Controls.Add(dropdown);
+                        break;
+                    default:
+                        break;
+                }
+            }
+            Height = 3 + controlRow * 29;
+        }
+
+        private static Point GetSettingPosition(int rowNum, bool secondCol = false)
+        {
+            return new Point(10 + (secondCol ? 200 : 0), -26 + rowNum * 29);
+        }
+        
+
+        private Label CreateSettingLabel(string settingName)
+        {
+            Label label = new()
+            {
+                Text = settingName + ": ",
+                TextAlign = System.Drawing.ContentAlignment.MiddleRight,
+                Width = 200,
+                ForeColor = Color.LightGray
+            };
+
+            return label;
+        }
+
+        private ComboBox CreateSettingDropdown(PropertyInfo setting, Dictionary<string, object> dropdownItems)
+        {
+            var backingValueName = (SettingBackingValue?)Attribute.GetCustomAttribute(setting, typeof(SettingBackingValue));
+
+            var backingValue = from s in PluginManagement.PluginManager.GetSettingDisplayNames(_plugin.Settings)
+                               where s.Value == backingValueName?.BackingProperty
+                               select s.Key;
+
+            if (backingValue.Count() != 1)
+                throw new($"{_plugin.ShortName}: Dictionary settings must have exactly one backing value.");
+
+            ComboBox comboBox = new()
+            {
+                Width = 200,
+                DropDownStyle = ComboBoxStyle.DropDownList
+            };
+
+            comboBox.Items.AddRange(dropdownItems.OrderBy(s => s.Key).Select(s => s.Key).ToArray());
+
+            string? currentSelection = backingValue.First().GetValue(_plugin.Settings)?.ToString();
+
+            if (currentSelection?.Length > 0)
+            {
+                comboBox.SelectedItem = currentSelection;
             }
 
-            // Then the rest
-            foreach (var setting in settings.Where(s => s.Key.PropertyType != typeof(bool)))
+            comboBox.SelectedValueChanged += (sender, e) =>
+            {
+                backingValue.First().SetValue(_plugin.Settings, comboBox.SelectedItem.ToString());
+                SaveSettings();
+            };
+
+            return comboBox;
+        }
+
+        private Button CreateSettingButton(string settingName, Action action)
+        {
+            Button button = new()
+            {
+                Text = settingName
+            };
+
+            button.Click += (sender, e) =>
+            {
+                action.Invoke();
+                SaveSettings();
+            };
+
+            return button;
+        }
+
+        private TrackBar CreateSettingTrackbar(PropertyInfo setting)
+        {
+            SettingNumericBounds? bounds = (SettingNumericBounds?)System.Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
+            TrackBar trackBar = new ()
+            {
+                Orientation = Orientation.Horizontal,
+                TickStyle = TickStyle.Both,
+                Width = 200, 
+                Minimum = Convert.ToInt32(bounds?.Minimum ?? 0),
+                Maximum = Convert.ToInt32(bounds?.Maximum ?? 100)
+            };
+
+            trackBar.Value = (int?)setting.GetValue(_plugin.Settings) ?? 0;
+
+            trackBar.ValueChanged += (sender, e) =>
+            {
+                setting.SetValue(_plugin.Settings, trackBar.Value);
+                SaveSettings();
+            };
+
+            return trackBar;
+        }
+
+        private NumericUpDown CreateSettingNumericUpDown(PropertyInfo setting)
+        {
+            SettingNumericBounds? bounds = (SettingNumericBounds?)System.Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
+            NumericUpDown numericUpDown = new()
             {
                 
-            }
+                Width = 200,
+                Minimum = Convert.ToInt32(bounds?.Minimum ?? Int32.MinValue),
+                Maximum = Convert.ToInt32(bounds?.Maximum ?? Int32.MaxValue),
+                Increment = Convert.ToInt32(bounds?.Increment ?? 1)
+            };
+
+            numericUpDown.Value = (int?)setting.GetValue(_plugin.Settings) ?? 0;
+
+            numericUpDown.ValueChanged += (sender, e) =>
+            {
+                setting.SetValue(_plugin.Settings, numericUpDown.Value);
+                SaveSettings();
+            };
+
+            return numericUpDown;
+        }
+
+        private CheckBox CreateBoolSetting(KeyValuePair<PropertyInfo, string> setting)
+        {
+            CheckBox checkBox = new()
+            {
+                Text = setting.Value,
+                TextAlign= System.Drawing.ContentAlignment.MiddleLeft,
+                Checked = (bool?)setting.Key.GetValue(_plugin.Settings) ?? false,
+                Width = 200,
+                ForeColor = Color.LightGray
+            };
+
+            checkBox.CheckedChanged += (sender, e) =>
+            {
+                setting.Key.SetValue(_plugin.Settings, checkBox.Checked);
+                SaveSettings();
+            };
+
+            return checkBox;
+        }
+
+        private TextBox CreateStringSetting(PropertyInfo setting)
+        {
+            TextBox textBox = new()
+            {
+                Text = (setting.GetValue(_plugin.Settings) ?? String.Empty).ToString(),
+                Width = 200
+            };
+
+            textBox.TextChanged += (object? sender, EventArgs e) =>
+            {
+                setting.SetValue(_plugin.Settings, textBox.Text);
+                SaveSettings();
+            };
+
+            return textBox;
+        }
+
+        private TextBox CreateFilePathSetting(PropertyInfo setting)
+        {
+            var fileInfo = (FileInfo?)setting.GetValue(_plugin.Settings);
+
+            TextBox textBox = new()
+            {
+                Text = fileInfo?.FullName ?? string.Empty,
+                Width = 200
+            };
+
+            textBox.TextChanged += (object? sender, EventArgs e) =>
+            {
+                setting.SetValue(_plugin.Settings, new FileInfo(textBox.Text));
+                SaveSettings();
+            };
+
+            return textBox;
+        }
+
+        private Button CreateFileBrowseSetting(PropertyInfo setting, TextBox textBox)
+        {
+            Button button = new()
+            {
+                Text = "Browse"
+            };
+
+            button.Click += (object? sender, EventArgs e) =>
+            {
+                var currentDir = ((FileInfo?)setting.GetValue(_plugin.Settings))?.DirectoryName;
+
+                OpenFileDialog ofd = new OpenFileDialog()
+                { 
+                    Title = "Select File...",
+                    Filter = "Lua files (*.lua)|*.lua|All files (*.*)|*.*",
+                    FilterIndex = 0,
+                    InitialDirectory = currentDir ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
+                };
+
+                var browseResult = ofd.ShowDialog();
+
+                if (browseResult == DialogResult.OK)
+                {
+                    textBox.Text = ofd.FileName;
+                }
+            };
+
+            return button;
         }
 
         private Label CreateHeader(string pluginName)
@@ -92,5 +359,10 @@ namespace Observatory.UI
             }
             this.Parent?.ResumeLayout();
         }
+
+        private void SaveSettings()
+        {
+            PluginManagement.PluginManager.GetInstance.SaveSettings(_plugin, _plugin.Settings);
+        }
     }
 }
diff --git a/ObservatoryCore/Utils/LogMonitor.cs b/ObservatoryCore/Utils/LogMonitor.cs
index 2fe2383..45fb68f 100644
--- a/ObservatoryCore/Utils/LogMonitor.cs
+++ b/ObservatoryCore/Utils/LogMonitor.cs
@@ -284,7 +284,7 @@ namespace Observatory.Utils
             if (Properties.Core.Default.JournalFolder != path)
             {
                 Properties.Core.Default.JournalFolder = path;
-                Properties.Core.Default.Save();
+                SettingsManager.Save();
             }
 
             return logDirectory;
diff --git a/ObservatoryCore/Utils/SettingsManager.cs b/ObservatoryCore/Utils/SettingsManager.cs
new file mode 100644
index 0000000..c1d8410
--- /dev/null
+++ b/ObservatoryCore/Utils/SettingsManager.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace Observatory.Utils
+{
+    internal static class SettingsManager
+    {
+        internal static void Save()
+        {
+#if DEBUG || RELEASE
+            Properties.Core.Default.Save();
+#elif PORTABLE
+
+            Dictionary<string, object?> settings = new();
+
+            foreach (PropertyInfo property in Properties.Core.Default.GetType().GetProperties())
+            {
+                if (property.CanRead && property.CanWrite && !property.GetIndexParameters().Any())
+                    settings.Add(
+                        property.Name,
+                        property.GetValue(Properties.Core.Default)
+                        );
+            }
+
+            string serializedSettings = JsonSerializer.Serialize(settings, new JsonSerializerOptions()
+            {
+                ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.Preserve,
+                
+            });
+            File.WriteAllText("Observatory.config", serializedSettings);
+#endif
+        }
+
+        internal static void Load()
+        {
+#if PORTABLE
+            if (File.Exists("Observatory.config"))
+            {
+                string savedSettings = File.ReadAllText("Observatory.config");
+                Dictionary<string, object?>? settings = JsonSerializer.Deserialize<Dictionary<string, object?>>(savedSettings);
+                if (settings != null)
+                {
+                    var properties = Properties.Core.Default.GetType().GetProperties();
+                    
+                    foreach (var savedProperty in settings)
+                    {
+
+                        var currentProperty = properties.Where(p => p.Name == savedProperty.Key);
+                        if (currentProperty.Any())
+                        {
+                            JsonElement? value = (JsonElement?)savedProperty.Value;
+                            var deserializedValue = value?.Deserialize(currentProperty.First().PropertyType);
+                            currentProperty.First().SetValue(Properties.Core.Default, deserializedValue);
+                        }
+
+                    }
+                }
+            }
+#endif
+        }
+    }
+}
diff --git a/ObservatoryDev/ObservatoryDev.sln b/ObservatoryDev/ObservatoryDev.sln
index a9a446e..151a08b 100644
--- a/ObservatoryDev/ObservatoryDev.sln
+++ b/ObservatoryDev/ObservatoryDev.sln
@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30128.74
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32922.545
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObservatoryBotanist", "..\ObservatoryBotanist\ObservatoryBotanist.csproj", "{498F7360-D443-4D64-895C-9EAB5570D019}"
 EndProject
@@ -16,27 +16,38 @@ EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
+		Portable|Any CPU = Portable|Any CPU
 		Release|Any CPU = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{498F7360-D443-4D64-895C-9EAB5570D019}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{498F7360-D443-4D64-895C-9EAB5570D019}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{498F7360-D443-4D64-895C-9EAB5570D019}.Portable|Any CPU.ActiveCfg = Portable|Any CPU
+		{498F7360-D443-4D64-895C-9EAB5570D019}.Portable|Any CPU.Build.0 = Portable|Any CPU
 		{498F7360-D443-4D64-895C-9EAB5570D019}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{498F7360-D443-4D64-895C-9EAB5570D019}.Release|Any CPU.Build.0 = Release|Any CPU
 		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Portable|Any CPU.ActiveCfg = Portable|Any CPU
+		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Portable|Any CPU.Build.0 = Portable|Any CPU
 		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{0E1C4F16-858E-4E53-948A-77D81A8F3395}.Release|Any CPU.Build.0 = Release|Any CPU
 		{E0FCF2A2-BF56-4F4D-836B-92A0E8269192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{E0FCF2A2-BF56-4F4D-836B-92A0E8269192}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E0FCF2A2-BF56-4F4D-836B-92A0E8269192}.Portable|Any CPU.ActiveCfg = Portable|Any CPU
+		{E0FCF2A2-BF56-4F4D-836B-92A0E8269192}.Portable|Any CPU.Build.0 = Portable|Any CPU
 		{E0FCF2A2-BF56-4F4D-836B-92A0E8269192}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{E0FCF2A2-BF56-4F4D-836B-92A0E8269192}.Release|Any CPU.Build.0 = Release|Any CPU
 		{27ABA3B7-AB3C-465F-BA40-4F06BD803811}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{27ABA3B7-AB3C-465F-BA40-4F06BD803811}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{27ABA3B7-AB3C-465F-BA40-4F06BD803811}.Portable|Any CPU.ActiveCfg = Portable|Any CPU
+		{27ABA3B7-AB3C-465F-BA40-4F06BD803811}.Portable|Any CPU.Build.0 = Portable|Any CPU
 		{27ABA3B7-AB3C-465F-BA40-4F06BD803811}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{27ABA3B7-AB3C-465F-BA40-4F06BD803811}.Release|Any CPU.Build.0 = Release|Any CPU
 		{BC57225F-D89B-4853-A816-9AB4865E7AC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{BC57225F-D89B-4853-A816-9AB4865E7AC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BC57225F-D89B-4853-A816-9AB4865E7AC5}.Portable|Any CPU.ActiveCfg = Portable|Any CPU
+		{BC57225F-D89B-4853-A816-9AB4865E7AC5}.Portable|Any CPU.Build.0 = Portable|Any CPU
 		{BC57225F-D89B-4853-A816-9AB4865E7AC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{BC57225F-D89B-4853-A816-9AB4865E7AC5}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
diff --git a/ObservatoryExplorer/DefaultCriteria.cs b/ObservatoryExplorer/DefaultCriteria.cs
index 3afe5f2..1d23ca5 100644
--- a/ObservatoryExplorer/DefaultCriteria.cs
+++ b/ObservatoryExplorer/DefaultCriteria.cs
@@ -16,6 +16,10 @@ namespace Observatory.Explorer
 
             bool isRing = scan.BodyName.Contains("Ring");
 
+#if DEBUG
+            // results.Add("Test Scan Event", "Test Detail");
+#endif
+
             #region Landable Checks
             if (scan.Landable)
             {
diff --git a/ObservatoryExplorer/ObservatoryExplorer.csproj b/ObservatoryExplorer/ObservatoryExplorer.csproj
index 4b0b304..0dac63d 100644
--- a/ObservatoryExplorer/ObservatoryExplorer.csproj
+++ b/ObservatoryExplorer/ObservatoryExplorer.csproj
@@ -5,6 +5,7 @@
 	<ImplicitUsings>enable</ImplicitUsings>
     <SignAssembly>false</SignAssembly>
     <AssemblyOriginatorKeyFile>ObservatoryKey.snk</AssemblyOriginatorKeyFile>
+    <Configurations>Debug;Release;Portable</Configurations>
   </PropertyGroup>
 
   <PropertyGroup>
@@ -20,10 +21,10 @@
   </PropertyGroup>
   
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">
-    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)plugins\&quot; /y" />
-    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetDir)NLua.dll&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)plugins\deps\&quot; /y" />
-    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetDir)KeraLua.dll&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)plugins\deps\&quot; /y" />
-    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetDir)runtimes\win-x64\native\lua54.dll&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)plugins\deps\&quot; /y" />
+    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)..\net6.0-windows\plugins\&quot; /y" />
+    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetDir)NLua.dll&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)..\net6.0-windows\plugins\deps\&quot; /y" />
+    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetDir)KeraLua.dll&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)..\net6.0-windows\plugins\deps\&quot; /y" />
+    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetDir)runtimes\win-x64\native\lua54.dll&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)..\net6.0-windows\plugins\deps\&quot; /y" />
     <Exec Condition=" '$(OS)' != 'Windows_NT' " Command="[ ! -d &quot;$(ProjectDir)../ObservatoryCore/$(OutDir)plugins/deps&quot; ] &amp;&amp; mkdir -p &quot;$(ProjectDir)../ObservatoryCore/$(OutDir)plugins/deps&quot; || echo Directory already exists" />
     <Exec Condition=" '$(OS)' != 'Windows_NT' " Command="cp &quot;$(TargetPath)&quot; &quot;$(ProjectDir)../ObservatoryCore/$(OutDir)plugins/&quot; -f" />
     <Exec Condition=" '$(OS)' != 'Windows_NT' " Command="cp &quot;$(TargetDir)NLua.dll&quot; &quot;$(ProjectDir)../ObservatoryCore/$(OutDir)plugins/deps/&quot; -f" />
diff --git a/ObservatoryFramework/Interfaces.cs b/ObservatoryFramework/Interfaces.cs
index 3f7e0e3..27ee27b 100644
--- a/ObservatoryFramework/Interfaces.cs
+++ b/ObservatoryFramework/Interfaces.cs
@@ -1,7 +1,6 @@
-using System;
-using System.Net.Http;
-using Observatory.Framework.Files;
+using Observatory.Framework.Files;
 using Observatory.Framework.Files.Journal;
+using System.Xml.XPath;
 
 namespace Observatory.Framework.Interfaces
 {
@@ -50,6 +49,13 @@ namespace Observatory.Framework.Interfaces
         /// </summary>
         public object Settings { get; set; }
 
+        /// <summary>
+        /// <para>Plugin-specific object implementing the IComparer interface which is used to sort columns in the basic UI datagrid.</para>
+        /// <para>If omitted a basic numeric compare sorter is used.</para>
+        /// </summary>
+        public IObservatoryComparer ColumnSorter
+        { get => null; }
+
     }
 
     /// <summary>
@@ -163,13 +169,6 @@ namespace Observatory.Framework.Interfaces
         /// <param name="items">Grid items to be added. Object types should match original template item used to create the grid.</param>
         public void AddGridItems(IObservatoryWorker worker, IEnumerable<object> items);
 
-        /// <summary>
-        /// Add multiple items to the bottom of the basic UI grid.
-        /// </summary>
-        /// <param name="worker">Reference to the calling plugin's worker interface.</param>
-        /// <param name="items">Grid items to be added. Object types should match original template item used to create the grid.</param>
-        public void AddGridItems(IObservatoryWorker worker, IEnumerable<object> items);
-
         /// <summary>
         /// Clears basic UI grid, removing all items.
         /// </summary>
@@ -221,4 +220,21 @@ namespace Observatory.Framework.Interfaces
         /// </summary>
         public string PluginStorageFolder { get; }
     }
+
+    /// <summary>
+    /// Extends the base IComparer interface with exposed values for the column ID and sort order to use.
+    /// </summary>
+    public interface IObservatoryComparer : System.Collections.IComparer
+    {
+        /// <summary>
+        /// Column ID to be currently sorted by.
+        /// </summary>
+        public int SortColumn { get; set; }
+
+        /// <summary>
+        /// Current order of sorting. Ascending = 1, Descending = -1, No sorting = 0.
+        /// </summary>
+        public int Order { get; set; }
+    }
+
 }
diff --git a/ObservatoryFramework/ObservatoryFramework.csproj b/ObservatoryFramework/ObservatoryFramework.csproj
index 8da2df4..c07018a 100644
--- a/ObservatoryFramework/ObservatoryFramework.csproj
+++ b/ObservatoryFramework/ObservatoryFramework.csproj
@@ -4,6 +4,7 @@
 	<TargetFramework>net6.0</TargetFramework>
 	<ImplicitUsings>enable</ImplicitUsings>
     <RootNamespace>Observatory.Framework</RootNamespace>
+    <Configurations>Debug;Release;Portable</Configurations>
   </PropertyGroup>
 
   <PropertyGroup>
@@ -17,5 +18,9 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
     <DocumentationFile>ObservatoryFramework.xml</DocumentationFile>
   </PropertyGroup>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Portable|AnyCPU'">
+    <DocumentationFile>ObservatoryFramework.xml</DocumentationFile>
+  </PropertyGroup>
   
 </Project>
diff --git a/ObservatoryFramework/ObservatoryFramework.xml b/ObservatoryFramework/ObservatoryFramework.xml
index a046077..2b3a07a 100644
--- a/ObservatoryFramework/ObservatoryFramework.xml
+++ b/ObservatoryFramework/ObservatoryFramework.xml
@@ -1350,6 +1350,12 @@
             If a public property is necessary but not required to be user accessible the [SettingIgnore] property will suppress display.</para>
             </summary>
         </member>
+        <member name="P:Observatory.Framework.Interfaces.IObservatoryPlugin.ColumnSorter">
+            <summary>
+            Plugin-specific object implementing the IComparer interface which is used to sort columns in the basic UI datagrid.
+            If omitted a basic string compare sorter is used.
+            </summary>
+        </member>
         <member name="T:Observatory.Framework.Interfaces.IObservatoryWorker">
             <summary>
             <para>Interface for worker plugins which process journal data to update their UI or send notifications.</para>
@@ -1504,6 +1510,21 @@
             Retrieves and ensures creation of a location which can be used by the plugin to store persistent data.
             </summary>
         </member>
+        <member name="T:Observatory.Framework.Interfaces.IObservatoryComparer">
+            <summary>
+            Extends the base IComparer interface with exposed values for the column ID and sort order to use.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Interfaces.IObservatoryComparer.SortColumn">
+            <summary>
+            Column ID to be currently sorted by.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Interfaces.IObservatoryComparer.Order">
+            <summary>
+            Current order of sorting. Ascending = 1, Descending = -1, No sorting = 0.
+            </summary>
+        </member>
         <member name="T:Observatory.Framework.PluginUI">
             <summary>
             Class permitting plugins to provide their UI, if any, to Observatory Core.
@@ -1516,13 +1537,12 @@
         </member>
         <member name="F:Observatory.Framework.PluginUI.UI">
             <summary>
-            <para>UI object used by plugins with UIType.Avalonia.</para>
-            <para>(Untested/not implemented)</para>
+            <para>UI object used by plugins with UIType.Panel.</para>
             </summary>
         </member>
         <member name="F:Observatory.Framework.PluginUI.DataGrid">
             <summary>
-            <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
+            <para>Collection bound to DataGrid used by plugins with UIType.Basic.</para>
             <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
             </summary>
         </member>
@@ -1531,7 +1551,7 @@
             Instantiate PluginUI of UIType.Basic.
             </summary>
             <param name="DataGrid">
-            <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
+            <para>Collection bound to DataGrid used by plugins with UIType.Basic.</para>
             <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
             </param>
         </member>
diff --git a/ObservatoryFramework/PluginUI.cs b/ObservatoryFramework/PluginUI.cs
index 0e73312..c65edbc 100644
--- a/ObservatoryFramework/PluginUI.cs
+++ b/ObservatoryFramework/PluginUI.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.ObjectModel;
 using System.Linq;
+using System.Security.Principal;
 using System.Text;
 using System.Threading.Tasks;
 
@@ -17,13 +18,12 @@ namespace Observatory.Framework
         public readonly UIType PluginUIType;
 
         /// <summary>
-        /// <para>UI object used by plugins with UIType.Avalonia.</para>
-        /// <para>(Untested/not implemented)</para>
+        /// <para>UI object used by plugins with UIType.Panel.</para>
         /// </summary>
         public object UI;
 
         /// <summary>
-        /// <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
+        /// <para>Collection bound to DataGrid used by plugins with UIType.Basic.</para>
         /// <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
         /// </summary>
         public ObservableCollection<object> DataGrid;
@@ -32,7 +32,7 @@ namespace Observatory.Framework
         /// Instantiate PluginUI of UIType.Basic.
         /// </summary>
         /// <param name="DataGrid">
-        /// <para>Collection bound to DataGrid used byu plugins with UIType.Basic.</para>
+        /// <para>Collection bound to DataGrid used by plugins with UIType.Basic.</para>
         /// <para>Objects in collection should be of a class defined within the plugin consisting of string properties.<br/>Each object is a single row, and the property names are used as column headers.</para>
         /// </param>
         public PluginUI(ObservableCollection<object> DataGrid)
diff --git a/ObservatoryHerald/ObservatoryHerald.csproj b/ObservatoryHerald/ObservatoryHerald.csproj
index 18db54b..312ef56 100644
--- a/ObservatoryHerald/ObservatoryHerald.csproj
+++ b/ObservatoryHerald/ObservatoryHerald.csproj
@@ -4,6 +4,7 @@
 	<TargetFramework>net6.0</TargetFramework>
 	<ImplicitUsings>enable</ImplicitUsings>
     <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
+    <Configurations>Debug;Release;Portable</Configurations>
   </PropertyGroup>
 
   <PropertyGroup>

From b8f5f6a73e95a3124cfb7e6f683fd32d9aa1d370 Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Sun, 21 Jan 2024 13:35:03 -0330
Subject: [PATCH 06/18] ready for testing

---
 .../ObservatoryBotanist.csproj                |   2 +-
 ObservatoryCore/App.config                    |   6 +
 ObservatoryCore/Assets/Resources.Designer.cs  |  73 ++
 ObservatoryCore/Assets/Resources.resx         | 124 +++
 .../NativeNotification/NativePopup.cs         |  11 +
 .../NativeNotification/NativeVoice.cs         |  16 +-
 ObservatoryCore/ObservatoryCore.csproj        |  18 +-
 .../PluginManagement/PluginCore.cs            |  50 +-
 .../PluginManagement/PluginEventHandler.cs    |  22 +
 .../PluginManagement/PluginManager.cs         |  20 +-
 ObservatoryCore/Properties/Core.Designer.cs   |  26 +-
 ObservatoryCore/Properties/Core.settings      |   6 +
 .../Resources/ObservatoryCoreIcon.ico         | Bin 0 -> 45451 bytes
 ObservatoryCore/UI/ColumnSizing.cs            |  27 +
 ObservatoryCore/UI/CoreForm.Designer.cs       | 942 +++++++++---------
 ObservatoryCore/UI/CoreForm.Plugins.cs        | 101 +-
 ObservatoryCore/UI/CoreForm.cs                | 115 ++-
 ObservatoryCore/UI/CoreForm.resx              |  65 +-
 .../UI/NotificationForm.Designer.cs           |  79 +-
 ObservatoryCore/UI/NotificationForm.cs        |  70 +-
 ObservatoryCore/UI/NotificationForm.resx      |  62 +-
 ObservatoryCore/UI/PluginHelper.cs            | 140 ++-
 ObservatoryCore/UI/PluginListView.cs          | 113 +++
 .../UI/ReadAllProgress.Designer.cs            |  84 ++
 ObservatoryCore/UI/ReadAllProgress.cs         |  52 +
 ObservatoryCore/UI/ReadAllProgress.resx       | 120 +++
 ObservatoryCore/UI/SettingsForm.Designer.cs   |  61 ++
 ObservatoryCore/UI/SettingsForm.cs            | 367 +++++++
 ObservatoryCore/UI/SettingsForm.resx          | 120 +++
 ObservatoryCore/UI/ThemeManager.cs            | 158 +++
 ObservatoryCore/Utils/AudioHandler.cs         |  30 +
 ObservatoryCore/Utils/LogMonitor.cs           |  71 +-
 ObservatoryExplorer/ExplorerUIResults.cs      |  13 +-
 .../ObservatoryExplorer.csproj                |   2 +-
 ObservatoryFramework/Attributes.cs            |  14 +
 .../ThargoidWarRemainingTimeConverter.cs      |  35 +
 .../Files/Journal/Combat/Bounty.cs            |   2 +
 .../Journal/Combat/EscapeInterdiction.cs      |   1 +
 .../Files/Journal/Combat/Interdicted.cs       |   1 +
 .../Exploration/FSSSignalDiscovered.cs        |   4 +
 .../Files/Journal/FleetCarrier/CarrierJump.cs |   4 +
 .../Files/Journal/Odyssey/Disembark.cs        |   3 +
 .../Files/Journal/Odyssey/ScanOrganic.cs      |   2 +
 .../Files/Journal/Other/ApproachSettlement.cs |  15 +-
 .../Files/Journal/Startup/Passengers.cs       |  18 +-
 .../Files/Journal/Startup/Statistics.cs       |   1 +
 .../Journal/StationServices/ClearImpound.cs   |  11 +
 .../Files/Journal/StationServices/Market.cs   |   3 +
 .../StationServices/MassModuleStore.cs        |   2 +-
 .../Journal/StationServices/Outfitting.cs     |   3 +
 .../Files/Journal/StationServices/Shipyard.cs |   3 +
 .../Journal/StationServices/StoredModules.cs  |   3 +
 .../Journal/StationServices/StoredShips.cs    |   3 +
 .../Files/Journal/Trade/MarketBuy.cs          |   2 +-
 .../Files/Journal/Trade/MarketSell.cs         |   2 +-
 .../Files/Journal/Travel/Docked.cs            |   6 +-
 .../Files/Journal/Travel/DockingRequested.cs  |   5 +-
 .../Files/Journal/Travel/FSDJump.cs           |   1 +
 .../Files/Journal/Travel/Location.cs          |   6 +-
 .../Files/Journal/Travel/StartJump.cs         |   1 +
 .../Travel/SupercruiseDestinationDrop.cs      |   9 +
 .../Files/Journal/Travel/SupercruiseEntry.cs  |   1 +
 .../Files/Journal/Travel/Undocked.cs          |   3 +
 ObservatoryFramework/Files/MarketFile.cs      |   2 +-
 ObservatoryFramework/Files/OutfittingFile.cs  |   2 +-
 .../Files/ParameterTypes/BankAccount.cs       |  16 +
 .../Files/ParameterTypes/BioData.cs           |   2 +
 .../Files/ParameterTypes/Combat.cs            |  32 +
 .../Files/ParameterTypes/Crafting.cs          |  24 +
 .../Files/ParameterTypes/Crime.cs             |  51 +
 .../Files/ParameterTypes/Exobiology.cs        |  45 +
 .../Files/ParameterTypes/Exploration.cs       |  21 +
 .../Files/ParameterTypes/MaterialTrader.cs    |   6 +
 .../Files/ParameterTypes/SearchAndRescue.cs   |  24 +
 .../Files/ParameterTypes/Thargoid.cs          |   6 +-
 .../Files/ParameterTypes/ThargoidWar.cs       |  16 +
 .../Files/ParameterTypes/Trading.cs           |   9 +
 ObservatoryFramework/Interfaces.cs            |  37 +-
 ObservatoryFramework/ObservatoryFramework.xml |  97 +-
 ObservatoryHerald/HeraldNotifier.cs           |   4 +-
 ObservatoryHerald/HeraldQueue.cs              |  25 +-
 .../NetCoreAudio/Interfaces/IPlayer.cs        |  19 -
 ObservatoryHerald/NetCoreAudio/Player.cs      |  98 --
 .../NetCoreAudio/Players/LinuxPlayer.cs       |  33 -
 .../NetCoreAudio/Players/MacPlayer.cs         |  25 -
 .../NetCoreAudio/Players/UnixPlayerBase.cs    | 110 --
 .../NetCoreAudio/Players/WindowsPlayer.cs     | 141 ---
 ObservatoryHerald/ObservatoryHerald.csproj    |   6 +-
 README.md                                     |  12 +-
 SignObservatory.ps1                           |  39 +
 buildAllComponents                            |   8 -
 buildAllComponents.cmd                        |   7 -
 92 files changed, 3061 insertions(+), 1186 deletions(-)
 create mode 100644 ObservatoryCore/Assets/Resources.Designer.cs
 create mode 100644 ObservatoryCore/Assets/Resources.resx
 create mode 100644 ObservatoryCore/Resources/ObservatoryCoreIcon.ico
 create mode 100644 ObservatoryCore/UI/ColumnSizing.cs
 create mode 100644 ObservatoryCore/UI/PluginListView.cs
 create mode 100644 ObservatoryCore/UI/ReadAllProgress.Designer.cs
 create mode 100644 ObservatoryCore/UI/ReadAllProgress.cs
 create mode 100644 ObservatoryCore/UI/ReadAllProgress.resx
 create mode 100644 ObservatoryCore/UI/SettingsForm.Designer.cs
 create mode 100644 ObservatoryCore/UI/SettingsForm.cs
 create mode 100644 ObservatoryCore/UI/SettingsForm.resx
 create mode 100644 ObservatoryCore/UI/ThemeManager.cs
 create mode 100644 ObservatoryCore/Utils/AudioHandler.cs
 create mode 100644 ObservatoryFramework/Files/Converters/ThargoidWarRemainingTimeConverter.cs
 create mode 100644 ObservatoryFramework/Files/Journal/StationServices/ClearImpound.cs
 create mode 100644 ObservatoryFramework/Files/Journal/Travel/SupercruiseDestinationDrop.cs
 create mode 100644 ObservatoryFramework/Files/ParameterTypes/Exobiology.cs
 create mode 100644 ObservatoryFramework/Files/ParameterTypes/ThargoidWar.cs
 delete mode 100644 ObservatoryHerald/NetCoreAudio/Interfaces/IPlayer.cs
 delete mode 100644 ObservatoryHerald/NetCoreAudio/Player.cs
 delete mode 100644 ObservatoryHerald/NetCoreAudio/Players/LinuxPlayer.cs
 delete mode 100644 ObservatoryHerald/NetCoreAudio/Players/MacPlayer.cs
 delete mode 100644 ObservatoryHerald/NetCoreAudio/Players/UnixPlayerBase.cs
 delete mode 100644 ObservatoryHerald/NetCoreAudio/Players/WindowsPlayer.cs
 create mode 100644 SignObservatory.ps1
 delete mode 100755 buildAllComponents
 delete mode 100644 buildAllComponents.cmd

diff --git a/ObservatoryBotanist/ObservatoryBotanist.csproj b/ObservatoryBotanist/ObservatoryBotanist.csproj
index b7dcb13..6ca2774 100644
--- a/ObservatoryBotanist/ObservatoryBotanist.csproj
+++ b/ObservatoryBotanist/ObservatoryBotanist.csproj
@@ -23,7 +23,7 @@
   </ItemGroup>
   
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">
-    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)plugins\&quot; /y" />
+    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)..\net6.0-windows\plugins\&quot; /y" />
     <Exec Condition=" '$(OS)' != 'Windows_NT' " Command="cp &quot;$(TargetPath)&quot; &quot;$(ProjectDir)../ObservatoryCore/$(OutDir)plugins/&quot; -f" />
   </Target>
 
diff --git a/ObservatoryCore/App.config b/ObservatoryCore/App.config
index 6a8c1b6..b69fc93 100644
--- a/ObservatoryCore/App.config
+++ b/ObservatoryCore/App.config
@@ -70,6 +70,12 @@
             <setting name="StartReadAll" serializeAs="String">
                 <value>False</value>
             </setting>
+            <setting name="Theme" serializeAs="String">
+                <value>Dark</value>
+            </setting>
+            <setting name="ColumnSizing" serializeAs="String">
+                <value />
+            </setting>
         </Observatory.Properties.Core>
     </userSettings>
 </configuration>
\ No newline at end of file
diff --git a/ObservatoryCore/Assets/Resources.Designer.cs b/ObservatoryCore/Assets/Resources.Designer.cs
new file mode 100644
index 0000000..9013041
--- /dev/null
+++ b/ObservatoryCore/Assets/Resources.Designer.cs
@@ -0,0 +1,73 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Observatory.Assets {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Observatory.Assets.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+        /// </summary>
+        internal static System.Drawing.Icon EOCIcon_Presized {
+            get {
+                object obj = ResourceManager.GetObject("EOCIcon_Presized", resourceCulture);
+                return ((System.Drawing.Icon)(obj));
+            }
+        }
+    }
+}
diff --git a/ObservatoryCore/Assets/Resources.resx b/ObservatoryCore/Assets/Resources.resx
new file mode 100644
index 0000000..e07a181
--- /dev/null
+++ b/ObservatoryCore/Assets/Resources.resx
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="EOCIcon_Presized" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>EOCIcon-Presized.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/ObservatoryCore/NativeNotification/NativePopup.cs b/ObservatoryCore/NativeNotification/NativePopup.cs
index eff794e..9f35b74 100644
--- a/ObservatoryCore/NativeNotification/NativePopup.cs
+++ b/ObservatoryCore/NativeNotification/NativePopup.cs
@@ -1,5 +1,6 @@
 using Observatory.Framework;
 using Observatory.UI;
+using System;
 
 namespace Observatory.NativeNotification
 {
@@ -21,6 +22,11 @@ namespace Observatory.NativeNotification
 
                 notification.FormClosed += NotifyWindow_Closed;
 
+                foreach(var notificationForm in notifications)
+                {
+                    notificationForm.Value.AdjustOffset(true);
+                }
+
                 notifications.Add(notificationGuid, notification);
                 notification.Show();
             });
@@ -34,6 +40,11 @@ namespace Observatory.NativeNotification
             {
                 var currentNotification = (NotificationForm)sender;
 
+                foreach (var notification in notifications.Where(n => n.Value.CreationTime < currentNotification.CreationTime))
+                {
+                    notification.Value.AdjustOffset(false);
+                }
+
                 if (notifications.ContainsKey(currentNotification.Guid))
                 {
                     notifications.Remove(currentNotification.Guid);
diff --git a/ObservatoryCore/NativeNotification/NativeVoice.cs b/ObservatoryCore/NativeNotification/NativeVoice.cs
index 9a21fa4..fd14368 100644
--- a/ObservatoryCore/NativeNotification/NativeVoice.cs
+++ b/ObservatoryCore/NativeNotification/NativeVoice.cs
@@ -10,7 +10,7 @@ namespace Observatory.NativeNotification
 {
     public class NativeVoice
     {
-        private Queue<NotificationArgs> notificationEvents;
+        private readonly Queue<NotificationArgs> notificationEvents;
         private bool processing;
 
         public NativeVoice()
@@ -83,20 +83,24 @@ namespace Observatory.NativeNotification
             processing = false;
         }
 
-        private string AddVoiceToSsml(string ssml, string voiceName)
+        private static string AddVoiceToSsml(string ssml, string voiceName)
         {
             XmlDocument ssmlDoc = new();
             ssmlDoc.LoadXml(ssml);
 
-            var ssmlNamespace = ssmlDoc.DocumentElement.NamespaceURI;
+            var ssmlNamespace = ssmlDoc.DocumentElement?.NamespaceURI;
             XmlNamespaceManager ssmlNs = new(ssmlDoc.NameTable);
-            ssmlNs.AddNamespace("ssml", ssmlNamespace);
+            ssmlNs.AddNamespace("ssml", ssmlNamespace ?? string.Empty);
 
 
             var voiceNode = ssmlDoc.SelectSingleNode("/ssml:speak/ssml:voice", ssmlNs);
 
-            voiceNode.Attributes.GetNamedItem("name").Value = voiceName;
-
+            var voiceNameNode = voiceNode?.Attributes?.GetNamedItem("name");
+            if (voiceNameNode != null)
+            {
+                voiceNameNode.Value = voiceName;
+            }
+            
             return ssmlDoc.OuterXml;
         }
     }
diff --git a/ObservatoryCore/ObservatoryCore.csproj b/ObservatoryCore/ObservatoryCore.csproj
index 6bd0e88..68c5174 100644
--- a/ObservatoryCore/ObservatoryCore.csproj
+++ b/ObservatoryCore/ObservatoryCore.csproj
@@ -22,8 +22,9 @@
     </PropertyGroup>
 
     <ItemGroup>
-      <PackageReference Include="Microsoft.Security.Extensions" Version="1.2.0" />
-      <PackageReference Include="System.Speech" Version="7.0.0" />
+      <PackageReference Include="Microsoft.Security.Extensions" Version="1.3.0" />
+      <PackageReference Include="NAudio" Version="2.2.1" />
+      <PackageReference Include="System.Speech" Version="8.0.0" />
     </ItemGroup>
 	
 	<ItemGroup>
@@ -33,6 +34,11 @@
 	</ItemGroup>
 	
 	<ItemGroup>
+	<Compile Update="Assets\Resources.Designer.cs">
+	  <DesignTime>True</DesignTime>
+	  <AutoGen>True</AutoGen>
+	  <DependentUpon>Resources.resx</DependentUpon>
+	</Compile>
 	<Compile Update="Properties\Core.Designer.cs">
 		<DesignTimeSharedInput>True</DesignTimeSharedInput>
 		<AutoGen>True</AutoGen>
@@ -46,6 +52,10 @@
 	</ItemGroup>
 	
 	<ItemGroup>
+	  <EmbeddedResource Update="Assets\Resources.resx">
+	    <Generator>ResXFileCodeGenerator</Generator>
+	    <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+	  </EmbeddedResource>
 	  <EmbeddedResource Update="Properties\Resources.resx">
 	    <Generator>ResXFileCodeGenerator</Generator>
 	    <LastGenOutput>Resources.Designer.cs</LastGenOutput>
@@ -58,6 +68,10 @@
 			<LastGenOutput>Core.Designer.cs</LastGenOutput>
 		</None>
 	</ItemGroup>
+	
+	<ItemGroup>
+	  <Folder Include="Resources\" />
+	</ItemGroup>
 
 	<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
 		<Exec Condition=" '$(OS)' == 'Windows_NT'" Command="if not exist &quot;$(ProjectDir)..\ObservatoryFramework\bin\Release\net6.0\ObservatoryFramework.dll&quot; dotnet build &quot;$(ProjectDir)..\ObservatoryFramework\ObservatoryFramework.csproj&quot; -c Release" />
diff --git a/ObservatoryCore/PluginManagement/PluginCore.cs b/ObservatoryCore/PluginManagement/PluginCore.cs
index 97773c2..05f1e47 100644
--- a/ObservatoryCore/PluginManagement/PluginCore.cs
+++ b/ObservatoryCore/PluginManagement/PluginCore.cs
@@ -14,11 +14,15 @@ namespace Observatory.PluginManagement
 
         private readonly NativeVoice NativeVoice;
         private readonly NativePopup NativePopup;
-
-        public PluginCore()
+        private bool OverridePopup;
+        private bool OverrideAudio;
+        
+        public PluginCore(bool OverridePopup = false, bool OverrideAudio = false)
         {
             NativeVoice = new();
             NativePopup = new();
+            this.OverridePopup = OverridePopup;
+            this.OverrideAudio = OverrideAudio;
         }
 
         public string Version => System.Reflection.Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0";
@@ -31,11 +35,8 @@ namespace Observatory.PluginManagement
             };
         }
 
-        public Status GetStatus()
-        {
-            throw new NotImplementedException();
-        }
-
+        public Status GetStatus() => LogMonitor.GetInstance.Status;
+        
         public Guid SendNotification(string title, string text)
         {
             return SendNotification(new NotificationArgs() { Title = title, Detail = text });
@@ -53,12 +54,12 @@ namespace Observatory.PluginManagement
                     handler?.Invoke(this, notificationArgs);
                 }
 
-                if (Properties.Core.Default.NativeNotify && notificationArgs.Rendering.HasFlag(NotificationRendering.NativeVisual))
+                if (!OverridePopup && Properties.Core.Default.NativeNotify && notificationArgs.Rendering.HasFlag(NotificationRendering.NativeVisual))
                 {
                     guid = NativePopup.InvokeNativeNotification(notificationArgs);
                 }
 
-                if (Properties.Core.Default.VoiceNotify && notificationArgs.Rendering.HasFlag(NotificationRendering.NativeVocal))
+                if (!OverrideAudio && Properties.Core.Default.VoiceNotify && notificationArgs.Rendering.HasFlag(NotificationRendering.NativeVocal))
                 {
                     NativeVoice.EnqueueAndAnnounce(notificationArgs);
                 }
@@ -69,14 +70,13 @@ namespace Observatory.PluginManagement
 
         public void CancelNotification(Guid id)
         {
-            NativePopup.CloseNotification(id);
+            ExecuteOnUIThread(() => NativePopup.CloseNotification(id));
         }
 
         public void UpdateNotification(Guid id, NotificationArgs notificationArgs)
         {
             if (!IsLogMonitorBatchReading)
             {
-
                 if (notificationArgs.Rendering.HasFlag(NotificationRendering.PluginNotifier))
                 {
                     var handler = Notification;
@@ -140,6 +140,8 @@ namespace Observatory.PluginManagement
 
         public event EventHandler<NotificationArgs> Notification;
 
+        internal event EventHandler<PluginMessageArgs> PluginMessage;
+
         public string PluginStorageFolder
         {
             get
@@ -161,25 +163,19 @@ namespace Observatory.PluginManagement
             }
         }
 
+        public async Task PlayAudioFile(string filePath)
+        {
+            await AudioHandler.PlayFile(filePath);
+        }
+
+        public void SendPluginMessage(IObservatoryPlugin plugin, object message)
+        {
+            PluginMessage?.Invoke(this, new PluginMessageArgs(plugin.Name, plugin.Version, message));
+        }
+
         internal void Shutdown()
         {
             NativePopup.CloseAll();
         }
-
-        private static bool FirstRowIsAllNull(IObservatoryWorker worker)
-        {
-            bool allNull = true;
-            Type itemType = worker.PluginUI.DataGrid[0].GetType();
-            foreach (var property in itemType.GetProperties())
-            {
-                if (property.GetValue(worker.PluginUI.DataGrid[0], null) != null)
-                {
-                    allNull = false;
-                    break;
-                }
-            }
-
-            return allNull;
-        }
     }
 }
diff --git a/ObservatoryCore/PluginManagement/PluginEventHandler.cs b/ObservatoryCore/PluginManagement/PluginEventHandler.cs
index 44eab77..3292896 100644
--- a/ObservatoryCore/PluginManagement/PluginEventHandler.cs
+++ b/ObservatoryCore/PluginManagement/PluginEventHandler.cs
@@ -110,6 +110,14 @@ namespace Observatory.PluginManagement
             }
         }
 
+        public void OnPluginMessageEvent(object _, PluginMessageArgs messageArgs)
+        {
+            foreach (var plugin in observatoryNotifiers.Cast<IObservatoryPlugin>().Concat(observatoryWorkers))
+            {
+                plugin.HandlePluginMessage(messageArgs.SourceName, messageArgs.SourceVersion, messageArgs.Message);
+            }
+        }
+
         private void ResetTimer()
         {
             timer.Stop();
@@ -146,4 +154,18 @@ namespace Observatory.PluginManagement
             }
         }
     }
+
+    internal class PluginMessageArgs
+    {
+        internal string SourceName;
+        internal string SourceVersion;
+        internal object Message;
+
+        internal PluginMessageArgs(string sourceName, string sourceVersion, object message)
+        {
+            SourceName = sourceName;
+            SourceVersion = sourceVersion;
+            Message = message;
+        }
+    }
 }
diff --git a/ObservatoryCore/PluginManagement/PluginManager.cs b/ObservatoryCore/PluginManagement/PluginManager.cs
index 2df6441..f9878bc 100644
--- a/ObservatoryCore/PluginManagement/PluginManager.cs
+++ b/ObservatoryCore/PluginManagement/PluginManager.cs
@@ -50,7 +50,10 @@ namespace Observatory.PluginManagement
             logMonitor.StatusUpdate += pluginHandler.OnStatusUpdate;
             logMonitor.LogMonitorStateChanged += pluginHandler.OnLogMonitorStateChanged;
 
-            core = new PluginCore();
+            var ovPopup = notifyPlugins.Any(n => n.plugin.OverridePopupNotifications);
+            var ovAudio = notifyPlugins.Any(n => n.plugin.OverrideAudioNotifications);
+
+            core = new PluginCore(ovPopup, ovAudio);
 
             List<IObservatoryPlugin> errorPlugins = new();
             
@@ -97,6 +100,7 @@ namespace Observatory.PluginManagement
             notifyPlugins.RemoveAll(n => errorPlugins.Contains(n.plugin));
 
             core.Notification += pluginHandler.OnNotificationEvent;
+            core.PluginMessage += pluginHandler.OnPluginMessageEvent;
 
             if (errorList.Any())
                 ErrorReporter.ShowErrorPopup("Plugin Load Error" + (errorList.Count > 1 ? "s" : String.Empty), errorList);
@@ -114,7 +118,15 @@ namespace Observatory.PluginManagement
 
             if (!String.IsNullOrWhiteSpace(savedSettings))
             {
-                pluginSettings = JsonSerializer.Deserialize<Dictionary<string, object>>(savedSettings);
+                var settings = JsonSerializer.Deserialize<Dictionary<string, object>>(savedSettings);
+                if (settings != null)
+                {
+                    pluginSettings = settings;
+                }
+                else
+                {
+                    pluginSettings = new();
+                }
             }
             else
             {
@@ -138,7 +150,7 @@ namespace Observatory.PluginManagement
                 var properties = settings.GetType().GetProperties();
                 foreach (var property in properties)
                 {
-                    var attrib = property.GetCustomAttribute<Framework.SettingDisplayName>();
+                    var attrib = property.GetCustomAttribute<SettingDisplayName>();
                     if (attrib == null)
                     {
                         settingNames.Add(property, property.Name);
@@ -396,7 +408,7 @@ namespace Observatory.PluginManagement
                 if (constructor != null)
                 {
                     object instance = constructor.Invoke(Array.Empty<object>());
-                    notifiers.Add(((instance as IObservatoryNotifier)!, PluginStatus.Signed));
+                    notifiers.Add(((instance as IObservatoryNotifier)!, pluginStatus));
                     pluginCount++;
                 }
             }
diff --git a/ObservatoryCore/Properties/Core.Designer.cs b/ObservatoryCore/Properties/Core.Designer.cs
index dd4d677..e421d71 100644
--- a/ObservatoryCore/Properties/Core.Designer.cs
+++ b/ObservatoryCore/Properties/Core.Designer.cs
@@ -12,7 +12,7 @@ namespace Observatory.Properties {
     
     
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")]
     internal sealed partial class Core : global::System.Configuration.ApplicationSettingsBase {
         
         private static Core defaultInstance = ((Core)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Core())));
@@ -285,5 +285,29 @@ namespace Observatory.Properties {
                 this["UnsignedAllowed"] = value;
             }
         }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Dark")]
+        public string Theme {
+            get {
+                return ((string)(this["Theme"]));
+            }
+            set {
+                this["Theme"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string ColumnSizing {
+            get {
+                return ((string)(this["ColumnSizing"]));
+            }
+            set {
+                this["ColumnSizing"] = value;
+            }
+        }
     }
 }
diff --git a/ObservatoryCore/Properties/Core.settings b/ObservatoryCore/Properties/Core.settings
index 41dcaac..da57358 100644
--- a/ObservatoryCore/Properties/Core.settings
+++ b/ObservatoryCore/Properties/Core.settings
@@ -68,5 +68,11 @@
     <Setting Name="UnsignedAllowed" Type="System.Collections.Specialized.StringCollection" Scope="User">
       <Value Profile="(Default)" />
     </Setting>
+    <Setting Name="Theme" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Dark</Value>
+    </Setting>
+    <Setting Name="ColumnSizing" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
   </Settings>
 </SettingsFile>
\ No newline at end of file
diff --git a/ObservatoryCore/Resources/ObservatoryCoreIcon.ico b/ObservatoryCore/Resources/ObservatoryCoreIcon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..5d06b9f2857b39f0b5d3395e3e7999ba6bcc3a38
GIT binary patch
literal 45451
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

literal 0
HcmV?d00001

diff --git a/ObservatoryCore/UI/ColumnSizing.cs b/ObservatoryCore/UI/ColumnSizing.cs
new file mode 100644
index 0000000..1385dae
--- /dev/null
+++ b/ObservatoryCore/UI/ColumnSizing.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Observatory.UI
+{
+    public class ColumnSizing
+    {
+        public string PluginName { get; set; }
+        public string PluginVersion { get; set; }
+        public Dictionary<string, int> ColumnWidth 
+        {
+            get
+            {
+                _columnWidth ??= new Dictionary<string, int>();
+
+                return _columnWidth;
+            }
+             
+            set => _columnWidth = value;
+        }
+
+        private Dictionary<string, int>? _columnWidth;
+    }
+}
diff --git a/ObservatoryCore/UI/CoreForm.Designer.cs b/ObservatoryCore/UI/CoreForm.Designer.cs
index 5258cbf..7d04d49 100644
--- a/ObservatoryCore/UI/CoreForm.Designer.cs
+++ b/ObservatoryCore/UI/CoreForm.Designer.cs
@@ -28,634 +28,577 @@
         /// </summary>
         private void InitializeComponent()
         {
+            components = new System.ComponentModel.Container();
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CoreForm));
-            this.CoreMenu = new System.Windows.Forms.MenuStrip();
-            this.coreToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
-            this.CorePanel = new System.Windows.Forms.Panel();
-            this.VoiceSettingsPanel = new System.Windows.Forms.Panel();
-            this.VoiceSpeedSlider = new System.Windows.Forms.TrackBar();
-            this.VoiceVolumeSlider = new System.Windows.Forms.TrackBar();
-            this.VoiceTestButton = new System.Windows.Forms.Button();
-            this.VoiceCheckbox = new System.Windows.Forms.CheckBox();
-            this.VoiceDropdown = new System.Windows.Forms.ComboBox();
-            this.VoiceLabel = new System.Windows.Forms.Label();
-            this.VoiceSpeedLabel = new System.Windows.Forms.Label();
-            this.VoiceVolumeLabel = new System.Windows.Forms.Label();
-            this.VoiceNotificationLabel = new System.Windows.Forms.Label();
-            this.PopupSettingsPanel = new System.Windows.Forms.Panel();
-            this.DurationSpinner = new System.Windows.Forms.NumericUpDown();
-            this.ScaleSpinner = new System.Windows.Forms.NumericUpDown();
-            this.LabelColour = new System.Windows.Forms.Label();
-            this.TestButton = new System.Windows.Forms.Button();
-            this.ColourButton = new System.Windows.Forms.Button();
-            this.PopupCheckbox = new System.Windows.Forms.CheckBox();
-            this.LabelDuration = new System.Windows.Forms.Label();
-            this.LabelScale = new System.Windows.Forms.Label();
-            this.FontDropdown = new System.Windows.Forms.ComboBox();
-            this.LabelFont = new System.Windows.Forms.Label();
-            this.CornerDropdown = new System.Windows.Forms.ComboBox();
-            this.DisplayDropdown = new System.Windows.Forms.ComboBox();
-            this.CornerLabel = new System.Windows.Forms.Label();
-            this.DisplayLabel = new System.Windows.Forms.Label();
-            this.PopupNotificationLabel = new System.Windows.Forms.Label();
-            this.PluginFolderButton = new System.Windows.Forms.Button();
-            this.PluginList = new System.Windows.Forms.ListView();
-            this.NameColumn = new System.Windows.Forms.ColumnHeader();
-            this.TypeColumn = new System.Windows.Forms.ColumnHeader();
-            this.VersionColumn = new System.Windows.Forms.ColumnHeader();
-            this.StatusColumn = new System.Windows.Forms.ColumnHeader();
-            this.ReadAllButton = new System.Windows.Forms.Button();
-            this.ToggleMonitorButton = new System.Windows.Forms.Button();
-            this.ClearButton = new System.Windows.Forms.Button();
-            this.ExportButton = new System.Windows.Forms.Button();
-            this.GithubLink = new System.Windows.Forms.LinkLabel();
-            this.DonateLink = new System.Windows.Forms.LinkLabel();
-            this.PopupColour = new System.Windows.Forms.ColorDialog();
-            this.CoreMenu.SuspendLayout();
-            this.CorePanel.SuspendLayout();
-            this.VoiceSettingsPanel.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.VoiceSpeedSlider)).BeginInit();
-            ((System.ComponentModel.ISupportInitialize)(this.VoiceVolumeSlider)).BeginInit();
-            this.PopupSettingsPanel.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.DurationSpinner)).BeginInit();
-            ((System.ComponentModel.ISupportInitialize)(this.ScaleSpinner)).BeginInit();
-            this.SuspendLayout();
+            CoreMenu = new MenuStrip();
+            coreToolStripMenuItem = new ToolStripMenuItem();
+            toolStripMenuItem1 = new ToolStripMenuItem();
+            CorePanel = new Panel();
+            ThemeLabel = new Label();
+            PluginSettingsButton = new Button();
+            VoiceSettingsPanel = new Panel();
+            VoiceSpeedSlider = new TrackBar();
+            VoiceVolumeSlider = new TrackBar();
+            VoiceTestButton = new Button();
+            VoiceCheckbox = new CheckBox();
+            VoiceDropdown = new ComboBox();
+            VoiceLabel = new Label();
+            VoiceSpeedLabel = new Label();
+            VoiceVolumeLabel = new Label();
+            VoiceNotificationLabel = new Label();
+            PopupSettingsPanel = new Panel();
+            DurationSpinner = new NumericUpDown();
+            ScaleSpinner = new NumericUpDown();
+            LabelColour = new Label();
+            TestButton = new Button();
+            ColourButton = new Button();
+            PopupCheckbox = new CheckBox();
+            LabelDuration = new Label();
+            LabelScale = new Label();
+            FontDropdown = new ComboBox();
+            LabelFont = new Label();
+            CornerDropdown = new ComboBox();
+            DisplayDropdown = new ComboBox();
+            CornerLabel = new Label();
+            DisplayLabel = new Label();
+            PopupNotificationLabel = new Label();
+            PluginFolderButton = new Button();
+            PluginList = new ListView();
+            NameColumn = new ColumnHeader();
+            TypeColumn = new ColumnHeader();
+            VersionColumn = new ColumnHeader();
+            StatusColumn = new ColumnHeader();
+            ReadAllButton = new Button();
+            ToggleMonitorButton = new Button();
+            ClearButton = new Button();
+            ExportButton = new Button();
+            GithubLink = new LinkLabel();
+            DonateLink = new LinkLabel();
+            PopupColour = new ColorDialog();
+            OverrideTooltip = new ToolTip(components);
+            CoreMenu.SuspendLayout();
+            CorePanel.SuspendLayout();
+            VoiceSettingsPanel.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)VoiceSpeedSlider).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)VoiceVolumeSlider).BeginInit();
+            PopupSettingsPanel.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)DurationSpinner).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)ScaleSpinner).BeginInit();
+            SuspendLayout();
             // 
             // CoreMenu
             // 
-            this.CoreMenu.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
-            | System.Windows.Forms.AnchorStyles.Left)));
-            this.CoreMenu.AutoSize = false;
-            this.CoreMenu.BackColor = System.Drawing.Color.Black;
-            this.CoreMenu.Dock = System.Windows.Forms.DockStyle.None;
-            this.CoreMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.coreToolStripMenuItem,
-            this.toolStripMenuItem1});
-            this.CoreMenu.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
-            this.CoreMenu.Location = new System.Drawing.Point(0, 0);
-            this.CoreMenu.Name = "CoreMenu";
-            this.CoreMenu.Size = new System.Drawing.Size(120, 691);
-            this.CoreMenu.TabIndex = 0;
+            CoreMenu.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
+            CoreMenu.AutoSize = false;
+            CoreMenu.Dock = DockStyle.None;
+            CoreMenu.Items.AddRange(new ToolStripItem[] { coreToolStripMenuItem, toolStripMenuItem1 });
+            CoreMenu.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
+            CoreMenu.Location = new Point(0, 0);
+            CoreMenu.Name = "CoreMenu";
+            CoreMenu.Size = new Size(120, 691);
+            CoreMenu.TabIndex = 0;
             // 
             // coreToolStripMenuItem
             // 
-            this.coreToolStripMenuItem.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
-            this.coreToolStripMenuItem.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
-            this.coreToolStripMenuItem.Name = "coreToolStripMenuItem";
-            this.coreToolStripMenuItem.Size = new System.Drawing.Size(113, 36);
-            this.coreToolStripMenuItem.Text = "Core";
-            this.coreToolStripMenuItem.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            coreToolStripMenuItem.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point);
+            coreToolStripMenuItem.Name = "coreToolStripMenuItem";
+            coreToolStripMenuItem.Size = new Size(113, 36);
+            coreToolStripMenuItem.Text = "Core";
+            coreToolStripMenuItem.TextAlign = ContentAlignment.MiddleLeft;
             // 
             // toolStripMenuItem1
             // 
-            this.toolStripMenuItem1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
-            this.toolStripMenuItem1.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
-            this.toolStripMenuItem1.ForeColor = System.Drawing.Color.Gainsboro;
-            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
-            this.toolStripMenuItem1.Size = new System.Drawing.Size(113, 36);
-            this.toolStripMenuItem1.Text = "<";
-            this.toolStripMenuItem1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            toolStripMenuItem1.Alignment = ToolStripItemAlignment.Right;
+            toolStripMenuItem1.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point);
+            toolStripMenuItem1.Name = "toolStripMenuItem1";
+            toolStripMenuItem1.Size = new Size(113, 36);
+            toolStripMenuItem1.Text = "<";
+            toolStripMenuItem1.TextAlign = ContentAlignment.MiddleLeft;
             // 
             // CorePanel
             // 
-            this.CorePanel.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.CorePanel.AutoScroll = true;
-            this.CorePanel.Controls.Add(this.VoiceSettingsPanel);
-            this.CorePanel.Controls.Add(this.VoiceNotificationLabel);
-            this.CorePanel.Controls.Add(this.PopupSettingsPanel);
-            this.CorePanel.Controls.Add(this.PopupNotificationLabel);
-            this.CorePanel.Controls.Add(this.PluginFolderButton);
-            this.CorePanel.Controls.Add(this.PluginList);
-            this.CorePanel.Location = new System.Drawing.Point(123, 12);
-            this.CorePanel.Name = "CorePanel";
-            this.CorePanel.Size = new System.Drawing.Size(665, 679);
-            this.CorePanel.TabIndex = 1;
+            CorePanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
+            CorePanel.AutoScroll = true;
+            CorePanel.Controls.Add(ThemeLabel);
+            CorePanel.Controls.Add(PluginSettingsButton);
+            CorePanel.Controls.Add(VoiceSettingsPanel);
+            CorePanel.Controls.Add(VoiceNotificationLabel);
+            CorePanel.Controls.Add(PopupSettingsPanel);
+            CorePanel.Controls.Add(PopupNotificationLabel);
+            CorePanel.Controls.Add(PluginFolderButton);
+            CorePanel.Controls.Add(PluginList);
+            CorePanel.Location = new Point(123, 12);
+            CorePanel.Name = "CorePanel";
+            CorePanel.Size = new Size(665, 679);
+            CorePanel.TabIndex = 1;
+            // 
+            // ThemeLabel
+            // 
+            ThemeLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+            ThemeLabel.BorderStyle = BorderStyle.FixedSingle;
+            ThemeLabel.Location = new Point(3, 603);
+            ThemeLabel.Name = "ThemeLabel";
+            ThemeLabel.Size = new Size(659, 23);
+            ThemeLabel.TabIndex = 7;
+            ThemeLabel.Text = "❯ Theme";
+            ThemeLabel.TextAlign = ContentAlignment.MiddleLeft;
+            // 
+            // PluginSettingsButton
+            // 
+            PluginSettingsButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+            PluginSettingsButton.FlatAppearance.BorderSize = 0;
+            PluginSettingsButton.FlatStyle = FlatStyle.Flat;
+            PluginSettingsButton.Location = new Point(396, 140);
+            PluginSettingsButton.Name = "PluginSettingsButton";
+            PluginSettingsButton.Size = new Size(130, 23);
+            PluginSettingsButton.TabIndex = 6;
+            PluginSettingsButton.Text = "Plugin Settings";
+            PluginSettingsButton.UseVisualStyleBackColor = false;
+            PluginSettingsButton.Click += PluginSettingsButton_Click;
             // 
             // VoiceSettingsPanel
             // 
-            this.VoiceSettingsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.VoiceSettingsPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
-            this.VoiceSettingsPanel.Controls.Add(this.VoiceSpeedSlider);
-            this.VoiceSettingsPanel.Controls.Add(this.VoiceVolumeSlider);
-            this.VoiceSettingsPanel.Controls.Add(this.VoiceTestButton);
-            this.VoiceSettingsPanel.Controls.Add(this.VoiceCheckbox);
-            this.VoiceSettingsPanel.Controls.Add(this.VoiceDropdown);
-            this.VoiceSettingsPanel.Controls.Add(this.VoiceLabel);
-            this.VoiceSettingsPanel.Controls.Add(this.VoiceSpeedLabel);
-            this.VoiceSettingsPanel.Controls.Add(this.VoiceVolumeLabel);
-            this.VoiceSettingsPanel.Location = new System.Drawing.Point(3, 426);
-            this.VoiceSettingsPanel.Name = "VoiceSettingsPanel";
-            this.VoiceSettingsPanel.Size = new System.Drawing.Size(659, 177);
-            this.VoiceSettingsPanel.TabIndex = 5;
-            this.VoiceSettingsPanel.Visible = false;
+            VoiceSettingsPanel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+            VoiceSettingsPanel.Controls.Add(VoiceSpeedSlider);
+            VoiceSettingsPanel.Controls.Add(VoiceVolumeSlider);
+            VoiceSettingsPanel.Controls.Add(VoiceTestButton);
+            VoiceSettingsPanel.Controls.Add(VoiceCheckbox);
+            VoiceSettingsPanel.Controls.Add(VoiceDropdown);
+            VoiceSettingsPanel.Controls.Add(VoiceLabel);
+            VoiceSettingsPanel.Controls.Add(VoiceSpeedLabel);
+            VoiceSettingsPanel.Controls.Add(VoiceVolumeLabel);
+            VoiceSettingsPanel.Location = new Point(3, 426);
+            VoiceSettingsPanel.Name = "VoiceSettingsPanel";
+            VoiceSettingsPanel.Size = new Size(659, 177);
+            VoiceSettingsPanel.TabIndex = 5;
+            VoiceSettingsPanel.Visible = false;
             // 
             // VoiceSpeedSlider
             // 
-            this.VoiceSpeedSlider.Location = new System.Drawing.Point(121, 51);
-            this.VoiceSpeedSlider.Maximum = 100;
-            this.VoiceSpeedSlider.Name = "VoiceSpeedSlider";
-            this.VoiceSpeedSlider.Size = new System.Drawing.Size(120, 45);
-            this.VoiceSpeedSlider.TabIndex = 15;
-            this.VoiceSpeedSlider.TickFrequency = 10;
-            this.VoiceSpeedSlider.TickStyle = System.Windows.Forms.TickStyle.Both;
-            this.VoiceSpeedSlider.Value = 50;
-            this.VoiceSpeedSlider.Scroll += new System.EventHandler(this.VoiceSpeedSlider_Scroll);
+            VoiceSpeedSlider.Location = new Point(121, 51);
+            VoiceSpeedSlider.Maximum = 100;
+            VoiceSpeedSlider.Name = "VoiceSpeedSlider";
+            VoiceSpeedSlider.Size = new Size(120, 45);
+            VoiceSpeedSlider.TabIndex = 15;
+            VoiceSpeedSlider.TickFrequency = 10;
+            VoiceSpeedSlider.TickStyle = TickStyle.Both;
+            VoiceSpeedSlider.Value = 50;
+            VoiceSpeedSlider.Scroll += VoiceSpeedSlider_Scroll;
             // 
             // VoiceVolumeSlider
             // 
-            this.VoiceVolumeSlider.LargeChange = 10;
-            this.VoiceVolumeSlider.Location = new System.Drawing.Point(120, 0);
-            this.VoiceVolumeSlider.Maximum = 100;
-            this.VoiceVolumeSlider.Name = "VoiceVolumeSlider";
-            this.VoiceVolumeSlider.Size = new System.Drawing.Size(121, 45);
-            this.VoiceVolumeSlider.TabIndex = 14;
-            this.VoiceVolumeSlider.TickFrequency = 10;
-            this.VoiceVolumeSlider.TickStyle = System.Windows.Forms.TickStyle.Both;
-            this.VoiceVolumeSlider.Value = 100;
-            this.VoiceVolumeSlider.Scroll += new System.EventHandler(this.VoiceVolumeSlider_Scroll);
+            VoiceVolumeSlider.LargeChange = 10;
+            VoiceVolumeSlider.Location = new Point(120, 0);
+            VoiceVolumeSlider.Maximum = 100;
+            VoiceVolumeSlider.Name = "VoiceVolumeSlider";
+            VoiceVolumeSlider.Size = new Size(121, 45);
+            VoiceVolumeSlider.TabIndex = 14;
+            VoiceVolumeSlider.TickFrequency = 10;
+            VoiceVolumeSlider.TickStyle = TickStyle.Both;
+            VoiceVolumeSlider.Value = 100;
+            VoiceVolumeSlider.Scroll += VoiceVolumeSlider_Scroll;
             // 
             // VoiceTestButton
             // 
-            this.VoiceTestButton.BackColor = System.Drawing.Color.DimGray;
-            this.VoiceTestButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.VoiceTestButton.ForeColor = System.Drawing.Color.WhiteSmoke;
-            this.VoiceTestButton.Location = new System.Drawing.Point(190, 131);
-            this.VoiceTestButton.Name = "VoiceTestButton";
-            this.VoiceTestButton.Size = new System.Drawing.Size(51, 23);
-            this.VoiceTestButton.TabIndex = 13;
-            this.VoiceTestButton.Text = "Test";
-            this.VoiceTestButton.UseVisualStyleBackColor = false;
+            VoiceTestButton.FlatStyle = FlatStyle.Flat;
+            VoiceTestButton.Location = new Point(190, 131);
+            VoiceTestButton.Name = "VoiceTestButton";
+            VoiceTestButton.Size = new Size(51, 23);
+            VoiceTestButton.TabIndex = 13;
+            VoiceTestButton.Text = "Test";
+            VoiceTestButton.UseVisualStyleBackColor = false;
             // 
             // VoiceCheckbox
             // 
-            this.VoiceCheckbox.AutoSize = true;
-            this.VoiceCheckbox.ForeColor = System.Drawing.Color.Gainsboro;
-            this.VoiceCheckbox.Location = new System.Drawing.Point(120, 134);
-            this.VoiceCheckbox.Name = "VoiceCheckbox";
-            this.VoiceCheckbox.Size = new System.Drawing.Size(68, 19);
-            this.VoiceCheckbox.TabIndex = 11;
-            this.VoiceCheckbox.Text = "Enabled";
-            this.VoiceCheckbox.UseVisualStyleBackColor = true;
-            this.VoiceCheckbox.CheckedChanged += new System.EventHandler(this.VoiceCheckbox_CheckedChanged);
+            VoiceCheckbox.AutoSize = true;
+            VoiceCheckbox.Location = new Point(120, 134);
+            VoiceCheckbox.Name = "VoiceCheckbox";
+            VoiceCheckbox.Size = new Size(68, 19);
+            VoiceCheckbox.TabIndex = 11;
+            VoiceCheckbox.Text = "Enabled";
+            VoiceCheckbox.UseVisualStyleBackColor = true;
+            VoiceCheckbox.CheckedChanged += VoiceCheckbox_CheckedChanged;
             // 
             // VoiceDropdown
             // 
-            this.VoiceDropdown.FormattingEnabled = true;
-            this.VoiceDropdown.Location = new System.Drawing.Point(121, 102);
-            this.VoiceDropdown.Name = "VoiceDropdown";
-            this.VoiceDropdown.Size = new System.Drawing.Size(121, 23);
-            this.VoiceDropdown.TabIndex = 5;
-            this.VoiceDropdown.SelectedIndexChanged += new System.EventHandler(this.VoiceDropdown_SelectedIndexChanged);
+            VoiceDropdown.FormattingEnabled = true;
+            VoiceDropdown.Location = new Point(121, 102);
+            VoiceDropdown.Name = "VoiceDropdown";
+            VoiceDropdown.Size = new Size(121, 23);
+            VoiceDropdown.TabIndex = 5;
+            VoiceDropdown.SelectedIndexChanged += VoiceDropdown_SelectedIndexChanged;
             // 
             // VoiceLabel
             // 
-            this.VoiceLabel.AutoSize = true;
-            this.VoiceLabel.ForeColor = System.Drawing.Color.Gainsboro;
-            this.VoiceLabel.Location = new System.Drawing.Point(77, 105);
-            this.VoiceLabel.Name = "VoiceLabel";
-            this.VoiceLabel.Size = new System.Drawing.Size(38, 15);
-            this.VoiceLabel.TabIndex = 4;
-            this.VoiceLabel.Text = "Voice:";
-            this.VoiceLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            VoiceLabel.AutoSize = true;
+            VoiceLabel.Location = new Point(77, 105);
+            VoiceLabel.Name = "VoiceLabel";
+            VoiceLabel.Size = new Size(38, 15);
+            VoiceLabel.TabIndex = 4;
+            VoiceLabel.Text = "Voice:";
+            VoiceLabel.TextAlign = ContentAlignment.MiddleRight;
             // 
             // VoiceSpeedLabel
             // 
-            this.VoiceSpeedLabel.AutoSize = true;
-            this.VoiceSpeedLabel.ForeColor = System.Drawing.Color.Gainsboro;
-            this.VoiceSpeedLabel.Location = new System.Drawing.Point(73, 63);
-            this.VoiceSpeedLabel.Name = "VoiceSpeedLabel";
-            this.VoiceSpeedLabel.Size = new System.Drawing.Size(42, 15);
-            this.VoiceSpeedLabel.TabIndex = 1;
-            this.VoiceSpeedLabel.Text = "Speed:";
-            this.VoiceSpeedLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            VoiceSpeedLabel.AutoSize = true;
+            VoiceSpeedLabel.Location = new Point(73, 63);
+            VoiceSpeedLabel.Name = "VoiceSpeedLabel";
+            VoiceSpeedLabel.Size = new Size(42, 15);
+            VoiceSpeedLabel.TabIndex = 1;
+            VoiceSpeedLabel.Text = "Speed:";
+            VoiceSpeedLabel.TextAlign = ContentAlignment.MiddleRight;
             // 
             // VoiceVolumeLabel
             // 
-            this.VoiceVolumeLabel.AutoSize = true;
-            this.VoiceVolumeLabel.ForeColor = System.Drawing.Color.Gainsboro;
-            this.VoiceVolumeLabel.Location = new System.Drawing.Point(64, 12);
-            this.VoiceVolumeLabel.Name = "VoiceVolumeLabel";
-            this.VoiceVolumeLabel.Size = new System.Drawing.Size(50, 15);
-            this.VoiceVolumeLabel.TabIndex = 0;
-            this.VoiceVolumeLabel.Text = "Volume:";
-            this.VoiceVolumeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            VoiceVolumeLabel.AutoSize = true;
+            VoiceVolumeLabel.Location = new Point(64, 12);
+            VoiceVolumeLabel.Name = "VoiceVolumeLabel";
+            VoiceVolumeLabel.Size = new Size(50, 15);
+            VoiceVolumeLabel.TabIndex = 0;
+            VoiceVolumeLabel.Text = "Volume:";
+            VoiceVolumeLabel.TextAlign = ContentAlignment.MiddleRight;
             // 
             // VoiceNotificationLabel
             // 
-            this.VoiceNotificationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.VoiceNotificationLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
-            this.VoiceNotificationLabel.ForeColor = System.Drawing.Color.LightGray;
-            this.VoiceNotificationLabel.Location = new System.Drawing.Point(3, 403);
-            this.VoiceNotificationLabel.Name = "VoiceNotificationLabel";
-            this.VoiceNotificationLabel.Size = new System.Drawing.Size(659, 23);
-            this.VoiceNotificationLabel.TabIndex = 4;
-            this.VoiceNotificationLabel.Text = "❯ Voice Notifications";
-            this.VoiceNotificationLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
-            this.VoiceNotificationLabel.Click += new System.EventHandler(this.VoiceNotificationLabel_Click);
+            VoiceNotificationLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+            VoiceNotificationLabel.BorderStyle = BorderStyle.FixedSingle;
+            VoiceNotificationLabel.Location = new Point(3, 403);
+            VoiceNotificationLabel.Name = "VoiceNotificationLabel";
+            VoiceNotificationLabel.Size = new Size(659, 23);
+            VoiceNotificationLabel.TabIndex = 4;
+            VoiceNotificationLabel.Text = "❯ Voice Notifications";
+            VoiceNotificationLabel.TextAlign = ContentAlignment.MiddleLeft;
+            VoiceNotificationLabel.Click += VoiceNotificationLabel_Click;
             // 
             // PopupSettingsPanel
             // 
-            this.PopupSettingsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.PopupSettingsPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
-            this.PopupSettingsPanel.Controls.Add(this.DurationSpinner);
-            this.PopupSettingsPanel.Controls.Add(this.ScaleSpinner);
-            this.PopupSettingsPanel.Controls.Add(this.LabelColour);
-            this.PopupSettingsPanel.Controls.Add(this.TestButton);
-            this.PopupSettingsPanel.Controls.Add(this.ColourButton);
-            this.PopupSettingsPanel.Controls.Add(this.PopupCheckbox);
-            this.PopupSettingsPanel.Controls.Add(this.LabelDuration);
-            this.PopupSettingsPanel.Controls.Add(this.LabelScale);
-            this.PopupSettingsPanel.Controls.Add(this.FontDropdown);
-            this.PopupSettingsPanel.Controls.Add(this.LabelFont);
-            this.PopupSettingsPanel.Controls.Add(this.CornerDropdown);
-            this.PopupSettingsPanel.Controls.Add(this.DisplayDropdown);
-            this.PopupSettingsPanel.Controls.Add(this.CornerLabel);
-            this.PopupSettingsPanel.Controls.Add(this.DisplayLabel);
-            this.PopupSettingsPanel.Location = new System.Drawing.Point(3, 195);
-            this.PopupSettingsPanel.Name = "PopupSettingsPanel";
-            this.PopupSettingsPanel.Size = new System.Drawing.Size(659, 208);
-            this.PopupSettingsPanel.TabIndex = 3;
-            this.PopupSettingsPanel.Visible = false;
+            PopupSettingsPanel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+            PopupSettingsPanel.Controls.Add(DurationSpinner);
+            PopupSettingsPanel.Controls.Add(ScaleSpinner);
+            PopupSettingsPanel.Controls.Add(LabelColour);
+            PopupSettingsPanel.Controls.Add(TestButton);
+            PopupSettingsPanel.Controls.Add(ColourButton);
+            PopupSettingsPanel.Controls.Add(PopupCheckbox);
+            PopupSettingsPanel.Controls.Add(LabelDuration);
+            PopupSettingsPanel.Controls.Add(LabelScale);
+            PopupSettingsPanel.Controls.Add(FontDropdown);
+            PopupSettingsPanel.Controls.Add(LabelFont);
+            PopupSettingsPanel.Controls.Add(CornerDropdown);
+            PopupSettingsPanel.Controls.Add(DisplayDropdown);
+            PopupSettingsPanel.Controls.Add(CornerLabel);
+            PopupSettingsPanel.Controls.Add(DisplayLabel);
+            PopupSettingsPanel.Location = new Point(3, 195);
+            PopupSettingsPanel.Name = "PopupSettingsPanel";
+            PopupSettingsPanel.Size = new Size(659, 208);
+            PopupSettingsPanel.TabIndex = 3;
+            PopupSettingsPanel.Visible = false;
             // 
             // DurationSpinner
             // 
-            this.DurationSpinner.BackColor = System.Drawing.Color.DimGray;
-            this.DurationSpinner.ForeColor = System.Drawing.Color.Gainsboro;
-            this.DurationSpinner.Increment = new decimal(new int[] {
-            25,
-            0,
-            0,
-            0});
-            this.DurationSpinner.Location = new System.Drawing.Point(121, 119);
-            this.DurationSpinner.Maximum = new decimal(new int[] {
-            60000,
-            0,
-            0,
-            0});
-            this.DurationSpinner.Minimum = new decimal(new int[] {
-            100,
-            0,
-            0,
-            0});
-            this.DurationSpinner.Name = "DurationSpinner";
-            this.DurationSpinner.Size = new System.Drawing.Size(120, 23);
-            this.DurationSpinner.TabIndex = 15;
-            this.DurationSpinner.Value = new decimal(new int[] {
-            8000,
-            0,
-            0,
-            0});
-            this.DurationSpinner.ValueChanged += new System.EventHandler(this.DurationSpinner_ValueChanged);
+            DurationSpinner.Increment = new decimal(new int[] { 25, 0, 0, 0 });
+            DurationSpinner.Location = new Point(121, 119);
+            DurationSpinner.Maximum = new decimal(new int[] { 60000, 0, 0, 0 });
+            DurationSpinner.Minimum = new decimal(new int[] { 100, 0, 0, 0 });
+            DurationSpinner.Name = "DurationSpinner";
+            DurationSpinner.Size = new Size(120, 23);
+            DurationSpinner.TabIndex = 15;
+            DurationSpinner.Value = new decimal(new int[] { 8000, 0, 0, 0 });
+            DurationSpinner.ValueChanged += DurationSpinner_ValueChanged;
             // 
             // ScaleSpinner
             // 
-            this.ScaleSpinner.BackColor = System.Drawing.Color.DimGray;
-            this.ScaleSpinner.ForeColor = System.Drawing.Color.Gainsboro;
-            this.ScaleSpinner.Location = new System.Drawing.Point(121, 90);
-            this.ScaleSpinner.Maximum = new decimal(new int[] {
-            500,
-            0,
-            0,
-            0});
-            this.ScaleSpinner.Minimum = new decimal(new int[] {
-            1,
-            0,
-            0,
-            0});
-            this.ScaleSpinner.Name = "ScaleSpinner";
-            this.ScaleSpinner.Size = new System.Drawing.Size(120, 23);
-            this.ScaleSpinner.TabIndex = 14;
-            this.ScaleSpinner.Value = new decimal(new int[] {
-            100,
-            0,
-            0,
-            0});
-            this.ScaleSpinner.ValueChanged += new System.EventHandler(this.ScaleSpinner_ValueChanged);
+            ScaleSpinner.Location = new Point(121, 90);
+            ScaleSpinner.Maximum = new decimal(new int[] { 500, 0, 0, 0 });
+            ScaleSpinner.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
+            ScaleSpinner.Name = "ScaleSpinner";
+            ScaleSpinner.Size = new Size(120, 23);
+            ScaleSpinner.TabIndex = 14;
+            ScaleSpinner.Value = new decimal(new int[] { 100, 0, 0, 0 });
+            ScaleSpinner.ValueChanged += ScaleSpinner_ValueChanged;
             // 
             // LabelColour
             // 
-            this.LabelColour.AutoSize = true;
-            this.LabelColour.ForeColor = System.Drawing.Color.Gainsboro;
-            this.LabelColour.Location = new System.Drawing.Point(68, 152);
-            this.LabelColour.Name = "LabelColour";
-            this.LabelColour.Size = new System.Drawing.Size(46, 15);
-            this.LabelColour.TabIndex = 13;
-            this.LabelColour.Text = "Colour:";
-            this.LabelColour.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            LabelColour.AutoSize = true;
+            LabelColour.Location = new Point(68, 152);
+            LabelColour.Name = "LabelColour";
+            LabelColour.Size = new Size(46, 15);
+            LabelColour.TabIndex = 13;
+            LabelColour.Text = "Colour:";
+            LabelColour.TextAlign = ContentAlignment.MiddleRight;
             // 
             // TestButton
             // 
-            this.TestButton.BackColor = System.Drawing.Color.DimGray;
-            this.TestButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.TestButton.ForeColor = System.Drawing.Color.WhiteSmoke;
-            this.TestButton.Location = new System.Drawing.Point(190, 148);
-            this.TestButton.Name = "TestButton";
-            this.TestButton.Size = new System.Drawing.Size(51, 23);
-            this.TestButton.TabIndex = 12;
-            this.TestButton.Text = "Test";
-            this.TestButton.UseVisualStyleBackColor = false;
-            this.TestButton.Click += new System.EventHandler(this.TestButton_Click);
+            TestButton.FlatStyle = FlatStyle.Flat;
+            TestButton.Location = new Point(190, 148);
+            TestButton.Name = "TestButton";
+            TestButton.Size = new Size(51, 23);
+            TestButton.TabIndex = 12;
+            TestButton.Text = "Test";
+            TestButton.UseVisualStyleBackColor = false;
+            TestButton.Click += TestButton_Click;
             // 
             // ColourButton
             // 
-            this.ColourButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.ColourButton.Location = new System.Drawing.Point(121, 148);
-            this.ColourButton.Name = "ColourButton";
-            this.ColourButton.Size = new System.Drawing.Size(51, 23);
-            this.ColourButton.TabIndex = 11;
-            this.ColourButton.UseVisualStyleBackColor = true;
-            this.ColourButton.Click += new System.EventHandler(this.ColourButton_Click);
+            ColourButton.FlatStyle = FlatStyle.Flat;
+            ColourButton.Location = new Point(121, 148);
+            ColourButton.Name = "ColourButton";
+            ColourButton.Size = new Size(51, 23);
+            ColourButton.TabIndex = 11;
+            ColourButton.UseVisualStyleBackColor = true;
+            ColourButton.Click += ColourButton_Click;
             // 
             // PopupCheckbox
             // 
-            this.PopupCheckbox.AutoSize = true;
-            this.PopupCheckbox.ForeColor = System.Drawing.Color.Gainsboro;
-            this.PopupCheckbox.Location = new System.Drawing.Point(120, 177);
-            this.PopupCheckbox.Name = "PopupCheckbox";
-            this.PopupCheckbox.Size = new System.Drawing.Size(68, 19);
-            this.PopupCheckbox.TabIndex = 10;
-            this.PopupCheckbox.Text = "Enabled";
-            this.PopupCheckbox.UseVisualStyleBackColor = true;
-            this.PopupCheckbox.CheckedChanged += new System.EventHandler(this.PopupCheckbox_CheckedChanged);
+            PopupCheckbox.AutoSize = true;
+            PopupCheckbox.Location = new Point(120, 177);
+            PopupCheckbox.Name = "PopupCheckbox";
+            PopupCheckbox.Size = new Size(68, 19);
+            PopupCheckbox.TabIndex = 10;
+            PopupCheckbox.Text = "Enabled";
+            PopupCheckbox.UseVisualStyleBackColor = true;
+            PopupCheckbox.CheckedChanged += PopupCheckbox_CheckedChanged;
             // 
             // LabelDuration
             // 
-            this.LabelDuration.AutoSize = true;
-            this.LabelDuration.ForeColor = System.Drawing.Color.Gainsboro;
-            this.LabelDuration.Location = new System.Drawing.Point(32, 121);
-            this.LabelDuration.Name = "LabelDuration";
-            this.LabelDuration.Size = new System.Drawing.Size(83, 15);
-            this.LabelDuration.TabIndex = 9;
-            this.LabelDuration.Text = "Duration (ms):";
-            this.LabelDuration.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            LabelDuration.AutoSize = true;
+            LabelDuration.Location = new Point(32, 121);
+            LabelDuration.Name = "LabelDuration";
+            LabelDuration.Size = new Size(83, 15);
+            LabelDuration.TabIndex = 9;
+            LabelDuration.Text = "Duration (ms):";
+            LabelDuration.TextAlign = ContentAlignment.MiddleRight;
             // 
             // LabelScale
             // 
-            this.LabelScale.AutoSize = true;
-            this.LabelScale.ForeColor = System.Drawing.Color.Gainsboro;
-            this.LabelScale.Location = new System.Drawing.Point(57, 92);
-            this.LabelScale.Name = "LabelScale";
-            this.LabelScale.Size = new System.Drawing.Size(58, 15);
-            this.LabelScale.TabIndex = 7;
-            this.LabelScale.Text = "Scale (%):";
-            this.LabelScale.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            LabelScale.AutoSize = true;
+            LabelScale.Location = new Point(57, 92);
+            LabelScale.Name = "LabelScale";
+            LabelScale.Size = new Size(58, 15);
+            LabelScale.TabIndex = 7;
+            LabelScale.Text = "Scale (%):";
+            LabelScale.TextAlign = ContentAlignment.MiddleRight;
             // 
             // FontDropdown
             // 
-            this.FontDropdown.FormattingEnabled = true;
-            this.FontDropdown.Location = new System.Drawing.Point(120, 61);
-            this.FontDropdown.Name = "FontDropdown";
-            this.FontDropdown.Size = new System.Drawing.Size(121, 23);
-            this.FontDropdown.TabIndex = 5;
-            this.FontDropdown.SelectedIndexChanged += new System.EventHandler(this.FontDropdown_SelectedIndexChanged);
+            FontDropdown.FormattingEnabled = true;
+            FontDropdown.Location = new Point(120, 61);
+            FontDropdown.Name = "FontDropdown";
+            FontDropdown.Size = new Size(121, 23);
+            FontDropdown.TabIndex = 5;
+            FontDropdown.SelectedIndexChanged += FontDropdown_SelectedIndexChanged;
             // 
             // LabelFont
             // 
-            this.LabelFont.AutoSize = true;
-            this.LabelFont.ForeColor = System.Drawing.Color.Gainsboro;
-            this.LabelFont.Location = new System.Drawing.Point(80, 64);
-            this.LabelFont.Name = "LabelFont";
-            this.LabelFont.Size = new System.Drawing.Size(34, 15);
-            this.LabelFont.TabIndex = 4;
-            this.LabelFont.Text = "Font:";
-            this.LabelFont.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            LabelFont.AutoSize = true;
+            LabelFont.Location = new Point(80, 64);
+            LabelFont.Name = "LabelFont";
+            LabelFont.Size = new Size(34, 15);
+            LabelFont.TabIndex = 4;
+            LabelFont.Text = "Font:";
+            LabelFont.TextAlign = ContentAlignment.MiddleRight;
             // 
             // CornerDropdown
             // 
-            this.CornerDropdown.FormattingEnabled = true;
-            this.CornerDropdown.Items.AddRange(new object[] {
-            "Bottom-Right",
-            "Bottom-Left",
-            "Top-Right",
-            "Top-Left"});
-            this.CornerDropdown.Location = new System.Drawing.Point(120, 32);
-            this.CornerDropdown.Name = "CornerDropdown";
-            this.CornerDropdown.Size = new System.Drawing.Size(121, 23);
-            this.CornerDropdown.TabIndex = 3;
-            this.CornerDropdown.SelectedIndexChanged += new System.EventHandler(this.CornerDropdown_SelectedIndexChanged);
+            CornerDropdown.FormattingEnabled = true;
+            CornerDropdown.Items.AddRange(new object[] { "Bottom-Right", "Bottom-Left", "Top-Right", "Top-Left" });
+            CornerDropdown.Location = new Point(120, 32);
+            CornerDropdown.Name = "CornerDropdown";
+            CornerDropdown.Size = new Size(121, 23);
+            CornerDropdown.TabIndex = 3;
+            CornerDropdown.SelectedIndexChanged += CornerDropdown_SelectedIndexChanged;
             // 
             // DisplayDropdown
             // 
-            this.DisplayDropdown.FormattingEnabled = true;
-            this.DisplayDropdown.Location = new System.Drawing.Point(120, 3);
-            this.DisplayDropdown.Name = "DisplayDropdown";
-            this.DisplayDropdown.Size = new System.Drawing.Size(121, 23);
-            this.DisplayDropdown.TabIndex = 2;
-            this.DisplayDropdown.SelectedIndexChanged += new System.EventHandler(this.DisplayDropdown_SelectedIndexChanged);
+            DisplayDropdown.FormattingEnabled = true;
+            DisplayDropdown.Location = new Point(120, 3);
+            DisplayDropdown.Name = "DisplayDropdown";
+            DisplayDropdown.Size = new Size(121, 23);
+            DisplayDropdown.TabIndex = 2;
+            DisplayDropdown.SelectedIndexChanged += DisplayDropdown_SelectedIndexChanged;
             // 
             // CornerLabel
             // 
-            this.CornerLabel.AutoSize = true;
-            this.CornerLabel.ForeColor = System.Drawing.Color.Gainsboro;
-            this.CornerLabel.Location = new System.Drawing.Point(68, 35);
-            this.CornerLabel.Name = "CornerLabel";
-            this.CornerLabel.Size = new System.Drawing.Size(46, 15);
-            this.CornerLabel.TabIndex = 1;
-            this.CornerLabel.Text = "Corner:";
-            this.CornerLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            CornerLabel.AutoSize = true;
+            CornerLabel.Location = new Point(68, 35);
+            CornerLabel.Name = "CornerLabel";
+            CornerLabel.Size = new Size(46, 15);
+            CornerLabel.TabIndex = 1;
+            CornerLabel.Text = "Corner:";
+            CornerLabel.TextAlign = ContentAlignment.MiddleRight;
             // 
             // DisplayLabel
             // 
-            this.DisplayLabel.AutoSize = true;
-            this.DisplayLabel.ForeColor = System.Drawing.Color.Gainsboro;
-            this.DisplayLabel.Location = new System.Drawing.Point(66, 6);
-            this.DisplayLabel.Name = "DisplayLabel";
-            this.DisplayLabel.Size = new System.Drawing.Size(48, 15);
-            this.DisplayLabel.TabIndex = 0;
-            this.DisplayLabel.Text = "Display:";
-            this.DisplayLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+            DisplayLabel.AutoSize = true;
+            DisplayLabel.Location = new Point(66, 6);
+            DisplayLabel.Name = "DisplayLabel";
+            DisplayLabel.Size = new Size(48, 15);
+            DisplayLabel.TabIndex = 0;
+            DisplayLabel.Text = "Display:";
+            DisplayLabel.TextAlign = ContentAlignment.MiddleRight;
             // 
             // PopupNotificationLabel
             // 
-            this.PopupNotificationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.PopupNotificationLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
-            this.PopupNotificationLabel.ForeColor = System.Drawing.Color.LightGray;
-            this.PopupNotificationLabel.Location = new System.Drawing.Point(3, 172);
-            this.PopupNotificationLabel.Name = "PopupNotificationLabel";
-            this.PopupNotificationLabel.Size = new System.Drawing.Size(659, 23);
-            this.PopupNotificationLabel.TabIndex = 2;
-            this.PopupNotificationLabel.Text = "❯ Popup Notifications";
-            this.PopupNotificationLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
-            this.PopupNotificationLabel.Click += new System.EventHandler(this.PopupNotificationLabel_Click);
+            PopupNotificationLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+            PopupNotificationLabel.BorderStyle = BorderStyle.FixedSingle;
+            PopupNotificationLabel.Location = new Point(3, 172);
+            PopupNotificationLabel.Name = "PopupNotificationLabel";
+            PopupNotificationLabel.Size = new Size(659, 23);
+            PopupNotificationLabel.TabIndex = 2;
+            PopupNotificationLabel.Text = "❯ Popup Notifications";
+            PopupNotificationLabel.TextAlign = ContentAlignment.MiddleLeft;
+            PopupNotificationLabel.Click += PopupNotificationLabel_Click;
             // 
             // PluginFolderButton
             // 
-            this.PluginFolderButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-            this.PluginFolderButton.BackColor = System.Drawing.Color.DimGray;
-            this.PluginFolderButton.FlatAppearance.BorderSize = 0;
-            this.PluginFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.PluginFolderButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
-            this.PluginFolderButton.Location = new System.Drawing.Point(532, 140);
-            this.PluginFolderButton.Name = "PluginFolderButton";
-            this.PluginFolderButton.Size = new System.Drawing.Size(130, 23);
-            this.PluginFolderButton.TabIndex = 1;
-            this.PluginFolderButton.Text = "Open Plugin Folder";
-            this.PluginFolderButton.UseVisualStyleBackColor = false;
+            PluginFolderButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+            PluginFolderButton.FlatAppearance.BorderSize = 0;
+            PluginFolderButton.FlatStyle = FlatStyle.Flat;
+            PluginFolderButton.Location = new Point(532, 140);
+            PluginFolderButton.Name = "PluginFolderButton";
+            PluginFolderButton.Size = new Size(130, 23);
+            PluginFolderButton.TabIndex = 1;
+            PluginFolderButton.Text = "Open Plugin Folder";
+            PluginFolderButton.UseVisualStyleBackColor = false;
             // 
             // PluginList
             // 
-            this.PluginList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.PluginList.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
-            this.PluginList.BorderStyle = System.Windows.Forms.BorderStyle.None;
-            this.PluginList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
-            this.NameColumn,
-            this.TypeColumn,
-            this.VersionColumn,
-            this.StatusColumn});
-            this.PluginList.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
-            this.PluginList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
-            this.PluginList.Location = new System.Drawing.Point(3, 3);
-            this.PluginList.MultiSelect = false;
-            this.PluginList.Name = "PluginList";
-            this.PluginList.OwnerDraw = true;
-            this.PluginList.Scrollable = false;
-            this.PluginList.Size = new System.Drawing.Size(659, 137);
-            this.PluginList.TabIndex = 0;
-            this.PluginList.UseCompatibleStateImageBehavior = false;
-            this.PluginList.View = System.Windows.Forms.View.Details;
-            this.PluginList.Resize += new System.EventHandler(this.PluginList_Resize);
+            PluginList.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+            PluginList.BorderStyle = BorderStyle.None;
+            PluginList.Columns.AddRange(new ColumnHeader[] { NameColumn, TypeColumn, VersionColumn, StatusColumn });
+            PluginList.HeaderStyle = ColumnHeaderStyle.Nonclickable;
+            PluginList.ImeMode = ImeMode.NoControl;
+            PluginList.Location = new Point(3, 3);
+            PluginList.MultiSelect = false;
+            PluginList.Name = "PluginList";
+            PluginList.OwnerDraw = true;
+            PluginList.Scrollable = false;
+            PluginList.Size = new Size(659, 137);
+            PluginList.TabIndex = 0;
+            PluginList.UseCompatibleStateImageBehavior = false;
+            PluginList.View = View.Details;
+            PluginList.Resize += PluginList_Resize;
             // 
             // NameColumn
             // 
-            this.NameColumn.Text = "Plugin";
-            this.NameColumn.Width = 180;
+            NameColumn.Text = "Plugin";
+            NameColumn.Width = 180;
             // 
             // TypeColumn
             // 
-            this.TypeColumn.Text = "Type";
-            this.TypeColumn.Width = 120;
+            TypeColumn.Text = "Type";
+            TypeColumn.Width = 120;
             // 
             // VersionColumn
             // 
-            this.VersionColumn.Text = "Version";
-            this.VersionColumn.Width = 120;
+            VersionColumn.Text = "Version";
+            VersionColumn.Width = 120;
             // 
             // StatusColumn
             // 
-            this.StatusColumn.Text = "Status";
+            StatusColumn.Text = "Status";
             // 
             // ReadAllButton
             // 
-            this.ReadAllButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-            this.ReadAllButton.BackColor = System.Drawing.Color.DimGray;
-            this.ReadAllButton.FlatAppearance.BorderSize = 0;
-            this.ReadAllButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.ReadAllButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
-            this.ReadAllButton.Location = new System.Drawing.Point(713, 698);
-            this.ReadAllButton.Name = "ReadAllButton";
-            this.ReadAllButton.Size = new System.Drawing.Size(75, 23);
-            this.ReadAllButton.TabIndex = 2;
-            this.ReadAllButton.Text = "Read All";
-            this.ReadAllButton.UseVisualStyleBackColor = false;
-            this.ReadAllButton.Click += new System.EventHandler(this.ReadAllButton_Click);
+            ReadAllButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+            ReadAllButton.FlatAppearance.BorderSize = 0;
+            ReadAllButton.FlatStyle = FlatStyle.Flat;
+            ReadAllButton.Location = new Point(713, 698);
+            ReadAllButton.Name = "ReadAllButton";
+            ReadAllButton.Size = new Size(75, 23);
+            ReadAllButton.TabIndex = 2;
+            ReadAllButton.Text = "Read All";
+            ReadAllButton.UseVisualStyleBackColor = false;
+            ReadAllButton.Click += ReadAllButton_Click;
             // 
             // ToggleMonitorButton
             // 
-            this.ToggleMonitorButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-            this.ToggleMonitorButton.BackColor = System.Drawing.Color.DimGray;
-            this.ToggleMonitorButton.FlatAppearance.BorderSize = 0;
-            this.ToggleMonitorButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.ToggleMonitorButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
-            this.ToggleMonitorButton.Location = new System.Drawing.Point(610, 698);
-            this.ToggleMonitorButton.Name = "ToggleMonitorButton";
-            this.ToggleMonitorButton.Size = new System.Drawing.Size(97, 23);
-            this.ToggleMonitorButton.TabIndex = 3;
-            this.ToggleMonitorButton.Text = "Start Monitor";
-            this.ToggleMonitorButton.UseVisualStyleBackColor = false;
-            this.ToggleMonitorButton.Click += new System.EventHandler(this.ToggleMonitorButton_Click);
+            ToggleMonitorButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+            ToggleMonitorButton.FlatAppearance.BorderSize = 0;
+            ToggleMonitorButton.FlatStyle = FlatStyle.Flat;
+            ToggleMonitorButton.Location = new Point(610, 698);
+            ToggleMonitorButton.Name = "ToggleMonitorButton";
+            ToggleMonitorButton.Size = new Size(97, 23);
+            ToggleMonitorButton.TabIndex = 3;
+            ToggleMonitorButton.Text = "Start Monitor";
+            ToggleMonitorButton.UseVisualStyleBackColor = false;
+            ToggleMonitorButton.Click += ToggleMonitorButton_Click;
             // 
             // ClearButton
             // 
-            this.ClearButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-            this.ClearButton.BackColor = System.Drawing.Color.DimGray;
-            this.ClearButton.FlatAppearance.BorderSize = 0;
-            this.ClearButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.ClearButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
-            this.ClearButton.Location = new System.Drawing.Point(529, 698);
-            this.ClearButton.Name = "ClearButton";
-            this.ClearButton.Size = new System.Drawing.Size(75, 23);
-            this.ClearButton.TabIndex = 4;
-            this.ClearButton.Text = "Clear";
-            this.ClearButton.UseVisualStyleBackColor = false;
+            ClearButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+            ClearButton.FlatAppearance.BorderSize = 0;
+            ClearButton.FlatStyle = FlatStyle.Flat;
+            ClearButton.Location = new Point(529, 698);
+            ClearButton.Name = "ClearButton";
+            ClearButton.Size = new Size(75, 23);
+            ClearButton.TabIndex = 4;
+            ClearButton.Text = "Clear";
+            ClearButton.UseVisualStyleBackColor = false;
             // 
             // ExportButton
             // 
-            this.ExportButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-            this.ExportButton.BackColor = System.Drawing.Color.DimGray;
-            this.ExportButton.FlatAppearance.BorderSize = 0;
-            this.ExportButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.ExportButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
-            this.ExportButton.Location = new System.Drawing.Point(448, 698);
-            this.ExportButton.Name = "ExportButton";
-            this.ExportButton.Size = new System.Drawing.Size(75, 23);
-            this.ExportButton.TabIndex = 5;
-            this.ExportButton.Text = "Export";
-            this.ExportButton.UseVisualStyleBackColor = false;
+            ExportButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+            ExportButton.FlatAppearance.BorderSize = 0;
+            ExportButton.FlatStyle = FlatStyle.Flat;
+            ExportButton.Location = new Point(448, 698);
+            ExportButton.Name = "ExportButton";
+            ExportButton.Size = new Size(75, 23);
+            ExportButton.TabIndex = 5;
+            ExportButton.Text = "Export";
+            ExportButton.UseVisualStyleBackColor = false;
             // 
             // GithubLink
             // 
-            this.GithubLink.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.GithubLink.AutoSize = true;
-            this.GithubLink.LinkColor = System.Drawing.Color.White;
-            this.GithubLink.Location = new System.Drawing.Point(12, 694);
-            this.GithubLink.Name = "GithubLink";
-            this.GithubLink.Size = new System.Drawing.Size(42, 15);
-            this.GithubLink.TabIndex = 6;
-            this.GithubLink.TabStop = true;
-            this.GithubLink.Text = "github";
+            GithubLink.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
+            GithubLink.AutoSize = true;
+            GithubLink.Location = new Point(12, 694);
+            GithubLink.Name = "GithubLink";
+            GithubLink.Size = new Size(42, 15);
+            GithubLink.TabIndex = 6;
+            GithubLink.TabStop = true;
+            GithubLink.Text = "github";
             // 
             // DonateLink
             // 
-            this.DonateLink.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.DonateLink.AutoSize = true;
-            this.DonateLink.LinkColor = System.Drawing.Color.White;
-            this.DonateLink.Location = new System.Drawing.Point(12, 709);
-            this.DonateLink.Name = "DonateLink";
-            this.DonateLink.Size = new System.Drawing.Size(45, 15);
-            this.DonateLink.TabIndex = 7;
-            this.DonateLink.TabStop = true;
-            this.DonateLink.Text = "Donate";
+            DonateLink.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
+            DonateLink.AutoSize = true;
+            DonateLink.Location = new Point(12, 709);
+            DonateLink.Name = "DonateLink";
+            DonateLink.Size = new Size(45, 15);
+            DonateLink.TabIndex = 7;
+            DonateLink.TabStop = true;
+            DonateLink.Text = "Donate";
             // 
             // CoreForm
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.BackColor = System.Drawing.Color.Black;
-            this.ClientSize = new System.Drawing.Size(800, 733);
-            this.Controls.Add(this.DonateLink);
-            this.Controls.Add(this.GithubLink);
-            this.Controls.Add(this.ExportButton);
-            this.Controls.Add(this.ClearButton);
-            this.Controls.Add(this.ToggleMonitorButton);
-            this.Controls.Add(this.ReadAllButton);
-            this.Controls.Add(this.CorePanel);
-            this.Controls.Add(this.CoreMenu);
-            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
-            this.MainMenuStrip = this.CoreMenu;
-            this.Name = "CoreForm";
-            this.Text = "Elite Observatory Core";
-            this.CoreMenu.ResumeLayout(false);
-            this.CoreMenu.PerformLayout();
-            this.CorePanel.ResumeLayout(false);
-            this.VoiceSettingsPanel.ResumeLayout(false);
-            this.VoiceSettingsPanel.PerformLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.VoiceSpeedSlider)).EndInit();
-            ((System.ComponentModel.ISupportInitialize)(this.VoiceVolumeSlider)).EndInit();
-            this.PopupSettingsPanel.ResumeLayout(false);
-            this.PopupSettingsPanel.PerformLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.DurationSpinner)).EndInit();
-            ((System.ComponentModel.ISupportInitialize)(this.ScaleSpinner)).EndInit();
-            this.ResumeLayout(false);
-            this.PerformLayout();
-
+            AutoScaleDimensions = new SizeF(7F, 15F);
+            AutoScaleMode = AutoScaleMode.Font;
+            ClientSize = new Size(800, 733);
+            Controls.Add(DonateLink);
+            Controls.Add(GithubLink);
+            Controls.Add(ExportButton);
+            Controls.Add(ClearButton);
+            Controls.Add(ToggleMonitorButton);
+            Controls.Add(ReadAllButton);
+            Controls.Add(CorePanel);
+            Controls.Add(CoreMenu);
+            Icon = (Icon)resources.GetObject("$this.Icon");
+            MainMenuStrip = CoreMenu;
+            Name = "CoreForm";
+            Text = "Elite Observatory Core";
+            CoreMenu.ResumeLayout(false);
+            CoreMenu.PerformLayout();
+            CorePanel.ResumeLayout(false);
+            VoiceSettingsPanel.ResumeLayout(false);
+            VoiceSettingsPanel.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)VoiceSpeedSlider).EndInit();
+            ((System.ComponentModel.ISupportInitialize)VoiceVolumeSlider).EndInit();
+            PopupSettingsPanel.ResumeLayout(false);
+            PopupSettingsPanel.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)DurationSpinner).EndInit();
+            ((System.ComponentModel.ISupportInitialize)ScaleSpinner).EndInit();
+            ResumeLayout(false);
+            PerformLayout();
         }
 
         #endregion
@@ -703,5 +646,8 @@
         private Label VoiceSpeedLabel;
         private Label VoiceVolumeLabel;
         private Label VoiceNotificationLabel;
+        private Button PluginSettingsButton;
+        private Label ThemeLabel;
+        private ToolTip OverrideTooltip;
     }
 }
\ No newline at end of file
diff --git a/ObservatoryCore/UI/CoreForm.Plugins.cs b/ObservatoryCore/UI/CoreForm.Plugins.cs
index 6b76cfa..cd7d73a 100644
--- a/ObservatoryCore/UI/CoreForm.Plugins.cs
+++ b/ObservatoryCore/UI/CoreForm.Plugins.cs
@@ -1,31 +1,34 @@
 using Observatory.PluginManagement;
 using Observatory.Framework.Interfaces;
+using System.Linq;
 
 namespace Observatory.UI
 {
     partial class CoreForm
     {
+        private Dictionary<ListViewItem, IObservatoryPlugin>? ListedPlugins;
 
         private void PopulatePluginList()
         {
-            List<IObservatoryPlugin> uniquePlugins = new();
+            ListedPlugins = new();
                         
             foreach (var (plugin, signed) in PluginManager.GetInstance.workerPlugins)
             {
-                if (!uniquePlugins.Contains(plugin))
+                if (!ListedPlugins.ContainsValue(plugin))
                 {
-                    uniquePlugins.Add(plugin);
+                    
                     ListViewItem item = new ListViewItem(new[] { plugin.Name, "Worker", plugin.Version, PluginStatusString(signed) });
+                    ListedPlugins.Add(item, plugin);
                     PluginList.Items.Add(item);
                 }
             }
 
             foreach (var (plugin, signed) in PluginManager.GetInstance.notifyPlugins)
             {
-                if (!uniquePlugins.Contains(plugin))
+                if (!ListedPlugins.ContainsValue(plugin))
                 {
-                    uniquePlugins.Add(plugin);
                     ListViewItem item = new ListViewItem(new[] { plugin.Name, "Notifier", plugin.Version, PluginStatusString(signed) });
+                    ListedPlugins.Add(item, plugin);
                     PluginList.Items.Add(item);
                 }
             }
@@ -71,39 +74,87 @@ namespace Observatory.UI
             {
                 pluginList.Add(item.Text, item);
             }
+
+            CoreMenu.Width = GetExpandedMenuWidth();
         }
 
-        private void CreatePluginSettings()
+        private void DisableOverriddenNotification()
         {
-            foreach (var plugin in PluginManager.GetInstance.workerPlugins)
+            var notifyPlugins = PluginManager.GetInstance.notifyPlugins;
+
+            var ovPopupPlugins = notifyPlugins.Where(n => n.plugin.OverridePopupNotifications);
+
+            if (ovPopupPlugins.Any())
             {
-                var pluginSettingsPanel = new SettingsPanel(plugin.plugin, AdjustPanelsBelow);
-                AddSettingsPanel(pluginSettingsPanel);
+                PopupCheckbox.Checked = false;
+                PopupCheckbox.Enabled = false;
+                DisplayDropdown.Enabled = false;
+                CornerDropdown.Enabled = false;
+                FontDropdown.Enabled = false;
+                ScaleSpinner.Enabled = false;
+                DurationSpinner.Enabled = false;
+                ColourButton.Enabled = false;
+                TestButton.Enabled = false;
+
+                var pluginNames = string.Join(", ", ovPopupPlugins.Select(o => o.plugin.ShortName));
+
+                PopupSettingsPanel.MouseMove += (_, _) =>
+                {
+                    OverrideTooltip.SetToolTip(PopupSettingsPanel, "Disabled by plugin: " + pluginNames);
+                };
             }
-            foreach (var plugin in PluginManager.GetInstance.notifyPlugins)
+
+            var ovAudioPlugins = notifyPlugins.Where(n => n.plugin.OverrideAudioNotifications);
+
+            if (ovAudioPlugins.Any())
             {
-                var pluginSettingsPanel = new SettingsPanel(plugin.plugin, AdjustPanelsBelow);
-                AddSettingsPanel(pluginSettingsPanel);
+                VoiceCheckbox.Checked = false;
+                VoiceCheckbox.Enabled = false;
+                VoiceVolumeSlider.Enabled = false;
+                VoiceSpeedSlider.Enabled = false;
+                VoiceDropdown.Enabled = false;
+                VoiceTestButton.Enabled = false;
+
+                var pluginNames = string.Join(", ", ovAudioPlugins.Select(o => o.plugin.ShortName));
+
+                VoiceSettingsPanel.MouseMove += (_, _) =>
+                {
+                    OverrideTooltip.SetToolTip(VoiceSettingsPanel, "Disabled by plugin: " + pluginNames);
+                };
             }
         }
 
-        private void AddSettingsPanel(SettingsPanel panel)
+        private int GetExpandedMenuWidth()
         {
-            int lowestPoint = 0;
-            foreach (Control control in CorePanel.Controls)
+            int maxWidth = 0;
+            foreach (ToolStripMenuItem item in CoreMenu.Items)
             {
-                if (control.Location.Y + control.Height > lowestPoint)
-                    lowestPoint = control.Location.Y + control.Height;
+                var itemWidth = TextRenderer.MeasureText(item.Text, item.Font);
+                maxWidth = itemWidth.Width > maxWidth ? itemWidth.Width : maxWidth;
             }
-            DuplicateControlVisuals(PopupNotificationLabel, panel.Header);
-            panel.Header.TextAlign = PopupNotificationLabel.TextAlign;
-            panel.Header.Location = new Point(PopupNotificationLabel.Location.X, lowestPoint);
 
-            DuplicateControlVisuals(PopupSettingsPanel, panel, false);
-            panel.Location = new Point(PopupSettingsPanel.Location.X, lowestPoint + panel.Header.Height);
-            panel.Visible = false;
-            CorePanel.Controls.Add(panel.Header);
-            CorePanel.Controls.Add(panel);
+            return maxWidth + 5;
         }
+
+        private void PluginSettingsButton_Click(object sender, EventArgs e)
+        {
+            if (ListedPlugins != null && PluginList.SelectedItems.Count != 0)
+            {
+                var plugin = ListedPlugins[PluginList.SelectedItems[0]];
+                if (SettingsForms.ContainsKey(plugin))
+                {
+                    SettingsForms[plugin].Activate();
+                }
+                else
+                {
+                    SettingsForm settingsForm = new(plugin);
+                    SettingsForms.Add(plugin, settingsForm);
+                    settingsForm.FormClosed += (_, _) => SettingsForms.Remove(plugin);
+                    settingsForm.Show();
+                }
+            }
+        }
+
+        private Dictionary<IObservatoryPlugin, SettingsForm> SettingsForms = new();
     }
 }
\ No newline at end of file
diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
index 03aefe9..9698031 100644
--- a/ObservatoryCore/UI/CoreForm.cs
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -2,6 +2,7 @@
 using Observatory.Framework.Interfaces;
 using Observatory.PluginManagement;
 using Observatory.Utils;
+using System.Runtime.InteropServices;
 using System.Text;
 using System.Windows.Forms;
 
@@ -9,10 +10,25 @@ namespace Observatory.UI
 {
     public partial class CoreForm : Form
     {
-        private Dictionary<object, Panel> uiPanels;
+        private readonly Dictionary<object, Panel> uiPanels;
+
+        [DllImport("user32.dll")]
+        private static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
+        private const int WM_SETREDRAW = 11;
+        private static void SuspendDrawing(Control control)
+        {
+            SendMessage(control.Handle, WM_SETREDRAW, false, 0);
+        }
+
+        private static void ResumeDrawing(Control control)
+        {
+            SendMessage(control.Handle, WM_SETREDRAW, true, 0);
+            control.Refresh();
+        }
 
         public CoreForm()
         {
+            DoubleBuffered = true;
             InitializeComponent();
 
             PopulateDropdownOptions();
@@ -24,14 +40,20 @@ namespace Observatory.UI
             string version = System.Reflection.Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0";
             Text += $" - v{version}";
             CoreMenu.SizeChanged += CoreMenu_SizeChanged;
-            uiPanels = new();
-            uiPanels.Add(coreToolStripMenuItem, CorePanel);
+            uiPanels = new()
+            {
+                { coreToolStripMenuItem, CorePanel }
+            };
+
+            
             pluginList = new Dictionary<string, ToolStripMenuItem>();
             CreatePluginTabs();
-            CreatePluginSettings();
+            DisableOverriddenNotification();
             CoreMenu.ItemClicked += CoreMenu_ItemClicked;
 
             PreCollapsePanels();
+
+            ThemeManager.GetInstance.RegisterControl(this);
         }
 
         private void PreCollapsePanels()
@@ -47,17 +69,7 @@ namespace Observatory.UI
 
         }
 
-        private Dictionary<string, ToolStripMenuItem> pluginList;
-
-        private static void DuplicateControlVisuals(Control source, Control target, bool applyHeight = true)
-        {
-            if (applyHeight) target.Height = source.Height;
-            target.Width = source.Width;
-            target.Font = source.Font;
-            target.ForeColor = source.ForeColor;
-            target.BackColor = source.BackColor;
-            target.Anchor = source.Anchor;
-        }
+        private readonly Dictionary<string, ToolStripMenuItem> pluginList;
 
         private void ToggleMonitorButton_Click(object sender, EventArgs e)
         {
@@ -73,9 +85,25 @@ namespace Observatory.UI
             }
         }
 
-        private void CoreMenu_ItemClicked(object? _, ToolStripItemClickedEventArgs e)
+        private void ResizePanels(Point location, int widthChange)
         {
             
+            CorePanel.Location = location;
+            CorePanel.Width += widthChange;
+            foreach (var panel in uiPanels)
+            {
+                if (Controls.Contains(panel.Value))
+                {
+                    panel.Value.Location = CorePanel.Location;
+                    panel.Value.Size = CorePanel.Size;
+                }
+            }
+            
+        }
+
+        private void CoreMenu_ItemClicked(object? _, ToolStripItemClickedEventArgs e)
+        {
+            SuspendDrawing(this);
             if (e.ClickedItem.Text == "<")
             {
                 foreach (KeyValuePair<string, ToolStripMenuItem> menuItem in pluginList)
@@ -86,8 +114,7 @@ namespace Observatory.UI
                         menuItem.Value.Text = menuItem.Key[..1];
                 }
                 CoreMenu.Width = 40;
-                CorePanel.Location = new Point(43, 12);
-                // CorePanel.Width += 40;
+                ResizePanels(new Point(43, 12), 0);
             }
             else if (e.ClickedItem.Text == ">")
             {
@@ -98,9 +125,8 @@ namespace Observatory.UI
                     else
                         menuItem.Value.Text = menuItem.Key;
                 }
-                CoreMenu.Width = 120;
-                CorePanel.Location = new Point(123, 12);
-                // CorePanel.Width -= 40;
+                CoreMenu.Width = GetExpandedMenuWidth();
+                ResizePanels(new Point(CoreMenu.Width + 3, 12), 0);
             }
             else
             {
@@ -114,26 +140,38 @@ namespace Observatory.UI
                     uiPanels[e.ClickedItem].Location = CorePanel.Location;
                     uiPanels[e.ClickedItem].Size = CorePanel.Size;
                     uiPanels[e.ClickedItem].BackColor = CorePanel.BackColor;
+                    uiPanels[e.ClickedItem].Parent = CorePanel.Parent;
                     Controls.Add(uiPanels[e.ClickedItem]);
                 }
                 uiPanels[e.ClickedItem].Visible = true;
+
+                SetClickedItem(e.ClickedItem);
+            }
+            ResumeDrawing(this);
+        }
+
+        private void SetClickedItem(ToolStripItem item)
+        {
+            foreach (ToolStripItem menuItem in CoreMenu.Items) 
+            {
+                bool bold = menuItem == item;
+                menuItem.Font = new Font(menuItem.Font, bold ? FontStyle.Bold : FontStyle.Regular);
             }
-            
         }
 
         private static void ColourListHeader(ref ListView list, Color backColor, Color foreColor)
         {
             list.OwnerDraw = true;
-            
+
             list.DrawColumnHeader +=
                 new DrawListViewColumnHeaderEventHandler
                 (
-                    (sender, e) => headerDraw(sender, e, backColor, foreColor)
+                    (sender, e) => HeaderDraw(sender, e, backColor, foreColor)
                 );
-            list.DrawItem += new DrawListViewItemEventHandler(bodyDraw);
+            list.DrawItem += new DrawListViewItemEventHandler(BodyDraw);
         }
 
-        private static void headerDraw(object? _, DrawListViewColumnHeaderEventArgs e, Color backColor, Color foreColor)
+        private static void HeaderDraw(object? _, DrawListViewColumnHeaderEventArgs e, Color backColor, Color foreColor)
         {
             using (SolidBrush backBrush = new(backColor))
             {
@@ -149,17 +187,19 @@ namespace Observatory.UI
             if (e.Font != null && e.Header != null)
                 using (SolidBrush foreBrush = new(foreColor))
                 {
-                    var format = new StringFormat();
-                    format.Alignment = (StringAlignment)e.Header.TextAlign;
-                    format.LineAlignment = StringAlignment.Center;
-                    
+                    var format = new StringFormat
+                    {
+                        Alignment = (StringAlignment)e.Header.TextAlign,
+                        LineAlignment = StringAlignment.Center
+                    };
+
                     var paddedBounds = new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width - 4, e.Bounds.Height - 4);
 
                     e.Graphics.DrawString(e.Header?.Text, e.Font, foreBrush, paddedBounds, format);
                 }
         }
 
-        private static void bodyDraw(object? _, DrawListViewItemEventArgs e)
+        private static void BodyDraw(object? _, DrawListViewItemEventArgs e)
         {
             e.DrawDefault = true;
         }
@@ -180,7 +220,11 @@ namespace Observatory.UI
 
         private void ReadAllButton_Click(object sender, EventArgs e)
         {
-            LogMonitor.GetInstance.ReadAllJournals();
+            var readAllDialogue = new ReadAllForm();
+            ThemeManager.GetInstance.RegisterControl(readAllDialogue);
+            readAllDialogue.StartPosition = FormStartPosition.Manual;
+            readAllDialogue.Location = Point.Add(Location, new Size(100,100));
+            readAllDialogue.ShowDialog();
         }
 
         private void PopupNotificationLabel_Click(object _, EventArgs e)
@@ -238,6 +282,8 @@ namespace Observatory.UI
             Up, Down
         }
 
+        private Observatory.NativeNotification.NativePopup? nativePopup;
+
         private void TestButton_Click(object sender, EventArgs e)
         {
             NotificationArgs args = new()
@@ -245,9 +291,10 @@ namespace Observatory.UI
                 Title = "Test Notification",
                 Detail = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec at elit maximus, ornare dui nec, accumsan velit. Vestibulum fringilla elit."
             };
-            var testNotify = new NotificationForm(new Guid(), args);
-            testNotify.Show();
 
+            nativePopup ??= new Observatory.NativeNotification.NativePopup();
+
+            nativePopup.InvokeNativeNotification(args);
         }
     }
 }
\ No newline at end of file
diff --git a/ObservatoryCore/UI/CoreForm.resx b/ObservatoryCore/UI/CoreForm.resx
index 7843956..fa8ebb1 100644
--- a/ObservatoryCore/UI/CoreForm.resx
+++ b/ObservatoryCore/UI/CoreForm.resx
@@ -1,4 +1,64 @@
-<root>
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema 
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
     <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
@@ -63,6 +123,9 @@
   <metadata name="PopupColour.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>126, 17</value>
   </metadata>
+  <metadata name="OverrideTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>251, 17</value>
+  </metadata>
   <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
diff --git a/ObservatoryCore/UI/NotificationForm.Designer.cs b/ObservatoryCore/UI/NotificationForm.Designer.cs
index 444350b..f6cbb0c 100644
--- a/ObservatoryCore/UI/NotificationForm.Designer.cs
+++ b/ObservatoryCore/UI/NotificationForm.Designer.cs
@@ -28,55 +28,54 @@
         /// </summary>
         private void InitializeComponent()
         {
-            this.Title = new System.Windows.Forms.Label();
-            this.Body = new System.Windows.Forms.Label();
-            this.SuspendLayout();
+            Title = new Label();
+            Body = new Label();
+            SuspendLayout();
             // 
             // Title
             // 
-            this.Title.Font = new System.Drawing.Font("Segoe UI", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
-            this.Title.ForeColor = System.Drawing.Color.OrangeRed;
-            this.Title.Location = new System.Drawing.Point(5, 5);
-            this.Title.MaximumSize = new System.Drawing.Size(355, 0);
-            this.Title.Name = "Title";
-            this.Title.Size = new System.Drawing.Size(338, 45);
-            this.Title.TabIndex = 0;
-            this.Title.Text = "Title";
+            Title.Font = new Font("Segoe UI", 24F, FontStyle.Regular, GraphicsUnit.Point);
+            Title.ForeColor = Color.OrangeRed;
+            Title.Location = new Point(5, 5);
+            Title.MaximumSize = new Size(355, 0);
+            Title.Name = "Title";
+            Title.Size = new Size(338, 45);
+            Title.TabIndex = 0;
+            Title.Text = "Title";
             // 
             // Body
             // 
-            this.Body.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-            this.Body.AutoSize = true;
-            this.Body.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
-            this.Body.ForeColor = System.Drawing.Color.OrangeRed;
-            this.Body.Location = new System.Drawing.Point(12, 45);
-            this.Body.MaximumSize = new System.Drawing.Size(320, 85);
-            this.Body.Name = "Body";
-            this.Body.Size = new System.Drawing.Size(51, 31);
-            this.Body.TabIndex = 1;
-            this.Body.Text = "Body";
-            this.Body.UseCompatibleTextRendering = true;
+            Body.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+            Body.AutoSize = true;
+            Body.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point);
+            Body.ForeColor = Color.OrangeRed;
+            Body.Location = new Point(12, 45);
+            Body.MaximumSize = new Size(320, 85);
+            Body.Name = "Body";
+            Body.Size = new Size(51, 31);
+            Body.TabIndex = 1;
+            Body.Text = "Body";
+            Body.UseCompatibleTextRendering = true;
             // 
             // NotificationForm
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
-            this.ClientSize = new System.Drawing.Size(355, 145);
-            this.ControlBox = false;
-            this.Controls.Add(this.Body);
-            this.Controls.Add(this.Title);
-            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
-            this.MaximizeBox = false;
-            this.MinimizeBox = false;
-            this.Name = "NotificationForm";
-            this.ShowIcon = false;
-            this.ShowInTaskbar = false;
-            this.Text = "NotificationForm";
-            this.ResumeLayout(false);
-            this.PerformLayout();
-
+            AutoScaleDimensions = new SizeF(7F, 15F);
+            AutoScaleMode = AutoScaleMode.Font;
+            BackColor = Color.FromArgb(64, 64, 64);
+            ClientSize = new Size(355, 145);
+            ControlBox = false;
+            Controls.Add(Body);
+            Controls.Add(Title);
+            Enabled = false;
+            FormBorderStyle = FormBorderStyle.None;
+            MaximizeBox = false;
+            MinimizeBox = false;
+            Name = "NotificationForm";
+            ShowIcon = false;
+            ShowInTaskbar = false;
+            Text = "NotificationForm";
+            ResumeLayout(false);
+            PerformLayout();
         }
 
         #endregion
diff --git a/ObservatoryCore/UI/NotificationForm.cs b/ObservatoryCore/UI/NotificationForm.cs
index dee4e2e..27c0b7b 100644
--- a/ObservatoryCore/UI/NotificationForm.cs
+++ b/ObservatoryCore/UI/NotificationForm.cs
@@ -23,7 +23,7 @@ namespace Observatory.UI
 
         protected override bool ShowWithoutActivation => true;
         protected override CreateParams CreateParams
-        { 
+        {
             get
             {
                 CreateParams cp = base.CreateParams;
@@ -31,11 +31,12 @@ namespace Observatory.UI
                 return cp;
             }
         }
-          
+
         public NotificationForm(Guid guid, NotificationArgs args)
         {
             _guid = guid;
             _color = Color.FromArgb((int)Properties.Core.Default.NativeNotifyColour);
+            CreationTime = DateTime.Now;
             InitializeComponent();
 
             Title.Paint += DrawText;
@@ -65,8 +66,8 @@ namespace Observatory.UI
             Body.ForeColor = _color;
             Body.Text = args.Detail;
             Body.Font = new Font(Properties.Core.Default.NativeNotifyFont, 14);
-            this.Paint += DrawBorder;
-
+            Paint += DrawBorder;
+            
             AdjustPosition(args.XPos / 100, args.YPos / 100);
 
             _timer = new();
@@ -78,10 +79,36 @@ namespace Observatory.UI
             }
         }
 
+        private void NotificationForm_FormClosed(object? sender, FormClosedEventArgs e)
+        {
+            throw new NotImplementedException();
+        }
+
+        public DateTime CreationTime { get; private init; }
+
         public void Update(NotificationArgs notificationArgs)
         {
-            Title.Text = notificationArgs.Title;
-            Body.Text = notificationArgs.Detail;
+            // Catch Cross-thread access and invoke
+            try
+            {
+                Title.Text = notificationArgs.Title;
+                Body.Text = notificationArgs.Detail;
+            }
+            catch
+            {
+                try
+                {
+                    Invoke(() =>
+                    {
+                        Title.Text = notificationArgs.Title;
+                        Body.Text = notificationArgs.Detail;
+                    });
+                }
+                catch (Exception ex)
+                {
+                    throw new Exception("Notification Update Failure, please inform Vithigar. Details: " + ex.Message);
+                }
+            }
         }
 
         private void AdjustPosition(double x = -1.0, double y = -1.0)
@@ -90,7 +117,6 @@ namespace Observatory.UI
             int corner = Properties.Core.Default.NativeNotifyCorner;
             Rectangle screenBounds;
 
-
             if (screen == -1 || screen > Screen.AllScreens.Length)
                 if (Screen.AllScreens.Length == 1)
                     screenBounds = Screen.GetBounds(this);
@@ -115,7 +141,7 @@ namespace Observatory.UI
                     case 0:
                         Location = Point.Add(
                             new Point(screenBounds.Right, screenBounds.Bottom),
-                            new Size(-(Width+50), -(Height+50)));
+                            new Size(-(Width + 50), -(Height + 50)));
                         break;
                     case 1:
                         Location = Point.Add(
@@ -151,7 +177,7 @@ namespace Observatory.UI
 
         protected override void WndProc(ref Message m)
         {
-            
+
             switch (m.Msg)
             {
                 case DwmHelper.WM_DWMCOMPOSITIONCHANGED:
@@ -190,13 +216,29 @@ namespace Observatory.UI
 
         public Guid Guid { get => _guid; }
 
-        private void AdjustText()
+        public void AdjustOffset(bool increase)
         {
+            if (_defaultPosition)
+            {
+                if (increase || Location != _originalLocation)
+                {
+                    var corner = Properties.Core.Default.NativeNotifyCorner;
 
+                    if ((corner >= 2 && increase) || (corner <= 1 && !increase))
+                    {
+                        Location = new Point(Location.X, Location.Y + Height);
+                    }
+                    else
+                    {
+                        Location = new Point(Location.X, Location.Y - Height);
+                    }
+                }
+            }
         }
 
         private void CloseNotification(object? sender, System.Timers.ElapsedEventArgs e)
         {
+            // Catch Cross-thread access and invoke
             try
             {
                 Close();
@@ -205,14 +247,14 @@ namespace Observatory.UI
             {
                 try
                 {
-                    this.Invoke(() => Close());
+                    Invoke(() => Close());
                 }
-                catch
+                catch (Exception ex)
                 {
-                    throw new Exception("blah");
+                    throw new Exception("Notification Close Failure, please inform Vithigar. Details: " + ex.Message);
                 }
             }
-            
+
             _timer.Stop();
             _timer.Dispose();
         }
diff --git a/ObservatoryCore/UI/NotificationForm.resx b/ObservatoryCore/UI/NotificationForm.resx
index f298a7b..af32865 100644
--- a/ObservatoryCore/UI/NotificationForm.resx
+++ b/ObservatoryCore/UI/NotificationForm.resx
@@ -1,4 +1,64 @@
-<root>
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema 
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
     <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
diff --git a/ObservatoryCore/UI/PluginHelper.cs b/ObservatoryCore/UI/PluginHelper.cs
index cb0fc56..a9ad8f7 100644
--- a/ObservatoryCore/UI/PluginHelper.cs
+++ b/ObservatoryCore/UI/PluginHelper.cs
@@ -1,7 +1,14 @@
 using Observatory.Framework.Interfaces;
+using Observatory.Framework;
 using System.Collections;
 using Observatory.PluginManagement;
 using Observatory.Utils;
+using System.Text.RegularExpressions;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text.Json;
+using System.Data.Common;
+using System.ComponentModel.Design.Serialization;
 
 namespace Observatory.UI
 {
@@ -39,6 +46,7 @@ namespace Observatory.UI
                 Font = menu.Items[0].Font,
                 TextAlign = menu.Items[0].TextAlign
             };
+            ThemeManager.GetInstance.RegisterControl(newItem);
             menu.Items.Add(newItem);
 
             if (plugin.PluginUI.PluginUIType == Framework.PluginUI.UIType.Basic)
@@ -49,7 +57,10 @@ namespace Observatory.UI
 
         private static Panel CreateBasicUI(IObservatoryPlugin plugin)
         {
-            Panel panel = new();
+            Panel panel = new()
+            {
+                Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Top
+            };
 
             IObservatoryComparer columnSorter;
             if (plugin.ColumnSorter != null)
@@ -57,7 +68,7 @@ namespace Observatory.UI
             else
                 columnSorter = new DefaultSorter();
 
-            ListView listView = new()
+            PluginListView listView = new()
             {
                 View = View.Details,
                 Location = new Point(0, 0),
@@ -65,16 +76,120 @@ namespace Observatory.UI
                 Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Top,
                 BackColor = Color.FromArgb(64, 64, 64),
                 ForeColor = Color.LightGray,
-                GridLines = true,
                 ListViewItemSorter = columnSorter,
                 Font = new Font(new FontFamily("Segoe UI"), 10, FontStyle.Regular)
             };
 
-            foreach (var property in plugin.PluginUI.DataGrid.First().GetType().GetProperties())
+            string colSize = Properties.Core.Default.ColumnSizing;
+            List<ColumnSizing>? columnSizing = null;
+            if (!string.IsNullOrWhiteSpace(colSize))
             {
-                listView.Columns.Add(property.Name);
+                try
+                {
+                    columnSizing = JsonSerializer.Deserialize<List<ColumnSizing>>(colSize);
+                }
+                catch
+                {
+                    // Failed deserialization means bad value, blow it away.
+                    Properties.Core.Default.ColumnSizing = string.Empty;
+                    Properties.Core.Default.Save();
+                }
             }
 
+            columnSizing ??= new List<ColumnSizing>();
+            // Is losing column sizes between versions acceptable?
+            ColumnSizing pluginColumnSizing = columnSizing
+                .Where(c => c.PluginName == plugin.Name && c.PluginVersion == plugin.Version)
+                .FirstOrDefault(new ColumnSizing() { PluginName = plugin.Name, PluginVersion = plugin.Version });
+
+            if (!columnSizing.Contains(pluginColumnSizing))
+            {
+                columnSizing.Add(pluginColumnSizing);
+            }
+
+            foreach (var property in plugin.PluginUI.DataGrid.First().GetType().GetProperties())
+            {
+                // https://stackoverflow.com/questions/5796383/insert-spaces-between-words-on-a-camel-cased-token
+                string columnLabel = Regex.Replace(
+                    Regex.Replace(
+                        property.Name,
+                        @"(\P{Ll})(\P{Ll}\p{Ll})",
+                        "$1 $2"
+                    ),
+                    @"(\p{Ll})(\P{Ll})",
+                    "$1 $2"
+                );
+
+                int width;
+
+                if (pluginColumnSizing.ColumnWidth.ContainsKey(columnLabel))
+                {
+                    width = pluginColumnSizing.ColumnWidth[columnLabel];
+                }
+                else
+                {
+                    var widthAttrib = property.GetCustomAttribute<ColumnSuggestedWidth>();
+
+                    width = widthAttrib == null
+                        // Rough approximation of width by label length if none specified.
+                        ? columnLabel.Length * 10
+                        : widthAttrib.Width;
+
+                    pluginColumnSizing.ColumnWidth.Add(columnLabel, width);
+                }
+         
+                listView.Columns.Add(columnLabel, width);
+
+            }
+
+            Properties.Core.Default.ColumnSizing = JsonSerializer.Serialize(columnSizing);
+            Properties.Core.Default.Save();
+
+            // Oddly, the listview resize event often fires after the column size change but
+            // with stale (default?!) column width values.
+            // Still need a resize handler to avoid the ugliness of the rightmost column
+            // leaving gaps, but preventing saving the width changes there should stop the
+            // stale resize event from overwriting with bad data.
+            // Using a higher-order function here to create two different versions of the
+            // event handler for these purposes.
+            var handleColSize = (bool saveProps) =>
+            (object? sender, EventArgs e) =>
+            {
+                int colTotalWidth = 0;
+                ColumnHeader? rightmost = null;
+                foreach (ColumnHeader column in listView.Columns)
+                {
+                    colTotalWidth += column.Width;
+                    if (rightmost == null || column.DisplayIndex > rightmost.DisplayIndex)
+                        rightmost = column;
+
+                    if (saveProps)
+                    {
+                        if (pluginColumnSizing.ColumnWidth.ContainsKey(column.Text))
+                            pluginColumnSizing.ColumnWidth[column.Text] = column.Width;
+                        else
+                            pluginColumnSizing.ColumnWidth.Add(column.Text, column.Width);
+                    }
+                }
+
+                if (rightmost != null && colTotalWidth < listView.Width)
+                {
+                    rightmost.Width = listView.Width - (colTotalWidth - rightmost.Width);
+
+                    if (saveProps)
+                        pluginColumnSizing.ColumnWidth[rightmost.Text] = rightmost.Width;
+                }
+
+                if (saveProps)
+                {
+                    Properties.Core.Default.ColumnSizing = JsonSerializer.Serialize(columnSizing);
+                    Properties.Core.Default.Save();
+                }
+            };
+
+            listView.ColumnWidthChanged += handleColSize(true).Invoke;
+            listView.Resize += handleColSize(false).Invoke;
+             
             listView.ColumnClick += (sender, e) =>
             {
                 if (e.Column == columnSorter.SortColumn)
@@ -99,10 +214,10 @@ namespace Observatory.UI
             };
 
             panel.Controls.Add(listView);
-            
+
             plugin.PluginUI.DataGrid.CollectionChanged += (sender, e) =>
             {
-                listView.Invoke(() =>
+                var updateGrid = () =>
                 {
                     if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add &&
                 e.NewItems != null)
@@ -153,7 +268,16 @@ namespace Observatory.UI
                             listView.Items.Add(listItem);
                         }
                     }
-                });
+                };
+
+                if (listView.Created)
+                {
+                    listView.Invoke(updateGrid);
+                }
+                else
+                {
+                    updateGrid();
+                }
             };
             
             return panel;
diff --git a/ObservatoryCore/UI/PluginListView.cs b/ObservatoryCore/UI/PluginListView.cs
new file mode 100644
index 0000000..3897123
--- /dev/null
+++ b/ObservatoryCore/UI/PluginListView.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Observatory.UI
+{
+    internal class PluginListView : ListView
+    {
+        [DllImport("user32.dll")]
+        private static extern int SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
+        
+        private const int WM_SETREDRAW = 11;
+
+        public PluginListView()
+        {
+            OwnerDraw = true;
+            GridLines = false;
+            DrawItem += PluginListView_DrawItem;
+            DrawSubItem += PluginListView_DrawSubItem;
+            DrawColumnHeader += PluginListView_DrawColumnHeader;
+            
+            
+            DoubleBuffered = true;
+            base.GridLines = false;//We should prevent the default drawing of gridlines.
+        }
+
+        private static void DrawBorder(Graphics graphics, Pen pen, Rectangle bounds, bool header = false)
+        {
+            
+            Point topRight = new(bounds.Right, bounds.Top);
+            Point bottomRight = new(bounds.Right, bounds.Bottom);
+            
+            graphics.DrawLine(pen, topRight, bottomRight);
+            
+            if (header)
+            {
+                Point bottomLeft = new(bounds.Left, bounds.Bottom);
+                // Point topLeft = new(bounds.Left, bounds.Top);
+                // graphics.DrawLine(pen, topLeft, topRight);
+                // graphics.DrawLine(pen, topLeft, bottomLeft);
+                graphics.DrawLine(pen, bottomLeft, bottomRight);
+            }
+        }
+
+        private void PluginListView_DrawColumnHeader(object? sender, DrawListViewColumnHeaderEventArgs e)
+        {
+            using (var g = e.Graphics)
+                if (g != null)
+                {
+                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+                    Pen pen = new(new SolidBrush(Color.LightGray));
+                    DrawBorder(g, pen, e.Bounds);
+                    using (var font = new Font(this.Font, FontStyle.Bold))
+                    {
+                        Brush textBrush = new SolidBrush(ForeColor);
+                        g.DrawString(e.Header?.Text, font, textBrush, e.Bounds);
+                    }
+                }
+        }
+
+        private void PluginListView_DrawSubItem(object? sender, DrawListViewSubItemEventArgs e)
+        {
+            using (var g = e.Graphics)
+                if (g != null)
+                {
+                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+                    Pen pen = new(new SolidBrush(Color.LightGray));
+                    DrawBorder(g, pen, e.Bounds, false);
+                    
+                    e.DrawText();
+                }
+        }
+
+        private void PluginListView_DrawItem(object? sender, DrawListViewItemEventArgs e)
+        {
+            var offsetColor = (int value) =>
+            {
+                if (value > 127)
+                {
+                    return value - 20;
+                }
+                else
+                {
+                    return value + 20;
+                }
+            };
+
+            using (var g = e.Graphics)
+            {
+                if (e.ItemIndex % 2 == 0)
+                {
+                    e.Item.BackColor = BackColor;
+                }
+                else
+                {
+                    e.Item.BackColor = Color.FromArgb(offsetColor(BackColor.R), offsetColor(BackColor.G), offsetColor(BackColor.B));
+                }
+
+                if (g != null)
+                {
+                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+                    Pen pen = new(new SolidBrush(Color.LightGray));
+                    e.DrawBackground();
+                }
+            }
+   
+        }
+    }
+}
diff --git a/ObservatoryCore/UI/ReadAllProgress.Designer.cs b/ObservatoryCore/UI/ReadAllProgress.Designer.cs
new file mode 100644
index 0000000..dcdbb18
--- /dev/null
+++ b/ObservatoryCore/UI/ReadAllProgress.Designer.cs
@@ -0,0 +1,84 @@
+namespace Observatory.UI
+{
+    partial class ReadAllForm
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            ReadAllProgress = new ProgressBar();
+            JournalLabel = new Label();
+            CancelButton = new Button();
+            SuspendLayout();
+            // 
+            // ReadAllProgress
+            // 
+            ReadAllProgress.Location = new Point(12, 27);
+            ReadAllProgress.Name = "ReadAllProgress";
+            ReadAllProgress.Size = new Size(371, 23);
+            ReadAllProgress.Step = 1;
+            ReadAllProgress.TabIndex = 0;
+            // 
+            // JournalLabel
+            // 
+            JournalLabel.AutoSize = true;
+            JournalLabel.Location = new Point(12, 9);
+            JournalLabel.Name = "JournalLabel";
+            JournalLabel.Size = new Size(45, 15);
+            JournalLabel.TabIndex = 1;
+            JournalLabel.Text = "foo.log";
+            // 
+            // CancelButton
+            // 
+            CancelButton.Location = new Point(308, 56);
+            CancelButton.Name = "CancelButton";
+            CancelButton.Size = new Size(75, 23);
+            CancelButton.TabIndex = 2;
+            CancelButton.Text = "Cancel";
+            CancelButton.UseVisualStyleBackColor = true;
+            CancelButton.Click += CancelButton_Click;
+            // 
+            // ReadAllForm
+            // 
+            AutoScaleDimensions = new SizeF(7F, 15F);
+            AutoScaleMode = AutoScaleMode.Font;
+            ClientSize = new Size(395, 86);
+            Controls.Add(CancelButton);
+            Controls.Add(JournalLabel);
+            Controls.Add(ReadAllProgress);
+            FormBorderStyle = FormBorderStyle.FixedDialog;
+            Name = "ReadAllForm";
+            Text = "Read All In Progress...";
+            ResumeLayout(false);
+            PerformLayout();
+        }
+
+        #endregion
+
+        private ProgressBar ReadAllProgress;
+        private Label JournalLabel;
+        private Button CancelButton;
+    }
+}
\ No newline at end of file
diff --git a/ObservatoryCore/UI/ReadAllProgress.cs b/ObservatoryCore/UI/ReadAllProgress.cs
new file mode 100644
index 0000000..f42becd
--- /dev/null
+++ b/ObservatoryCore/UI/ReadAllProgress.cs
@@ -0,0 +1,52 @@
+using Observatory.Utils;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Observatory.UI
+{
+    public partial class ReadAllForm : Form
+    {
+        private CancellationTokenSource ReadAllCancel;
+
+        public ReadAllForm()
+        {
+            InitializeComponent();
+            
+            var ReadAllJournals = LogMonitor.GetInstance.ReadAllGenerator(out int fileCount);
+            int progressCount = 0;
+            ReadAllCancel = new CancellationTokenSource();
+            HandleCreated += (_,_) =>
+            Task.Run(() =>
+            {
+                foreach (var journal in ReadAllJournals())
+                {
+                    if (ReadAllCancel.IsCancellationRequested)
+                    {
+                        break;
+                    }
+
+                    progressCount++;
+                    Invoke(() =>
+                    {
+                        JournalLabel.Text = journal.ToString();
+                        ReadAllProgress.Value = (progressCount * 100) / fileCount;
+                    });
+                }
+                Invoke(()=>Close());
+            });
+            
+        }
+
+        private void CancelButton_Click(object sender, EventArgs e)
+        {
+            ReadAllCancel.Cancel();
+        }
+    }
+}
diff --git a/ObservatoryCore/UI/ReadAllProgress.resx b/ObservatoryCore/UI/ReadAllProgress.resx
new file mode 100644
index 0000000..af32865
--- /dev/null
+++ b/ObservatoryCore/UI/ReadAllProgress.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema 
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/SettingsForm.Designer.cs b/ObservatoryCore/UI/SettingsForm.Designer.cs
new file mode 100644
index 0000000..b661275
--- /dev/null
+++ b/ObservatoryCore/UI/SettingsForm.Designer.cs
@@ -0,0 +1,61 @@
+namespace Observatory.UI
+{
+    partial class SettingsForm
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            PluginSettingsCloseButton = new Button();
+            SuspendLayout();
+            // 
+            // PluginSettingsCloseButton
+            // 
+            PluginSettingsCloseButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+            PluginSettingsCloseButton.Location = new Point(339, 5);
+            PluginSettingsCloseButton.Name = "PluginSettingsCloseButton";
+            PluginSettingsCloseButton.Size = new Size(75, 23);
+            PluginSettingsCloseButton.TabIndex = 0;
+            PluginSettingsCloseButton.Text = "Close";
+            PluginSettingsCloseButton.UseVisualStyleBackColor = true;
+            PluginSettingsCloseButton.Click += PluginSettingsCloseButton_Click;
+            // 
+            // SettingsForm
+            // 
+            AutoScaleDimensions = new SizeF(7F, 15F);
+            AutoScaleMode = AutoScaleMode.Font;
+            ClientSize = new Size(426, 40);
+            Controls.Add(PluginSettingsCloseButton);
+            FormBorderStyle = FormBorderStyle.FixedSingle;
+            Name = "SettingsForm";
+            Text = "SettingsForm";
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private Button PluginSettingsCloseButton;
+    }
+}
\ No newline at end of file
diff --git a/ObservatoryCore/UI/SettingsForm.cs b/ObservatoryCore/UI/SettingsForm.cs
new file mode 100644
index 0000000..20a74f4
--- /dev/null
+++ b/ObservatoryCore/UI/SettingsForm.cs
@@ -0,0 +1,367 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Observatory.Assets;
+using Observatory.Framework;
+using Observatory.Framework.Interfaces;
+
+namespace Observatory.UI
+{
+    public partial class SettingsForm : Form
+    {
+        private readonly IObservatoryPlugin _plugin;
+        private readonly List<int> _colHeight = new List<int>();
+
+        public SettingsForm(IObservatoryPlugin plugin)
+        {
+            InitializeComponent();
+            _plugin = plugin;
+
+            // Filtered to only settings without SettingIgnore attribute
+            var settings = PluginManagement.PluginManager.GetSettingDisplayNames(plugin.Settings).Where(s => !Attribute.IsDefined(s.Key, typeof(SettingIgnore)));
+            CreateControls(settings);
+
+            
+            Text = plugin.Name + " Settings";
+            Icon = Resources.EOCIcon_Presized;
+            ThemeManager.GetInstance.RegisterControl(this);
+        }
+
+        private void CreateControls(IEnumerable<KeyValuePair<PropertyInfo, string>> settings)
+        {
+            bool recentHalfCol = false;
+
+            int settingsHeight = 0;
+            
+            var trackBottomEdge = (Control control) =>
+            {
+                var controlBottom = control.Location.Y + control.Height;
+                if (controlBottom > settingsHeight)
+                    settingsHeight = controlBottom;
+            };
+
+
+            foreach (var setting in settings)
+            {
+                // Reset the column tracking for checkboxes if this isn't a checkbox
+                if (setting.Key.PropertyType.Name != "Boolean")
+                    recentHalfCol = false;
+
+                int addedHeight = 29;
+
+                switch (setting.Key.GetValue(_plugin.Settings))
+                {
+                    case bool:
+                        var checkBox = CreateBoolSetting(setting);
+                        addedHeight = recentHalfCol ? 0 : addedHeight;
+                        checkBox.Location = GetSettingPosition(recentHalfCol);
+
+                        recentHalfCol = !recentHalfCol;
+
+                        Controls.Add(checkBox);
+                        trackBottomEdge(checkBox);
+                        break;
+                    case string:
+                        var stringLabel = CreateSettingLabel(setting.Value);
+                        var textBox = CreateStringSetting(setting.Key);
+                        stringLabel.Location = GetSettingPosition();
+                        textBox.Location = GetSettingPosition(true);
+
+                        Controls.Add(stringLabel);
+                        Controls.Add(textBox);
+                        trackBottomEdge(textBox);
+                        break;
+                    case FileInfo:
+                        var fileLabel = CreateSettingLabel(setting.Value);
+                        var pathTextBox = CreateFilePathSetting(setting.Key);
+                        var pathButton = CreateFileBrowseSetting(setting.Key, pathTextBox);
+
+                        fileLabel.Location = GetSettingPosition();
+                        pathTextBox.Location = GetSettingPosition(true);
+                        _colHeight.Add(addedHeight);
+                        pathButton.Location = GetSettingPosition(true);
+
+                        Controls.Add(fileLabel);
+                        Controls.Add(pathTextBox);
+                        Controls.Add(pathButton);
+                        trackBottomEdge(pathButton);
+                        break;
+                    case int:
+                        // We have two options for integer values:
+                        // 1) A slider (explicit by way of the SettingIntegerUseSlider attribute and bounded to 0..100 by default)
+                        // 2) A numeric up/down (default otherwise, and is unbounded by default).
+                        // Bounds for both can be set via the SettingNumericBounds attribute, only the up/down uses Increment.
+                        var intLabel = CreateSettingLabel(setting.Value);
+                        Control intControl;
+                        if (Attribute.IsDefined(setting.Key, typeof(SettingNumericUseSlider)))
+                        {
+                            intControl = CreateSettingTrackbar(setting.Key);
+                        }
+                        else
+                        {
+                            intControl = CreateSettingNumericUpDown(setting.Key);
+                        }
+                        intLabel.Location = GetSettingPosition();
+                        intControl.Location = GetSettingPosition(true);
+
+                        addedHeight = intControl.Height;
+                        intLabel.Height = intControl.Height;
+                        intLabel.TextAlign = ContentAlignment.MiddleRight;
+
+                        Controls.Add(intLabel);
+                        Controls.Add(intControl);
+                        trackBottomEdge(intControl);
+                        break;
+                    case Action action:
+                        var button = CreateSettingButton(setting.Value, action);
+
+                        button.Location = GetSettingPosition();
+
+                        Controls.Add(button);
+                        trackBottomEdge(button);
+                        break;
+                    case Dictionary<string, object> dictSetting:
+                        var dictLabel = CreateSettingLabel(setting.Value);
+                        var dropdown = CreateSettingDropdown(setting.Key, dictSetting);
+                       
+                        dictLabel.Location = GetSettingPosition();
+                        dropdown.Location = GetSettingPosition(true);
+                        Controls.Add(dictLabel);
+                        Controls.Add(dropdown);
+                        trackBottomEdge(dropdown);
+                        break;
+                    default:
+                        break;
+                }
+                _colHeight.Add(addedHeight);
+            }
+            Height = settingsHeight + 80;
+        }
+
+        private Point GetSettingPosition(bool secondCol = false)
+        {
+            return new Point(10 + (secondCol ? 200 : 0), -26 + _colHeight.Sum());
+        }
+
+
+        private Label CreateSettingLabel(string settingName)
+        {
+            Label label = new()
+            {
+                Text = settingName + ": ",
+                TextAlign = System.Drawing.ContentAlignment.MiddleRight,
+                Width = 200,
+                ForeColor = Color.LightGray
+            };
+
+            return label;
+        }
+
+        private ComboBox CreateSettingDropdown(PropertyInfo setting, Dictionary<string, object> dropdownItems)
+        {
+            var backingValueName = (SettingBackingValue?)Attribute.GetCustomAttribute(setting, typeof(SettingBackingValue));
+
+            var backingValue = from s in PluginManagement.PluginManager.GetSettingDisplayNames(_plugin.Settings)
+                               where s.Value == backingValueName?.BackingProperty
+                               select s.Key;
+
+            if (backingValue.Count() != 1)
+                throw new($"{_plugin.ShortName}: Dictionary settings must have exactly one backing value.");
+
+            ComboBox comboBox = new()
+            {
+                Width = 200,
+                DropDownStyle = ComboBoxStyle.DropDownList
+            };
+
+            comboBox.Items.AddRange(dropdownItems.OrderBy(s => s.Key).Select(s => s.Key).ToArray());
+
+            string? currentSelection = backingValue.First().GetValue(_plugin.Settings)?.ToString();
+
+            if (currentSelection?.Length > 0)
+            {
+                comboBox.SelectedItem = currentSelection;
+            }
+
+            comboBox.SelectedValueChanged += (sender, e) =>
+            {
+                backingValue.First().SetValue(_plugin.Settings, comboBox.SelectedItem.ToString());
+                SaveSettings();
+            };
+
+            return comboBox;
+        }
+
+        private Button CreateSettingButton(string settingName, Action action)
+        {
+            Button button = new()
+            {
+                Text = settingName
+            };
+
+            button.Click += (sender, e) =>
+            {
+                action.Invoke();
+                SaveSettings();
+            };
+
+            return button;
+        }
+
+        private TrackBar CreateSettingTrackbar(PropertyInfo setting)
+        {
+            SettingNumericBounds? bounds = (SettingNumericBounds?)System.Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
+
+            var minBound = Convert.ToInt32(bounds?.Minimum ?? 0);
+            var maxBound = Convert.ToInt32(bounds?.Maximum ?? 100);
+
+            var tickFrequency = maxBound - minBound >= 20 ? (maxBound - minBound) / 10 : 1;
+
+            TrackBar trackBar = new()
+            {
+                Orientation = Orientation.Horizontal,
+                TickStyle = TickStyle.Both,
+                TickFrequency = tickFrequency,
+                Width = 200,
+                Minimum = minBound,
+                Maximum = maxBound,
+            };
+
+            trackBar.Value = (int?)setting.GetValue(_plugin.Settings) ?? 0;
+
+            trackBar.ValueChanged += (sender, e) =>
+            {
+                setting.SetValue(_plugin.Settings, trackBar.Value);
+                SaveSettings();
+            };
+
+            return trackBar;
+        }
+
+        private NumericUpDown CreateSettingNumericUpDown(PropertyInfo setting)
+        {
+            SettingNumericBounds? bounds = (SettingNumericBounds?)System.Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
+            NumericUpDown numericUpDown = new()
+            {
+
+                Width = 200,
+                Minimum = Convert.ToInt32(bounds?.Minimum ?? Int32.MinValue),
+                Maximum = Convert.ToInt32(bounds?.Maximum ?? Int32.MaxValue),
+                Increment = Convert.ToInt32(bounds?.Increment ?? 1)
+            };
+
+            numericUpDown.Value = (int?)setting.GetValue(_plugin.Settings) ?? 0;
+
+            numericUpDown.ValueChanged += (sender, e) =>
+            {
+                setting.SetValue(_plugin.Settings, numericUpDown.Value);
+                SaveSettings();
+            };
+
+            return numericUpDown;
+        }
+
+        private CheckBox CreateBoolSetting(KeyValuePair<PropertyInfo, string> setting)
+        {
+            CheckBox checkBox = new()
+            {
+                Text = setting.Value,
+                TextAlign = System.Drawing.ContentAlignment.MiddleLeft,
+                Checked = (bool?)setting.Key.GetValue(_plugin.Settings) ?? false,
+                Width = 200,
+                ForeColor = Color.LightGray
+            };
+
+            checkBox.CheckedChanged += (sender, e) =>
+            {
+                setting.Key.SetValue(_plugin.Settings, checkBox.Checked);
+                SaveSettings();
+            };
+
+            return checkBox;
+        }
+
+        private TextBox CreateStringSetting(PropertyInfo setting)
+        {
+            TextBox textBox = new()
+            {
+                Text = (setting.GetValue(_plugin.Settings) ?? String.Empty).ToString(),
+                Width = 200
+            };
+
+            textBox.TextChanged += (object? sender, EventArgs e) =>
+            {
+                setting.SetValue(_plugin.Settings, textBox.Text);
+                SaveSettings();
+            };
+
+            return textBox;
+        }
+
+        private TextBox CreateFilePathSetting(PropertyInfo setting)
+        {
+            var fileInfo = (FileInfo?)setting.GetValue(_plugin.Settings);
+
+            TextBox textBox = new()
+            {
+                Text = fileInfo?.FullName ?? string.Empty,
+                Width = 200
+            };
+
+            textBox.TextChanged += (object? sender, EventArgs e) =>
+            {
+                setting.SetValue(_plugin.Settings, new FileInfo(textBox.Text));
+                SaveSettings();
+            };
+
+            return textBox;
+        }
+
+        private Button CreateFileBrowseSetting(PropertyInfo setting, TextBox textBox)
+        {
+            Button button = new()
+            {
+                Text = "Browse"
+            };
+
+            button.Click += (object? sender, EventArgs e) =>
+            {
+                var currentDir = ((FileInfo?)setting.GetValue(_plugin.Settings))?.DirectoryName;
+
+                OpenFileDialog ofd = new OpenFileDialog()
+                {
+                    Title = "Select File...",
+                    Filter = "Lua files (*.lua)|*.lua|All files (*.*)|*.*",
+                    FilterIndex = 0,
+                    InitialDirectory = currentDir ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
+                };
+
+                var browseResult = ofd.ShowDialog();
+
+                if (browseResult == DialogResult.OK)
+                {
+                    textBox.Text = ofd.FileName;
+                }
+            };
+
+            return button;
+        }
+
+        private void SaveSettings()
+        {
+            PluginManagement.PluginManager.GetInstance.SaveSettings(_plugin, _plugin.Settings);
+        }
+
+        private void PluginSettingsCloseButton_Click(object sender, EventArgs e)
+        {
+            Close();
+        }
+    }
+}
diff --git a/ObservatoryCore/UI/SettingsForm.resx b/ObservatoryCore/UI/SettingsForm.resx
new file mode 100644
index 0000000..af32865
--- /dev/null
+++ b/ObservatoryCore/UI/SettingsForm.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema 
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/ObservatoryCore/UI/ThemeManager.cs b/ObservatoryCore/UI/ThemeManager.cs
new file mode 100644
index 0000000..c6460ca
--- /dev/null
+++ b/ObservatoryCore/UI/ThemeManager.cs
@@ -0,0 +1,158 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Observatory.UI
+{
+    internal class ThemeManager
+    {
+        public static ThemeManager GetInstance
+        {
+            get
+            {
+                return _instance.Value;
+            }
+        }
+        private static readonly Lazy<ThemeManager> _instance = new(() => new ThemeManager());
+        private bool _init;
+
+        private ThemeManager()
+        {
+            _init = true;
+            controls = new List<Control>();
+            Themes = new()
+            {
+                { "Dark", DarkTheme },
+                { "Light", LightTheme }
+            };
+            SelectedTheme = "Dark";
+        }
+
+        private readonly List<Control> controls;
+
+        public List<string> GetThemes
+        {
+            get => Themes.Keys.ToList();
+        }
+
+        public string CurrentTheme
+        {
+            get => SelectedTheme;
+
+            set
+            {
+                if (Themes.ContainsKey(value))
+                {
+                    SelectedTheme = value;
+                    foreach (var control in controls)
+                    {
+                        ApplyTheme(control);
+                    }
+                }
+            }
+        }
+
+        public void RegisterControl(Control control)
+        {
+            // First time registering a control, build the "light" theme based
+            // on defaults.
+            if (_init)
+            {
+                SaveTheme(control, LightTheme);
+                _init = false;
+            }
+
+            controls.Add(control);
+            ApplyTheme(control);
+            if (control.HasChildren)
+                foreach (Control child in control.Controls)
+                {
+                    RegisterControl(child);
+                }
+        }
+
+        // This doesn't inherit from Control? Seriously?
+        public void RegisterControl(ToolStripMenuItem toolStripMenuItem)
+        {
+            ApplyTheme(toolStripMenuItem);
+        }
+
+        private void SaveTheme(Control control, Dictionary<string, Color> theme)
+        {
+            Control rootControl = control;
+            while (rootControl.Parent != null)
+            {
+                rootControl = rootControl.Parent;
+            }
+
+            SaveThemeControl(rootControl, theme);
+            var themeJson = System.Text.Json.JsonSerializer.Serialize(DarkTheme);
+        }
+
+        private void SaveThemeControl(Control control, Dictionary<string, Color> theme)
+        {
+            var properties = control.GetType().GetProperties();
+            var colorProperties = properties.Where(p => p.PropertyType == typeof(Color));
+
+            foreach (var colorProperty in colorProperties)
+            {
+                string controlKey = control.GetType().Name + "." + colorProperty.Name;
+                if (!theme.ContainsKey(controlKey))
+                {
+                    theme.Add(controlKey, (Color)colorProperty.GetValue(control)!);
+                }
+            }
+
+            foreach (Control child in control.Controls)
+            {
+                SaveThemeControl(child, theme);
+            }
+        }
+
+        public void DeRegisterControl(Control control)
+        { 
+            if (control.HasChildren)
+                foreach (Control child in control.Controls)
+                {
+                    DeRegisterControl(child);
+                }
+            controls.Remove(control); 
+        }
+
+        private void ApplyTheme(Object control)
+        {
+            var controlType = control.GetType();
+
+            var theme = Themes.ContainsKey(SelectedTheme)
+                ? Themes[SelectedTheme] : Themes["Light"];
+
+            foreach (var property in controlType.GetProperties().Where(p => p.PropertyType == typeof(Color)))
+            {
+                string themeControl = Themes[SelectedTheme].ContainsKey(controlType.Name + "." + property.Name)
+                    ? controlType.Name
+                    : "Default";
+
+                if (Themes[SelectedTheme].ContainsKey(themeControl + "." + property.Name))
+                    property.SetValue(control, Themes[SelectedTheme][themeControl + "." + property.Name]);
+            }
+
+        }
+
+        private Dictionary<string, Dictionary<string, Color>> Themes;
+
+        private string SelectedTheme;
+
+        private Dictionary<string, Color> LightTheme = new Dictionary<string, Color>();
+
+        static private Dictionary<string, Color> DarkTheme = new Dictionary<string, Color>
+        {
+            {"Default.ForeColor", Color.LightGray },
+            {"Default.BackColor", Color.Black },
+            {"Button.ForeColor", Color.LightGray },
+            {"Button.BackColor", Color.DimGray }
+        };
+    }
+}
diff --git a/ObservatoryCore/Utils/AudioHandler.cs b/ObservatoryCore/Utils/AudioHandler.cs
new file mode 100644
index 0000000..f6fd2ed
--- /dev/null
+++ b/ObservatoryCore/Utils/AudioHandler.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NAudio.Wave;
+
+namespace Observatory.Utils
+{
+    internal static class AudioHandler
+    {
+        internal static async Task PlayFile(string filePath)
+        {
+            await Task.Run(() =>
+            {
+                using (var file = new AudioFileReader(filePath))
+                using (var output = new WaveOutEvent())
+                {
+                    output.Init(file);
+                    output.Play();
+
+                    while (output.PlaybackState == PlaybackState.Playing)
+                    {
+                        Thread.Sleep(250);
+                    }
+                };
+            });
+        }
+    }
+}
diff --git a/ObservatoryCore/Utils/LogMonitor.cs b/ObservatoryCore/Utils/LogMonitor.cs
index 45fb68f..878c4ff 100644
--- a/ObservatoryCore/Utils/LogMonitor.cs
+++ b/ObservatoryCore/Utils/LogMonitor.cs
@@ -22,7 +22,7 @@ namespace Observatory.Utils
             }
         }
 
-        private static readonly Lazy<LogMonitor> _instance = new Lazy<LogMonitor>(NewLogMonitor);
+        private static readonly Lazy<LogMonitor> _instance = new(NewLogMonitor);
 
         private static LogMonitor NewLogMonitor()
         {
@@ -44,6 +44,9 @@ namespace Observatory.Utils
         {
             get => currentState;
         }
+
+        public Status Status { get; private set; }
+        
         #endregion
 
         #region Public Methods
@@ -87,28 +90,31 @@ namespace Observatory.Utils
             return LogMonitorStateChangedEventArgs.IsBatchRead(currentState);
         }
 
-        public void ReadAllJournals()
-        {
-            ReadAllJournals(string.Empty);
-        }
-
-        public void ReadAllJournals(string path)
+        public Func<IEnumerable<string>> ReadAllGenerator(out int fileCount)
         {
             // Prevent pre-reading when starting monitoring after reading all.
             firstStartMonitor = false;
             SetLogMonitorState(currentState | LogMonitorState.Batch);
 
-            DirectoryInfo logDirectory = GetJournalFolder(path);
+            DirectoryInfo logDirectory = GetJournalFolder();
             var files = GetJournalFilesOrdered(logDirectory);
-            var readErrors = new List<(Exception ex, string file, string line)>();
-            foreach (var file in files)
-            {
-                readErrors.AddRange(
-                    ProcessLines(ReadAllLines(file.FullName), file.Name));
-            }
+            fileCount = files.Count();
 
-            ReportErrors(readErrors);
-            SetLogMonitorState(currentState & ~LogMonitorState.Batch);
+            IEnumerable<string> ReadAllJournals()
+            {
+                var readErrors = new List<(Exception ex, string file, string line)>();
+                foreach (var file in files)
+                {
+                    yield return file.Name;
+                    readErrors.AddRange(
+                        ProcessLines(ReadAllLines(file.FullName), file.Name));
+                }
+
+                ReportErrors(readErrors);
+                SetLogMonitorState(currentState & ~LogMonitorState.Batch);
+            };
+
+            return ReadAllJournals;
         }
 
         public void PrereadJournals()
@@ -187,13 +193,13 @@ namespace Observatory.Utils
 
         #region Private Fields
 
-        private FileSystemWatcher journalWatcher;
-        private FileSystemWatcher statusWatcher;
-        private Dictionary<string, Type> journalTypes;
-        private Dictionary<string, int> currentLine;
+        private FileSystemWatcher? journalWatcher;
+        private FileSystemWatcher? statusWatcher;
+        private readonly Dictionary<string, Type> journalTypes;
+        private readonly Dictionary<string, int> currentLine;
         private LogMonitorState currentState = LogMonitorState.Idle; // Change via #SetLogMonitorState
         private bool firstStartMonitor = true;
-        private string[] EventsWithAncillaryFile = new string[]
+        private readonly string[] EventsWithAncillaryFile = new string[]
         {
             "Cargo",
             "NavRoute",
@@ -242,7 +248,7 @@ namespace Observatory.Utils
             statusWatcher.Changed += StatusUpdateEvent;
         }
 
-        private DirectoryInfo GetJournalFolder(string path = "")
+        private static DirectoryInfo GetJournalFolder(string path = "")
         {
             DirectoryInfo logDirectory;
 
@@ -370,7 +376,7 @@ namespace Observatory.Utils
             }
         }
 
-        private void ReportErrors(List<(Exception ex, string file, string line)> readErrors)
+        private static void ReportErrors(List<(Exception ex, string file, string line)> readErrors)
         {
             if (readErrors.Any())
             {
@@ -410,24 +416,22 @@ namespace Observatory.Utils
                 }
                 catch (Exception ex)
                 {
-                    ReportErrors(new List<(Exception ex, string file, string line)>() { (ex, eventArgs.Name, line) });
+                    ReportErrors(new List<(Exception ex, string file, string line)>() { (ex, eventArgs.Name ?? string.Empty, line) });
                 }
             }
 
             currentLine[eventArgs.FullPath] = fileContent.Count;
         }
 
-        private List<string> ReadAllLines(string path)
+        private static List<string> ReadAllLines(string path)
         {
             var lines = new List<string>();
             try
             {
-                using (StreamReader file = new StreamReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
+                using StreamReader file = new(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
+                while (!file.EndOfStream)
                 {
-                    while (!file.EndOfStream)
-                    {
-                        lines.Add(file.ReadLine());
-                    }
+                    lines.Add(file.ReadLine() ?? string.Empty);
                 }
             }
             catch (IOException ioEx)
@@ -450,6 +454,7 @@ namespace Observatory.Utils
             if (statusLines.Count > 0)
             {
                 var status = JournalReader.ObservatoryDeserializer<Status>(statusLines[0]);
+                Status = status;
                 handler?.Invoke(this, new JournalEventArgs() { journalType = typeof(Status), journalEvent = status });
             }
         }
@@ -486,9 +491,9 @@ namespace Observatory.Utils
             IntPtr pathPtr = IntPtr.Zero;
             try
             {
-                Guid FolderSavedGames = new Guid("4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4");
+                Guid FolderSavedGames = new ("4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4");
                 SHGetKnownFolderPath(ref FolderSavedGames, 0, IntPtr.Zero, out pathPtr);
-                return Marshal.PtrToStringUni(pathPtr);
+                return Marshal.PtrToStringUni(pathPtr) ?? string.Empty;
             }
             finally
             {
@@ -496,7 +501,7 @@ namespace Observatory.Utils
             }
         }
 
-        private IEnumerable<FileInfo> GetJournalFilesOrdered(DirectoryInfo journalFolder)
+        private static IEnumerable<FileInfo> GetJournalFilesOrdered(DirectoryInfo journalFolder)
         {
             return from file in journalFolder.GetFiles("Journal.*.??.log")
                    orderby file.LastWriteTime
diff --git a/ObservatoryExplorer/ExplorerUIResults.cs b/ObservatoryExplorer/ExplorerUIResults.cs
index 142b9e8..945bfd6 100644
--- a/ObservatoryExplorer/ExplorerUIResults.cs
+++ b/ObservatoryExplorer/ExplorerUIResults.cs
@@ -1,16 +1,19 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using Observatory.Framework;
 
 namespace Observatory.Explorer
 {
     public class ExplorerUIResults
     {
+        [ColumnSuggestedWidth(150)]
         public string Time { get; set; }
+
+        [ColumnSuggestedWidth(150)]
         public string BodyName { get; set; }
+
+        [ColumnSuggestedWidth(200)]
         public string Description { get; set; }
+
+        [ColumnSuggestedWidth(200)]
         public string Details { get; set; }
     }
 }
diff --git a/ObservatoryExplorer/ObservatoryExplorer.csproj b/ObservatoryExplorer/ObservatoryExplorer.csproj
index 0dac63d..93576f7 100644
--- a/ObservatoryExplorer/ObservatoryExplorer.csproj
+++ b/ObservatoryExplorer/ObservatoryExplorer.csproj
@@ -33,7 +33,7 @@
   </Target>
   
   <ItemGroup>
-    <PackageReference Include="NLua" Version="1.6.0" />
+    <PackageReference Include="NLua" Version="1.6.3" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/ObservatoryFramework/Attributes.cs b/ObservatoryFramework/Attributes.cs
index 05bf691..8bfd806 100644
--- a/ObservatoryFramework/Attributes.cs
+++ b/ObservatoryFramework/Attributes.cs
@@ -33,6 +33,20 @@ namespace Observatory.Framework
         }
     }
 
+    /// <summary>
+    /// Suggests default column width when building basic UI
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+    public class ColumnSuggestedWidth : Attribute
+    { 
+        public ColumnSuggestedWidth(int width)
+        {
+            Width = width;
+        }
+
+        public int Width { get; } 
+    }
+
     /// <summary>
     /// Indicates that the property should not be displayed to the user in the UI.
     /// </summary>
diff --git a/ObservatoryFramework/Files/Converters/ThargoidWarRemainingTimeConverter.cs b/ObservatoryFramework/Files/Converters/ThargoidWarRemainingTimeConverter.cs
new file mode 100644
index 0000000..f4a6795
--- /dev/null
+++ b/ObservatoryFramework/Files/Converters/ThargoidWarRemainingTimeConverter.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Text.Json;
+using System.Threading.Tasks;
+using System.Reflection.Metadata.Ecma335;
+
+namespace Observatory.Framework.Files.Converters
+{
+    class ThargoidWarRemainingTimeConverter : JsonConverter<int>
+    {
+        public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        {
+            if (reader.TokenType == JsonTokenType.String)
+            {
+                string value = reader.GetString();
+                
+                int dayCount = Int32.TryParse(value.Split(' ')[0], out int days)
+                    ? days
+                    : 0;
+
+                return dayCount;
+            }                
+            else
+                return reader.GetInt32();
+        }
+
+        public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
+        {
+            writer.WriteStringValue(value.ToString() + " Days");
+        }
+    }
+}
diff --git a/ObservatoryFramework/Files/Journal/Combat/Bounty.cs b/ObservatoryFramework/Files/Journal/Combat/Bounty.cs
index 54c4470..13e8a12 100644
--- a/ObservatoryFramework/Files/Journal/Combat/Bounty.cs
+++ b/ObservatoryFramework/Files/Journal/Combat/Bounty.cs
@@ -6,6 +6,8 @@ namespace Observatory.Framework.Files.Journal
     public class Bounty : JournalBase
     {
         public ImmutableList<Rewards> Rewards { get; init; }
+        public string PilotName { get; set; }
+        public string PilotName_Localised { get; set; }
         public string Target { get; init; }
         public string Target_Localised { get; init; }
         public string Faction { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/Combat/EscapeInterdiction.cs b/ObservatoryFramework/Files/Journal/Combat/EscapeInterdiction.cs
index c917d3b..2648d25 100644
--- a/ObservatoryFramework/Files/Journal/Combat/EscapeInterdiction.cs
+++ b/ObservatoryFramework/Files/Journal/Combat/EscapeInterdiction.cs
@@ -4,5 +4,6 @@
     {
         public string Interdictor { get; init; }
         public bool IsPlayer { get; init; }
+        public bool IsThargoid { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Combat/Interdicted.cs b/ObservatoryFramework/Files/Journal/Combat/Interdicted.cs
index 17b6121..f0cb0b9 100644
--- a/ObservatoryFramework/Files/Journal/Combat/Interdicted.cs
+++ b/ObservatoryFramework/Files/Journal/Combat/Interdicted.cs
@@ -9,5 +9,6 @@
         public int CombatRank { get; init; }
         public string Faction { get; init; }
         public string Power { get; init; }
+        public bool IsThargoid { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Exploration/FSSSignalDiscovered.cs b/ObservatoryFramework/Files/Journal/Exploration/FSSSignalDiscovered.cs
index 2ced548..21ed41c 100644
--- a/ObservatoryFramework/Files/Journal/Exploration/FSSSignalDiscovered.cs
+++ b/ObservatoryFramework/Files/Journal/Exploration/FSSSignalDiscovered.cs
@@ -14,6 +14,10 @@
         /// </summary>
         public string SignalName_Localised { get; init; }
         /// <summary>
+        /// Type of signal location.
+        /// </summary>
+        public string SignalType { get; init; }
+        /// <summary>
         /// Faction state or circumstance that caused this signal to appear.
         /// </summary>
         public string SpawningState { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/FleetCarrier/CarrierJump.cs b/ObservatoryFramework/Files/Journal/FleetCarrier/CarrierJump.cs
index 4e39831..9ecc398 100644
--- a/ObservatoryFramework/Files/Journal/FleetCarrier/CarrierJump.cs
+++ b/ObservatoryFramework/Files/Journal/FleetCarrier/CarrierJump.cs
@@ -8,6 +8,10 @@ namespace Observatory.Framework.Files.Journal
     public class CarrierJump : FSDJump
     {
         public bool Docked { get; init; }
+        public bool OnFoot { get; init; }
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StationType { get; init; }
         public ulong MarketID { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/Odyssey/Disembark.cs b/ObservatoryFramework/Files/Journal/Odyssey/Disembark.cs
index 6ee667c..508cc48 100644
--- a/ObservatoryFramework/Files/Journal/Odyssey/Disembark.cs
+++ b/ObservatoryFramework/Files/Journal/Odyssey/Disembark.cs
@@ -18,6 +18,9 @@ namespace Observatory.Framework.Files.Journal
         public int BodyID { get; init; }
         public bool OnStation { get; init; }
         public bool OnPlanet { get; init; }
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StationType { get; init; }
         public ulong MarketID { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/Odyssey/ScanOrganic.cs b/ObservatoryFramework/Files/Journal/Odyssey/ScanOrganic.cs
index 7237f07..766a5e6 100644
--- a/ObservatoryFramework/Files/Journal/Odyssey/ScanOrganic.cs
+++ b/ObservatoryFramework/Files/Journal/Odyssey/ScanOrganic.cs
@@ -11,6 +11,8 @@ namespace Observatory.Framework.Files.Journal
         public string Genus_Localised { get; init; }
         public string Species { get; init; }
         public string Species_Localised { get; init; }
+        public string Variant {  get; init; }
+        public string Variant_Localised { get; init; }
         public ulong SystemAddress { get; init; }
         public int Body { get; init; }
     }
diff --git a/ObservatoryFramework/Files/Journal/Other/ApproachSettlement.cs b/ObservatoryFramework/Files/Journal/Other/ApproachSettlement.cs
index 6ebb960..65b8a3c 100644
--- a/ObservatoryFramework/Files/Journal/Other/ApproachSettlement.cs
+++ b/ObservatoryFramework/Files/Journal/Other/ApproachSettlement.cs
@@ -1,4 +1,9 @@
-namespace Observatory.Framework.Files.Journal
+using Observatory.Framework.Files.Converters;
+using Observatory.Framework.Files.ParameterTypes;
+using System.Collections.Immutable;
+using System.Text.Json.Serialization;
+
+namespace Observatory.Framework.Files.Journal
 {
     public class ApproachSettlement : JournalBase
     {
@@ -10,5 +15,13 @@
         public float Longitude { get; init; }
         public int BodyID { get; init; }
         public string BodyName { get; init; }
+        public ImmutableList<StationEconomy> StationEconomies { get; init; }
+        public string StationEconomy { get; init; }
+        public string StationEconomy_Localised { get; init; }
+        public Faction StationFaction { get; init; }
+        public string StationGovernment { get; init; }
+        public string StationGovernment_Localised { get; init; }
+        [JsonConverter(typeof(StationServiceConverter))]
+        public StationService StationServices { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Startup/Passengers.cs b/ObservatoryFramework/Files/Journal/Startup/Passengers.cs
index 830e74b..eb61b94 100644
--- a/ObservatoryFramework/Files/Journal/Startup/Passengers.cs
+++ b/ObservatoryFramework/Files/Journal/Startup/Passengers.cs
@@ -1,11 +1,27 @@
 using Observatory.Framework.Files.ParameterTypes;
 using System.Collections.Immutable;
+using System.Text.Json.Serialization;
 
 namespace Observatory.Framework.Files.Journal
 {
     public class Passengers : JournalBase
     {
-        public ImmutableList<Passenger> Manifest { get; init; }
+        [JsonPropertyName("Passengers_Missions_Accepted")]
+        public int PassengersMissionsAccepted { get; init; }
 
+        [JsonPropertyName("Passengers_Missions_Bulk")]
+        public int PassengersMissionsBulk { get; init; }
+
+        [JsonPropertyName("Passengers_Missions_Delivered")]
+        public int PassengersMissionsDelivered { get; init; }
+
+        [JsonPropertyName("Passengers_Missions_Disgruntled")]
+        public int PassengersMissionsDisgruntled { get; init; }
+
+        [JsonPropertyName("Passengers_Missions_Ejected")]
+        public int PassengersMissionsEjected { get; init; }
+
+        [JsonPropertyName("Passengers_Missions_VIP")]
+        public int PassengersMissionsVip { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Startup/Statistics.cs b/ObservatoryFramework/Files/Journal/Startup/Statistics.cs
index 1b26b88..da6ed6f 100644
--- a/ObservatoryFramework/Files/Journal/Startup/Statistics.cs
+++ b/ObservatoryFramework/Files/Journal/Startup/Statistics.cs
@@ -27,5 +27,6 @@ namespace Observatory.Framework.Files.Journal
         public CQC CQC { get; init; }
         [JsonPropertyName("FLEETCARRIER")]
         public FleetCarrier FleetCarrier { get; init; }
+        public Exobiology Exobiology { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/StationServices/ClearImpound.cs b/ObservatoryFramework/Files/Journal/StationServices/ClearImpound.cs
new file mode 100644
index 0000000..9951e05
--- /dev/null
+++ b/ObservatoryFramework/Files/Journal/StationServices/ClearImpound.cs
@@ -0,0 +1,11 @@
+namespace Observatory.Framework.Files.Journal
+{
+    public class ClearImpound : JournalBase
+    {
+        public string ShipType { get; init; }
+        public string ShipType_Localised { get; init; }
+        public ulong ShipID { get; init; }
+        public ulong ShipMarketID { get; init; }
+        public ulong MarketID { get; init; }
+    }
+}
diff --git a/ObservatoryFramework/Files/Journal/StationServices/Market.cs b/ObservatoryFramework/Files/Journal/StationServices/Market.cs
index 2b80fa3..de87e41 100644
--- a/ObservatoryFramework/Files/Journal/StationServices/Market.cs
+++ b/ObservatoryFramework/Files/Journal/StationServices/Market.cs
@@ -7,6 +7,9 @@ namespace Observatory.Framework.Files.Journal
     public class Market : JournalBase
     {
         public ulong MarketID { get; init; }
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StationType { get; init; }
         public string StarSystem { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/StationServices/MassModuleStore.cs b/ObservatoryFramework/Files/Journal/StationServices/MassModuleStore.cs
index b406b8d..57a989a 100644
--- a/ObservatoryFramework/Files/Journal/StationServices/MassModuleStore.cs
+++ b/ObservatoryFramework/Files/Journal/StationServices/MassModuleStore.cs
@@ -5,7 +5,7 @@ namespace Observatory.Framework.Files.Journal
 {
     public class MassModuleStore : JournalBase
     {
-        public long MarketID { get; init; }
+        public ulong MarketID { get; init; }
         public string Ship { get; init; }
         public ulong ShipID { get; init; }
         public ImmutableList<Item> Items { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/StationServices/Outfitting.cs b/ObservatoryFramework/Files/Journal/StationServices/Outfitting.cs
index bfb406e..43765b4 100644
--- a/ObservatoryFramework/Files/Journal/StationServices/Outfitting.cs
+++ b/ObservatoryFramework/Files/Journal/StationServices/Outfitting.cs
@@ -3,6 +3,9 @@
     public class Outfitting : JournalBase
     {
         public ulong MarketID { get; init; }
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StarSystem { get; init; }
     }
diff --git a/ObservatoryFramework/Files/Journal/StationServices/Shipyard.cs b/ObservatoryFramework/Files/Journal/StationServices/Shipyard.cs
index 8fa1b67..34457f3 100644
--- a/ObservatoryFramework/Files/Journal/StationServices/Shipyard.cs
+++ b/ObservatoryFramework/Files/Journal/StationServices/Shipyard.cs
@@ -3,6 +3,9 @@
     public class Shipyard : JournalBase
     {
         public ulong MarketID { get; init; }
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StarSystem { get; init; }
     }
diff --git a/ObservatoryFramework/Files/Journal/StationServices/StoredModules.cs b/ObservatoryFramework/Files/Journal/StationServices/StoredModules.cs
index 6567717..646baac 100644
--- a/ObservatoryFramework/Files/Journal/StationServices/StoredModules.cs
+++ b/ObservatoryFramework/Files/Journal/StationServices/StoredModules.cs
@@ -6,6 +6,9 @@ namespace Observatory.Framework.Files.Journal
     public class StoredModules : JournalBase
     {
         public string StarSystem { get; init; }
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public ulong MarketID { get; init; }
         public ImmutableList<StoredItem> Items { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/StationServices/StoredShips.cs b/ObservatoryFramework/Files/Journal/StationServices/StoredShips.cs
index 55fda63..e7294ac 100644
--- a/ObservatoryFramework/Files/Journal/StationServices/StoredShips.cs
+++ b/ObservatoryFramework/Files/Journal/StationServices/StoredShips.cs
@@ -6,6 +6,9 @@ namespace Observatory.Framework.Files.Journal
     public class StoredShips : JournalBase
     {
         public ulong MarketID { get; init; }
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StarSystem { get; init; }
         public ImmutableList<StoredShip> ShipsHere { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/Trade/MarketBuy.cs b/ObservatoryFramework/Files/Journal/Trade/MarketBuy.cs
index 23254db..ad9bf75 100644
--- a/ObservatoryFramework/Files/Journal/Trade/MarketBuy.cs
+++ b/ObservatoryFramework/Files/Journal/Trade/MarketBuy.cs
@@ -2,7 +2,7 @@
 {
     public class MarketBuy : JournalBase
     {
-        public long MarketID { get; init; }
+        public ulong MarketID { get; init; }
         public string Type { get; init; }
         public string Type_Localised { get; init; }
         public int Count { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/Trade/MarketSell.cs b/ObservatoryFramework/Files/Journal/Trade/MarketSell.cs
index 8d479be..276be75 100644
--- a/ObservatoryFramework/Files/Journal/Trade/MarketSell.cs
+++ b/ObservatoryFramework/Files/Journal/Trade/MarketSell.cs
@@ -2,7 +2,7 @@
 {
     public class MarketSell : JournalBase
     {
-        public long MarketID { get; init; }
+        public ulong MarketID { get; init; }
         public string Type { get; init; }
         public string Type_Localised { get; init; }
         public int Count { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/Travel/Docked.cs b/ObservatoryFramework/Files/Journal/Travel/Docked.cs
index 1fa7299..93a7a4d 100644
--- a/ObservatoryFramework/Files/Journal/Travel/Docked.cs
+++ b/ObservatoryFramework/Files/Journal/Travel/Docked.cs
@@ -7,12 +7,14 @@ namespace Observatory.Framework.Files.Journal
 {
     public class Docked : JournalBase
     {
-
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StationType { get; init; }
         public string StarSystem { get; init; }
         public ulong SystemAddress { get; init; }
-        public long MarketID { get; init; }
+        public ulong MarketID { get; init; }
 
         [JsonConverter(typeof(Converters.LegacyFactionConverter<Faction>))]
         public Faction StationFaction { get; init; }
diff --git a/ObservatoryFramework/Files/Journal/Travel/DockingRequested.cs b/ObservatoryFramework/Files/Journal/Travel/DockingRequested.cs
index 07f19dc..8eb6a79 100644
--- a/ObservatoryFramework/Files/Journal/Travel/DockingRequested.cs
+++ b/ObservatoryFramework/Files/Journal/Travel/DockingRequested.cs
@@ -4,9 +4,12 @@ namespace Observatory.Framework.Files.Journal
 {
     public class DockingRequested : JournalBase
     {
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StationType { get; init; }
-        public long MarketID { get; init; }
+        public ulong MarketID { get; init; }
         public LandingPads LandingPads { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Travel/FSDJump.cs b/ObservatoryFramework/Files/Journal/Travel/FSDJump.cs
index 0a83152..ae4da99 100644
--- a/ObservatoryFramework/Files/Journal/Travel/FSDJump.cs
+++ b/ObservatoryFramework/Files/Journal/Travel/FSDJump.cs
@@ -49,5 +49,6 @@ namespace Observatory.Framework.Files.Journal
         public string PowerplayState { get; init; }
         public bool Taxi { get; init; }
         public bool Multicrew { get; init; }
+        public ThargoidWar ThargoidWar { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Travel/Location.cs b/ObservatoryFramework/Files/Journal/Travel/Location.cs
index f771569..c401fbc 100644
--- a/ObservatoryFramework/Files/Journal/Travel/Location.cs
+++ b/ObservatoryFramework/Files/Journal/Travel/Location.cs
@@ -24,11 +24,14 @@ namespace Observatory.Framework.Files.Journal
                 //Stale Data, discard
             }
         }
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StationType { get; init; }
         public float Longitude { get; init; }
         public float Latitude { get; init; }
-        public long MarketID { get; init; }
+        public ulong MarketID { get; init; }
 
         [JsonConverter(typeof(LegacyFactionConverter<Faction>))]
         public Faction StationFaction { get; init; }
@@ -68,5 +71,6 @@ namespace Observatory.Framework.Files.Journal
         public bool Multicrew { get; init; }
         public bool OnFoot { get; init; }
         public bool InSRV { get; init; }
+        public ThargoidWar ThargoidWar { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Travel/StartJump.cs b/ObservatoryFramework/Files/Journal/Travel/StartJump.cs
index b09297b..5c24c4a 100644
--- a/ObservatoryFramework/Files/Journal/Travel/StartJump.cs
+++ b/ObservatoryFramework/Files/Journal/Travel/StartJump.cs
@@ -6,5 +6,6 @@
         public string StarSystem { get; init; }
         public ulong SystemAddress { get; init; }
         public string StarClass { get; init; }
+        public bool Taxi {  get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Travel/SupercruiseDestinationDrop.cs b/ObservatoryFramework/Files/Journal/Travel/SupercruiseDestinationDrop.cs
new file mode 100644
index 0000000..245eefc
--- /dev/null
+++ b/ObservatoryFramework/Files/Journal/Travel/SupercruiseDestinationDrop.cs
@@ -0,0 +1,9 @@
+namespace Observatory.Framework.Files.Journal
+{
+    public class SupercruiseDestinationDrop : JournalBase
+    {
+        public string Type { get; init; }
+        public int Threat { get; init; }
+        public ulong MarketID { get; init; }
+    }
+}
diff --git a/ObservatoryFramework/Files/Journal/Travel/SupercruiseEntry.cs b/ObservatoryFramework/Files/Journal/Travel/SupercruiseEntry.cs
index f5c1cc5..442a47f 100644
--- a/ObservatoryFramework/Files/Journal/Travel/SupercruiseEntry.cs
+++ b/ObservatoryFramework/Files/Journal/Travel/SupercruiseEntry.cs
@@ -6,5 +6,6 @@
         public ulong SystemAddress { get; init; }
         public bool Taxi { get; init; }
         public bool Multicrew { get; init; }
+        public bool? Wanted { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/Travel/Undocked.cs b/ObservatoryFramework/Files/Journal/Travel/Undocked.cs
index 747e0d7..435fca2 100644
--- a/ObservatoryFramework/Files/Journal/Travel/Undocked.cs
+++ b/ObservatoryFramework/Files/Journal/Travel/Undocked.cs
@@ -2,6 +2,9 @@
 {
     public class Undocked : JournalBase
     {
+        /// <summary>
+        /// Name of the station at which this event occurred.
+        /// </summary>
         public string StationName { get; init; }
         public string StationType { get; init; }
         public ulong MarketID { get; init; }
diff --git a/ObservatoryFramework/Files/MarketFile.cs b/ObservatoryFramework/Files/MarketFile.cs
index fb22d0b..edbe655 100644
--- a/ObservatoryFramework/Files/MarketFile.cs
+++ b/ObservatoryFramework/Files/MarketFile.cs
@@ -11,7 +11,7 @@ namespace Observatory.Framework.Files
         /// <summary>
         /// Unique ID of current market.
         /// </summary>
-        public long MarketID { get; init; }
+        public ulong MarketID { get; init; }
         /// <summary>
         /// Name of the station where the market is located.
         /// </summary>
diff --git a/ObservatoryFramework/Files/OutfittingFile.cs b/ObservatoryFramework/Files/OutfittingFile.cs
index 40600c2..7c23398 100644
--- a/ObservatoryFramework/Files/OutfittingFile.cs
+++ b/ObservatoryFramework/Files/OutfittingFile.cs
@@ -11,7 +11,7 @@ namespace Observatory.Framework.Files
         /// <summary>
         /// Unique ID of current market.
         /// </summary>
-        public long MarketID { get; init; }
+        public ulong MarketID { get; init; }
         /// <summary>
         /// Name of the station where the market is located.
         /// </summary>
diff --git a/ObservatoryFramework/Files/ParameterTypes/BankAccount.cs b/ObservatoryFramework/Files/ParameterTypes/BankAccount.cs
index ca98037..ecf2841 100644
--- a/ObservatoryFramework/Files/ParameterTypes/BankAccount.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/BankAccount.cs
@@ -27,5 +27,21 @@ namespace Observatory.Framework.Files.ParameterTypes
 
         [JsonPropertyName("Spent_On_Insurance")]
         public long SpentOnInsurance { get; init; }
+        [JsonPropertyName("Owned_Ship_Count")]
+        public int OwnedShipCount { get; init; }
+        [JsonPropertyName("Premium_Stock_Bought")]
+        public int PremiumStockBought {  get; init; }
+        [JsonPropertyName("Spent_On_Premium_Stock")]
+        public long SpentOnPremiumStock { get; init; }
+        [JsonPropertyName("Spent_On_Suit_Consumables")]
+        public long SpentOnSuitConsumables { get; init; }
+        [JsonPropertyName("Spent_On_Suits")]
+        public long SpentOnSuits { get; init; }
+        [JsonPropertyName("Spent_On_Weapons")]
+        public long SpentOnWeapons { get; init; }
+        [JsonPropertyName("Suits_Owned")]
+        public int SuitsOwned { get; init; }
+        [JsonPropertyName("Weapons_Owned")]
+        public int WeaponsOwned { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/ParameterTypes/BioData.cs b/ObservatoryFramework/Files/ParameterTypes/BioData.cs
index 50dbfd4..9dd5694 100644
--- a/ObservatoryFramework/Files/ParameterTypes/BioData.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/BioData.cs
@@ -6,6 +6,8 @@
         public string Genus_Localised { get; init; }
         public string Species { get; init; }
         public string Species_Localised { get; init; }
+        public string Variant { get; init; }
+        public string Variant_Localised { get; init; }
         public int Value { get; init; }
         public int Bonus { get; init; }
     }
diff --git a/ObservatoryFramework/Files/ParameterTypes/Combat.cs b/ObservatoryFramework/Files/ParameterTypes/Combat.cs
index 39ddeea..27c0572 100644
--- a/ObservatoryFramework/Files/ParameterTypes/Combat.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/Combat.cs
@@ -26,5 +26,37 @@ namespace Observatory.Framework.Files.ParameterTypes
 
         [JsonPropertyName("Skimmers_Killed")]
         public int SkimmersKilled { get; init; }
+        [JsonPropertyName("ConflictZone_High")]
+        public int ConflictZoneHigh { get; init; }
+        [JsonPropertyName("ConflictZone_High_Wins")]
+        public int ConflictZoneHighWins { get; init; }
+        [JsonPropertyName("ConflictZone_Low")]
+        public int ConflictZoneLow { get; init; }
+        [JsonPropertyName("ConflictZone_Low_Wins")]
+        public int ConflictZoneLowWins { get; init; }
+        [JsonPropertyName("ConflictZone_Medium")]
+        public int ConflictZoneMedium { get; init; }
+        [JsonPropertyName("ConflictZone_Medium_Wins")]
+        public int ConflictZoneMediumWins { get; init; }
+        [JsonPropertyName("ConflictZone_Total")]
+        public int ConflictZoneTotal { get; init; }
+        [JsonPropertyName("ConflictZone_Total_Wins")]
+        public int ConflictZoneTotalWins { get; init; }
+        [JsonPropertyName("OnFoot_Combat_Bonds")]
+        public int OnFootCombatBonds { get; init; }
+        [JsonPropertyName("OnFoot_Combat_Bonds_Profits")]
+        public int OnFootCombatBondsProfits { get; init; }
+        [JsonPropertyName("OnFoot_Scavs_Killed")]
+        public int OnFootScavsKilled { get; init; }
+        [JsonPropertyName("OnFoot_Ships_Destroyed")]
+        public int OnFootShipsDestroyed { get; init; }
+        [JsonPropertyName("OnFoot_Skimmers_Killed")]
+        public int OnFootSkimmersKilled { get; init; }
+        [JsonPropertyName("OnFoot_Vehicles_Destroyed")]
+        public int OnFootVehiclesDestroyed { get; init; }
+        [JsonPropertyName("Settlement_Conquered")]
+        public int SettlementConquered {  get; init; }
+        [JsonPropertyName("Settlement_Defended")]
+        public int SettlementDefended { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/ParameterTypes/Crafting.cs b/ObservatoryFramework/Files/ParameterTypes/Crafting.cs
index 2903945..b545084 100644
--- a/ObservatoryFramework/Files/ParameterTypes/Crafting.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/Crafting.cs
@@ -29,6 +29,30 @@ namespace Observatory.Framework.Files.ParameterTypes
         [JsonPropertyName("Recipes_Generated_Rank_5")]
         public int RecipesGeneratedRank5 { get; init; }
 
+        [JsonPropertyName("Suit_Mods_Applied")]
+        public int SuitModsApplied { get; init; }
+        
+        [JsonPropertyName("Suit_Mods_Applied_Full")]
+        public int SuitModsAppliedFull { get; init; }
+
+        [JsonPropertyName("Suits_Upgraded")]
+        public int SuitsUpgraded { get; init; }
+
+        [JsonPropertyName("Suits_Upgraded_Full")]
+        public int SuitsUpgradedFull { get; init; }
+
+        [JsonPropertyName("Weapon_Mods_Applied")]
+        public int WeaponModsApplied { get; init; }
+
+        [JsonPropertyName("Weapon_Mods_Applied_Full")]
+        public int WeaponModsAppliedFull { get; init; }
+
+        [JsonPropertyName("Weapons_Upgraded")]
+        public int WeaponsUpgraded { get; init; }
+
+        [JsonPropertyName("Weapons_Upgraded_Full")]
+        public int WeaponsUpgradedFull { get; init; }
+
         [JsonPropertyName("Recipes_Applied"), Obsolete(JournalUtilities.ObsoleteMessage)]
         public int RecipesApplied { get; init; }
 
diff --git a/ObservatoryFramework/Files/ParameterTypes/Crime.cs b/ObservatoryFramework/Files/ParameterTypes/Crime.cs
index d3c4982..e7ff2e2 100644
--- a/ObservatoryFramework/Files/ParameterTypes/Crime.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/Crime.cs
@@ -19,5 +19,56 @@ namespace Observatory.Framework.Files.ParameterTypes
 
         [JsonPropertyName("Highest_Bounty")]
         public decimal HighestBounty { get; init; }
+        
+        [JsonPropertyName("Citizens_Murdered")]
+        public int CitizensMurdered { get; init; }
+
+        [JsonPropertyName("Data_Stolen")]
+        public int DataStolen {  get; init; }
+
+        [JsonPropertyName("Goods_Stolen")]
+        public int GoodsStolen { get; init; }
+
+        [JsonPropertyName("Guards_Murdered")]
+        public int GuardsMurdered { get; init; }
+
+        [JsonPropertyName("Malware_Uploaded")]
+        public int MalwareUploaded { get; init; }
+
+        [JsonPropertyName("Omnipol_Murdered")]
+        public int OmnipolMurdered { get; init; }
+
+        [JsonPropertyName("Production_Sabotage")]
+        public int ProductionSabotage { get; init; }
+
+        [JsonPropertyName("Production_Theft")]
+        public int ProductionTheft {  get; init; }
+
+        [JsonPropertyName("Profiles_Cloned")]
+        public int ProfilesCloned { get; init; }
+
+        [JsonPropertyName("Sample_Stolen")]
+        public int SampleStolen { get; init; }
+
+        [JsonPropertyName("Settlements_State_Shutdown")]
+        public int SettlementsStateShutdown { get; init; }
+
+        [JsonPropertyName("Total_Murders")]
+        public int TotalMurders { get; init; }
+
+        [JsonPropertyName("Total_Stolen")]
+        public int TotalStolen { get; init; }
+
+        [JsonPropertyName("Turrets_Destroyed")]
+        public int TurretsDestroyed { get; init; }
+
+        [JsonPropertyName("Turrets_Overloaded")]
+        public int TurretsOverloaded { get; init; }
+
+        [JsonPropertyName("Turrets_Total")]
+        public int TurretsTotal { get; init; }
+
+        [JsonPropertyName("Value_Stolen_StateChange")]
+        public int ValueStolenStatechange { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/ParameterTypes/Exobiology.cs b/ObservatoryFramework/Files/ParameterTypes/Exobiology.cs
new file mode 100644
index 0000000..9920ebe
--- /dev/null
+++ b/ObservatoryFramework/Files/ParameterTypes/Exobiology.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace Observatory.Framework.Files.ParameterTypes
+{
+    public class Exobiology
+    {
+        [JsonPropertyName("First_Logged")]
+        public int FirstLogged { get; init; }
+
+        [JsonPropertyName("First_Logged_Profits")]
+        public long FirstLoggedProfits { get; init; }
+
+        [JsonPropertyName("Organic_Data")]
+        public int OrganicData { get; init; }
+
+        [JsonPropertyName("Organic_Data_Profits")]
+        public long OrganicDataProfits { get; init; }
+
+        [JsonPropertyName("Organic_Genus")]
+        public int OrganicGenus { get; init; }
+
+        [JsonPropertyName("Organic_Genus_Encountered")]
+        public int OrganicGenusEncountered { get; init; }
+
+        [JsonPropertyName("Organic_Planets")]
+        public int OrganicPlanets { get; init; }
+
+        [JsonPropertyName("Organic_Species")]
+        public int OrganicSpecies { get; init; }
+
+        [JsonPropertyName("Organic_Species_Encountered")]
+        public int OrganicSpeciesEncountered { get; init; }
+
+        [JsonPropertyName("Organic_Systems")]
+        public int OrganicSystems { get; init; }
+
+        [JsonPropertyName("Organic_Variant_Encountered")]
+        public int OrganicVariantEncountered { get; init; }
+    }
+}
diff --git a/ObservatoryFramework/Files/ParameterTypes/Exploration.cs b/ObservatoryFramework/Files/ParameterTypes/Exploration.cs
index df7fa01..c457526 100644
--- a/ObservatoryFramework/Files/ParameterTypes/Exploration.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/Exploration.cs
@@ -40,5 +40,26 @@ namespace Observatory.Framework.Files.ParameterTypes
 
         [JsonPropertyName("Efficient_Scans")]
         public int EfficientScans { get; init; }
+
+        [JsonPropertyName("First_Footfalls")]
+        public int FirstFootfalls { get; init; }
+
+        [JsonPropertyName("OnFoot_Distance_Travelled")]
+        public long OnFootDistanceTravelled { get; init; }
+
+        [JsonPropertyName("Planet_Footfalls")]
+        public int PlanetFootfalls { get; init; }
+
+        [JsonPropertyName("Settlements_Visited")]
+        public int SettlementsVisited { get; init; }
+
+        [JsonPropertyName("Shuttle_Distance_Travelled")]
+        public double ShuttleDistanceTravelled { get; init; }
+
+        [JsonPropertyName("Shuttle_Journeys")]
+        public int ShuttleJourneys { get; init; }
+
+        [JsonPropertyName("Spent_On_Shuttles")]
+        public long SpentOnShuttles { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/ParameterTypes/MaterialTrader.cs b/ObservatoryFramework/Files/ParameterTypes/MaterialTrader.cs
index 8186c75..0c4c4f6 100644
--- a/ObservatoryFramework/Files/ParameterTypes/MaterialTrader.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/MaterialTrader.cs
@@ -4,6 +4,12 @@ namespace Observatory.Framework.Files.ParameterTypes
 {
     public class MaterialTrader
     {
+        [JsonPropertyName("Assets_Traded_In")]
+        public int AssetsTradedIn { get; init; }
+
+        [JsonPropertyName("Assets_Traded_Out")]
+        public int AssetsTradedOut { get; init; }
+
         [JsonPropertyName("Trades_Completed")]
         public int TradesCompleted { get; init; }
 
diff --git a/ObservatoryFramework/Files/ParameterTypes/SearchAndRescue.cs b/ObservatoryFramework/Files/ParameterTypes/SearchAndRescue.cs
index a3e27e4..8dce88c 100644
--- a/ObservatoryFramework/Files/ParameterTypes/SearchAndRescue.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/SearchAndRescue.cs
@@ -12,5 +12,29 @@ namespace Observatory.Framework.Files.ParameterTypes
 
         [JsonPropertyName("SearchRescue_Count")]
         public int Count { get; init; }
+
+        [JsonPropertyName("Maglocks_Opened")]
+        public int MaglocksOpened { get; init; }
+
+        [JsonPropertyName("Panels_Opened")]
+        public int PanelsOpened { get; init; }
+
+        [JsonPropertyName("Salvage_Illegal_POI")]
+        public int SalvageIllegalPoi { get; init; }
+
+        [JsonPropertyName("Salvage_Illegal_Settlements")]
+        public int SalvageIllegalSettlements { get; init; }
+
+        [JsonPropertyName("Salvage_Legal_POI")]
+        public int SalvageLegalPoi { get; init; }
+
+        [JsonPropertyName("Salvage_Legal_Settlements")]
+        public int SalvageLegalSettlements { get; init; }
+
+        [JsonPropertyName("Settlements_State_FireOut")]
+        public int SettlementsStateFireOut { get; init; }
+
+        [JsonPropertyName("Settlements_State_Reboot")]
+        public int SettlementsStateReboot { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/ParameterTypes/Thargoid.cs b/ObservatoryFramework/Files/ParameterTypes/Thargoid.cs
index 1cb7806..3805a1e 100644
--- a/ObservatoryFramework/Files/ParameterTypes/Thargoid.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/Thargoid.cs
@@ -4,6 +4,9 @@ namespace Observatory.Framework.Files.ParameterTypes
 {
     public class Thargoid
     {
+        [JsonPropertyName("TG_ENCOUNTER_KILLED")]
+        public int EncounterKilled { get; init; }
+
         [JsonPropertyName("TG_ENCOUNTER_WAKES")]
         public int EncounterWakes { get; init; }
 
@@ -18,8 +21,5 @@ namespace Observatory.Framework.Files.ParameterTypes
 
         [JsonPropertyName("TG_ENCOUNTER_TOTAL_LAST_SHIP")]
         public string LastShip { get; init; }
-
-        [JsonPropertyName("TG_SCOUT_COUNT")]
-        public int ScoutCount { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Files/ParameterTypes/ThargoidWar.cs b/ObservatoryFramework/Files/ParameterTypes/ThargoidWar.cs
new file mode 100644
index 0000000..05fbc76
--- /dev/null
+++ b/ObservatoryFramework/Files/ParameterTypes/ThargoidWar.cs
@@ -0,0 +1,16 @@
+using System.Text.Json.Serialization;
+
+namespace Observatory.Framework.Files.ParameterTypes
+{
+    public class ThargoidWar
+    {
+        public string CurrentState { get; init; }
+        public string NextStateSuccess { get; init; }
+        public string NextStateFailure { get; init; }
+        public bool SuccessStateReached { get; init; }
+        public double WarProgress { get; init; }
+        public int RemainingPorts { get; init; }
+        [JsonConverter(typeof(Converters.ThargoidWarRemainingTimeConverter))]
+        public int EstimatedRemainingTime { get; init; }
+    }
+}
diff --git a/ObservatoryFramework/Files/ParameterTypes/Trading.cs b/ObservatoryFramework/Files/ParameterTypes/Trading.cs
index f15d5ef..b347cb4 100644
--- a/ObservatoryFramework/Files/ParameterTypes/Trading.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/Trading.cs
@@ -18,5 +18,14 @@ namespace Observatory.Framework.Files.ParameterTypes
 
         [JsonPropertyName("Highest_Single_Transaction")]
         public long HighestSingleTransaction { get; init; }
+
+        [JsonPropertyName("Assets_Sold")]
+        public int AssetsSold { get; init; }
+
+        [JsonPropertyName("Data_Sold")]
+        public int DataSold { get; init; }
+
+        [JsonPropertyName("Goods_Sold")]
+        public int GoodsSold { get; init; }
     }
 }
diff --git a/ObservatoryFramework/Interfaces.cs b/ObservatoryFramework/Interfaces.cs
index 27ee27b..e595679 100644
--- a/ObservatoryFramework/Interfaces.cs
+++ b/ObservatoryFramework/Interfaces.cs
@@ -1,6 +1,5 @@
 using Observatory.Framework.Files;
 using Observatory.Framework.Files.Journal;
-using System.Xml.XPath;
 
 namespace Observatory.Framework.Interfaces
 {
@@ -51,11 +50,16 @@ namespace Observatory.Framework.Interfaces
 
         /// <summary>
         /// <para>Plugin-specific object implementing the IComparer interface which is used to sort columns in the basic UI datagrid.</para>
-        /// <para>If omitted a basic numeric compare sorter is used.</para>
+        /// <para>If omitted a natural sort order is used.</para>
         /// </summary>
         public IObservatoryComparer ColumnSorter
         { get => null; }
 
+        /// <summary>
+        /// Receives data sent by other plugins.
+        /// </summary>
+        public void HandlePluginMessage(string sourceName, string sourceVersion, object messageArgs)
+        { }
     }
 
     /// <summary>
@@ -94,7 +98,7 @@ namespace Observatory.Framework.Interfaces
         /// Used to track if a "Read All" operation is in progress or not to avoid unnecessary processing or notifications.<br/>
         /// Can be omitted for plugins which do not require the distinction.
         /// </summary>
-        [Obsolete] // Replaced by LogMonitorStateChanged 
+        [Obsolete("Deprecated in favour of LogMonitorStateChanged")]
         public void ReadAllStarted()
         { }
 
@@ -103,7 +107,7 @@ namespace Observatory.Framework.Interfaces
         /// Used to track if a "Read All" operation is in progress or not to avoid unnecessary processing or notifications.<br/>
         /// Can be omitted for plugins which do not require the distinction.
         /// </summary>
-        [Obsolete] // Replaced by LogMonitorStateChanged
+        [Obsolete("Deprecated in favour of LogMonitorStateChanged")]
         public void ReadAllFinished()
         { }
     }
@@ -120,6 +124,20 @@ namespace Observatory.Framework.Interfaces
         /// </summary>
         /// <param name="notificationEventArgs">Details of the notification as sent from the originating worker plugin.</param>
         public void OnNotificationEvent(NotificationArgs notificationEventArgs);
+
+        /// <summary>
+        /// Property set by notification plugins to indicate to Core 
+        /// that native audio notifications should be disabled/suppressed.
+        /// </summary>
+        public bool OverrideAudioNotifications
+        { get => false; }
+
+        /// <summary>
+        /// Property set by notification plugins to indicate to Core 
+        /// that native popup notifications should be disabled/suppressed.
+        /// </summary>
+        public bool OverridePopupNotifications
+        { get => false; }
     }
 
     /// <summary>
@@ -219,6 +237,17 @@ namespace Observatory.Framework.Interfaces
         /// Retrieves and ensures creation of a location which can be used by the plugin to store persistent data.
         /// </summary>
         public string PluginStorageFolder { get; }
+
+        /// <summary>
+        /// Plays audio file using default audio device.
+        /// </summary>
+        /// <param name="filePath">Absolute path to audio file.</param>
+        public Task PlayAudioFile(string filePath);
+
+        /// <summary>
+        /// Sends arbitrary data to all other plugins. The full name and version of the sending plugin will be used to identify the sender to any recipients.
+        /// </summary>
+        public void SendPluginMessage(IObservatoryPlugin plugin, object message);
     }
 
     /// <summary>
diff --git a/ObservatoryFramework/ObservatoryFramework.xml b/ObservatoryFramework/ObservatoryFramework.xml
index 2b3a07a..c65f353 100644
--- a/ObservatoryFramework/ObservatoryFramework.xml
+++ b/ObservatoryFramework/ObservatoryFramework.xml
@@ -20,6 +20,11 @@
             Accessor to get/set displayed name.
             </summary>
         </member>
+        <member name="T:Observatory.Framework.ColumnSuggestedWidth">
+            <summary>
+            Suggests default column width when building basic UI
+            </summary>
+        </member>
         <member name="T:Observatory.Framework.SettingIgnore">
             <summary>
             Indicates that the property should not be displayed to the user in the UI.
@@ -489,6 +494,11 @@
             Localised name of the signal type.
             </summary>
         </member>
+        <member name="P:Observatory.Framework.Files.Journal.FSSSignalDiscovered.SignalType">
+            <summary>
+            Type of signal location.
+            </summary>
+        </member>
         <member name="P:Observatory.Framework.Files.Journal.FSSSignalDiscovered.SpawningState">
             <summary>
             Faction state or circumstance that caused this signal to appear.
@@ -1005,6 +1015,61 @@
             Total amount made from selling data.
             </summary>
         </member>
+        <member name="P:Observatory.Framework.Files.Journal.CarrierJump.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.Disembark.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.Market.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.Outfitting.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.Shipyard.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.StoredModules.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.StoredShips.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.Docked.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.DockingRequested.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.Location.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Files.Journal.Undocked.StationName">
+            <summary>
+            Name of the station at which this event occurred.
+            </summary>
+        </member>
         <member name="T:Observatory.Framework.Files.CargoFile">
             <summary>
             Elite Dangerous cargo.json file. Describes the current cargo carried above the player's ship.
@@ -1352,8 +1417,13 @@
         </member>
         <member name="P:Observatory.Framework.Interfaces.IObservatoryPlugin.ColumnSorter">
             <summary>
-            Plugin-specific object implementing the IComparer interface which is used to sort columns in the basic UI datagrid.
-            If omitted a basic string compare sorter is used.
+            <para>Plugin-specific object implementing the IComparer interface which is used to sort columns in the basic UI datagrid.</para>
+            <para>If omitted a natural sort order is used.</para>
+            </summary>
+        </member>
+        <member name="M:Observatory.Framework.Interfaces.IObservatoryPlugin.HandlePluginMessage(System.String,System.String,System.Object)">
+            <summary>
+            Receives data sent by other plugins.
             </summary>
         </member>
         <member name="T:Observatory.Framework.Interfaces.IObservatoryWorker">
@@ -1412,6 +1482,18 @@
             </summary>
             <param name="notificationEventArgs">Details of the notification as sent from the originating worker plugin.</param>
         </member>
+        <member name="P:Observatory.Framework.Interfaces.IObservatoryNotifier.OverrideAudioNotifications">
+            <summary>
+            Property set by notification plugins to indicate to Core 
+            that native audio notifications should be disabled/suppressed.
+            </summary>
+        </member>
+        <member name="P:Observatory.Framework.Interfaces.IObservatoryNotifier.OverridePopupNotifications">
+            <summary>
+            Property set by notification plugins to indicate to Core 
+            that native popup notifications should be disabled/suppressed.
+            </summary>
+        </member>
         <member name="T:Observatory.Framework.Interfaces.IObservatoryCore">
             <summary>
             Interface passed by Observatory Core to plugins. Primarily used for sending notifications and UI updates back to Core.
@@ -1510,6 +1592,17 @@
             Retrieves and ensures creation of a location which can be used by the plugin to store persistent data.
             </summary>
         </member>
+        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.PlayAudioFile(System.String)">
+            <summary>
+            Plays audio file using default audio device.
+            </summary>
+            <param name="filePath">Absolute path to audio file.</param>
+        </member>
+        <member name="M:Observatory.Framework.Interfaces.IObservatoryCore.SendPluginMessage(Observatory.Framework.Interfaces.IObservatoryPlugin,System.Object)">
+            <summary>
+            Sends arbitrary data to all other plugins. The full name and version of the sending plugin will be used to identify the sender to any recipients.
+            </summary>
+        </member>
         <member name="T:Observatory.Framework.Interfaces.IObservatoryComparer">
             <summary>
             Extends the base IComparer interface with exposed values for the column ID and sort order to use.
diff --git a/ObservatoryHerald/HeraldNotifier.cs b/ObservatoryHerald/HeraldNotifier.cs
index 8c84548..a66fa28 100644
--- a/ObservatoryHerald/HeraldNotifier.cs
+++ b/ObservatoryHerald/HeraldNotifier.cs
@@ -28,6 +28,8 @@ namespace Observatory.Herald
 
         public string ShortName => "Herald";
 
+        public bool OverrideAudioNotifications => true;
+
         public string Version => typeof(HeraldNotifier).Assembly.GetName().Version.ToString();
 
         public PluginUI PluginUI => new (PluginUI.UIType.None, null);
@@ -55,7 +57,7 @@ namespace Observatory.Herald
         {
             var speechManager = new SpeechRequestManager(
                 heraldSettings, observatoryCore.HttpClient, observatoryCore.PluginStorageFolder, observatoryCore.GetPluginErrorLogger(this));
-            heraldSpeech = new HeraldQueue(speechManager, observatoryCore.GetPluginErrorLogger(this));
+            heraldSpeech = new HeraldQueue(speechManager, observatoryCore.GetPluginErrorLogger(this), observatoryCore);
             heraldSettings.Test = TestVoice;
         }
 
diff --git a/ObservatoryHerald/HeraldQueue.cs b/ObservatoryHerald/HeraldQueue.cs
index b0256c2..ae4dc4b 100644
--- a/ObservatoryHerald/HeraldQueue.cs
+++ b/ObservatoryHerald/HeraldQueue.cs
@@ -2,10 +2,10 @@
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using System.Linq;
-using NetCoreAudio;
 using System.Threading;
 using System;
 using System.Diagnostics;
+using Observatory.Framework.Interfaces;
 
 namespace Observatory.Herald
 {
@@ -18,15 +18,15 @@ namespace Observatory.Herald
         private string rate;
         private byte volume;
         private SpeechRequestManager speechManager;
-        private Player audioPlayer;
         private Action<Exception, String> ErrorLogger;
+        private IObservatoryCore core;
 
-        public HeraldQueue(SpeechRequestManager speechManager, Action<Exception, String> errorLogger)
+        public HeraldQueue(SpeechRequestManager speechManager, Action<Exception, String> errorLogger, IObservatoryCore core)
         {
             this.speechManager = speechManager;
+            this.core = core;
             processing = false;
             notifications = new();
-            audioPlayer = new();
             ErrorLogger = errorLogger;
         }
 
@@ -74,7 +74,7 @@ namespace Observatory.Herald
             {
                 while (notifications.Any())
                 {
-                    audioPlayer.SetVolume(volume).Wait();
+                    // audioPlayer.SetVolume(volume).Wait();
                     notification = notifications.Dequeue();
                     Debug.WriteLine("Processing notification: {0} - {1}", notification.Title, notification.Detail);
 
@@ -118,7 +118,7 @@ namespace Observatory.Herald
             return await speechManager.GetAudioFileFromSsml(ssml, voice, style, rate);
         }
 
-        private void PlayAudioRequestsSequentially(List<Task<string>> requestTasks)
+        private async void PlayAudioRequestsSequentially(List<Task<string>> requestTasks)
         {
             foreach (var request in requestTasks)
             {
@@ -126,19 +126,20 @@ namespace Observatory.Herald
                 try
                 {
                     Debug.WriteLine($"Playing audio file: {file}");
-                    audioPlayer.Play(file).Wait();
+                    await core.PlayAudioFile(file);
+                    // audioPlayer.Play(file).Wait();
                 } catch (Exception ex)
                 {
                     Debug.WriteLine($"Failed to play {file}: {ex.Message}");
                     ErrorLogger(ex, $"while playing: {file}");
                 }
 
-                while (audioPlayer.Playing)
-                    Thread.Sleep(50);
+                //while (audioPlayer.Playing)
+                //    Thread.Sleep(50);
 
-                // Explicit stop to ensure device is ready for next file.
-                // ...hopefully.
-                audioPlayer.Stop(true).Wait();
+                //// Explicit stop to ensure device is ready for next file.
+                //// ...hopefully.
+                //audioPlayer.Stop(true).Wait();
 
             }
             speechManager.CommitCache();
diff --git a/ObservatoryHerald/NetCoreAudio/Interfaces/IPlayer.cs b/ObservatoryHerald/NetCoreAudio/Interfaces/IPlayer.cs
deleted file mode 100644
index ed38bdb..0000000
--- a/ObservatoryHerald/NetCoreAudio/Interfaces/IPlayer.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-namespace NetCoreAudio.Interfaces
-{
-    public interface IPlayer : IDisposable
-    {
-        event EventHandler PlaybackFinished;
-
-        bool Playing { get; }
-        bool Paused { get; }
-
-        Task Play(string fileName);
-        Task Pause();
-        Task Resume();
-        Task Stop(bool force);
-        Task SetVolume(byte percent);
-    }
-}
diff --git a/ObservatoryHerald/NetCoreAudio/Player.cs b/ObservatoryHerald/NetCoreAudio/Player.cs
deleted file mode 100644
index f38707c..0000000
--- a/ObservatoryHerald/NetCoreAudio/Player.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-using NetCoreAudio.Interfaces;
-using NetCoreAudio.Players;
-using System;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace NetCoreAudio
-{
-    public class Player : IPlayer
-    {
-        private readonly IPlayer _internalPlayer;
-
-        /// <summary>
-        /// Internally, sets Playing flag to false. Additional handlers can be attached to it to handle any custom logic.
-        /// </summary>
-        public event EventHandler PlaybackFinished;
-
-        /// <summary>
-        /// Indicates that the audio is currently playing.
-        /// </summary>
-        public bool Playing => _internalPlayer.Playing;
-
-        /// <summary>
-        /// Indicates that the audio playback is currently paused.
-        /// </summary>
-        public bool Paused => _internalPlayer.Paused;
-
-        public Player()
-        {
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
-                _internalPlayer = new WindowsPlayer();
-            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
-                _internalPlayer = new LinuxPlayer();
-            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
-                _internalPlayer = new MacPlayer();
-            else
-                throw new Exception("No implementation exist for the current OS");
-
-            _internalPlayer.PlaybackFinished += OnPlaybackFinished;
-        }
-
-        /// <summary>
-        /// Will stop any current playback and will start playing the specified audio file. The fileName parameter can be an absolute path or a path relative to the directory where the library is located. Sets Playing flag to true. Sets Paused flag to false.
-        /// </summary>
-        /// <param name="fileName"></param>
-        /// <returns></returns>
-        public async Task Play(string fileName)
-        {
-            await _internalPlayer.Play(fileName);
-        }
-
-        /// <summary>
-        /// Pauses any ongong playback. Sets Paused flag to true. Doesn't modify Playing flag.
-        /// </summary>
-        /// <returns></returns>
-        public async Task Pause()
-        {
-            await _internalPlayer.Pause();
-        }
-
-        /// <summary>
-        /// Resumes any paused playback. Sets Paused flag to false. Doesn't modify Playing flag.
-        /// </summary>
-        /// <returns></returns>
-        public async Task Resume()
-        {
-            await _internalPlayer.Resume();
-        }
-
-        /// <summary>
-        /// Stops any current playback and clears the buffer. Sets Playing and Paused flags to false.
-        /// </summary>
-        /// <returns></returns>
-        public async Task Stop(bool force = false)
-        {
-            await _internalPlayer.Stop(force);
-        }
-
-        private void OnPlaybackFinished(object sender, EventArgs e)
-        {
-            PlaybackFinished?.Invoke(this, e);
-        }
-
-        /// <summary>
-        /// Sets the playing volume as percent
-        /// </summary>
-        /// <returns></returns>
-        public async Task SetVolume(byte percent)
-        {
-            await _internalPlayer.SetVolume(percent);
-        }
-
-        public void Dispose()
-        {
-            _internalPlayer.Dispose();
-        }
-    }
-}
diff --git a/ObservatoryHerald/NetCoreAudio/Players/LinuxPlayer.cs b/ObservatoryHerald/NetCoreAudio/Players/LinuxPlayer.cs
deleted file mode 100644
index 425b0e4..0000000
--- a/ObservatoryHerald/NetCoreAudio/Players/LinuxPlayer.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using System.IO;
-using System.Threading.Tasks;
-using NetCoreAudio.Interfaces;
-
-namespace NetCoreAudio.Players
-{
-    internal class LinuxPlayer : UnixPlayerBase, IPlayer
-    {
-        protected override string GetBashCommand(string fileName)
-        {
-            if (Path.GetExtension(fileName).ToLower().Equals(".mp3"))
-            {
-                return "mpg123 -q";
-            }
-            else
-            {
-                return "aplay -q";
-            }
-        }
-
-        public override Task SetVolume(byte percent)
-        {
-            if (percent > 100)
-                throw new ArgumentOutOfRangeException(nameof(percent), "Percent can't exceed 100");
-
-            var tempProcess = StartBashProcess($"amixer -M set 'Master' {percent}%");
-            tempProcess.WaitForExit();
-
-            return Task.CompletedTask;
-        }
-    }
-}
diff --git a/ObservatoryHerald/NetCoreAudio/Players/MacPlayer.cs b/ObservatoryHerald/NetCoreAudio/Players/MacPlayer.cs
deleted file mode 100644
index 708c8bc..0000000
--- a/ObservatoryHerald/NetCoreAudio/Players/MacPlayer.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using NetCoreAudio.Interfaces;
-
-namespace NetCoreAudio.Players
-{
-    internal class MacPlayer : UnixPlayerBase, IPlayer
-    {
-        protected override string GetBashCommand(string fileName)
-        {
-            return "afplay";
-        }
-
-        public override Task SetVolume(byte percent)
-        {
-            if (percent > 100)
-                throw new ArgumentOutOfRangeException(nameof(percent), "Percent can't exceed 100");
-
-            var tempProcess = StartBashProcess($"osascript -e \"set volume output volume {percent}\"");
-            tempProcess.WaitForExit();
-
-            return Task.CompletedTask;
-        }
-    }
-}
diff --git a/ObservatoryHerald/NetCoreAudio/Players/UnixPlayerBase.cs b/ObservatoryHerald/NetCoreAudio/Players/UnixPlayerBase.cs
deleted file mode 100644
index 32ce4cf..0000000
--- a/ObservatoryHerald/NetCoreAudio/Players/UnixPlayerBase.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-using NetCoreAudio.Interfaces;
-using System;
-using System.Diagnostics;
-using System.Threading.Tasks;
-
-namespace NetCoreAudio.Players
-{
-    internal abstract class UnixPlayerBase : IPlayer
-    {
-        private Process _process = null;
-
-        internal const string PauseProcessCommand = "kill -STOP {0}";
-        internal const string ResumeProcessCommand = "kill -CONT {0}";
-
-        public event EventHandler PlaybackFinished;
-
-        public bool Playing { get; private set; }
-
-        public bool Paused { get; private set; }
-
-        protected abstract string GetBashCommand(string fileName);
-
-        public async Task Play(string fileName)
-        {
-            await Stop();
-            var BashToolName = GetBashCommand(fileName);
-            _process = StartBashProcess($"{BashToolName} '{fileName}'");
-            _process.EnableRaisingEvents = true;
-            _process.Exited += HandlePlaybackFinished;
-            _process.ErrorDataReceived += HandlePlaybackFinished;
-            _process.Disposed += HandlePlaybackFinished;
-            Playing = true;
-        }
-
-        public Task Pause()
-        {
-            if (Playing && !Paused && _process != null)
-            {
-                var tempProcess = StartBashProcess(string.Format(PauseProcessCommand, _process.Id));
-                tempProcess.WaitForExit();
-                Paused = true;
-            }
-
-            return Task.CompletedTask;
-        }
-
-        public Task Resume()
-        {
-            if (Playing && Paused && _process != null)
-            {
-                var tempProcess = StartBashProcess(string.Format(ResumeProcessCommand, _process.Id));
-                tempProcess.WaitForExit();
-                Paused = false;
-            }
-
-            return Task.CompletedTask;
-        }
-
-        public Task Stop(bool force = false)
-        {
-            if (_process != null)
-            {
-                _process.Kill();
-                _process.Dispose();
-                _process = null;
-            }
-
-            Playing = false;
-            Paused = false;
-
-            return Task.CompletedTask;
-        }
-
-        protected Process StartBashProcess(string command)
-        {
-            var escapedArgs = command.Replace("\"", "\\\"");
-
-            var process = new Process()
-            {
-                StartInfo = new ProcessStartInfo
-                {
-                    FileName = "/bin/bash",
-                    Arguments = $"-c \"{escapedArgs}\"",
-                    RedirectStandardOutput = true,
-                    RedirectStandardInput = true,
-                    UseShellExecute = false,
-                    CreateNoWindow = true,
-                }
-            };
-            process.Start();
-            return process;
-        }
-
-        internal void HandlePlaybackFinished(object sender, EventArgs e)
-        {
-            if (Playing)
-            {
-                Playing = false;
-                PlaybackFinished?.Invoke(this, e);
-            }
-        }
-
-        public abstract Task SetVolume(byte percent);
-
-        public void Dispose()
-        {
-            Stop().Wait();
-        }
-    }
-}
diff --git a/ObservatoryHerald/NetCoreAudio/Players/WindowsPlayer.cs b/ObservatoryHerald/NetCoreAudio/Players/WindowsPlayer.cs
deleted file mode 100644
index c92c1ed..0000000
--- a/ObservatoryHerald/NetCoreAudio/Players/WindowsPlayer.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using NetCoreAudio.Interfaces;
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-using System.Timers;
-
-namespace NetCoreAudio.Players
-{
-    internal class WindowsPlayer : IPlayer
-    {
-        [DllImport("winmm.dll")]
-        private static extern int mciSendString(string command, StringBuilder stringReturn, int returnLength, IntPtr hwndCallback);
-
-		[DllImport("winmm.dll")]
-		private static extern int mciGetErrorString(int errorCode, StringBuilder errorText, int errorTextSize);
-
-        [DllImport("winmm.dll")]
-        public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
-
-		private System.Timers.Timer _playbackTimer;
-        private Stopwatch _playStopwatch;
-
-		private string _fileName;
-
-        public event EventHandler PlaybackFinished;
-
-        public bool Playing { get; private set; }
-        public bool Paused { get; private set; }
-
-        public Task Play(string fileName)
-        {
-            _fileName = $"\"{fileName}\"";
-            _playbackTimer = new System.Timers.Timer
-            {
-                AutoReset = false
-            };
-            _playStopwatch = new Stopwatch();
-            
-            ExecuteMciCommand($"Status {_fileName} Length");
-            ExecuteMciCommand($"Play {_fileName}");
-            Paused = false;
-            Playing = true;
-            _playbackTimer.Elapsed += HandlePlaybackFinished;
-            _playbackTimer.Start();
-            _playStopwatch.Start();
-
-            return Task.CompletedTask;
-        }
-
-        public Task Pause()
-        {
-            if (Playing && !Paused)
-            {
-                ExecuteMciCommand($"Pause {_fileName}");
-                Paused = true;
-                _playbackTimer.Stop();
-                _playStopwatch.Stop();
-                _playbackTimer.Interval -= _playStopwatch.ElapsedMilliseconds;
-            }
-
-            return Task.CompletedTask;
-        }
-
-        public Task Resume()
-        {
-            if (Playing && Paused)
-            {
-                ExecuteMciCommand($"Resume {_fileName}");
-                Paused = false;
-                _playbackTimer.Start();
-                _playStopwatch.Reset();
-                _playStopwatch.Start();
-            }
-            return Task.CompletedTask;
-        }
-
-        public Task Stop(bool force = false)
-        {
-            if (Playing || force)
-            {
-                ExecuteMciCommand($"Stop {_fileName}");
-				Playing = false;
-                Paused = false;
-                _playbackTimer?.Stop();
-                _playStopwatch?.Stop();
-            }
-            return Task.CompletedTask;
-        }
-
-		private void HandlePlaybackFinished(object sender, ElapsedEventArgs e)
-        {
-            Playing = false;
-            PlaybackFinished?.Invoke(this, e);
-            _playbackTimer?.Dispose();
-            _playbackTimer = null;
-        }
-
-        private Task ExecuteMciCommand(string commandString)
-        {
-            var sb = new StringBuilder();
-
-            var result = mciSendString(commandString, sb, 1024 * 1024, IntPtr.Zero);
-
-            if (result != 0)
-            {
-				var errorSb = new StringBuilder($"Error executing MCI command '{commandString}'. Error code: {result}.");
-				var sb2 = new StringBuilder(128);
-
-				mciGetErrorString(result, sb2, 128);
-				errorSb.Append($" Message: {sb2}");
-
-				throw new Exception(errorSb.ToString());
-            }
-
-            if (commandString.ToLower().StartsWith("status") && int.TryParse(sb.ToString(), out var length))
-                _playbackTimer.Interval = length + 75;
-
-            return Task.CompletedTask;
-        }
-
-        public Task SetVolume(byte percent)
-        {
-            // Calculate the volume that's being set
-            int NewVolume = ushort.MaxValue / 100 * percent;
-            // Set the same volume for both the left and the right channels
-            uint NewVolumeAllChannels = ((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16);
-            // Set the volume
-            waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
-
-            return Task.CompletedTask;
-        }
-
-        public void Dispose()
-        {
-            Stop().Wait();
-            ExecuteMciCommand("Close All");
-        }
-	}
-}
diff --git a/ObservatoryHerald/ObservatoryHerald.csproj b/ObservatoryHerald/ObservatoryHerald.csproj
index 312ef56..71c8d2b 100644
--- a/ObservatoryHerald/ObservatoryHerald.csproj
+++ b/ObservatoryHerald/ObservatoryHerald.csproj
@@ -37,12 +37,8 @@
     </EmbeddedResource>
   </ItemGroup>
 
-  <ItemGroup>
-    <Folder Include="NetCoreAudio\Players\" />
-  </ItemGroup>
-
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">
-    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)plugins\&quot; /y" />
+    <Exec Condition=" '$(OS)' == 'Windows_NT' " Command="xcopy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)..\ObservatoryCore\$(OutDir)..\net6.0-windows\plugins\&quot; /y" />
     <Exec Condition=" '$(OS)' != 'Windows_NT' " Command="[ ! -d &quot;$(ProjectDir)../ObservatoryCore/$(OutDir)plugins/deps&quot; ] &amp;&amp; mkdir -p &quot;$(ProjectDir)../ObservatoryCore/$(OutDir)plugins/deps&quot; || echo Directory already exists" />
   </Target>
   
diff --git a/README.md b/README.md
index e86f21d..b6198c8 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,12 @@
 # Elite Observatory *Core*
-Tool for reading/monitoring Elite Dangerous journals for interesting objects. Successor to the original Elite Observatory, rewritten from scratch using .NET 6.0 and AvaloniaUI.
+Tool for reading/monitoring Elite Dangerous journals for interesting objects. Successor to the original Elite Observatory, rewritten from scratch using .NET 6.0.
 
 ## *IMPORTANT*
-Observatory Core and it's associated plugins are currently in an alpha state and are neither feature-complete nor using a finalised UI. A major update to the UI is expected soon, which will likely break compatibility with all current plugins.
+Observatory Core and it's associated plugins are currently in a state of ongoing development and are neither feature-complete nor using a finalised UI.
 
 Omissions to current functionality include:
 * Integration with Frontier's Companion API
 * Data submission to IGAU
-* Sortable columns in plugin data grids
 * Non-grid plugin UI options
 * Light mode
 * *And more...*
@@ -32,8 +31,9 @@ If you want to chat or collaborate with other users of Observatory you can find
 For information on how to create a plugin, refer to this article about [ObservatoryFramework](https://github.com/Xjph/ObservatoryCore/wiki/Framework).
 
 ## Prerequisites for use
-.NET 6, and by extension one of its [supported OSes](https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md).
-(This will be installed automatically by the Observatory Core installer.)
+All you need is .NET 6, which should be installed automatically by the Observatory Core installer.
+
+The portable build has no prerequisites due to bundling the .NET runtime along with the program, though this does make the exe commensurately larger.
 
 ## Prerequisites for building
-C# 9.0, .NET 6.0, [AvaloniaUI ~~0.10.3~~](https://github.com/AvaloniaUI/Avalonia) (specific version in flux during UI rewrite), and of course [ObservatoryFramework](https://github.com/Xjph/ObservatoryFramework).
+C# 9.0, .NET 6.0, and [ObservatoryFramework](https://github.com/Xjph/ObservatoryFramework).
diff --git a/SignObservatory.ps1 b/SignObservatory.ps1
new file mode 100644
index 0000000..b9cab31
--- /dev/null
+++ b/SignObservatory.ps1
@@ -0,0 +1,39 @@
+$cert = Get-ChildItem Cert:\LocalMachine\My -CodeSigningCert
+Set-AuthenticodeSignature -FilePath ./ObservatoryCore/bin/Release/net6.0-windows/ObservatoryCore.exe -Certificate $cert
+Set-AuthenticodeSignature -FilePath ./ObservatoryCore/bin/Release/net6.0-windows/plugins/ObservatoryExplorer.dll -Certificate $cert
+Set-AuthenticodeSignature -FilePath ./ObservatoryCore/bin/Release/net6.0-windows/plugins/ObservatoryBotanist.dll -Certificate $cert
+Set-AuthenticodeSignature -FilePath ./ObservatoryCore/bin/Release/net6.0-windows/plugins/ObservatoryHerald.dll -Certificate $cert
+# SIG # Begin signature block
+# MIIF0AYJKoZIhvcNAQcCoIIFwTCCBb0CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
+# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
+# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUjqIsfdT62QvQPP+a5YOXVRCf
+# 3o6gggNKMIIDRjCCAi6gAwIBAgIQQbRFPs6oPodFBj0fsFanmzANBgkqhkiG9w0B
+# AQsFADA7MRgwFgYDVQQDDA9Kb25hdGhhbiBNaWxsZXIxHzAdBgkqhkiG9w0BCQEW
+# EGptaWxsZXJAeGpwaC5uZXQwHhcNMjMwMzI4MTgxNTM3WhcNMjQwMzI4MTgzNTM3
+# WjA7MRgwFgYDVQQDDA9Kb25hdGhhbiBNaWxsZXIxHzAdBgkqhkiG9w0BCQEWEGpt
+# aWxsZXJAeGpwaC5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
+# eeKY2sY4SAMLgjE+sm1lj8Tje5QArsuSqLFC0gpWzHFq2HZYHLGR5l9Kz1Jm4iNm
+# bdkQiEtt5o6e48L2GLqftM0XklmkNVzyuj6SqL99K1JCuO/kLRVorqRV/88NpOOe
+# Bpn1W5FTA7m1PVCYXbz3a6l93hNY6mI4yb9MV8nKFDnmmAtiwIsKgXuNf81sU8bg
+# 4A7mB9A7Jgvx1/Gs7rFu0m1qWIGpfhsh8EQtpJaiVvzCBqdpIvDEnMwlVd6S0nkj
+# jCCB7s12oiXKYjBS1Vm1YfwoaPkHe9E+z7zgHnhZ5hrTt8g/TZM+cS2o+5JQYTr9
+# RZUjQ3EmsUfZMAuSekERAgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE
+# DDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUCeFpbq5cQi1Z5DQydkmiF8MIfyMwDQYJ
+# KoZIhvcNAQELBQADggEBAHF/lRtemEggwTFiwTI01Z3erV6YGNT2miD4NrUrnQEe
+# kI+Ezh/MLj2vRmqeVz7XX1ePZX0sd7sViRMnPm+LTl8UltZqhTWV/h7qmi/2Vf74
+# QHLE/Ht3olWBdGOVzeeP5XLMBqqg7HWPHGpTA8lx0ApI4YhYu7w/SgwzYUj2NF2O
+# GRmV78kcHeYf+h5lZzAKjc+dgH+ucsqpKgDxCk8lBhUkd102YGMUZophz0L8RTD4
+# k/CAliVZo3m8ENsR6pMnjsgifeZ8Q9ydpBXawIdcqW9xtZanvYN9+GAHMYeFWWBf
+# 0fBcoPAy4X5bcvQmK/0d7znpgDmgm4jYywF5ptHXoAIxggHwMIIB7AIBATBPMDsx
+# GDAWBgNVBAMMD0pvbmF0aGFuIE1pbGxlcjEfMB0GCSqGSIb3DQEJARYQam1pbGxl
+# ckB4anBoLm5ldAIQQbRFPs6oPodFBj0fsFanmzAJBgUrDgMCGgUAoHgwGAYKKwYB
+# BAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAc
+# BgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUfXa2
+# HgFmPrFbD6PqO1Z7s6yzLkowDQYJKoZIhvcNAQEBBQAEggEASEcYW2MnOLX+dMin
+# lEVxL8fTOrf/XuE05QwqQSHOBqqO4GMuR+IeBjE2R4EjxQsZMQVok1dK302ByHA9
+# OVv37xG4exqP/vkP3NX/z2s1Cl2PE1gzxVNgdGlbkzIQF9EiMXr9P/QGifCg2TLV
+# 2mk4Vt+mA1/tU066tNXahbL9N9b+yLcB3VNfru/SnvO/ZPzKCmjNZW54mnNKnRCE
+# PJDVKEKla/ufh8iMR+SiIaaXrwypvdz8CYK9OSs9qr0Cjp9jY1TXLxgNZiTenUoY
+# n+sVQzv+N1PAy2nvSXlnesbxlO3T2XPp6fYkpj1uYCoun3Ztpr2MoKRKBgzybo7Z
+# GYn3QA==
+# SIG # End signature block
diff --git a/buildAllComponents b/buildAllComponents
deleted file mode 100755
index dfe5b86..0000000
--- a/buildAllComponents
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-dotnet build ./ObservatoryFramework/ObservatoryFramework.csproj "$@"
-dotnet build ./ObservatoryExplorer/ObservatoryExplorer.csproj "$@"
-dotnet build ./ObservatoryBotanist/ObservatoryBotanist.csproj "$@"
-if [ -f ../NetCoreAudio/NetCoreAudio/NetCoreAudio.csproj ]; then
-    dotnet build ../NetCoreAudio/NetCoreAudio/NetCoreAudio.csproj -c Release
-    dotnet build ./ObservatoryHerald/ObservatoryHerald.csproj "$@"
-fi
diff --git a/buildAllComponents.cmd b/buildAllComponents.cmd
deleted file mode 100644
index 0102a06..0000000
--- a/buildAllComponents.cmd
+++ /dev/null
@@ -1,7 +0,0 @@
-dotnet build ./ObservatoryFramework/ObservatoryFramework.csproj %*
-dotnet build ./ObservatoryExplorer/ObservatoryExplorer.csproj %*
-dotnet build ./ObservatoryBotanist/ObservatoryBotanist.csproj %*
-IF EXIST ..\NetCoreAudio\NetCoreAudio\NetCoreAudio.csproj (
-    dotnet build ../NetCoreAudio/NetCoreAudio/NetCoreAudio.csproj -c Release
-    dotnet build ./ObservatoryHerald/ObservatoryHerald.csproj %* 
-)

From 59da2f783b551c553033f8be10f2538d0691df3b Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Sun, 21 Jan 2024 14:11:07 -0330
Subject: [PATCH 07/18] wire up donate and github links

---
 ObservatoryCore/UI/CoreForm.Designer.cs |  2 ++
 ObservatoryCore/UI/CoreForm.cs          | 26 ++++++++++++++++++++-----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/ObservatoryCore/UI/CoreForm.Designer.cs b/ObservatoryCore/UI/CoreForm.Designer.cs
index 7d04d49..0c28ce6 100644
--- a/ObservatoryCore/UI/CoreForm.Designer.cs
+++ b/ObservatoryCore/UI/CoreForm.Designer.cs
@@ -557,6 +557,7 @@
             GithubLink.TabIndex = 6;
             GithubLink.TabStop = true;
             GithubLink.Text = "github";
+            GithubLink.LinkClicked += GithubLink_LinkClicked;
             // 
             // DonateLink
             // 
@@ -568,6 +569,7 @@
             DonateLink.TabIndex = 7;
             DonateLink.TabStop = true;
             DonateLink.Text = "Donate";
+            DonateLink.LinkClicked += DonateLink_LinkClicked;
             // 
             // CoreForm
             // 
diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
index 9698031..7e76e76 100644
--- a/ObservatoryCore/UI/CoreForm.cs
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -2,6 +2,7 @@
 using Observatory.Framework.Interfaces;
 using Observatory.PluginManagement;
 using Observatory.Utils;
+using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Windows.Forms;
@@ -45,7 +46,7 @@ namespace Observatory.UI
                 { coreToolStripMenuItem, CorePanel }
             };
 
-            
+
             pluginList = new Dictionary<string, ToolStripMenuItem>();
             CreatePluginTabs();
             DisableOverriddenNotification();
@@ -87,7 +88,7 @@ namespace Observatory.UI
 
         private void ResizePanels(Point location, int widthChange)
         {
-            
+
             CorePanel.Location = location;
             CorePanel.Width += widthChange;
             foreach (var panel in uiPanels)
@@ -98,7 +99,7 @@ namespace Observatory.UI
                     panel.Value.Size = CorePanel.Size;
                 }
             }
-            
+
         }
 
         private void CoreMenu_ItemClicked(object? _, ToolStripItemClickedEventArgs e)
@@ -152,7 +153,7 @@ namespace Observatory.UI
 
         private void SetClickedItem(ToolStripItem item)
         {
-            foreach (ToolStripItem menuItem in CoreMenu.Items) 
+            foreach (ToolStripItem menuItem in CoreMenu.Items)
             {
                 bool bold = menuItem == item;
                 menuItem.Font = new Font(menuItem.Font, bold ? FontStyle.Bold : FontStyle.Regular);
@@ -223,7 +224,7 @@ namespace Observatory.UI
             var readAllDialogue = new ReadAllForm();
             ThemeManager.GetInstance.RegisterControl(readAllDialogue);
             readAllDialogue.StartPosition = FormStartPosition.Manual;
-            readAllDialogue.Location = Point.Add(Location, new Size(100,100));
+            readAllDialogue.Location = Point.Add(Location, new Size(100, 100));
             readAllDialogue.ShowDialog();
         }
 
@@ -296,5 +297,20 @@ namespace Observatory.UI
 
             nativePopup.InvokeNativeNotification(args);
         }
+
+        private void GithubLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+        {
+            OpenURL("https://github.com/Xjph/ObservatoryCore");
+        }
+
+        private void DonateLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+        {
+            OpenURL("https://www.paypal.com/paypalme/eliteobservatory");
+        }
+
+        private void OpenURL(string url)
+        {
+            Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
+        }
     }
 }
\ No newline at end of file

From 2e3cfc8f6b2ba8cc6318a0160f7e3c1fc423d587 Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Sun, 21 Jan 2024 15:57:48 -0330
Subject: [PATCH 08/18] add `collidedWithDamage` crime type

---
 ObservatoryFramework/Files/ParameterTypes/Enumerations.cs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ObservatoryFramework/Files/ParameterTypes/Enumerations.cs b/ObservatoryFramework/Files/ParameterTypes/Enumerations.cs
index b47cfc8..25cbb8f 100644
--- a/ObservatoryFramework/Files/ParameterTypes/Enumerations.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/Enumerations.cs
@@ -82,7 +82,8 @@ namespace Observatory.Framework.Files.ParameterTypes
         onFoot_failureToSubmitToPolice,
         onfoot_dataTransfer,
         onFoot_carryingStolenGoods,
-        onFoot_eBreachUse
+        onFoot_eBreachUse,
+        collidedWithDamage
     }
 
     public enum LimpetDrone

From cfeb7160646039d338a470330ad06ab95e7a0e96 Mon Sep 17 00:00:00 2001
From: Fred K <mr.fredk@gmail.com>
Date: Mon, 22 Jan 2024 00:16:00 -0500
Subject: [PATCH 09/18] [ObservatoryCore] UI tweaks

Polishing a few rough edges:
* Enable scrolling on the Plugin List view. It only fit 6 or 7. I have 13.
* I fiddled a bit with column auto-sizing (left it commented out, see comment).
* A whole bunch of tweaks to the settings view:
  * first row of controls was cut off at the top (under the window title bar)
  * fixing that revealed uneven spacing between columns
  * action buttons were teensy tiny and unreadable
  * settings view columns were too narrow (200 px).
  * added some spacing to help with readability
  * settings windows now start in center of current screen rather than some random place.
---
 ObservatoryCore/UI/CoreForm.Designer.cs     |  1 -
 ObservatoryCore/UI/CoreForm.cs              |  6 +++
 ObservatoryCore/UI/SettingsForm.Designer.cs |  3 +-
 ObservatoryCore/UI/SettingsForm.cs          | 42 +++++++++++++--------
 4 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/ObservatoryCore/UI/CoreForm.Designer.cs b/ObservatoryCore/UI/CoreForm.Designer.cs
index 0c28ce6..826d0a1 100644
--- a/ObservatoryCore/UI/CoreForm.Designer.cs
+++ b/ObservatoryCore/UI/CoreForm.Designer.cs
@@ -471,7 +471,6 @@
             PluginList.MultiSelect = false;
             PluginList.Name = "PluginList";
             PluginList.OwnerDraw = true;
-            PluginList.Scrollable = false;
             PluginList.Size = new Size(659, 137);
             PluginList.TabIndex = 0;
             PluginList.UseCompatibleStateImageBehavior = false;
diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
index 7e76e76..e0c964f 100644
--- a/ObservatoryCore/UI/CoreForm.cs
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -212,6 +212,12 @@ namespace Observatory.UI
 
         private void FitColumns()
         {
+            // This sizes to fit the column width to the text. However, when the listview is resized (by
+            // expanding setting sections below the list), it causes flashing/jank. Visually, it looks cleaner
+            // (because the default column sizes are too small) and helps avoid horizontal scrollbar.
+            //foreach (ColumnHeader col in PluginList.Columns)
+            //    col.Width = -2;
+
             int totalWidth = 0;
             foreach (ColumnHeader col in PluginList.Columns)
                 totalWidth += col.Width;
diff --git a/ObservatoryCore/UI/SettingsForm.Designer.cs b/ObservatoryCore/UI/SettingsForm.Designer.cs
index b661275..8566b21 100644
--- a/ObservatoryCore/UI/SettingsForm.Designer.cs
+++ b/ObservatoryCore/UI/SettingsForm.Designer.cs
@@ -1,4 +1,4 @@
-namespace Observatory.UI
+namespace Observatory.UI
 {
     partial class SettingsForm
     {
@@ -50,6 +50,7 @@
             Controls.Add(PluginSettingsCloseButton);
             FormBorderStyle = FormBorderStyle.FixedSingle;
             Name = "SettingsForm";
+            StartPosition = FormStartPosition.CenterScreen;
             Text = "SettingsForm";
             ResumeLayout(false);
         }
diff --git a/ObservatoryCore/UI/SettingsForm.cs b/ObservatoryCore/UI/SettingsForm.cs
index 20a74f4..f05f38c 100644
--- a/ObservatoryCore/UI/SettingsForm.cs
+++ b/ObservatoryCore/UI/SettingsForm.cs
@@ -18,6 +18,7 @@ namespace Observatory.UI
     {
         private readonly IObservatoryPlugin _plugin;
         private readonly List<int> _colHeight = new List<int>();
+        private int _colWidth = 400;
 
         public SettingsForm(IObservatoryPlugin plugin)
         {
@@ -51,16 +52,18 @@ namespace Observatory.UI
             foreach (var setting in settings)
             {
                 // Reset the column tracking for checkboxes if this isn't a checkbox
+                int addedHeight = 35;
                 if (setting.Key.PropertyType.Name != "Boolean")
+                {
+                    if (recentHalfCol) _colHeight.Add(addedHeight);
                     recentHalfCol = false;
-
-                int addedHeight = 29;
+                }
 
                 switch (setting.Key.GetValue(_plugin.Settings))
                 {
                     case bool:
                         var checkBox = CreateBoolSetting(setting);
-                        addedHeight = recentHalfCol ? 0 : addedHeight;
+                        addedHeight = recentHalfCol ? addedHeight : 0;
                         checkBox.Location = GetSettingPosition(recentHalfCol);
 
                         recentHalfCol = !recentHalfCol;
@@ -111,7 +114,7 @@ namespace Observatory.UI
                         intLabel.Location = GetSettingPosition();
                         intControl.Location = GetSettingPosition(true);
 
-                        addedHeight = intControl.Height;
+                        addedHeight = intControl.Height + 2;
                         intLabel.Height = intControl.Height;
                         intLabel.TextAlign = ContentAlignment.MiddleRight;
 
@@ -125,6 +128,7 @@ namespace Observatory.UI
                         button.Location = GetSettingPosition();
 
                         Controls.Add(button);
+                        addedHeight = button.Height;
                         trackBottomEdge(button);
                         break;
                     case Dictionary<string, object> dictSetting:
@@ -142,12 +146,14 @@ namespace Observatory.UI
                 }
                 _colHeight.Add(addedHeight);
             }
-            Height = settingsHeight + 80;
+            Height = settingsHeight + 160;
+            Width = _colWidth * 2 + 80;
         }
 
         private Point GetSettingPosition(bool secondCol = false)
         {
-            return new Point(10 + (secondCol ? 200 : 0), -26 + _colHeight.Sum());
+            //return new Point(10 + (secondCol ? 200 : 0), -26 + _colHeight.Sum());
+            return new Point(10 + (secondCol ? _colWidth : 0), 15 + _colHeight.Sum());
         }
 
 
@@ -157,7 +163,7 @@ namespace Observatory.UI
             {
                 Text = settingName + ": ",
                 TextAlign = System.Drawing.ContentAlignment.MiddleRight,
-                Width = 200,
+                Width = _colWidth,
                 ForeColor = Color.LightGray
             };
 
@@ -177,7 +183,7 @@ namespace Observatory.UI
 
             ComboBox comboBox = new()
             {
-                Width = 200,
+                Width = _colWidth,
                 DropDownStyle = ComboBoxStyle.DropDownList
             };
 
@@ -203,7 +209,9 @@ namespace Observatory.UI
         {
             Button button = new()
             {
-                Text = settingName
+                Text = settingName,
+                Width = Convert.ToInt32(_colWidth * 0.8),
+                Height = 35,
             };
 
             button.Click += (sender, e) =>
@@ -229,7 +237,7 @@ namespace Observatory.UI
                 Orientation = Orientation.Horizontal,
                 TickStyle = TickStyle.Both,
                 TickFrequency = tickFrequency,
-                Width = 200,
+                Width = _colWidth,
                 Minimum = minBound,
                 Maximum = maxBound,
             };
@@ -250,8 +258,7 @@ namespace Observatory.UI
             SettingNumericBounds? bounds = (SettingNumericBounds?)System.Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
             NumericUpDown numericUpDown = new()
             {
-
-                Width = 200,
+                Width = _colWidth,
                 Minimum = Convert.ToInt32(bounds?.Minimum ?? Int32.MinValue),
                 Maximum = Convert.ToInt32(bounds?.Maximum ?? Int32.MaxValue),
                 Increment = Convert.ToInt32(bounds?.Increment ?? 1)
@@ -275,7 +282,8 @@ namespace Observatory.UI
                 Text = setting.Value,
                 TextAlign = System.Drawing.ContentAlignment.MiddleLeft,
                 Checked = (bool?)setting.Key.GetValue(_plugin.Settings) ?? false,
-                Width = 200,
+                Height = 30,
+                Width = _colWidth,
                 ForeColor = Color.LightGray
             };
 
@@ -293,7 +301,7 @@ namespace Observatory.UI
             TextBox textBox = new()
             {
                 Text = (setting.GetValue(_plugin.Settings) ?? String.Empty).ToString(),
-                Width = 200
+                Width = _colWidth,
             };
 
             textBox.TextChanged += (object? sender, EventArgs e) =>
@@ -312,7 +320,7 @@ namespace Observatory.UI
             TextBox textBox = new()
             {
                 Text = fileInfo?.FullName ?? string.Empty,
-                Width = 200
+                Width = _colWidth,
             };
 
             textBox.TextChanged += (object? sender, EventArgs e) =>
@@ -328,7 +336,9 @@ namespace Observatory.UI
         {
             Button button = new()
             {
-                Text = "Browse"
+                Text = "Browse",
+                Height = 35,
+                Width = _colWidth / 2,
             };
 
             button.Click += (object? sender, EventArgs e) =>

From 5257527c51906a7b1933a30902885ebf62d30166 Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Mon, 22 Jan 2024 08:59:04 -0330
Subject: [PATCH 10/18] suspend main window draw during read all

---
 ObservatoryCore/UI/CoreForm.cs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
index 7e76e76..5cb93d8 100644
--- a/ObservatoryCore/UI/CoreForm.cs
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -225,7 +225,9 @@ namespace Observatory.UI
             ThemeManager.GetInstance.RegisterControl(readAllDialogue);
             readAllDialogue.StartPosition = FormStartPosition.Manual;
             readAllDialogue.Location = Point.Add(Location, new Size(100, 100));
+            SuspendDrawing(this);
             readAllDialogue.ShowDialog();
+            ResumeDrawing(this);
         }
 
         private void PopupNotificationLabel_Click(object _, EventArgs e)

From d061275e36ca9ae4558265c950f2d701bdb3a4de Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Mon, 22 Jan 2024 09:19:19 -0330
Subject: [PATCH 11/18] missing crime types

---
 ObservatoryFramework/Files/ParameterTypes/Enumerations.cs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ObservatoryFramework/Files/ParameterTypes/Enumerations.cs b/ObservatoryFramework/Files/ParameterTypes/Enumerations.cs
index 25cbb8f..aa2e938 100644
--- a/ObservatoryFramework/Files/ParameterTypes/Enumerations.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/Enumerations.cs
@@ -83,6 +83,8 @@ namespace Observatory.Framework.Files.ParameterTypes
         onfoot_dataTransfer,
         onFoot_carryingStolenGoods,
         onFoot_eBreachUse,
+        onFoot_breakingAndEntering,
+        shuttleDestruction,
         collidedWithDamage
     }
 

From dce2516414a4968148f209b6b79e26e9614a4242 Mon Sep 17 00:00:00 2001
From: F K <54195004+fredjk-gh@users.noreply.github.com>
Date: Mon, 22 Jan 2024 18:59:31 -0500
Subject: [PATCH 12/18] [Observatory Core] New UI tweaks round 1 (#128) Plus
 merging #119 from main onto this branch

* [Framework] Add a DateTime property for CarrierJumpRequest DepartureTime (#119)

Refactored out the logic backing the JournalBase TimestampDateTime property so it can be used for any DateTime type property, providing a standardized json String -> DateTime conversion for any date-time property. Implemented as an `internal static` method on JournalBase so journal objects which inherit from JournalBase or don't inherit from it can use it.

Used this to provide a DepatureTimeDateTime on CarrierJumpRequest (this property was added in Update 14) and to implement the existing ExpiryDateTime on CurrentGoal.

From a quick search in the journal documentation, I don't see any other applications for this.

* [ObservatoryCore] UI tweaks

Polishing a few rough edges:
* Enable scrolling on the Plugin List view. It only fit 6 or 7. I have 13.
* I fiddled a bit with column auto-sizing (left it commented out, see comment).
* A whole bunch of tweaks to the settings view:
  * first row of controls was cut off at the top (under the window title bar)
  * fixing that revealed uneven spacing between columns
  * action buttons were teensy tiny and unreadable
  * settings view columns were too narrow (200 px).
  * added some spacing to help with readability
  * settings windows now start in center of current screen rather than some random place.
---
 ObservatoryCore/UI/CoreForm.Designer.cs       |  1 -
 ObservatoryCore/UI/CoreForm.cs                |  6 +++
 ObservatoryCore/UI/SettingsForm.Designer.cs   |  3 +-
 ObservatoryCore/UI/SettingsForm.cs            | 42 ++++++++++++-------
 .../FleetCarrier/CarrierJumpRequest.cs        |  9 +++-
 .../Files/Journal/JournalBase.cs              | 17 ++++++--
 .../Files/ParameterTypes/CurrentGoal.cs       | 13 +-----
 7 files changed, 57 insertions(+), 34 deletions(-)

diff --git a/ObservatoryCore/UI/CoreForm.Designer.cs b/ObservatoryCore/UI/CoreForm.Designer.cs
index 0c28ce6..826d0a1 100644
--- a/ObservatoryCore/UI/CoreForm.Designer.cs
+++ b/ObservatoryCore/UI/CoreForm.Designer.cs
@@ -471,7 +471,6 @@
             PluginList.MultiSelect = false;
             PluginList.Name = "PluginList";
             PluginList.OwnerDraw = true;
-            PluginList.Scrollable = false;
             PluginList.Size = new Size(659, 137);
             PluginList.TabIndex = 0;
             PluginList.UseCompatibleStateImageBehavior = false;
diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
index 5cb93d8..c559d9b 100644
--- a/ObservatoryCore/UI/CoreForm.cs
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -212,6 +212,12 @@ namespace Observatory.UI
 
         private void FitColumns()
         {
+            // This sizes to fit the column width to the text. However, when the listview is resized (by
+            // expanding setting sections below the list), it causes flashing/jank. Visually, it looks cleaner
+            // (because the default column sizes are too small) and helps avoid horizontal scrollbar.
+            //foreach (ColumnHeader col in PluginList.Columns)
+            //    col.Width = -2;
+
             int totalWidth = 0;
             foreach (ColumnHeader col in PluginList.Columns)
                 totalWidth += col.Width;
diff --git a/ObservatoryCore/UI/SettingsForm.Designer.cs b/ObservatoryCore/UI/SettingsForm.Designer.cs
index b661275..8566b21 100644
--- a/ObservatoryCore/UI/SettingsForm.Designer.cs
+++ b/ObservatoryCore/UI/SettingsForm.Designer.cs
@@ -1,4 +1,4 @@
-namespace Observatory.UI
+namespace Observatory.UI
 {
     partial class SettingsForm
     {
@@ -50,6 +50,7 @@
             Controls.Add(PluginSettingsCloseButton);
             FormBorderStyle = FormBorderStyle.FixedSingle;
             Name = "SettingsForm";
+            StartPosition = FormStartPosition.CenterScreen;
             Text = "SettingsForm";
             ResumeLayout(false);
         }
diff --git a/ObservatoryCore/UI/SettingsForm.cs b/ObservatoryCore/UI/SettingsForm.cs
index 20a74f4..f05f38c 100644
--- a/ObservatoryCore/UI/SettingsForm.cs
+++ b/ObservatoryCore/UI/SettingsForm.cs
@@ -18,6 +18,7 @@ namespace Observatory.UI
     {
         private readonly IObservatoryPlugin _plugin;
         private readonly List<int> _colHeight = new List<int>();
+        private int _colWidth = 400;
 
         public SettingsForm(IObservatoryPlugin plugin)
         {
@@ -51,16 +52,18 @@ namespace Observatory.UI
             foreach (var setting in settings)
             {
                 // Reset the column tracking for checkboxes if this isn't a checkbox
+                int addedHeight = 35;
                 if (setting.Key.PropertyType.Name != "Boolean")
+                {
+                    if (recentHalfCol) _colHeight.Add(addedHeight);
                     recentHalfCol = false;
-
-                int addedHeight = 29;
+                }
 
                 switch (setting.Key.GetValue(_plugin.Settings))
                 {
                     case bool:
                         var checkBox = CreateBoolSetting(setting);
-                        addedHeight = recentHalfCol ? 0 : addedHeight;
+                        addedHeight = recentHalfCol ? addedHeight : 0;
                         checkBox.Location = GetSettingPosition(recentHalfCol);
 
                         recentHalfCol = !recentHalfCol;
@@ -111,7 +114,7 @@ namespace Observatory.UI
                         intLabel.Location = GetSettingPosition();
                         intControl.Location = GetSettingPosition(true);
 
-                        addedHeight = intControl.Height;
+                        addedHeight = intControl.Height + 2;
                         intLabel.Height = intControl.Height;
                         intLabel.TextAlign = ContentAlignment.MiddleRight;
 
@@ -125,6 +128,7 @@ namespace Observatory.UI
                         button.Location = GetSettingPosition();
 
                         Controls.Add(button);
+                        addedHeight = button.Height;
                         trackBottomEdge(button);
                         break;
                     case Dictionary<string, object> dictSetting:
@@ -142,12 +146,14 @@ namespace Observatory.UI
                 }
                 _colHeight.Add(addedHeight);
             }
-            Height = settingsHeight + 80;
+            Height = settingsHeight + 160;
+            Width = _colWidth * 2 + 80;
         }
 
         private Point GetSettingPosition(bool secondCol = false)
         {
-            return new Point(10 + (secondCol ? 200 : 0), -26 + _colHeight.Sum());
+            //return new Point(10 + (secondCol ? 200 : 0), -26 + _colHeight.Sum());
+            return new Point(10 + (secondCol ? _colWidth : 0), 15 + _colHeight.Sum());
         }
 
 
@@ -157,7 +163,7 @@ namespace Observatory.UI
             {
                 Text = settingName + ": ",
                 TextAlign = System.Drawing.ContentAlignment.MiddleRight,
-                Width = 200,
+                Width = _colWidth,
                 ForeColor = Color.LightGray
             };
 
@@ -177,7 +183,7 @@ namespace Observatory.UI
 
             ComboBox comboBox = new()
             {
-                Width = 200,
+                Width = _colWidth,
                 DropDownStyle = ComboBoxStyle.DropDownList
             };
 
@@ -203,7 +209,9 @@ namespace Observatory.UI
         {
             Button button = new()
             {
-                Text = settingName
+                Text = settingName,
+                Width = Convert.ToInt32(_colWidth * 0.8),
+                Height = 35,
             };
 
             button.Click += (sender, e) =>
@@ -229,7 +237,7 @@ namespace Observatory.UI
                 Orientation = Orientation.Horizontal,
                 TickStyle = TickStyle.Both,
                 TickFrequency = tickFrequency,
-                Width = 200,
+                Width = _colWidth,
                 Minimum = minBound,
                 Maximum = maxBound,
             };
@@ -250,8 +258,7 @@ namespace Observatory.UI
             SettingNumericBounds? bounds = (SettingNumericBounds?)System.Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
             NumericUpDown numericUpDown = new()
             {
-
-                Width = 200,
+                Width = _colWidth,
                 Minimum = Convert.ToInt32(bounds?.Minimum ?? Int32.MinValue),
                 Maximum = Convert.ToInt32(bounds?.Maximum ?? Int32.MaxValue),
                 Increment = Convert.ToInt32(bounds?.Increment ?? 1)
@@ -275,7 +282,8 @@ namespace Observatory.UI
                 Text = setting.Value,
                 TextAlign = System.Drawing.ContentAlignment.MiddleLeft,
                 Checked = (bool?)setting.Key.GetValue(_plugin.Settings) ?? false,
-                Width = 200,
+                Height = 30,
+                Width = _colWidth,
                 ForeColor = Color.LightGray
             };
 
@@ -293,7 +301,7 @@ namespace Observatory.UI
             TextBox textBox = new()
             {
                 Text = (setting.GetValue(_plugin.Settings) ?? String.Empty).ToString(),
-                Width = 200
+                Width = _colWidth,
             };
 
             textBox.TextChanged += (object? sender, EventArgs e) =>
@@ -312,7 +320,7 @@ namespace Observatory.UI
             TextBox textBox = new()
             {
                 Text = fileInfo?.FullName ?? string.Empty,
-                Width = 200
+                Width = _colWidth,
             };
 
             textBox.TextChanged += (object? sender, EventArgs e) =>
@@ -328,7 +336,9 @@ namespace Observatory.UI
         {
             Button button = new()
             {
-                Text = "Browse"
+                Text = "Browse",
+                Height = 35,
+                Width = _colWidth / 2,
             };
 
             button.Click += (object? sender, EventArgs e) =>
diff --git a/ObservatoryFramework/Files/Journal/FleetCarrier/CarrierJumpRequest.cs b/ObservatoryFramework/Files/Journal/FleetCarrier/CarrierJumpRequest.cs
index d88d086..c7429e5 100644
--- a/ObservatoryFramework/Files/Journal/FleetCarrier/CarrierJumpRequest.cs
+++ b/ObservatoryFramework/Files/Journal/FleetCarrier/CarrierJumpRequest.cs
@@ -1,4 +1,6 @@
-namespace Observatory.Framework.Files.Journal
+using System.Text.Json.Serialization;
+
+namespace Observatory.Framework.Files.Journal
 {
     public class CarrierJumpRequest : JournalBase
     {
@@ -9,5 +11,10 @@
         public string SystemName { get; init; }
         public ulong SystemID { get; init; }
         public string DepartureTime { get; init; }
+
+        [JsonIgnore]
+        public DateTime DepartureTimeDateTime {
+            get => ParseDateTime(DepartureTime);
+        }
     }
 }
diff --git a/ObservatoryFramework/Files/Journal/JournalBase.cs b/ObservatoryFramework/Files/Journal/JournalBase.cs
index 3d53e91..289bcb4 100644
--- a/ObservatoryFramework/Files/Journal/JournalBase.cs
+++ b/ObservatoryFramework/Files/Journal/JournalBase.cs
@@ -12,10 +12,7 @@ namespace Observatory.Framework.Files.Journal
         [JsonIgnore]
         public DateTime TimestampDateTime
         {
-            get
-            {
-                return DateTime.ParseExact(Timestamp, "yyyy-MM-ddTHH:mm:ssZ", null, System.Globalization.DateTimeStyles.AssumeUniversal);
-            }
+            get => ParseDateTime(Timestamp);
         }
 
         [JsonPropertyName("event")]
@@ -43,5 +40,17 @@ namespace Observatory.Framework.Files.Journal
 
         private string json;
 
+        // For use by Journal object classes for .*DateTime properties, like TimestampeDateTime, above.
+        internal static DateTime ParseDateTime(string value)
+        {
+            if (DateTime.TryParseExact(value, "yyyy-MM-ddTHH:mm:ssZ", null, System.Globalization.DateTimeStyles.AssumeUniversal, out DateTime dateTimeValue))
+            {
+                return dateTimeValue;
+            }
+            else
+            {
+                return new DateTime();
+            }
+        }
     }
 }
diff --git a/ObservatoryFramework/Files/ParameterTypes/CurrentGoal.cs b/ObservatoryFramework/Files/ParameterTypes/CurrentGoal.cs
index 4e92e3a..fe00418 100644
--- a/ObservatoryFramework/Files/ParameterTypes/CurrentGoal.cs
+++ b/ObservatoryFramework/Files/ParameterTypes/CurrentGoal.cs
@@ -1,4 +1,5 @@
 using Microsoft.VisualBasic.CompilerServices;
+using Observatory.Framework.Files.Journal;
 using System;
 using System.Numerics;
 
@@ -13,17 +14,7 @@ namespace Observatory.Framework.Files.ParameterTypes
         public string Expiry { get; init; }
         public DateTime ExpiryDateTime
         {
-            get
-            {
-                if (DateTime.TryParseExact(Expiry, "yyyy-MM-ddTHH:mm:ssZ", null, System.Globalization.DateTimeStyles.AssumeUniversal, out DateTime expiryDateTime))
-                {
-                    return expiryDateTime;
-                }
-                else
-                {
-                    return new DateTime();
-                }
-            }
+            get => JournalBase.ParseDateTime(Expiry);
         }
         public bool IsComplete { get; init; }
         public long CurrentTotal { get; init; }

From 95d0a28004bb7a0b57bf1f70e236886331a1b71e Mon Sep 17 00:00:00 2001
From: F K <54195004+fredjk-gh@users.noreply.github.com>
Date: Tue, 23 Jan 2024 19:21:02 -0500
Subject: [PATCH 13/18] [Core] Improve(?) Plugin List column sizing (#133)

After populating the list of plugins, auto-size the columns once. In the Resize event handler, do what you did before but account for the scrollbar width too. Prevents horizontal scrollbar appearing except for really fast resize movements.

I didn't try it yet with fewer than a scrollable # of plugins yet.

This cleans up my commented out code from #128.
---
 ObservatoryCore/UI/CoreForm.Plugins.cs | 3 +++
 ObservatoryCore/UI/CoreForm.cs         | 8 +-------
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/ObservatoryCore/UI/CoreForm.Plugins.cs b/ObservatoryCore/UI/CoreForm.Plugins.cs
index cd7d73a..640d7c8 100644
--- a/ObservatoryCore/UI/CoreForm.Plugins.cs
+++ b/ObservatoryCore/UI/CoreForm.Plugins.cs
@@ -32,6 +32,9 @@ namespace Observatory.UI
                     PluginList.Items.Add(item);
                 }
             }
+
+            PluginList.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
+            PluginList.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
         }
 
         private static string PluginStatusString(PluginManager.PluginStatus status)
diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
index c559d9b..9019222 100644
--- a/ObservatoryCore/UI/CoreForm.cs
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -212,17 +212,11 @@ namespace Observatory.UI
 
         private void FitColumns()
         {
-            // This sizes to fit the column width to the text. However, when the listview is resized (by
-            // expanding setting sections below the list), it causes flashing/jank. Visually, it looks cleaner
-            // (because the default column sizes are too small) and helps avoid horizontal scrollbar.
-            //foreach (ColumnHeader col in PluginList.Columns)
-            //    col.Width = -2;
-
             int totalWidth = 0;
             foreach (ColumnHeader col in PluginList.Columns)
                 totalWidth += col.Width;
 
-            PluginList.Columns[3].Width += PluginList.Width - totalWidth;
+            PluginList.Columns[3].Width += PluginList.Width - totalWidth - 1 - SystemInformation.VerticalScrollBarWidth;
         }
 
         private void ReadAllButton_Click(object sender, EventArgs e)

From 6143d4bd2c6baf9013469b2a5ff3caecf331901b Mon Sep 17 00:00:00 2001
From: F K <54195004+fredjk-gh@users.noreply.github.com>
Date: Tue, 23 Jan 2024 19:34:49 -0500
Subject: [PATCH 14/18] [Herald] Force Herald to act as NativeVocal
 notification target (#132)

This makes Herald, a plugin ONLY react to NativeVocal notifications so notifications can be sent silently by using `Rendering = NotificationRendering.PluginNotifier` on NotificationArgs. These notifications will be picked up by other notification listeners (eg. Aggregator).
---
 ObservatoryHerald/HeraldNotifier.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ObservatoryHerald/HeraldNotifier.cs b/ObservatoryHerald/HeraldNotifier.cs
index a66fa28..064e1ac 100644
--- a/ObservatoryHerald/HeraldNotifier.cs
+++ b/ObservatoryHerald/HeraldNotifier.cs
@@ -77,7 +77,7 @@ namespace Observatory.Herald
 
         public void OnNotificationEvent(NotificationArgs notificationEventArgs)
         {
-            if (heraldSettings.Enabled)
+            if (heraldSettings.Enabled && notificationEventArgs.Rendering.HasFlag(NotificationRendering.NativeVocal))
                 heraldSpeech.Enqueue(
                     notificationEventArgs, 
                     GetAzureNameFromSetting(heraldSettings.SelectedVoice),

From 31a9cfc92d91a1364cdf6bab66926cdaf71867bf Mon Sep 17 00:00:00 2001
From: F K <54195004+fredjk-gh@users.noreply.github.com>
Date: Tue, 23 Jan 2024 19:36:16 -0500
Subject: [PATCH 15/18] [Framework] Add 3 new properties to NotificationArgs to
 expand detail (#131)

The new properties are:

* string Sender: The name of the plugin sending the notification.
* string ExtendedDetails: Even more detail than Title and Detail convey. This value will not be spoken nor included in pop-up notifications. However, other notifier plugins may use this value.
* int ColescingId: An id which can be used to correlate multiple notifications together (ie. for sorting/grouping) without depending on arbitrary string values. I recommend reserving -1 for system, 0 .. 1000 for system bodies and anything else is arbitrary and can be agreed upon between Core and Plugin authors, as desired.

While the motivating use is a new notifier plugin I am authoring (my Aggregator plugin, see GitHub), I have tried to make this as general purpose as possible.

I have modified Explorer as an example of usage. After this is merged, I'll follow up with another PR to use this in Botanist as well (I have other changes pending for Botanist; see #120).

Comments welcomed!
---
 ObservatoryExplorer/Explorer.cs               |  7 ++++++-
 ObservatoryFramework/EventArgs.cs             | 12 ++++++++++++
 ObservatoryFramework/ObservatoryFramework.xml | 15 +++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/ObservatoryExplorer/Explorer.cs b/ObservatoryExplorer/Explorer.cs
index 968fbc4..e66c918 100644
--- a/ObservatoryExplorer/Explorer.cs
+++ b/ObservatoryExplorer/Explorer.cs
@@ -240,6 +240,7 @@ namespace Observatory.Explorer
             if (results.Count > 0)
             {
                 StringBuilder notificationDetail = new();
+                StringBuilder notificationExtendedDetail = new();
                 foreach (var result in results)
                 {
                     var scanResult = new ExplorerUIResults()
@@ -251,6 +252,7 @@ namespace Observatory.Explorer
                     };
                     ObservatoryCore.AddGridItem(ExplorerWorker, scanResult);
                     notificationDetail.AppendLine(result.Description);
+                    notificationExtendedDetail.AppendLine(result.Detail);
                 }
 
                 string bodyAffix;
@@ -293,7 +295,10 @@ namespace Observatory.Explorer
                 {
                     Title = bodyLabel + bodyAffix,
                     TitleSsml = $"<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name=\"\">{bodyLabel} {spokenAffix}</voice></speak>",
-                    Detail = notificationDetail.ToString()
+                    Detail = notificationDetail.ToString(),
+                    Sender = ExplorerWorker.ShortName,
+                    ExtendedDetails = notificationExtendedDetail.ToString(),
+                    CoalescingId = scanEvent.BodyID,
                 };
 
                 ObservatoryCore.SendNotification(args);
diff --git a/ObservatoryFramework/EventArgs.cs b/ObservatoryFramework/EventArgs.cs
index d2b1166..de638a8 100644
--- a/ObservatoryFramework/EventArgs.cs
+++ b/ObservatoryFramework/EventArgs.cs
@@ -62,6 +62,18 @@ namespace Observatory.Framework
         /// Specifies if some part of the notification should be suppressed. Not supported by all notifiers. Defaults to <see cref="NotificationSuppression.None"/>.
         /// </summary>
         public NotificationSuppression Suppression = NotificationSuppression.None;
+        /// <summary>
+        /// The plugin sending this notification.
+        /// </summary>
+        public string Sender = "";
+        /// <summary>
+        /// Additional notification detailed (generally not rendered by voice or popup; potentially used by aggregating/logging plugins).
+        /// </summary>
+        public string ExtendedDetails;
+        /// <summary>
+        /// A value which allows grouping of notifications together. For example, values &gt;= 0 &lt;= 1000 could be system body IDs, -1 is the system, anything else is arbitrary.
+        /// </summary>
+        public int CoalescingId;
     }
 
     /// <summary>
diff --git a/ObservatoryFramework/ObservatoryFramework.xml b/ObservatoryFramework/ObservatoryFramework.xml
index c65f353..63ab194 100644
--- a/ObservatoryFramework/ObservatoryFramework.xml
+++ b/ObservatoryFramework/ObservatoryFramework.xml
@@ -148,6 +148,21 @@
             Specifies if some part of the notification should be suppressed. Not supported by all notifiers. Defaults to <see cref="F:Observatory.Framework.NotificationSuppression.None"/>.
             </summary>
         </member>
+        <member name="F:Observatory.Framework.NotificationArgs.Sender">
+            <summary>
+            The plugin sending this notification.
+            </summary>
+        </member>
+        <member name="F:Observatory.Framework.NotificationArgs.ExtendedDetails">
+            <summary>
+            Additional notification detailed (generally not rendered by voice or popup; potentially used by aggregating/logging plugins).
+            </summary>
+        </member>
+        <member name="F:Observatory.Framework.NotificationArgs.CoalescingId">
+            <summary>
+            A value which allows grouping of notifications together. For example, values &gt;= 0 &lt;= 1000 could be system body IDs, -1 is the system, anything else is arbitrary.
+            </summary>
+        </member>
         <member name="T:Observatory.Framework.NotificationSuppression">
             <summary>
             Defines constants for suppression of title or detail announcement in a notification.

From 4299b0613be613a8f503b8417ffa6b404271c12d Mon Sep 17 00:00:00 2001
From: F K <54195004+fredjk-gh@users.noreply.github.com>
Date: Tue, 23 Jan 2024 19:36:57 -0500
Subject: [PATCH 16/18] [ObservatoryCore] Add Statistics and OnFoot
 CarrierJumps to preread data (#129)

CarrierJump w/ OnFoot is needed for many location tracking things -- ATTN MattG as this is causing problems with BioInsights.

I'm requesting Statistics for use by StatsScanner.
---
 ObservatoryCore/Utils/LogMonitor.cs | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/ObservatoryCore/Utils/LogMonitor.cs b/ObservatoryCore/Utils/LogMonitor.cs
index 878c4ff..a6000d8 100644
--- a/ObservatoryCore/Utils/LogMonitor.cs
+++ b/ObservatoryCore/Utils/LogMonitor.cs
@@ -131,7 +131,7 @@ namespace Observatory.Utils
             // journal is mostly empty) but keeping only the lines since the last FSDJump.
             List<string> lastSystemLines = new();
             List<string> lastFileLines = new();
-            string lastLoadGame = string.Empty;
+            List<String> fileHeaderLines = new();
             bool sawFSDJump = false;
             foreach (var file in files.Skip(Math.Max(files.Count() - 2, 0)))
             {
@@ -139,7 +139,7 @@ namespace Observatory.Utils
                 foreach (var line in lines)
                 {
                     var eventType = JournalUtilities.GetEventType(line);
-                    if (eventType.Equals("FSDJump") || eventType.Equals("CarrierJump") && line.Contains("\"Docked\":true"))
+                    if (eventType.Equals("FSDJump") || (eventType.Equals("CarrierJump") && (line.Contains("\"Docked\":true") || line.Contains("\"OnFoot\":true"))))
                     {
                         // Reset, start collecting again.
                         lastSystemLines.Clear();
@@ -148,10 +148,13 @@ namespace Observatory.Utils
                     else if (eventType.Equals("Fileheader"))
                     {
                         lastFileLines.Clear();
+                        fileHeaderLines.Clear();
+                        fileHeaderLines.Add(line);
                     }
-                    else if (eventType.Equals("LoadGame"))
+                    else if (eventType.Equals("LoadGame") || eventType.Equals("Statistics"))
                     {
-                        lastLoadGame = line;
+                        // A few header lines to collect.
+                        fileHeaderLines.Add(line);
                     }
                     lastSystemLines.Add(line);
                     lastFileLines.Add(line);
@@ -166,11 +169,11 @@ namespace Observatory.Utils
             List<string> linesToRead = lastFileLines;
             if (sawFSDJump)
             {
-                // If we saw a LoadGame, insert it as well. This ensures odyssey biologicials are properly
-                // counted/presented.
-                if (!string.IsNullOrEmpty(lastLoadGame))
+                // If we saw any relevant header lines, insert them as well. This ensures odyssey biologicials are properly
+                // counted/presented, current Commander name is present, etc.
+                if (fileHeaderLines.Count > 0)
                 {
-                    lastSystemLines.Insert(0, lastLoadGame);
+                    lastSystemLines.InsertRange(0, fileHeaderLines);
                 }
                 linesToRead = lastSystemLines;
             }

From 5e8ac004c713dcbb2bd527cc8ea90b723484556a Mon Sep 17 00:00:00 2001
From: F K <54195004+fredjk-gh@users.noreply.github.com>
Date: Wed, 24 Jan 2024 08:51:46 -0500
Subject: [PATCH 17/18] [Core] Fix: Convert Decimal control values to int32 for
 Int settings (#134)

Attempting to set decimal values to int properties tends to throw errors. ;-)
---
 ObservatoryCore/UI/SettingsForm.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ObservatoryCore/UI/SettingsForm.cs b/ObservatoryCore/UI/SettingsForm.cs
index f05f38c..c13f5ac 100644
--- a/ObservatoryCore/UI/SettingsForm.cs
+++ b/ObservatoryCore/UI/SettingsForm.cs
@@ -246,7 +246,7 @@ namespace Observatory.UI
 
             trackBar.ValueChanged += (sender, e) =>
             {
-                setting.SetValue(_plugin.Settings, trackBar.Value);
+                setting.SetValue(_plugin.Settings, Convert.ToInt32(trackBar.Value));
                 SaveSettings();
             };
 
@@ -268,7 +268,7 @@ namespace Observatory.UI
 
             numericUpDown.ValueChanged += (sender, e) =>
             {
-                setting.SetValue(_plugin.Settings, numericUpDown.Value);
+                setting.SetValue(_plugin.Settings, Convert.ToInt32(numericUpDown.Value));
                 SaveSettings();
             };
 

From 07ef51e6409902e528de2e8aa38eaa2d15730c5c Mon Sep 17 00:00:00 2001
From: Xjph <archseraphim@gmail.com>
Date: Thu, 25 Jan 2024 23:04:05 -0330
Subject: [PATCH 18/18] remove sorting from list views while reading all

---
 ObservatoryCore/UI/CoreForm.cs | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/ObservatoryCore/UI/CoreForm.cs b/ObservatoryCore/UI/CoreForm.cs
index 9019222..fae7d39 100644
--- a/ObservatoryCore/UI/CoreForm.cs
+++ b/ObservatoryCore/UI/CoreForm.cs
@@ -226,10 +226,41 @@ namespace Observatory.UI
             readAllDialogue.StartPosition = FormStartPosition.Manual;
             readAllDialogue.Location = Point.Add(Location, new Size(100, 100));
             SuspendDrawing(this);
+            SuspendSorting();
             readAllDialogue.ShowDialog();
+            ResumeSorting();
             ResumeDrawing(this);
         }
 
+        private Dictionary<PluginListView, object> PluginComparer;
+
+        private void SuspendSorting()
+        {
+            PluginComparer = new();
+            foreach (var panel in uiPanels.Values)
+            {
+                foreach (var control in panel.Controls)
+                {
+                    if (control?.GetType() == typeof(PluginListView))
+                    {
+                        var listView = (PluginListView)control;
+                        PluginComparer.Add(listView, listView.ListViewItemSorter);
+                        listView.ListViewItemSorter = null;
+                    }
+                }
+            }
+        }
+
+        private void ResumeSorting()
+        {
+            if (PluginComparer?.Any() ?? false)
+                foreach (var panel in PluginComparer.Keys)
+                {
+                    panel.ListViewItemSorter = (IObservatoryComparer)PluginComparer[panel];
+                }
+            PluginComparer?.Clear();
+        }
+
         private void PopupNotificationLabel_Click(object _, EventArgs e)
         {
             CorePanel.SuspendLayout();