commit 4940e6a30a5a99a909887fe2eccbc261e879886c Author: Ray Date: Tue Aug 6 21:27:08 2024 +0100 Initial commit (release/0.3.4.164) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..30a047b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/.vs +/bin +/obj +*.user +*.pubxml.user +*.csproj.user diff --git a/AppResource.Designer.cs b/AppResource.Designer.cs new file mode 100644 index 0000000..9cf055e --- /dev/null +++ b/AppResource.Designer.cs @@ -0,0 +1,169 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace RokettoLaunch { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class AppResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal AppResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RokettoLaunch.AppResource", typeof(AppResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to . + /// + internal static string AppAuthorURL { + get { + return ResourceManager.GetString("AppAuthorURL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to https://www.hiimray.co.uk. + /// + internal static string AppCompanyURL { + get { + return ResourceManager.GetString("AppCompanyURL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to https://www.hiimray.co.uk/software-rokettolaunch. + /// + internal static string AppHelpURL { + get { + return ResourceManager.GetString("AppHelpURL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to https://www.hiimray.co.uk/software-rokettolaunch. + /// + internal static string AppProductURL { + get { + return ResourceManager.GetString("AppProductURL", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cog2 { + get { + object obj = ResourceManager.GetObject("cog2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap disk2 { + get { + object obj = ResourceManager.GetObject("disk2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap file { + get { + object obj = ResourceManager.GetObject("file", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap folder { + get { + object obj = ResourceManager.GetObject("folder", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap folder_32 { + get { + object obj = ResourceManager.GetObject("folder_32", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap help2 { + get { + object obj = ResourceManager.GetObject("help2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap icon_64 { + get { + object obj = ResourceManager.GetObject("icon_64", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/AppResource.resx b/AppResource.resx new file mode 100644 index 0000000..22ca018 --- /dev/null +++ b/AppResource.resx @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + + https://www.hiimray.co.uk + + + https://www.hiimray.co.uk/software-rokettolaunch + + + https://www.hiimray.co.uk/software-rokettolaunch + + + + Resources\cog2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\disk2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\file.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\folder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\folder_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\help2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\icon-64.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/EditGroupForm.cs b/EditGroupForm.cs new file mode 100644 index 0000000..68e0228 --- /dev/null +++ b/EditGroupForm.cs @@ -0,0 +1,155 @@ +using System.Windows.Forms; +using RokettoLaunch.Models; +using RyzStudio.Windows.Forms; +using RyzStudio.Windows.ThemedForms.ButtonTextBox; +using RyzStudio.Windows.ThemedForms.PickerBox; + +namespace RokettoLaunch +{ + public class EditGroupForm : Form + { + private Label label2; + private Label label1; + private ThYesNoPickerBox pickerBox1; + private ThClearableTextBox textBox1; + private RyzStudio.Windows.ThemedForms.Composite.DialogFooter dialogFooter1; + + + private TileGroupModel result = null; + + + public EditGroupForm(TileGroupModel model = null) + { + InitializeComponent(); + + UISetup.Dialog(this); + + this.Text = (result == null) ? "Add Group" : "Edit Group"; + + result = model; + + pickerBox1.ComboBox.Items.Clear(); + pickerBox1.ComboBox.Items.AddRange(new string[] { "No", "Yes" }); + if (pickerBox1.ComboBox.Items.Count > 0) + { + pickerBox1.ComboBox.SelectedIndex = 0; + } + + if (result != null) + { + textBox1.Text = result.Title?.Trim() ?? string.Empty; + pickerBox1.Value = result.IsExpanded; + } + } + + private void InitializeComponent() + { + textBox1 = new ThClearableTextBox(); + label2 = new Label(); + label1 = new Label(); + pickerBox1 = new ThYesNoPickerBox(); + dialogFooter1 = new RyzStudio.Windows.ThemedForms.Composite.DialogFooter(); + SuspendLayout(); + // + // textBox1 + // + textBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox1.BackColor = System.Drawing.Color.Transparent; + textBox1.ClearedValue = ""; + textBox1.EnableReactiveVisual = true; + textBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F); + textBox1.Icon = "O"; + textBox1.IconSize = 13F; + textBox1.Location = new System.Drawing.Point(192, 20); + textBox1.Name = "textBox1"; + textBox1.Size = new System.Drawing.Size(177, 32); + textBox1.TabIndex = 152; + textBox1.TabStop = false; + textBox1.UseSystemPasswordChar = false; + // + // label2 + // + label2.AutoSize = true; + label2.BackColor = System.Drawing.Color.Transparent; + label2.ForeColor = System.Drawing.SystemColors.ControlText; + label2.Location = new System.Drawing.Point(10, 62); + label2.Margin = new Padding(0); + label2.Name = "label2"; + label2.Padding = new Padding(0, 9, 0, 0); + label2.Size = new System.Drawing.Size(91, 24); + label2.TabIndex = 155; + label2.Text = "Show Expanded"; + label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // label1 + // + label1.AutoSize = true; + label1.BackColor = System.Drawing.Color.Transparent; + label1.ForeColor = System.Drawing.SystemColors.ControlText; + label1.Location = new System.Drawing.Point(10, 20); + label1.Margin = new Padding(0); + label1.Name = "label1"; + label1.Padding = new Padding(0, 9, 0, 0); + label1.Size = new System.Drawing.Size(29, 24); + label1.TabIndex = 153; + label1.Text = "Title"; + label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // pickerBox1 + // + pickerBox1.Anchor = AnchorStyles.Top | AnchorStyles.Right; + pickerBox1.BackColor = System.Drawing.Color.Transparent; + pickerBox1.EnableReactiveVisual = true; + pickerBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F); + pickerBox1.Location = new System.Drawing.Point(285, 62); + pickerBox1.Name = "pickerBox1"; + pickerBox1.SelectedIndex = 0; + pickerBox1.Size = new System.Drawing.Size(84, 34); + pickerBox1.TabIndex = 174; + pickerBox1.TabStop = false; + pickerBox1.Value = false; + // + // dialogFooter1 + // + dialogFooter1.BackColor = System.Drawing.Color.FromArgb(240, 240, 240); + dialogFooter1.Button1Text = "&Save"; + dialogFooter1.Dialog = this; + dialogFooter1.Dock = DockStyle.Bottom; + dialogFooter1.Location = new System.Drawing.Point(0, 437); + dialogFooter1.Name = "dialogFooter1"; + dialogFooter1.Size = new System.Drawing.Size(384, 84); + // + // EditGroupForm + // + BackColor = System.Drawing.Color.White; + ClientSize = new System.Drawing.Size(384, 521); + Controls.Add(dialogFooter1); + Controls.Add(pickerBox1); + Controls.Add(label2); + Controls.Add(label1); + Controls.Add(textBox1); + MinimumSize = new System.Drawing.Size(400, 560); + Name = "EditGroupForm"; + Text = "Edit Group"; + ResumeLayout(false); + PerformLayout(); + } + + public TileGroupModel Result + { + get + { + if (result == null) + { + result = new TileGroupModel(); + } + + result.Title = textBox1.Text?.Trim() ?? string.Empty; + result.IsExpanded = pickerBox1.Value; + + return result; + } + } + + } +} \ No newline at end of file diff --git a/EditGroupForm.resx b/EditGroupForm.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/EditGroupForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/EditTileFolderForm.cs b/EditTileFolderForm.cs new file mode 100644 index 0000000..7e0dcb9 --- /dev/null +++ b/EditTileFolderForm.cs @@ -0,0 +1,283 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using RokettoLaunch.Models; +using RyzStudio.Windows.Forms; +using RyzStudio.Windows.ThemedForms; +using RyzStudio.Windows.ThemedForms.ButtonTextBox; + +namespace RokettoLaunch +{ + public class EditTileFolderForm : Form + { + private Label label1; + private ThClearableTextBox textBox1; + private ThListBox listBox1; + private Label label2; + private RyzStudio.Windows.ThemedForms.Composite.DialogFooter dialogFooter1; + + + private TileModel result = null; + + + public EditTileFolderForm(TileModel model = null) + { + InitializeComponent(); + + UISetup.Dialog(this); + + this.Text = (result == null) ? "Add Folder" : "Edit Folder"; + + result = model; + + if (result != null) + { + textBox1.Text = result?.Title ?? string.Empty; + + foreach (TileModel item in result.Items ?? new List()) + { + if (item.IsGroup) + { + continue; + } + + listBox1.ListBox.Items.Add(item); + } + } + } + + private void InitializeComponent() + { + textBox1 = new ThClearableTextBox(); + label1 = new Label(); + listBox1 = new ThListBox(); + label2 = new Label(); + dialogFooter1 = new RyzStudio.Windows.ThemedForms.Composite.DialogFooter(); + SuspendLayout(); + // + // textBox1 + // + textBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox1.BackColor = Color.Transparent; + textBox1.ClearedValue = ""; + textBox1.EnableReactiveVisual = true; + textBox1.Font = new Font("Microsoft Sans Serif", 8.25F); + textBox1.Icon = "O"; + textBox1.IconSize = 13F; + textBox1.Location = new Point(109, 20); + textBox1.Name = "textBox1"; + textBox1.Size = new Size(275, 32); + textBox1.TabIndex = 152; + textBox1.TabStop = false; + textBox1.UseSystemPasswordChar = false; + // + // label1 + // + label1.AutoSize = true; + label1.BackColor = Color.Transparent; + label1.ForeColor = SystemColors.ControlText; + label1.Location = new Point(10, 20); + label1.Margin = new Padding(0); + label1.Name = "label1"; + label1.Padding = new Padding(0, 9, 0, 0); + label1.Size = new Size(29, 24); + label1.TabIndex = 153; + label1.Text = "Title"; + label1.TextAlign = ContentAlignment.MiddleLeft; + // + // listBox1 + // + listBox1.AllowDrop = true; + listBox1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + listBox1.BackColor = Color.Transparent; + listBox1.EnableReactiveVisual = true; + listBox1.Font = new Font("Microsoft Sans Serif", 8.25F); + listBox1.Location = new Point(109, 62); + listBox1.Name = "listBox1"; + listBox1.Size = new Size(260, 366); + listBox1.TabIndex = 180; + listBox1.OnAdd += listBox1_OnAdd; + listBox1.OnEdit += listBox1_OnEdit; + listBox1.OnCopy += listBox1_OnCopy; + listBox1.DragDrop += listBox1_DragDrop; + listBox1.DragOver += listBox1_DragOver; + // + // label2 + // + label2.AutoSize = true; + label2.BackColor = Color.Transparent; + label2.ForeColor = SystemColors.ControlText; + label2.Location = new Point(10, 62); + label2.Margin = new Padding(0); + label2.Name = "label2"; + label2.Padding = new Padding(0, 9, 0, 0); + label2.Size = new Size(82, 24); + label2.TabIndex = 181; + label2.Text = "Tile Collection"; + label2.TextAlign = ContentAlignment.MiddleLeft; + // + // dialogFooter1 + // + dialogFooter1.BackColor = Color.FromArgb(240, 240, 240); + dialogFooter1.Button1Text = "&Save"; + dialogFooter1.Dialog = this; + dialogFooter1.Dock = DockStyle.Bottom; + dialogFooter1.Location = new Point(0, 437); + dialogFooter1.Name = "dialogFooter1"; + dialogFooter1.Size = new Size(384, 84); + // + // EditTileFolderForm + // + BackColor = Color.White; + ClientSize = new Size(384, 521); + Controls.Add(dialogFooter1); + Controls.Add(label2); + Controls.Add(listBox1); + Controls.Add(label1); + Controls.Add(textBox1); + MinimumSize = new Size(400, 560); + Name = "EditTileFolderForm"; + Text = "Add List Tile"; + ResumeLayout(false); + PerformLayout(); + } + + public TileModel Result + { + get + { + if (result == null) + { + result = new TileModel(); + } + + result.Title = textBox1.Text?.Trim() ?? string.Empty; + result.IsGroup = true; + result.Items = new List(); + + foreach (TileModel item in listBox1.ListBox.Items.OfType()) + { + if (item.IsGroup) + { + continue; + } + + result.Items.Add(item); + } + + return result; + } + } + + + private void listBox1_OnAdd(object sender, EventArgs e) + { + var form = new EditTileForm(); + if (form.ShowDialog() == DialogResult.OK) + { + listBox1.ListBox.Items.Add(form.Result); + }; + } + + private void listBox1_OnEdit(object sender, EventArgs e) + { + if (listBox1.ListBox.Items.Count <= 0) + { + return; + } + + var n = listBox1.ListBox.SelectedIndex; + if (n < 0) + { + return; + } + + if (listBox1.ListBox.SelectedItem == null) + { + return; + } + + var form = new EditTileForm((TileModel)listBox1.ListBox.SelectedItem); + if (form.ShowDialog() == DialogResult.OK) + { + listBox1.ListBox.Items.RemoveAt(n); + listBox1.ListBox.Items.Insert(n, form.Result); + }; + } + + private void listBox1_OnCopy(object sender, EventArgs e) + { + listBox1.ListBox.CopyItem(); + } + + private void listBox1_DragOver(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + e.Effect = DragDropEffects.Link; + } + else + { + e.Effect = DragDropEffects.None; + } + } + + private void listBox1_DragDrop(object sender, DragEventArgs e) + { + var fileList = e.Data.GetData(DataFormats.FileDrop) as string[]; + if (fileList == null) + { + return; + } + + if (fileList.Length <= 0) + { + return; + } + + if (string.IsNullOrWhiteSpace(fileList[0])) + { + return; + } + + var model = new TileModel() + { + ProcessFilename = fileList[0], + Title = Path.GetFileName(fileList[0]) + }; + + // exe + if (Path.GetExtension(fileList[0]).Equals(".exe", StringComparison.CurrentCultureIgnoreCase)) + { + if (File.Exists(fileList[0])) + { + try + { + FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(fileList[0]); + if (fvi != null) + { + model.Title = fvi.ProductName; + } + } + catch + { + // do nothing + } + } + + + if (string.IsNullOrWhiteSpace(model.Title)) + { + model.Title = Path.GetFileNameWithoutExtension(fileList[0]); + } + } + + listBox1.ListBox.Items.Add(model); + } + + } +} \ No newline at end of file diff --git a/EditTileFolderForm.resx b/EditTileFolderForm.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/EditTileFolderForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/EditTileForm.cs b/EditTileForm.cs new file mode 100644 index 0000000..29b6bd9 --- /dev/null +++ b/EditTileForm.cs @@ -0,0 +1,330 @@ +using System.Drawing; +using System.Windows.Forms; +using RokettoLaunch.Models; +using RyzStudio.Windows.Forms; +using RyzStudio.Windows.ThemedForms; +using RyzStudio.Windows.ThemedForms.ButtonTextBox; +using RyzStudio.Windows.ThemedForms.PickerBox; + +namespace RokettoLaunch +{ + public class EditTileForm : Form + { + private Label label6; + private Label label7; + private Label label4; + private Label label3; + private Label label2; + private Label label1; + private ThPathDialogTextBox textBox2; + private ThClearableTextBox textBox3; + private ThPathDialogTextBox textBox4; + private ThPickerBox pickerBox1; + private ThYesNoPickerBox pickerBox2; + private THorizontalSeparator horizontalSeparator1; + private ThClearableTextBox textBox1; + private RyzStudio.Windows.ThemedForms.Composite.DialogFooter dialogFooter1; + + + private TileModel result = null; + + + public EditTileForm(TileModel model = null) + { + InitializeComponent(); + + UISetup.Dialog(this); + + this.Text = (result == null) ? "Add Tile" : "Edit Tile"; + + result = model; + + pickerBox1.ComboBox.Items.Clear(); + pickerBox1.ComboBox.Items.AddRange(new string[] { "Normal", "Hidden", "Minimized", "Maximized" }); + if (pickerBox1.ComboBox.Items.Count > 0) + { + pickerBox1.ComboBox.SelectedIndex = 0; + } + + if (result != null) + { + textBox1.Text = result?.Title ?? string.Empty; + textBox2.Text = result?.ProcessFilename ?? string.Empty; + textBox3.Text = result?.ProcessArgument ?? string.Empty; + textBox4.Text = result?.ProcessWorkingDirectory ?? string.Empty; + pickerBox1.ComboBox.SelectedIndex = (int)result.ProcessWindowStyle; + pickerBox2.Value = result.ProcessAsAdmin; + } + } + + private void InitializeComponent() + { + textBox1 = new ThClearableTextBox(); + label6 = new Label(); + label7 = new Label(); + label4 = new Label(); + label3 = new Label(); + label2 = new Label(); + label1 = new Label(); + textBox2 = new ThPathDialogTextBox(); + textBox3 = new ThClearableTextBox(); + textBox4 = new ThPathDialogTextBox(); + pickerBox1 = new ThPickerBox(); + pickerBox2 = new ThYesNoPickerBox(); + horizontalSeparator1 = new THorizontalSeparator(); + dialogFooter1 = new RyzStudio.Windows.ThemedForms.Composite.DialogFooter(); + SuspendLayout(); + // + // textBox1 + // + textBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox1.BackColor = Color.Transparent; + textBox1.ClearedValue = ""; + textBox1.EnableReactiveVisual = true; + textBox1.Font = new Font("Segoe UI", 9F); + textBox1.Icon = "O"; + textBox1.IconSize = 13F; + textBox1.Location = new Point(109, 20); + textBox1.Name = "textBox1"; + textBox1.Size = new Size(260, 32); + textBox1.TabIndex = 152; + textBox1.TabStop = false; + textBox1.UseSystemPasswordChar = false; + // + // label6 + // + label6.AutoSize = true; + label6.BackColor = Color.Transparent; + label6.ForeColor = SystemColors.ControlText; + label6.Location = new Point(10, 264); + label6.Margin = new Padding(0); + label6.Name = "label6"; + label6.Padding = new Padding(0, 9, 0, 0); + label6.Size = new Size(83, 24); + label6.TabIndex = 163; + label6.Text = "Run As Admin"; + label6.TextAlign = ContentAlignment.MiddleLeft; + // + // label7 + // + label7.AutoSize = true; + label7.BackColor = Color.Transparent; + label7.ForeColor = SystemColors.ControlText; + label7.Location = new Point(10, 220); + label7.Margin = new Padding(0); + label7.Name = "label7"; + label7.Padding = new Padding(0, 9, 0, 0); + label7.Size = new Size(79, 24); + label7.TabIndex = 161; + label7.Text = "Window Style"; + label7.TextAlign = ContentAlignment.MiddleLeft; + // + // label4 + // + label4.AutoSize = true; + label4.BackColor = Color.Transparent; + label4.ForeColor = SystemColors.ControlText; + label4.Location = new Point(10, 146); + label4.Margin = new Padding(0); + label4.Name = "label4"; + label4.Padding = new Padding(0, 9, 0, 0); + label4.Size = new Size(103, 24); + label4.TabIndex = 159; + label4.Text = "Working Directory"; + label4.TextAlign = ContentAlignment.MiddleLeft; + // + // label3 + // + label3.AutoSize = true; + label3.BackColor = Color.Transparent; + label3.ForeColor = SystemColors.ControlText; + label3.Location = new Point(10, 104); + label3.Margin = new Padding(0); + label3.Name = "label3"; + label3.Padding = new Padding(0, 9, 0, 0); + label3.Size = new Size(61, 24); + label3.TabIndex = 157; + label3.Text = "Argument"; + label3.TextAlign = ContentAlignment.MiddleLeft; + // + // label2 + // + label2.AutoSize = true; + label2.BackColor = Color.Transparent; + label2.ForeColor = SystemColors.ControlText; + label2.Location = new Point(10, 62); + label2.Margin = new Padding(0); + label2.Name = "label2"; + label2.Padding = new Padding(0, 9, 0, 0); + label2.Size = new Size(55, 24); + label2.TabIndex = 155; + label2.Text = "Filename"; + label2.TextAlign = ContentAlignment.MiddleLeft; + // + // label1 + // + label1.AutoSize = true; + label1.BackColor = Color.Transparent; + label1.ForeColor = SystemColors.ControlText; + label1.Location = new Point(10, 20); + label1.Margin = new Padding(0); + label1.Name = "label1"; + label1.Padding = new Padding(0, 9, 0, 0); + label1.Size = new Size(29, 24); + label1.TabIndex = 153; + label1.Text = "Title"; + label1.TextAlign = ContentAlignment.MiddleLeft; + // + // textBox2 + // + textBox2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox2.BackColor = Color.Transparent; + textBox2.DialogMode = ThPathDialogTextBox.DialogType.OpenFile; + textBox2.EnableReactiveVisual = true; + textBox2.FolderBrowserDialog = null; + textBox2.Font = new Font("Segoe UI", 9F); + textBox2.Icon = "C"; + textBox2.IconSize = 13F; + textBox2.Location = new Point(109, 62); + textBox2.Name = "textBox2"; + textBox2.OpenFileDialog = null; + textBox2.SaveFileDialog = null; + textBox2.Size = new Size(260, 32); + textBox2.TabIndex = 170; + textBox2.TabStop = false; + textBox2.UseSystemPasswordChar = false; + // + // textBox3 + // + textBox3.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox3.BackColor = Color.Transparent; + textBox3.ClearedValue = ""; + textBox3.EnableReactiveVisual = true; + textBox3.Font = new Font("Segoe UI", 9F); + textBox3.Icon = "O"; + textBox3.IconSize = 13F; + textBox3.Location = new Point(149, 104); + textBox3.Name = "textBox3"; + textBox3.Size = new Size(220, 32); + textBox3.TabIndex = 171; + textBox3.TabStop = false; + textBox3.UseSystemPasswordChar = false; + // + // textBox4 + // + textBox4.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox4.BackColor = Color.Transparent; + textBox4.DialogMode = ThPathDialogTextBox.DialogType.FolderBrowser; + textBox4.EnableReactiveVisual = true; + textBox4.FolderBrowserDialog = null; + textBox4.Font = new Font("Segoe UI", 9F); + textBox4.Icon = "D"; + textBox4.IconSize = 13F; + textBox4.Location = new Point(149, 146); + textBox4.Name = "textBox4"; + textBox4.OpenFileDialog = null; + textBox4.SaveFileDialog = null; + textBox4.Size = new Size(220, 32); + textBox4.TabIndex = 172; + textBox4.TabStop = false; + textBox4.UseSystemPasswordChar = false; + // + // pickerBox1 + // + pickerBox1.Anchor = AnchorStyles.Top | AnchorStyles.Right; + pickerBox1.BackColor = Color.Transparent; + pickerBox1.EnableReactiveVisual = true; + pickerBox1.Font = new Font("Segoe UI", 9F); + pickerBox1.Location = new Point(249, 220); + pickerBox1.Name = "pickerBox1"; + pickerBox1.SelectedIndex = -1; + pickerBox1.Size = new Size(120, 34); + pickerBox1.TabIndex = 174; + pickerBox1.TabStop = false; + // + // pickerBox2 + // + pickerBox2.Anchor = AnchorStyles.Top | AnchorStyles.Right; + pickerBox2.BackColor = Color.Transparent; + pickerBox2.EnableReactiveVisual = true; + pickerBox2.Font = new Font("Segoe UI", 9F); + pickerBox2.Location = new Point(289, 264); + pickerBox2.Name = "pickerBox2"; + pickerBox2.SelectedIndex = 0; + pickerBox2.Size = new Size(80, 34); + pickerBox2.TabIndex = 175; + pickerBox2.TabStop = false; + pickerBox2.Value = false; + // + // horizontalSeparator1 + // + horizontalSeparator1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + horizontalSeparator1.AutoScrollMargin = new Size(0, 0); + horizontalSeparator1.AutoScrollMinSize = new Size(0, 0); + horizontalSeparator1.BackColor = Color.Transparent; + horizontalSeparator1.Location = new Point(10, 187); + horizontalSeparator1.Margin = new Padding(0, 10, 0, 0); + horizontalSeparator1.MaximumSize = new Size(4920, 2); + horizontalSeparator1.MinimumSize = new Size(0, 22); + horizontalSeparator1.Name = "horizontalSeparator1"; + horizontalSeparator1.Size = new Size(364, 22); + horizontalSeparator1.TabIndex = 176; + horizontalSeparator1.TabStop = false; + // + // dialogFooter1 + // + dialogFooter1.BackColor = Color.FromArgb(240, 240, 240); + dialogFooter1.Button1Text = "&Save"; + dialogFooter1.Dialog = this; + dialogFooter1.Dock = DockStyle.Bottom; + dialogFooter1.Location = new Point(0, 437); + dialogFooter1.Name = "dialogFooter1"; + dialogFooter1.Size = new Size(384, 84); + // + // EditTileForm + // + BackColor = Color.White; + ClientSize = new Size(384, 521); + Controls.Add(dialogFooter1); + Controls.Add(horizontalSeparator1); + Controls.Add(pickerBox2); + Controls.Add(pickerBox1); + Controls.Add(textBox4); + Controls.Add(textBox3); + Controls.Add(textBox2); + Controls.Add(label6); + Controls.Add(label7); + Controls.Add(label4); + Controls.Add(label3); + Controls.Add(label2); + Controls.Add(label1); + Controls.Add(textBox1); + MinimumSize = new Size(400, 560); + Name = "EditTileForm"; + Text = "Add Tile"; + ResumeLayout(false); + PerformLayout(); + } + + public TileModel Result + { + get + { + if (result == null) + { + result = new TileModel(); + } + + result.Title = textBox1.Text?.Trim() ?? string.Empty; + result.ProcessFilename = textBox2.Text?.Trim() ?? string.Empty; + result.ProcessArgument = textBox3.Text?.Trim() ?? string.Empty; + result.ProcessWorkingDirectory = textBox4.Text?.Trim(); + result.ProcessWindowStyle = (System.Diagnostics.ProcessWindowStyle)pickerBox1.ComboBox.SelectedIndex; + result.ProcessAsAdmin = pickerBox2.Value; + + return result; + } + } + + } +} \ No newline at end of file diff --git a/EditTileForm.resx b/EditTileForm.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/EditTileForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs new file mode 100644 index 0000000..819c016 --- /dev/null +++ b/MainForm.Designer.cs @@ -0,0 +1,531 @@ +using RokettoLaunch.Windows.Forms; + +namespace RokettoLaunch +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + notifyIcon1 = new System.Windows.Forms.NotifyIcon(components); + contextMenuStrip2 = new System.Windows.Forms.ContextMenuStrip(components); + exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + menuStrip1 = new System.Windows.Forms.MenuStrip(); + fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem13 = new System.Windows.Forms.ToolStripSeparator(); + closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem14 = new System.Windows.Forms.ToolStripSeparator(); + saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem15 = new System.Windows.Forms.ToolStripSeparator(); + exitToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + addGroupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + showBigIconsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + alwaysOnTopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + helpToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + viewHelpToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem16 = new System.Windows.Forms.ToolStripSeparator(); + aboutToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + tileContainerMenu1 = new System.Windows.Forms.ContextMenuStrip(components); + addGroupToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem(); + editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem5 = new System.Windows.Forms.ToolStripMenuItem(); + toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + addRowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + removeRowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem(); + topToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + upToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + downToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + bottomToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + panel1 = new System.Windows.Forms.Panel(); + tileMenu1 = new System.Windows.Forms.ContextMenuStrip(components); + editToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem6 = new System.Windows.Forms.ToolStripMenuItem(); + toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + removeToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + contextMenuStrip2.SuspendLayout(); + menuStrip1.SuspendLayout(); + tileContainerMenu1.SuspendLayout(); + panel1.SuspendLayout(); + tileMenu1.SuspendLayout(); + SuspendLayout(); + // + // saveFileDialog1 + // + saveFileDialog1.Filter = "Session files (compressed)|*.jsnx|Session files|*.json;*.jsonfig"; + saveFileDialog1.Title = "Choose file to save the session"; + // + // openFileDialog1 + // + openFileDialog1.Filter = "All supported files|*.json;*.jsonfig;*.jsnx|Session files (compressed)|*.jsnx|Session files|*.json;*.jsonfig"; + openFileDialog1.Title = "Choose session file"; + // + // notifyIcon1 + // + notifyIcon1.ContextMenuStrip = contextMenuStrip2; + notifyIcon1.Icon = (System.Drawing.Icon)resources.GetObject("notifyIcon1.Icon"); + notifyIcon1.Text = "notifyIcon1"; + notifyIcon1.Visible = true; + notifyIcon1.MouseClick += notifyIcon1_MouseClick; + // + // contextMenuStrip2 + // + contextMenuStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { exitToolStripMenuItem1 }); + contextMenuStrip2.Name = "contextMenuStrip2"; + contextMenuStrip2.Size = new System.Drawing.Size(94, 26); + // + // exitToolStripMenuItem1 + // + exitToolStripMenuItem1.Name = "exitToolStripMenuItem1"; + exitToolStripMenuItem1.Size = new System.Drawing.Size(93, 22); + exitToolStripMenuItem1.Text = "E&xit"; + exitToolStripMenuItem1.Click += exitToolStripMenuItem1_Click; + // + // menuStrip1 + // + menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { fileToolStripMenuItem, toolStripMenuItem1, viewToolStripMenuItem, toolsToolStripMenuItem, helpToolStripMenuItem1 }); + menuStrip1.Location = new System.Drawing.Point(0, 0); + menuStrip1.Name = "menuStrip1"; + menuStrip1.Size = new System.Drawing.Size(404, 24); + menuStrip1.TabIndex = 2; + menuStrip1.MenuActivate += menuStrip1_MenuActivate; + // + // fileToolStripMenuItem + // + fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { newToolStripMenuItem, openToolStripMenuItem, toolStripMenuItem13, closeToolStripMenuItem, toolStripMenuItem14, saveToolStripMenuItem, saveAsToolStripMenuItem, toolStripMenuItem15, exitToolStripMenuItem2 }); + fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + fileToolStripMenuItem.Text = "&File"; + // + // newToolStripMenuItem + // + newToolStripMenuItem.Image = AppResource.file; + newToolStripMenuItem.Name = "newToolStripMenuItem"; + newToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N; + newToolStripMenuItem.Size = new System.Drawing.Size(146, 22); + newToolStripMenuItem.Text = "&New"; + newToolStripMenuItem.Click += newToolStripMenuItem_Click; + // + // openToolStripMenuItem + // + openToolStripMenuItem.Image = AppResource.folder; + openToolStripMenuItem.Name = "openToolStripMenuItem"; + openToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O; + openToolStripMenuItem.Size = new System.Drawing.Size(146, 22); + openToolStripMenuItem.Text = "&Open"; + openToolStripMenuItem.Click += openToolStripMenuItem_Click; + // + // toolStripMenuItem13 + // + toolStripMenuItem13.Name = "toolStripMenuItem13"; + toolStripMenuItem13.Size = new System.Drawing.Size(143, 6); + // + // closeToolStripMenuItem + // + closeToolStripMenuItem.Name = "closeToolStripMenuItem"; + closeToolStripMenuItem.Size = new System.Drawing.Size(146, 22); + closeToolStripMenuItem.Text = "&Close"; + closeToolStripMenuItem.Click += closeToolStripMenuItem_Click; + // + // toolStripMenuItem14 + // + toolStripMenuItem14.Name = "toolStripMenuItem14"; + toolStripMenuItem14.Size = new System.Drawing.Size(143, 6); + // + // saveToolStripMenuItem + // + saveToolStripMenuItem.Image = AppResource.disk2; + saveToolStripMenuItem.Name = "saveToolStripMenuItem"; + saveToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S; + saveToolStripMenuItem.Size = new System.Drawing.Size(146, 22); + saveToolStripMenuItem.Text = "&Save"; + saveToolStripMenuItem.Click += saveToolStripMenuItem_Click; + // + // saveAsToolStripMenuItem + // + saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; + saveAsToolStripMenuItem.Size = new System.Drawing.Size(146, 22); + saveAsToolStripMenuItem.Text = "Save &As..."; + saveAsToolStripMenuItem.Click += saveAsToolStripMenuItem_Click; + // + // toolStripMenuItem15 + // + toolStripMenuItem15.Name = "toolStripMenuItem15"; + toolStripMenuItem15.Size = new System.Drawing.Size(143, 6); + // + // exitToolStripMenuItem2 + // + exitToolStripMenuItem2.Name = "exitToolStripMenuItem2"; + exitToolStripMenuItem2.Size = new System.Drawing.Size(146, 22); + exitToolStripMenuItem2.Text = "E&xit"; + exitToolStripMenuItem2.Click += exitToolStripMenuItem2_Click; + // + // toolStripMenuItem1 + // + toolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { addGroupToolStripMenuItem }); + toolStripMenuItem1.Name = "toolStripMenuItem1"; + toolStripMenuItem1.Size = new System.Drawing.Size(39, 20); + toolStripMenuItem1.Text = "&Edit"; + // + // addGroupToolStripMenuItem + // + addGroupToolStripMenuItem.Name = "addGroupToolStripMenuItem"; + addGroupToolStripMenuItem.Size = new System.Drawing.Size(132, 22); + addGroupToolStripMenuItem.Text = "&Add Group"; + addGroupToolStripMenuItem.Click += addGroupToolStripMenuItem_Click; + // + // viewToolStripMenuItem + // + viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { showBigIconsToolStripMenuItem, alwaysOnTopToolStripMenuItem }); + viewToolStripMenuItem.Name = "viewToolStripMenuItem"; + viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + viewToolStripMenuItem.Text = "&View"; + // + // showBigIconsToolStripMenuItem + // + showBigIconsToolStripMenuItem.Name = "showBigIconsToolStripMenuItem"; + showBigIconsToolStripMenuItem.Size = new System.Drawing.Size(154, 22); + showBigIconsToolStripMenuItem.Text = "Show &Big Icons"; + showBigIconsToolStripMenuItem.Click += showBigIconsToolStripMenuItem_Click; + // + // alwaysOnTopToolStripMenuItem + // + alwaysOnTopToolStripMenuItem.Name = "alwaysOnTopToolStripMenuItem"; + alwaysOnTopToolStripMenuItem.Size = new System.Drawing.Size(154, 22); + alwaysOnTopToolStripMenuItem.Text = "Always On &Top"; + alwaysOnTopToolStripMenuItem.Click += alwaysOnTopToolStripMenuItem_Click; + // + // toolsToolStripMenuItem + // + toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { optionsToolStripMenuItem }); + toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20); + toolsToolStripMenuItem.Text = "&Tools"; + // + // optionsToolStripMenuItem + // + optionsToolStripMenuItem.Image = AppResource.cog2; + optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + optionsToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F12; + optionsToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + optionsToolStripMenuItem.Text = "&Options"; + optionsToolStripMenuItem.Click += optionsToolStripMenuItem_Click; + // + // helpToolStripMenuItem1 + // + helpToolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { viewHelpToolStripMenuItem1, toolStripMenuItem16, aboutToolStripMenuItem1 }); + helpToolStripMenuItem1.Name = "helpToolStripMenuItem1"; + helpToolStripMenuItem1.Size = new System.Drawing.Size(44, 20); + helpToolStripMenuItem1.Text = "&Help"; + // + // viewHelpToolStripMenuItem1 + // + viewHelpToolStripMenuItem1.Image = AppResource.help2; + viewHelpToolStripMenuItem1.Name = "viewHelpToolStripMenuItem1"; + viewHelpToolStripMenuItem1.ShortcutKeys = System.Windows.Forms.Keys.F1; + viewHelpToolStripMenuItem1.Size = new System.Drawing.Size(146, 22); + viewHelpToolStripMenuItem1.Text = "&View Help"; + viewHelpToolStripMenuItem1.Click += viewHelpToolStripMenuItem1_Click; + // + // toolStripMenuItem16 + // + toolStripMenuItem16.Name = "toolStripMenuItem16"; + toolStripMenuItem16.Size = new System.Drawing.Size(143, 6); + // + // aboutToolStripMenuItem1 + // + aboutToolStripMenuItem1.Name = "aboutToolStripMenuItem1"; + aboutToolStripMenuItem1.Size = new System.Drawing.Size(146, 22); + aboutToolStripMenuItem1.Text = "&About"; + aboutToolStripMenuItem1.Click += aboutToolStripMenuItem1_Click; + // + // tileContainerMenu1 + // + tileContainerMenu1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { addGroupToolStripMenuItem1, toolStripMenuItem4, editToolStripMenuItem, toolStripMenuItem5, toolStripSeparator1, toolStripMenuItem2, toolStripSeparator2, toolStripMenuItem3, toolStripSeparator3, removeToolStripMenuItem }); + tileContainerMenu1.Name = "tileContainerMenu1"; + tileContainerMenu1.Size = new System.Drawing.Size(133, 176); + // + // addGroupToolStripMenuItem1 + // + addGroupToolStripMenuItem1.Name = "addGroupToolStripMenuItem1"; + addGroupToolStripMenuItem1.Size = new System.Drawing.Size(132, 22); + addGroupToolStripMenuItem1.Text = "&Add Tile"; + addGroupToolStripMenuItem1.Click += addGroupToolStripMenuItem1_Click; + // + // toolStripMenuItem4 + // + toolStripMenuItem4.Name = "toolStripMenuItem4"; + toolStripMenuItem4.Size = new System.Drawing.Size(132, 22); + toolStripMenuItem4.Text = "Add &Group"; + toolStripMenuItem4.Click += toolStripMenuItem4_Click; + // + // editToolStripMenuItem + // + editToolStripMenuItem.Name = "editToolStripMenuItem"; + editToolStripMenuItem.Size = new System.Drawing.Size(132, 22); + editToolStripMenuItem.Text = "&Edit"; + editToolStripMenuItem.Click += editToolStripMenuItem_Click; + // + // toolStripMenuItem5 + // + toolStripMenuItem5.Name = "toolStripMenuItem5"; + toolStripMenuItem5.Size = new System.Drawing.Size(132, 22); + toolStripMenuItem5.Text = "&Duplicate"; + toolStripMenuItem5.Click += toolStripMenuItem5_Click; + // + // toolStripSeparator1 + // + toolStripSeparator1.Name = "toolStripSeparator1"; + toolStripSeparator1.Size = new System.Drawing.Size(129, 6); + // + // toolStripMenuItem2 + // + toolStripMenuItem2.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { addRowToolStripMenuItem, removeRowToolStripMenuItem }); + toolStripMenuItem2.Name = "toolStripMenuItem2"; + toolStripMenuItem2.Size = new System.Drawing.Size(132, 22); + toolStripMenuItem2.Text = "Ro&w"; + // + // addRowToolStripMenuItem + // + addRowToolStripMenuItem.Name = "addRowToolStripMenuItem"; + addRowToolStripMenuItem.Size = new System.Drawing.Size(143, 22); + addRowToolStripMenuItem.Text = "A&dd Row"; + addRowToolStripMenuItem.Click += addRowToolStripMenuItem_Click; + // + // removeRowToolStripMenuItem + // + removeRowToolStripMenuItem.Name = "removeRowToolStripMenuItem"; + removeRowToolStripMenuItem.Size = new System.Drawing.Size(143, 22); + removeRowToolStripMenuItem.Text = "Remo&ve Row"; + removeRowToolStripMenuItem.Click += removeRowToolStripMenuItem_Click; + // + // toolStripSeparator2 + // + toolStripSeparator2.Name = "toolStripSeparator2"; + toolStripSeparator2.Size = new System.Drawing.Size(129, 6); + // + // toolStripMenuItem3 + // + toolStripMenuItem3.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { topToolStripMenuItem, upToolStripMenuItem, downToolStripMenuItem, bottomToolStripMenuItem }); + toolStripMenuItem3.Name = "toolStripMenuItem3"; + toolStripMenuItem3.Size = new System.Drawing.Size(132, 22); + toolStripMenuItem3.Text = "&Move"; + // + // topToolStripMenuItem + // + topToolStripMenuItem.Name = "topToolStripMenuItem"; + topToolStripMenuItem.Size = new System.Drawing.Size(114, 22); + topToolStripMenuItem.Text = "&Top"; + topToolStripMenuItem.Click += topToolStripMenuItem_Click; + // + // upToolStripMenuItem + // + upToolStripMenuItem.Name = "upToolStripMenuItem"; + upToolStripMenuItem.Size = new System.Drawing.Size(114, 22); + upToolStripMenuItem.Text = "&Up"; + upToolStripMenuItem.Click += upToolStripMenuItem_Click; + // + // downToolStripMenuItem + // + downToolStripMenuItem.Name = "downToolStripMenuItem"; + downToolStripMenuItem.Size = new System.Drawing.Size(114, 22); + downToolStripMenuItem.Text = "&Down"; + downToolStripMenuItem.Click += downToolStripMenuItem_Click; + // + // bottomToolStripMenuItem + // + bottomToolStripMenuItem.Name = "bottomToolStripMenuItem"; + bottomToolStripMenuItem.Size = new System.Drawing.Size(114, 22); + bottomToolStripMenuItem.Text = "&Bottom"; + bottomToolStripMenuItem.Click += bottomToolStripMenuItem_Click; + // + // toolStripSeparator3 + // + toolStripSeparator3.Name = "toolStripSeparator3"; + toolStripSeparator3.Size = new System.Drawing.Size(129, 6); + // + // removeToolStripMenuItem + // + removeToolStripMenuItem.Name = "removeToolStripMenuItem"; + removeToolStripMenuItem.Size = new System.Drawing.Size(132, 22); + removeToolStripMenuItem.Text = "&Remove"; + removeToolStripMenuItem.Click += removeToolStripMenuItem_Click; + // + // flowLayoutPanel1 + // + flowLayoutPanel1.AutoScroll = true; + flowLayoutPanel1.BackColor = System.Drawing.Color.Transparent; + flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + flowLayoutPanel1.Location = new System.Drawing.Point(6, 0); + flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); + flowLayoutPanel1.Name = "flowLayoutPanel1"; + flowLayoutPanel1.Size = new System.Drawing.Size(398, 417); + flowLayoutPanel1.TabIndex = 8; + flowLayoutPanel1.WrapContents = false; + // + // panel1 + // + panel1.BackColor = System.Drawing.Color.Transparent; + panel1.Controls.Add(flowLayoutPanel1); + panel1.Dock = System.Windows.Forms.DockStyle.Fill; + panel1.Location = new System.Drawing.Point(0, 24); + panel1.Margin = new System.Windows.Forms.Padding(0); + panel1.Name = "panel1"; + panel1.Padding = new System.Windows.Forms.Padding(6, 0, 0, 0); + panel1.Size = new System.Drawing.Size(404, 417); + panel1.TabIndex = 9; + // + // tileMenu1 + // + tileMenu1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { editToolStripMenuItem1, toolStripMenuItem6, toolStripSeparator4, removeToolStripMenuItem1 }); + tileMenu1.Name = "tileMenu1"; + tileMenu1.Size = new System.Drawing.Size(125, 76); + // + // editToolStripMenuItem1 + // + editToolStripMenuItem1.Name = "editToolStripMenuItem1"; + editToolStripMenuItem1.Size = new System.Drawing.Size(124, 22); + editToolStripMenuItem1.Text = "&Edit"; + editToolStripMenuItem1.Click += editToolStripMenuItem1_Click; + // + // toolStripMenuItem6 + // + toolStripMenuItem6.Name = "toolStripMenuItem6"; + toolStripMenuItem6.Size = new System.Drawing.Size(124, 22); + toolStripMenuItem6.Text = "&Duplicate"; + toolStripMenuItem6.Click += toolStripMenuItem6_Click; + // + // toolStripSeparator4 + // + toolStripSeparator4.Name = "toolStripSeparator4"; + toolStripSeparator4.Size = new System.Drawing.Size(121, 6); + // + // removeToolStripMenuItem1 + // + removeToolStripMenuItem1.Name = "removeToolStripMenuItem1"; + removeToolStripMenuItem1.Size = new System.Drawing.Size(124, 22); + removeToolStripMenuItem1.Text = "&Remove"; + removeToolStripMenuItem1.Click += removeToolStripMenuItem1_Click; + // + // MainForm + // + AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + BackColor = System.Drawing.Color.White; + BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + ClientSize = new System.Drawing.Size(404, 441); + Controls.Add(panel1); + Controls.Add(menuStrip1); + DoubleBuffered = true; + ForeColor = System.Drawing.SystemColors.ControlText; + Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + MainMenuStrip = menuStrip1; + MaximizeBox = false; + MinimizeBox = false; + MinimumSize = new System.Drawing.Size(300, 320); + Name = "MainForm"; + contextMenuStrip2.ResumeLayout(false); + menuStrip1.ResumeLayout(false); + menuStrip1.PerformLayout(); + tileContainerMenu1.ResumeLayout(false); + panel1.ResumeLayout(false); + tileMenu1.ResumeLayout(false); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.NotifyIcon notifyIcon1; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip2; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem1; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem13; + private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem14; + private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem15; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem showBigIconsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem alwaysOnTopToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem viewHelpToolStripMenuItem1; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem16; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem addGroupToolStripMenuItem; + private System.Windows.Forms.ContextMenuStrip tileContainerMenu1; + private System.Windows.Forms.ToolStripMenuItem addGroupToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem4; + private System.Windows.Forms.ToolStripMenuItem addRowToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem removeRowToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem topToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem upToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem downToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem bottomToolStripMenuItem; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem5; + private System.Windows.Forms.ContextMenuStrip tileMenu1; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem6; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + } +} + diff --git a/MainForm.cs b/MainForm.cs new file mode 100644 index 0000000..c4ac8ca --- /dev/null +++ b/MainForm.cs @@ -0,0 +1,1038 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text.Json; +using System.Threading.Tasks; +using System.Windows.Forms; +using RokettoLaunch.Models; +using RokettoLaunch.Windows.Forms; +using RyzStudio; +using RyzStudio.Windows.Forms; +using RyzStudio.Windows.ThemedForms; +using RyzStudio.Windows.ThemedForms.ButtonTextBox; +using RyzStudio.Windows.TileForms; + +namespace RokettoLaunch +{ + public partial class MainForm : Form + { + private readonly FileSessionManager _fileSessionManager; + + private bool _isBusy = false; + private bool _requestExit = false; + + + public MainForm() + { + InitializeComponent(); + + this.AutoScaleMode = AutoScaleMode.None; + this.Text = Application.ProductName; + + _fileSessionManager = new FileSessionManager(); + _fileSessionManager.OpenFileDialog = openFileDialog1; + _fileSessionManager.SaveFileDialog = saveFileDialog1; + _fileSessionManager.OnNewing += fileSessionManager_OnNewSession; + _fileSessionManager.OnLoading += fileSessionManager_OnLoadSession; + _fileSessionManager.OnSaving += fileSessionManager_OnSaveSession; + _fileSessionManager.OnClearing += fileSessionManager_OnClearSession; + _fileSessionManager.OnFilenameChanged += fileSessionManager_OnFilenameChanged; + + notifyIcon1.Text = Application.ProductName; + } + + protected async override void OnShown(EventArgs e) + { + base.OnShown(e); + + var args = WinApplication.GetCommandLine(); + + string jsonfigFilename = args.Where(x => (x.Key.Equals("o") || x.Key.Equals("open"))).Select(x => x.Value).FirstOrDefault(); + if (string.IsNullOrWhiteSpace(jsonfigFilename)) + { + jsonfigFilename = Path.ChangeExtension(Application.ExecutablePath, "jsonfig"); + } + + if (!string.IsNullOrWhiteSpace(jsonfigFilename) && File.Exists(jsonfigFilename)) + { + await _fileSessionManager.OpenSession(jsonfigFilename); + } + else + { + this.CurrentSession = new AppOptions(); + + InvalidateOptions(); + } + } + + protected async override void OnClosing(CancelEventArgs e) + { + base.OnClosing(e); + + if (this.CurrentSession == null) + { + this.CurrentSession = new AppOptions(); + } + + if (this.CurrentSession.HideOnClose && !_requestExit) + { + this.Visible = !this.Visible; + e.Cancel = true; + return; + } + + _requestExit = false; + + await _fileSessionManager.CloseSession(); + + if ((this.CurrentSession?.ShowToggleHotkey ?? new ThKeyCodeTextBox.Results()).Key != Keys.None) + { +#if !DEBUG + RyzStudio.Runtime.InteropServices.User32.UnregisterHotKey((IntPtr)Handle, 1); +#endif + } + } + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case RyzStudio.Runtime.InteropServices.User32.WM_HOTKEY: + if (m.WParam.ToInt32() == 1) + { + this.Visible = !this.Visible; + } + + break; + case RyzStudio.Runtime.InteropServices.User32.WM_QUERYENDSESSION: + _requestExit = true; + + Application.Exit(); + + break; + default: + break; + } + + base.WndProc(ref m); + } + + + public AppOptions CurrentSession { get; set; } = null; + + + private void InvalidateOptions() + { + /// todo: big icons + +#if !DEBUG + UIControl.Invoke(this, (x) => + { + RyzStudio.Runtime.InteropServices.User32.UnregisterHotKey((IntPtr)Handle, 1); + }); + + if ((this.CurrentSession?.ShowToggleHotkey ?? new ThKeyCodeTextBox.Results()).Key != Keys.None) + { + UIControl.Invoke(this, (x) => + { + RyzStudio.Runtime.InteropServices.User32.RegisterHotKey((IntPtr)Handle, 1, this.CurrentSession.ShowToggleHotkey.ModifierCode, this.CurrentSession.ShowToggleHotkey.KeyCode); + }); + } +#endif + + UIControl.SetTopMost(this, this.CurrentSession.AlwaysOnTop); + } + + private void menuStrip1_MenuActivate(object sender, EventArgs e) + { + closeToolStripMenuItem.Enabled = (_fileSessionManager.SessionState != FileSessionManager.SessionStateEnum.Close); + + saveToolStripMenuItem.Enabled = (_fileSessionManager.SessionState == FileSessionManager.SessionStateEnum.Open); + saveAsToolStripMenuItem.Enabled = (_fileSessionManager.SessionState != FileSessionManager.SessionStateEnum.Close); + + addGroupToolStripMenuItem.Enabled = (_fileSessionManager.SessionState != FileSessionManager.SessionStateEnum.Close); + + showBigIconsToolStripMenuItem.Checked = this.CurrentSession?.ShowBigIcons ?? true; + alwaysOnTopToolStripMenuItem.Checked = this.CurrentSession?.AlwaysOnTop ?? false; + } + + private void tileContainer_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Middle) + { + return; + } + + var control = (sender as Control); + if (control == null) + { + return; + } + + var container = UIControl.GetParentsUntil(sender as Control); + if (container == null) + { + return; + } + + var newCoord = container.GetNextCoord(); + + var tileModel = new TileModel() + { + Title = "New Tile", + IsGroup = false + }; + + var newTile = new RokettoLaunch.Windows.Forms.TilePanel(); + newTile.ContextMenuStrip = tileMenu1; + newTile.LoadInfo(tileModel); + + container.Add(newTile, newCoord.X, newCoord.Y); + + _fileSessionManager.HasChanged = true; + } + + #region Main Menu + + /// + /// New + /// + /// + /// + private async void newToolStripMenuItem_Click(object sender, EventArgs e) + { + if (_isBusy) + { + return; + } + + await _fileSessionManager.NewSession(); + } + + /// + /// Open + /// + /// + /// + private async void openToolStripMenuItem_Click(object sender, EventArgs e) + { + if (_isBusy) + { + return; + } + + await _fileSessionManager.OpenSession(); + } + + /// + /// Close + /// + /// + /// + private async void closeToolStripMenuItem_Click(object sender, EventArgs e) + { + if (_isBusy) + { + return; + } + + await _fileSessionManager.CloseSession(); + } + + /// + /// Save + /// + /// + /// + private async void saveToolStripMenuItem_Click(object sender, EventArgs e) + { + if (_isBusy) + { + return; + } + + await _fileSessionManager.SaveSession(); + } + + /// + /// Save As + /// + /// + /// + private async void saveAsToolStripMenuItem_Click(object sender, EventArgs e) + { + if (_isBusy) + { + return; + } + + await _fileSessionManager.SaveAsSession(); + } + + /// + /// Exit + /// + /// + /// + private void exitToolStripMenuItem2_Click(object sender, EventArgs e) + { + if (_isBusy) + { + return; + } + + _requestExit = true; + + this.Close(); + } + + + /// + /// Add group + /// + /// + /// + private async void addGroupToolStripMenuItem_Click(object sender, EventArgs e) + { + await AddNewTileGroup(); + } + + + /// + /// Show big icons + /// + /// + /// + private void showBigIconsToolStripMenuItem_Click(object sender, EventArgs e) + { + if (this.CurrentSession == null) + { + return; + } + + this.CurrentSession.ShowBigIcons = !this.CurrentSession.ShowBigIcons; + } + + /// + /// Always on top + /// + /// + /// + private void alwaysOnTopToolStripMenuItem_Click(object sender, EventArgs e) + { + if (this.CurrentSession == null) + { + return; + } + + this.CurrentSession.AlwaysOnTop = !this.CurrentSession.AlwaysOnTop; + + this.TopMost = this.CurrentSession.AlwaysOnTop; + } + + + /// + /// Options + /// + /// + /// + private void optionsToolStripMenuItem_Click(object sender, EventArgs e) + { + var form = new OptionsForm(this.CurrentSession); + if (form.ShowDialog() == DialogResult.OK) + { + this.CurrentSession = form.Result; + + InvalidateOptions(); + } + } + + + /// + /// View help + /// + /// + /// + private void viewHelpToolStripMenuItem1_Click(object sender, EventArgs e) + { + RyzStudio.Diagnostics.Process.Execute(AppResource.AppHelpURL); + } + + /// + /// About + /// + /// + /// + private void aboutToolStripMenuItem1_Click(object sender, EventArgs e) + { + var form = new RyzStudio.Windows.ThemedForms.AboutForm(); + form.ProductURL = AppResource.AppProductURL; + form.AuthorURL = AppResource.AppAuthorURL; + form.CompanyURL = AppResource.AppCompanyURL; + form.ProductCopyrightStartYear = 2020; + form.ProductLogo = AppResource.icon_64; + + form.ShowDialog(); + } + + #endregion + + #region Notification Icon + + private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + this.Visible = !this.Visible; + } + } + + private void exitToolStripMenuItem1_Click(object sender, EventArgs e) + { + _requestExit = true; + + this.Close(); + } + + #endregion + + + #region File Session Manager + + private async Task fileSessionManager_OnNewSession(FileSessionManager sender) + { + return await Task.Run(async () => + { + var form = new NewForm(); + if (form.ShowDialog() == DialogResult.OK) + { + var result = form.Result; + + UIControl.Clear(flowLayoutPanel1); + + this.CurrentSession.TilesPerRow = result.ColumnCount; + + for (var i = 0; i < result.GroupCount; i++) + { + await AddNewTileGroup(); + } + } + + AutoResize(); + + return true; + }); + } + + private async Task fileSessionManager_OnLoadSession(FileSessionManager sender, string filename, int formatType) + { + return await Task.Run(async () => + { + var result = GenericResult.Create(); + + switch (Path.GetExtension(filename?.ToLower()?.Trim() ?? string.Empty)) + { + case ".json": + case ".jsonfig": + this.CurrentSession = RyzStudio.Text.Json.JsonSerialiser.DeserialiseFile(filename); + break; + case ".jsnx": + this.CurrentSession = await RyzStudio.IO.Compression.ZFile.ReadFile(filename, "Document.json"); + break; + default: + this.CurrentSession = null; + break; + } + + if (this.CurrentSession == null) + { + ThMessageBox.Show(this, "Unable to read session", "Load session"); + + return false; + } + + if (this.CurrentSession == null) + { + this.CurrentSession = new AppOptions(); + } + + // Reposition + resize + if (!this.CurrentSession.StartPosition.IsEmpty) + { + UIControl.SetLocation(this, this.CurrentSession.StartPosition); + } + + if (this.CurrentSession.Height > 0) + { + UIControl.SetClientHeight(this, this.CurrentSession.Height); + } + + InvalidateOptions(); + + // Load tiles + await LoadTileGroups(this.CurrentSession.Groups); + + AutoResize(); + + UIControl.SetFocus(this); + + return true; + }); + } + + private async Task fileSessionManager_OnSaveSession(FileSessionManager sender, string filename, int formatType, bool showNotices) + { + if (string.IsNullOrWhiteSpace(filename)) + { + return false; + } + + if (!flowLayoutPanel1.Controls.OfType().Any()) + { + return true; + } + + return await Task.Run(async () => + { + if (_isBusy) + { + return false; + } + + _isBusy = true; + + // update session + if (this.CurrentSession == null) + { + this.CurrentSession = new AppOptions(); + } + + this.CurrentSession.StartPosition = this.Location; + this.CurrentSession.Height = this.Height; + + this.CurrentSession.Groups = new List(); + foreach (var container in flowLayoutPanel1.Controls.OfType()) + { + var newTag = (TileGroupModel)container.Tag; + if (newTag == null) + { + continue; + } + + newTag.Items = new List(); + + foreach (var tile in container.Controls.OfType()) + { + tile.ModelInfo.Position = container.GetCoord(tile); + + newTag.Items.Add(tile.ModelInfo); + } + + this.CurrentSession.Groups.Add(newTag); + } + + var result = GenericResult.Create(); + + switch (Path.GetExtension(filename?.ToLower()?.Trim() ?? string.Empty)) + { + case ".json": + case ".jsonfig": + result = RyzStudio.Text.Json.JsonSerialiser.SerialiseFile(filename, this.CurrentSession); + break; + case ".jsnx": + try + { + System.IO.File.Delete(filename); + } + catch(Exception) + { + // do nothing + } + + result = await RyzStudio.IO.Compression.ZFile.WriteFile(filename, "Document.json", this.CurrentSession); + break; + default: + result = GenericResult.Fault("Format not supported"); + break; + } + + if (result.IsSuccess) + { + if (showNotices) + { + ThMessageBox.Show(this, "Session saved!", "Save session", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + else + { + if (showNotices) + { + ThMessageBox.Show(this, "Session saved!", "Save session"); + } + } + + _isBusy = false; + + return result.IsSuccess; + }); + } + + private async Task fileSessionManager_OnClearSession(FileSessionManager sender) + { + await Task.Run(() => + { + UIControl.Clear(flowLayoutPanel1); + }); + + return true; + } + + private async Task fileSessionManager_OnFilenameChanged(FileSessionManager sender, string filename) + { + await Task.Run(() => + { + switch (sender.SessionState) + { + case FileSessionManager.SessionStateEnum.New: + UIControl.SetText(this, "New Session - " + Application.ProductName); + break; + case FileSessionManager.SessionStateEnum.Open: + UIControl.SetText(this, Path.GetFileNameWithoutExtension(filename) + " - " + Application.ProductName); + break; + case FileSessionManager.SessionStateEnum.Close: + UIControl.SetText(this, Application.ProductName); + break; + default: + break; + } + }); + } + + #endregion + + #region Tile Container + + /// + /// Add Tile + /// + /// + /// + private void addGroupToolStripMenuItem1_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripMenuItem)sender); + if (container == null) + { + return; + } + + var form = new EditTileForm(); + if (form.ShowDialog() == DialogResult.OK) + { + var result = form.Result; + var newCoord = container.GetNextCoord(); + + var newTile = new RokettoLaunch.Windows.Forms.TilePanel(); + newTile.ContextMenuStrip = tileMenu1; + newTile.LoadInfo(result); + + container.Add(newTile, newCoord.X, newCoord.Y); + + _fileSessionManager.HasChanged = true; + }; + } + + /// + /// Add Tile Group + /// + /// + /// + private void toolStripMenuItem4_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripMenuItem)sender); + if (container == null) + { + return; + } + + var form = new EditTileFolderForm(); + if (form.ShowDialog() == DialogResult.OK) + { + var result = form.Result; + var newCoord = container.GetNextCoord(); + + var newTile = new RokettoLaunch.Windows.Forms.TilePanel(); + newTile.ContextMenuStrip = tileMenu1; + newTile.LoadInfo(result); + + container.Add(newTile, newCoord.X, newCoord.Y); + + _fileSessionManager.HasChanged = true; + }; + } + + /// + /// Edit + /// + /// + /// + private void editToolStripMenuItem_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripMenuItem)sender); + if (container == null) + { + return; + } + + var model = UIControl.GetTag(container); + + var form = new EditGroupForm(model); + if (form.ShowDialog() == DialogResult.OK) + { + var result = form.Result; + + container.Title = result.Title; + container.Tag = result; + + container.Invalidate(); + + _fileSessionManager.HasChanged = true; + }; + } + + /// + /// Duplicate + /// + /// + /// + private async void toolStripMenuItem5_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripMenuItem)sender); + if (container == null) + { + return; + } + + var model = UIControl.GetTag(container); + model.IsExpanded = true; + + try + { + var newModel = JsonSerializer.Deserialize(JsonSerializer.Serialize(model)); + + await AddTileGroups(newModel); + } + catch (Exception) + { + return; + } + + _fileSessionManager.HasChanged = true; + } + + + /// + /// Row - Add Row + /// + /// + /// + private void addRowToolStripMenuItem_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripDropDownItem)sender); + if (container == null) + { + return; + } + + container.AddRow(); + + _fileSessionManager.HasChanged = true; + } + + /// + /// Row - Remove Row + /// + /// + /// + private void removeRowToolStripMenuItem_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripDropDownItem)sender); + if (container == null) + { + return; + } + + container.RemoveRow(); + + _fileSessionManager.HasChanged = true; + } + + /// + /// Move Top + /// + /// + /// + private void topToolStripMenuItem_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripDropDownItem)sender); + if (container == null) + { + return; + } + + UIControl.MoveTop(flowLayoutPanel1, container); + + _fileSessionManager.HasChanged = true; + } + + /// + /// Move Up + /// + /// + /// + private void upToolStripMenuItem_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripDropDownItem)sender); + if (container == null) + { + return; + } + + UIControl.MoveUp(flowLayoutPanel1, container); + + _fileSessionManager.HasChanged = true; + } + + /// + /// Move Down + /// + /// + /// + private void downToolStripMenuItem_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripDropDownItem)sender); + if (container == null) + { + return; + } + + UIControl.MoveDown(flowLayoutPanel1, container); + + _fileSessionManager.HasChanged = true; + } + + /// + /// Move Bottom + /// + /// + /// + private void bottomToolStripMenuItem_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripDropDownItem)sender); + if (container == null) + { + return; + } + + UIControl.MoveBottom(flowLayoutPanel1, container); + + _fileSessionManager.HasChanged = true; + } + + /// + /// Remove + /// + /// + /// + private void removeToolStripMenuItem_Click(object sender, EventArgs e) + { + var container = UIControl.GetOwner((ToolStripMenuItem)sender); + if (container == null) + { + return; + } + + flowLayoutPanel1.Controls.Remove(container); + + _fileSessionManager.HasChanged = true; + } + + #endregion + + #region Tile + + /// + /// Edit + /// + /// + /// + private void editToolStripMenuItem1_Click(object sender, EventArgs e) + { + var tile = UIControl.GetOwner((ToolStripMenuItem)sender); + if (tile == null) + { + return; + } + + if (tile.ModelInfo.IsGroup) + { + var form = new EditTileFolderForm(tile.ModelInfo); + if (form.ShowDialog() == DialogResult.OK) + { + tile.LoadInfo(form.Result); + + _fileSessionManager.HasChanged = true; + }; + } + else + { + var form = new EditTileForm(tile.ModelInfo); + if (form.ShowDialog() == DialogResult.OK) + { + tile.LoadInfo(form.Result); + + _fileSessionManager.HasChanged = true; + }; + } + } + + /// + /// Duplicate + /// + /// + /// + private void toolStripMenuItem6_Click(object sender, EventArgs e) + { + var tile = UIControl.GetOwner((ToolStripMenuItem)sender); + if (tile == null) + { + return; + } + + var container = UIControl.GetParentsUntil(tile); + if (container == null) + { + return; + } + + var newModel = new TileModel(); + + try + { + newModel = JsonSerializer.Deserialize(JsonSerializer.Serialize(tile.ModelInfo)); + } + catch (Exception) + { + return; + } + + var newCoord = container.GetNextCoord(); + + var newTile = new RokettoLaunch.Windows.Forms.TilePanel(); + newTile.ContextMenuStrip = tileMenu1; + newTile.LoadInfo(newModel); + + container.Add(newTile, newCoord.X, newCoord.Y); + + _fileSessionManager.HasChanged = true; + } + + /// + /// Remove + /// + /// + /// + private void removeToolStripMenuItem1_Click(object sender, EventArgs e) + { + var tile = UIControl.GetOwner((ToolStripMenuItem)sender); + if (tile == null) + { + return; + } + + var container = UIControl.GetParentsUntil(tile); + if (container == null) + { + return; + } + + container.Controls?.Remove(tile); + + _fileSessionManager.HasChanged = true; + } + + #endregion + + + private async Task AddNewTileGroup() + { + var group = new TileGroupModel(); + group.Title = "New Group"; + group.IsExpanded = true; + group.GridSize = new System.Drawing.Size(this.CurrentSession.TilesPerRow, 1); + + await AddTileGroups(group); + + _fileSessionManager.HasChanged = true; + } + + private async Task AddTileGroups(TileGroupModel model) + { + await Task.Run(() => + { + var panel = new RyzStudio.Windows.TileForms.TileContainer(); + panel.Title = model.Title; + panel.IsOpen = model.IsExpanded; + panel.TitleContextMenuStrip = tileContainerMenu1; + panel.PaddingBottom = 0; + panel.AutoSizeHeight = true; + panel.Tag = model; + panel.AutoSize(model.GridSize.Width, model.GridSize.Height); + panel.Height += 4; + + panel.MouseClick += tileContainer_MouseClick; + + UIControl.Add(flowLayoutPanel1, panel); + + // Load tiles + foreach (var item2 in model.Items ?? new List()) + { + var newTile = new RokettoLaunch.Windows.Forms.TilePanel(); + newTile.ContextMenuStrip = tileMenu1; + newTile.LoadInfo(item2); + + panel.Add(newTile, item2.Position.X, item2.Position.Y); + } + }); + } + + private void AutoResize() + { + if (flowLayoutPanel1.Controls.Count <= 0) + { + return; + } + + var width = 0; + foreach (var item in flowLayoutPanel1.Controls.OfType()) + { + width = Math.Max(width, item.Width); + } + + UIControl.SetClientWidth(this, width + panel1.Padding.Horizontal + this.Padding.Horizontal + SystemInformation.VerticalScrollBarWidth); + } + + private async Task LoadTileGroups(List groupList) + { + UIControl.Clear(flowLayoutPanel1); + + foreach (var item in groupList ?? new List()) + { + await AddTileGroups(item); + } + } + + } +} \ No newline at end of file diff --git a/MainForm.resx b/MainForm.resx new file mode 100644 index 0000000..4a573f9 --- /dev/null +++ b/MainForm.resx @@ -0,0 +1,736 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 172, 17 + + + 308, 17 + + + 448, 17 + + + 561, 17 + + + + + AAABAAQAMDAAAAEAIACoJQAARgAAACAgAAABACAAqBAAAO4lAAAYGAAAAQAgAIgJAACWNgAAEBAAAAEA + IABoBAAAHkAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGtZ + UytrW1Tra1tVuGxbUjsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGxaU0d0ZF7Ra1tU/2tbVPlrXFW1aVlVPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGlcVUtsW1T7dmdh/6yjn/lxYlv3bF1V6mtcVKprW1RDAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpcVDprW1T/cWJb///////08/L/s6un+XJk + XfVtXlfZbFtUlWtbVEwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxZUyhrW1T/a1tU//v6 + +v////////////f39v+4sK35dGRe9W5fWdVsXFSOallTTQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhd + URZrW1T/a1tU//Dv7v//////////////////////+Pf3/763tPx3aWL0c2Ndw2tbVHltWlNEAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIBAQARrW1T+a1tU/+Xj4f/////////////////////////////////5+fj/vre0/HZn + YfRzZV6+bFxTUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqWlTwa1tU/9vX1f////////////////////////////// + /////////////8fBvv9rW1T/a1tVygAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsW1X0a1tU/4N1b//Qy8n///////// + /////////////////////////////83Hxf9rW1T/a1tU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxdVSFqW1P+a1tU/2tb + VP9rW1T/louG/+3r6v///////////////////////////9LNy/9rW1T/a1tU3QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGtc + VKdrW1T/fXBq/3RlXv9rW1T/a1tU/3JjXP+/uLX//f39/////////////////9fT0f9rW1T/bFtU5gAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAalxVSGtbVP9rW1T/0czK//7+/v+poJz/bVxW/2tbVP9rW1T/jIB6/+zq6f///////////93Z + 1/9rW1T/a1tU8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABsWFgaa1tU6WtbVP+YjYj/////////////////7uzr/4J1b/9rW1T/a1tU/3Nk + Xf/KxMH//////+Lf3f9rW1T/a1tU+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGBgYAhrW1XEa1tU/3lqZP/x8O////////////////////////// + //+2rqn/bF1V/2tbVP9rW1T/opiU/+Dd2/9rW1T/a1tU/4BAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAAmtcVKprW1T/bV1W/9nV0/////////////// + ////////////////////////6OTk/3dpYv9rW1T/a1tU/3xuaP9rW1T/a1tU/2JiTg0AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgIACbFtUmmtbVP9rW1T/w7y5//// + //////////////////////////////////////////////39/f+UiYT/a1tU/2tbVP9rW1T/a1tU/2hd + URYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVVQNrWlSea1tU/2tb + VP+yqab/////////////////////////////////////////////////////////////////uLCu/2tc + Vf9rW1T/a1tU/2lZVlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbVtbDmtb + VLdrW1T/a1tU/6+mov////////////////////////////////////////////////////////////// + /////////////9DKyP9tXVb/a1tU/2tcVPRqW1RGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtVVUValpVMGheVRuAQEAEAAAAAAAAAAAAAAAAAAAAAAAA + AABsW1I7altU2mtbVP9sXFX/tKyo//////////////////////////////////////////////////// + ///////////////////////////////////o5uX/f3Js/2tbVP9rW1T2bFxUQAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrW1PfbV5XuWtbVP5rW1T9a1tU5Wtb + VcprW1Sxa1xUp2xbVNVrW1T9a1tU/29fWf/KxMH///////////////////////////////////////// + ////////////////////////////////////////////////////////8vHw/4N1b/9rW1T/a1tU82pc + VDoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrW1TVa1tU/2tb + VP9rW1T/a1tU/2tbVP9rW1T/a1tU/2tbVP9rW1T/iXx2/+Xi4f////////////////////////////// + //////////////////////////////////////////////////////////////////////////////Dv + 7v+Ac23/a1tU/2tbVO9qXVcpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABrW1Rwa1tU/763tP/Szcv/w7y5/7SsqP+jmZX/iXx3/2tbVP9sXFX/9vb1//////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////u7Oz/fW9p/2tbVP9rW1TdZllZFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABpWloRa1tU9ZaMhvH/////////////////////7+7t/21dVv9rW1T/rKSf//// + ////////////////////////////////////////////////////////9ebn/+S4vP/jt7r/47e6/+O3 + uv/jt7r/5r3A//rz8///////////////////////5ePh/3NkXf9rW1T/a1xUw21JSQcAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa1tUnWxcVfzw7+7//////////////////////5uQ + i/9rW1T/cmNc///////////////////////////////////////////////////////9+vr/yHB2/8Rl + bP/EZWz/xGVs/8RlbP/EZWz/xGVs/9SOk////////////////////////////9bRz/9tXlf/a1tU/2tb + VI8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaltSNWtbVP+0ran5//////// + /////////////97b2f9rW1T/a1tU/7atqf////////////////////////////////////////////// + ///25uf/xGVs/+/V1///////////////////////4bG1/8hwdv////////////////////////////// + //+7tLH/a1tU/2tbVP5sXFVOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGta + VMt2Z2D0/f39//////////////////////+aj4r/a1tU/29gWf/8+/v///////////////////////// + ///////////////////25uf/xGVs/+/U1v////////////P7///d8/7/0Ku1/8Zvdv/d8/7/3fP+//f8 + ///////////////////+/v7/louG/2tbVP9rW1TsbFhYGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGxaVWNrW1T/0czJ///////////////////////p5+b/bl5X/2tbVP+hl5L///////// + ///////////////////////////////////25uf/xGVs/+/U1v//////wOn+/wyo+f8ApPn/Y4Sy/7Zq + dv8ApPn/AKT5/xas+v/b8v7/////////////////8/Hx/3psZf9rW1T/alpVrwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFVVQlrW1TujoJ88P//////////////////////////qJ+a/2tb + VP9sXFX/6Obk///////////////////////////////////////25uf/xGVs/+/U1v//////aMn7/x+v + +v+q4f3/t6K0/8Judv+q4f3/quH9/wam+f+O1/z//////////////////////9POzP9rW1T/a1tU/2xa + VFUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrW1SPa1tU/uvo6P////////////// + ////////8/Ly/3hpY/9rW1T/fG5n///////////////////////////////////////25uf/xGVs/+/U + 1v//////Ysf7/y60+v//////4bG1/8hwdv///////////wmn+f+G1Pz///////////////////////// + //+flJD/a1tU/2xbVOZqVVUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsWVMoa1tU/qyk + oPf//////////////////////////87Ixv9rW1T/a1tU/6qhnv////////////////////////////// + ///47e7/xGVs/9ugpP/jt7r/j5m4/3SPt//jt7r/042T/8VwfP+ypPL/sqTy/wak+f9epPX/sqTy/8i+ + 9v/9/f/////////////z8fH/dGVf/2tbVP9rW1OBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAa1tUv3JiXPf6+vr///////////////////////////+ckYz/a1tU/2xcVf/a1tT///////// + ////////////////////////26Ck/8Vnbv/EZWz/xGVs/8RlbP/EZWz/xWlz/4ZOsv9bPeT/Wz3k/wOg + +P8wbu7/Wz3k/1s95P/AtPX/////////////////vLSx/2tbVP9rW1T0bFhYGgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAbFpUVWtbVP+lm5f/vbaz/8S9u//NyMX/087M/9jU0v/V0M7/cGFa/2tb + VP9vYFn/7+7t////////////////////////////////////////////Ysf7/y60+v//////rJ3x/2dL + 5v///////////wmn+f+G1Pz//////3NZ6P+gju///////////////////Pv7/39ya/9rW1T/a1tUkQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZmZmBWxbVOZrW1T/a1tU/2tbVP9rW1T/a1tU/2tb + VP9rW1T/a1tU/2tbVP9rW1T/emxl//v6+v//////////////////////////////////////Y8f7/yiy + +v/d8/7/lZ7y/1lX6P/d8/7/3fP+/win+f+I1fz//////3NZ6P+gju///////////////////////8bA + vf9rW1T/a1tU92ZcUhkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxbVVdrW1TJa1xT3Gxb + VOZrW1Tva1tU/2tbVP9rW1T/a1tU/2tbVP9rW1T/a1tU/52Sjv/8/Pz///////////////////////// + ////////o979/wCk+f8ApPn/AKT5/wCk+f8ApPn/AKT5/wGk+f/I6/7//////3NZ6P+gju////////// + //////////////z8/P99b2n/a1tU/2tbVIYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRdXQttVVUVaVpTIm1cUS9rXVSMa1tU/2tbVP+Zjon/+/r6//// + /////////////////////////////8jr/v+q4f3/c6D0/0Vp7P+q4f3/quH9/9Tw/v///////////3NZ + 6P+gju/////////////////////////////Aubb/a1tU/2tcVOptSUkHAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa1pUd2tb + VP9rW1T/lIiD//f39v//////////////////////////////////////rJ3x/2dL5v////////////// + /////////////3NZ6P+gju/////////////////////////////29fX/cmNc/2tbVP9qWlRbAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGxbVG1rW1T+a1tU/4N2cP/o5uX/////////////////////////////////tKbz/2FE + 5f+ypPL/sqTy/7Kk8v+ypPL/sqTy/2hM5v+nl/D/////////////////////////////////ppyY/2tb + VP9qW1W7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqXFRea1pU+GtbVP9zZF3/z8rI//////////////////// + ////////6+f8/3Zd6P9bPeT/Wz3k/1s95P9bPeT/Wz3k/3JY6P/l4Pv///////////////////////// + ////////3NjX/2tbVP9rW1T8b1lZFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbVpVNmtbU+JrW1T/a1tU/6CW + kf/z8vL///////////////////////////////////////////////////////////////////////// + /////////////////////////v7+/3xuZ/9rW1T/a1pVaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhd + URZrWlS6a1tU/2tbVP94aWP/ycPB//7+/v////////////////////////////////////////////// + /////////////////////////////////////////////6mgnP9rW1T/a1tUqwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABalxUXmtbVO1rW1T/a1tU/4R3cf/Tz83///////////////////////// + /////////////////////////////////////////////////////////////87Jx/9rW1T/a1tU6QAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1bUhxrWlWsa1tU/mtbVP9rW1T/joJ8/9HM + yv/+/v7///////////////////////////////////////////////////////////////////////Px + 8f9sXFX/a1tU/21bVSoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa1lVOWtc + VMNrW1T/a1tU/2tbVP+Bc23/u7Sx//Dv7v////////////////////////////////////////////// + //////////////////+Ed3H/a1tU/2taVWkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABqW1RGa1pUumtbVP9rW1T/a1tU/21dVv+ViYT/w7y5/+/u7f////////////// + //////////////////////////////////+mnJj/a1tU/2pbVJcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpaVTBrW1SYa1tU72tbVP9rW1T/a1tU/2xc + Vf+Fd3L/qaCc/83Hxf/n5eT//Pz8//////////////////////+5sq//a1tU/2tbVLcAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYGBgCGta + VFhrW1Sra1tU8mtbVP9rW1T/a1tU/2tbVP9rW1T/bl5X/4R3cf+cko3/sKik/7y0sf+jmZT/a1tU/2tb + U9YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAbUlJB2pbVEZrW1SGa1tVxGtaVPhrW1T/a1tU/2tbVP9rW1T/a1tU/2tb + VP9rW1T/a1tU/2tbVPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQARrXlcma1tVUWtc + VHprW1Ola1xUw2tbVNVsW1Tma1pU+GpbVLb//4f////xBP//gf////EE//+Af///8QT//4AP///xBP// + gAP///EE//+AAP//8QT//4AA///xBP//wAD///EE///AAP//8QT//4AA///xBP//gAD///EE//8AAP// + 8QT//gAA///xBP/8AAB///EE//gAAH//8QT/8AAAf//xBP/gAAB///EE/8AAAD//8QQPgAAAH//xBAAA + AAAP//EEAAAAAAf/8QQAAAAAA//xBAAAAAAB//EEgAAAAAH/8QSAAAAAAP/xBMAAAAAAf/EEwAAAAAB/ + 8QTAAAAAAD/xBOAAAAAAH/EE4AAAAAAf8QTwAAAAAA/xBPAAAAAAD/EE8AAAAAAH8QT4AAAAAAfxBP/g + AAAAA/EE//8AAAAD8QT//4AAAAPxBP//wAAAAfEE///gAAAB8QT///AAAAHxBP//+AAAAPEE///+AAAA + 8QT///+AAADxBP///+AAAPEE////+AAA8QT////+AADxBP/////AAPEE//////wA8QQoAAAAIAAAAEAA + AAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABoWFgga1xU6WtbVJFqWFgdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGtcUjJzY13yh3t18W9fWe5rW1SGaFhYIAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbVdXI2tbVP/Qy8n/7uzr/6SaleVzZF3kbF1Wdmpc + VSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpWloRa1tU/8a/vf////////////Lx + 8P+qoZ3pd2li22xcVW9rWlIfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFsXFX9u7Sx//// + ///////////////////y8fD/n5SQ7HZnX85tVVUVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG5d + VvmSh4L/7Orp///////////////////////c2Nb/a1tU/2tdUzcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABrWVMra1tU/m1eV/9uXlj/tq+r//z7+////////////+He3f9rW1T/bFxUQAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAgICAAmxcVsF2aGH83dvY/3tsZv9rW1T/hHVw/uLf3f//////5+Tj/2tbVP9sW1RJAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABrWlSFa1tU/8vGw////////////7Kppv9tXlf/bl5Y/722s//s6un/a1tU/2xc + U1MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAa1pUWGtbVP6rop7//////////////////////+rm5v96a2X/a1tU/42B + e/9rW1T/bFtTXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxcVU5tXFX5koaB/f38/P////////////////////////////7+ + /v+YjYn/bFxV/2tbVP9qWlNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrW1Nia1xV/IyAe/329fT///////////////////////// + //////////////////+4r6z/bFxU/21cVedvXlUeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAa1tVUWpaVFtrWlRPbVpVNmxYWBpsWFgaa1xTlmtbVP6XjIf++fn4//////////////////// + ///////////////////////////////////b19X/c2Ve/G1eVt9sWFgaAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABsXVXsbl5Y/WtbVP9rW1T/a1tU/2xbVP9sW1T+r6ai//38/P////////////// + ///////////////////////////////////////////////////h3t3/cmNd/G1dVtlxVVUSAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGtaU42UiYTs3tvZ/9DLyf/Aubb/emxm/3hpY/////////////// + ///////////////////////////////////////////////////////////////////e2tn/b2BZ/W1d + VsBmZmYFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaVxVJ29fWfP39/b///////////+4sK3/a1xV/9zY + 1v/////////////////////////////////z3uD/x210/8RlbP/EZWz/xGVs/9iYnf////////////// + ///OyMb/bFxV/2tbVJEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbVxVtr+3tfL///////////Dv + 7v9wYFr/gHNs/////////////////////////////////+W7vv/hsLP//////////////v7/x21z//// + //////////////////+wqKT/a1tU/m1aU0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrW1VRfnBq5v// + /////////////7Orp/9sXFX/zcnF////////////////////////////5bu+/+Gws///////c838/0W7 + +v+9anP/RLz7/1XC+//x+v////////z7+/+Fd3L8bV1W53FVVRIAAAAAAAAAAAAAAAAAAAAAAAAAAGZm + ZgVvXlfb3dnX/f//////////9/b2/3ZoYf90ZV7//f39///////////////////////lu77/4bCz/+75 + //8Yrfr/u+b8/8Rsc/+75/3/Q7z7/7Pk/f///////////+Xj4f9uXlj9bF1VpQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGtaVHeYjYjk////////////////zsjG/2tbVP+Zjon//////////////////////+a/ + wv/Xl5z/3sfO/1aXy//ry83/xm53/8i+9v9Irvj/ibX3/9TM+P/+/v///////7uzsP9rW1T/aVtSOAAA + AAAAAAAAAAAAAAAAAAAAAAAAbVtSHHFiW+jz8vL/////////////////m5CL/2xdVf/Jw8D///////// + ////////+fHx/9ugpP/Rlp3/jn2b/9iYnf+PWbj/kn7t/zWW9f9kifH/c1no/8/G9///////+/r6/3ps + ZvxtXVa+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbF1Ul2xdVv5zZF38e21n+4FzbfyBcmz+a1tU/25e + V//l4uL//////////////////////+z4//8er/r/7fj//1xN5//u+f//VcL7/7Dj/f+ikfD/v7T1//// + ////////xb+8/2tbVP9qWlJBAAAAAAAAAAAAAAAAAAAAAAAAAABoWFggbFxUgGtcU5lqW1SjbFtUrWpb + VbtsW1XQbVxW+35wa/zv7u3//////////////////////0u/+/8Rqvn/B573/xGq+f8rs/r/6Pf+/6KR + 8P+/tPX////////////9/Pz/fnBq/GxcVb8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABtWlU2bV1W8n1vafzr6ej///////////////////////7+//9jR+X///////// + ////////opHw/7+09f/////////////////Aubb/a1tU/mlaUyIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtWFMxbV1W7nRlX/zW0tD//////////////////////2xS + 5/+Sfu3/kn7t/5J+7f9zWej/zsX3//////////////////Py8v9tXlf9a1tTgQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpWlMibV1X02xcVf6vp6P/+vr6//// + ////////5uH7/8i+9v/Ivvb/yL72/9LK+P/+/f///////////////////////5uQjP5uXlbjAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmZk0Ka1xTmWtb + VP6AcWv8087M////////////////////////////////////////////////////////////y8bD/2tb + VP9rXlcmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAbVpTRGxdV91rW1T/jYF8/dDLyf/9/f3///////////////////////////////////////// + ///w7u7/a1tU/2pbU2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAZmZmBWtbU2ttXVbma1tU/3psZfy3r6z/7+7t//////////////////// + //////////////////9/cWv7a1tTogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQARqWlRSbFxVvWtbVP5sXFX/hXhy/a6m + ov/W0tD/9PPy/////////////////5yRjP9tXVfLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbFlTKGtc + VHpsXFXBbFtU+2tbVP9rW1T/dmdh/JGFgP6flZD/g3Zw/21eVuwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABqVVUMa1pTSmtaVHdsWlShbV1WzG1eV+VtXFb0bV1W3//h////4H///+Af///g + B///4AP///AD///gA///wAP//8AD//+AA///AAP//gAB/wAAAP8AAAB/AAAAPwAAAD+AAAAfgAAAD4AA + AA/AAAAHwAAAB+AAAAPgAAAD/8AAAf/gAAH/8AAB//gAAP/+AAD//wAA///AAP//+AD///8AKAAAABgA + AAAwAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAaF5VG25gWeBuXVZ5YmJODQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbF1VIW5eV/zBu7frgHNt13Fi + WmNqVVUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAZlVVD2tbVP/6+vr//v7+/8rEwuuKf3jHd2pjTWZmZgUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWxc + Vfzv7u3////////////+/v7/vLaz8HlrZLoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcVVVCXBgWv2JfXf94d7c////////////5+Xk/29f + WfMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAbF5Wf4V4c/aNgnz9bV5X/6qhnf36+vr/7Orq/25dV/kAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrW1RDb19Y+eLf3f//////0MrI/3Rk + Xv6Bcmz+2dXT/2tbVP4AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAG1bVSpvX1nyycPB/v////////////////n5+f+IenT9bl9Y/2tbVP9xVVUJAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaVtSOG9fWfK1rqr7//////// + ////////////////////////o5qW/mxdVf9tXFReAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG5f + WHRrW1SGbFtUbWpbVVdrW1eMbl5X+cC6t/7//////////////////////////////////////////9PP + zf9vX1j5a1pUTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHNkXdyZjon7joJ89HttZ/hvYVn/2NTS//// + ///////////////////////////////////////////////////RzMr/bl9X+GpZVTwAAAAAAAAAAAAA + AAAAAAAAAAAAAGtaVWm6s7Dk//////38/P91Zl/+uLGt/////////////////////////v7/2Z2h/9SO + k//UjpP/3qmt////////////xL67/m9fWPRtV1cjAAAAAAAAAAAAAAAAAAAAAGJiTg17bGfd//////// + //+4sKz+dmhh/f7+/v/////////////////68vP/2p2i///////z+///0I6W/+75///9/v///////6qh + nPtxYlzNVVVVAwAAAAAAAAAAAAAAAAAAAABwYVmb29bU9f/////5+fj/dmdg/quinv////////////// + ///68vP/2p2i/8rs/v81t/r/pX+V/1XC+/9ix/v///////r5+f9/cmv3b19YfAAAAAAAAAAAAAAAAAAA + AABpWVMuj4N92v//////////zsjG/29hWf/o5uT////////////79PX/1I6T/7XB1/+iu9f/zoWN/9PL + +P88r/n/29T5//7+///i393/bl5Y+mtaUh8AAAAAAAAAAAAAAAAAAAAAdGVfytnV0//j397/6+no/5CE + fv15a2X9+/r6////////////58DC/7ugsP+vnLD/oXPA/6iY8f8voff/h3Hr/9jR+f//////oZeS+XFh + W6MAAAAAAAAAAAAAAAAAAAAAbFxTUG9gWPBtXlb4a1tU/2tbVP9rW1T/kYaB+/7+/v///////////8Hp + /v88ufr/N5Dz/2bI+/9Xw/v/uazz/8/G9///////7Orq/25eWPpuWlMlAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHBgUBBrXFIycGBa5qSalvr9/f3////////////W8P7/bn7v/8zt/v/0+///uazz/8/G + 9////////////6CWkflvYFmPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbVtSHHFg + Wt6Qg3738/Ly////////////nYvv/4dx6/+Hcev/eWHp/+Pe+v///////////9vX1f9wYFrvgEBABAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1bWw5xYlu0c2Rd+MW/vP/+/v7///////// + //////////////////////////////7+/v95amP1a1tUQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAa1tVUXBhWuiHeXT21dHP//7+/v////////////////////////////// + //+jmZT5bF1VhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZm + TQpuXlaCcGBZ8HttZ/a8tLH+6efm///////////////////////Jw8H/dGReywAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbUlJB2paVFtyY13JbFxV/Hhq + ZPaglZH6u7Sx/9LNy//Gv73/cWJb7QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYmJODWxcVU5qW1SJc2RdvXNjXONvX1j0bl5X7f8P + /0H/A/9B/wD/Qf8A/0H/AP9B/wD/Qf4Af0H8AH9B+AB/QQAAP0EAAB9BAAAPQQAAB0GAAAdBgAADQcAA + A0HAAAFB/AABQf8AAEH/gABB/+AAQf/wAEH//ABB//+AQSgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZZWRR3Z2LZeWpmZ4BVVQYAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtW1sOkIN/5eTi4PSnnprDin54V1VV + VQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIJzbfD9/f3//////9zY + 1vaCdG+VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFiWkSDdm/3hHZx+9rW + 1f3y8PD/f3FquwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhdURZ+cGri8/Hx/+nn + 5v+Bc236rKSg+X5wa8YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpgVRh7bWfZ4d7c/v// + /////////f39/5WKhfh3aWPrbUlJBwAAAAAAAAAAAAAAAAAAAAB6amSyfm9puHpsZraAcmzm4+Df/v// + ////////////////////////ysPB+HlsZbuAgIACAAAAAAAAAAAAAAAAh3p0rOrn5v+6s7D9mI2I+f// + //////////////Ha3P/jt7r/6sfK//////++uLX0e21mogAAAAAAAAAAAAAAAG9fVj7Szszk+/r6/35w + a/zy8fD////////////jtbn/5fb+/66iuP+m3/3//////6CWke1zZF1SAAAAAAAAAAAAAAABnZKNuP// + ///Oycf7iHx2+f//////////4rO2/43E6P/PprH/icv7/8rf+//5+Pj/gHFr5G1bWw4AAAAAAAAAAH5x + amOzqqfxvbaz935wav2rop75//////bp6v+ar8z/sZrV/3+19/+PnfL/5+P7/83Hxfp7bWeNAAAAAAAA + AACAVVUGa1tUQ2xaVFVsWlNmd2hh19DLyPn/////3PP+/16j9f+V2f3/zsb3/9/a+v/+/v7/gnRv5GBg + YAgAAAAAAAAAAAAAAAAAAAAAAAAAAHFVVQl5bGW9t6+r9P38/P/b1Pn/sqTy/6+h8v/29P7//////7y1 + svR0ZF5cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAAndpY3yBdG3l19PR/f7+/v////////////// + ///u7Oz/f3BquQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZlxSGXttZ5+Acmzmtq2q8+He + 3P/8/Pz//////4FzbdwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZmZNCm5e + VVF8b2moe21n2YBzbeNyYlvu+H+sQfgfrEH8H6xB+B+sQfAfrEHgD6xBAAesQQAHrEEAA6xBAAGsQYAB + rEGAAKxB+ACsQfwArEH/AKxB/8CsQQ== + + + + 716, 17 + + + 831, 17 + + + 990, 17 + + + + AAABAAQAMDAAAAEAIACoJQAARgAAACAgAAABACAAqBAAAO4lAAAYGAAAAQAgAIgJAACWNgAAEBAAAAEA + IABoBAAAHkAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kqyjn1BtXVbuc2Rex5uOiWP///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////KpaMh2Z6a2TYa1tU/2xcVftzZFzKkISAbvn5+Sz///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////KpaJhGhrW1T9d2hh/722s/x5amT1b19Z73Nk + XcWLfnh57+npL////yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KqKalFhrW1T/cGBZ//// + ///8/Pz/yMPA/n5xa/RwYFrvc2NdyIZ5c4fZ1dU2////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KrWu + qkhrW1T/a1tU//n5+P////////////7+/v/Szcv/jIF78nRmX+l1Z2C9joF8dc/Kxjr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////KtXRzDdrW1T/a1tU/+7s6////////////////////////////93Z1/+Th4Lzd2li6nhq + Y7SShoJuwr66P////yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kvn5+StrXFX8a1tU/+Pf3v////////////////////////////// + ////////5uPi/5KFgPdzY1zwhHdyif///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yptXVfxa1tU/8vFw/////////////// + /////////////////////////////8jDwP9rW1T/cWFb1f///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kvn5+SttW1X5a1tU/2xc + Vf+aj4r/6+jo/////////////////////////////////87Jx/9rW1T/b2Ba3v///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KpKG + gm5rW1T/a1tU/2tbVP9rW1T/cGFa/7avq//7+vr//////////////////////9TPzf9rW1T/bl5Y5v// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q2dnUNW5fV+drW1T/o5mV/7Oppv9uX1j/a1tU/2tbVP+Bc23/2dXT/////////////////9rW + 1P9rW1T/bV1W7v///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8qd2ljsmtbVP92Z2H/8/Hx///////49/f/l4yH/2xbVf9rW1T/bFxV/6ad + mP/5+Pj//////9/c2v9rW1T/bFxV9v///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yqFeHKGa1tU/2tbVP/Nx8X//////////////////////9vX + 1f92Z2D/a1tU/2tbVP+CdW//4d7c/+Xi4f9rW1T/a1tU/fn5+Sv///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////KpCEgG5rW1T8a1tU/6yjn/////////////// + ///////////////////+/v7/oJaR/2tcVP9rW1T/bl5X/6mgnP9rW1T/a1tU/+bg4DL///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8ql4uGZWxbVflrW1T/lYmE//z8 + /P///////////////////////////////////////////9jT0v9xYlz/a1tU/2tbVP9rW1T/a1tU/8/K + xjr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yqTh4JqbFxU+Gtb + VP+Lfnn/+Pf3///////////////////////////////////////////////////////4+Pj/iHx2/2tb + VP9rW1T/a1tU/6yiok3///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KoR3 + colrW1T8a1tU/42BfP/29fT///////////////////////////////////////////////////////// + /////////////6CXkv9rW1T/a1tU/29gWt3AuLRB////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yrLx8c7dmhhtmtbVP9rW1T/lImE//n4+P////////////////////////////////////////////// + ///////////////////////////////////CvLn/cWJa/2tbVP9vX1njvrezQ////yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///ypzZFzKdWZfu25fWOhxYlvSdWZfvnts + ZaaAcm2ThXhxiHlpYrFtXVbua1tU/2tbVP+tpKD//fz8//////////////////////////////////// + ////////////////////////////////////////////////////////4d7d/3ZnYf9rW1T/bl5Y47y0 + sET///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///ypuXljma1tU/2tb + VP9rW1T/a1tU/2tbVP9rW1T/a1tU/2tbVP9rW1T/e2xm/9LNy/////////////////////////////// + /////////////////////////////////////////////////////////////////////////////+Th + 3/93aGH/a1tU/25eWOPCvro/////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yqCdG+Ra1tU/7SsqP/Bu7j/tKyo/6Salv+Wi4b/f3Jr/2tbVP9sXFX/9PPy//////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////k4eD/d2hh/2tbVP9wYlvW2dnUNf///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yrMxMQ8bFxU+JySjfX/////////////////////7Orq/2xcVf9rW1T/sqmm//// + ////////////////////////////////////////////////////////+Ozt/+W7vv/jt7r/47e6/+O3 + uv/jt7r/6MLF//z39///////////////////////39za/3FhW/9rW1T/dGVfxO7u7i7///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8qeWpjr2xdVvzx8O///////////////////////5mO + iv9rW1T/c2Nd///////////////////////////////////////////////////////9+vr/yXF4/8Rl + bP/EZWz/xGVs/8RlbP/EZWz/xGVs/9WSl////////////////////////////9PPzf9tXlf/a1tU/31v + aJ////8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8qp56YVGtbVP+0q6j6//////// + /////////////+Dc2/9sXFX/a1tU/7Oqp/////////////////////////////////////////////// + ///25uf/xGVs/+/V1///////////////////////4bG1/8hwdv////////////////////////////// + //+/uLX/a1tU/2tbVP6QhIBu////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KnNj + XM92ZmD3/Pv7//////////////////////+flZD/a1tU/25fWP/39/f///////////////////////// + ///////////////////25uf/xGVs/+/U1v///////////+f2/v/M7f7/yKi1/8Rvdv/M7f7/zO3+/+35 + ////////////////////////nZOO/2tbVP9sXFXztq+rRv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////KpCDfnNrW1T/ysTC/v/////////////////////u7Oz/cWFb/2tbVP+Wi4b///////// + ///////////////////////////////////25uf/xGVs/+/U1v//////s+T9/wOl+f8ApPn/Y4Sy/7Zq + dv8ApPn/AKT5/wuo+f/W8P7/////////////////9/f2/4J1b/9rW1T/c2Rcyvn5+Sz///8q////Kv// + /yr///8q////Kv///yr///8q////Ku7u7i5uXVfohXdy8v//////////////////////////ta2p/2tb + VP9rW1T/2dTT///////////////////////////////////////25uf/xGVs/+/U1v//////ZMj7/yWx + +v/M7f7/yKi1/8Rvdv/M7f7/zO3+/wem+f+K1fz//////////////////////+Dd2/9tXlf/a1tU/4Z5 + c4f///8q////Kv///yr///8q////Kv///yr///8q////Kv///yqAc2ySa1tU/+Dc2/////////////// + ////////+/r6/4V4cv9rW1T/cmNc//r6+v/////////////////////////////////25uf/xGVs/+/U + 1v//////Ysf7/y60+v//////4bG1/8hwdv///////////wmn+f+G1Pz///////////////////////// + //+yqqb/a1tU/2xcVfbAuLRB////Kv///yr///8q////Kv///yr///8q////Kv///yrIxL88bFxU+JyR + jfT//////////////////////////+Pf3v9uX1j/a1tU/4+Dfv////////////////////////////// + ///79PT/xWdu/8+DiP/UjpP/qn+S/5x6kv/UjpP/y3mA/79ugv+Hcev/h3Hr/wWi+P9HifH/h3Hr/6CP + 7//08v3////////////8+/v/gXNt/2tbVP94aWKz////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8qeGhjsGxdVvzx8O////////////////////////////+3r6z/a1tU/2tbVP+zq6f///////// + ////////////////////////6sfK/9WRlv/UjpP/qn+S/5x6kv/UjpP/wX2Y/3ZJyv+Hcev/h3Hr/wWi + +P9HifH/h3Hr/2FF5f+ypPL/////////////////08/N/2tbVP9rW1T+oJiSWf///yr///8q////Kv// + /yr///8q////Kv///yr///8qpZyZVWtbVP9+cGr9kYWA/5WKhf+cko3/pJuW/6mgnP+upqL/cWFb/2tb + VP9rW1T/ycTB////////////////////////////////////////////Ysf7/y60+v//////rJ3x/2dL + 5v///////////wmn+f+G1Pz//////3NZ6P+gju///////////////////////5WJhP9rW1T/c2Rdxf// + /yr///8q////Kv///yr///8q////Kv///yr///8q////KnJjXcxrW1T/a1tU/2tbVP9rW1T/a1tU/2tb + VP9rW1T/a1tU/2tbVP9rW1T/bl5X/+fk4///////////////////////////////////////cMz8/xas + +v93zvz/UKD1/zB68P93zvz/d878/wSl+f+U2fz//////3NZ6P+gju///////////////////////+He + 3P9sXFX/a1tU/6CVj1v///8q////Kv///yr///8q////Kv///yr///8q////KsK+uj+KfXd8hHdyiYJ0 + b5F+cWqce2xlpnlqZK12aGG4dGVew3NkXM9sXFX4a1tU/3hqY//j397///////////////////////// + ////////1fD+/zO2+v8Rqvn/C6P4/wee9/8Rqvn/Ear5/0G7+//r+P///////3NZ6P+gju////////// + //////////////////+YjYj/a1tU/3VmYMD///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yq2r6tGbl9Y5WtbVP9zZF3/2tbU//// + ////////////////////////////////////////rJ3x/2dL5v///////////////////////////3NZ + 6P+gju/////////////////////////////d2df/a1tU/2tbVP21rqpI////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8qwLi0QW9g + WdxrW1T/cGBZ/8W/vP//////////////////////////////////////rJ3x/2dL5v////////////// + /////////////3NZ6P+gju//////////////////////////////////h3t1/2tbVP98bmig////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////KtLJyTlxYlzQa1tU/2tbVP+hl5L/+fj4////////////////////////////zcT3/1s9 + 5P9bPeT/Wz3k/1s95P9bPeT/Wz3k/1s95P/Ct/X/////////////////////////////////xL27/2tb + VP9uXVfr9O7uLf///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yrl5eUxeWxmqGtbVP9rW1T/gnRu/9vX1f////////////// + /////////////9TM+P+ypPL/sqTy/7Kk8v+ypPL/sqTy/8/H9//+/f////////////////////////// + ////////9vX0/3BgWf9rW1T/l4uGZf///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Ko2Ce3RsXVX1a1tU/2xc + Vf+km5b/9fPz//////////////////////////////////////////////////////////////////// + /////////////////////////////5mOiv9rW1T/fGxmpf///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yq6s69GdGVfwmtbVP9rW1T/cmNc/7CopP/39vb///////////////////////////////////////// + /////////////////////////////////////////////8K7uf9rW1T/cGFa2////yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Ko+CfXRuXlfqa1tU/2tbVP94aWP/uLGt//Py8v////////////// + /////////////////////////////////////////////////////////////+nn5v9rW1T/a1tU/sK+ + uj////8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yrg4NsyhHZwjWxeVvBrW1T/a1tU/3Bh + Wv+lm5f/3drY//7+/v////////////////////////////////////////////////////////////// + //97bWf/a1tU/46BfHX///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KtXR + 0TeBdW+Obl9Y6GtbVP9rW1T/a1tU/39xa/+yqab/3tvZ//7+/v////////////////////////////// + //////////////////+glpH/a1tU/3xuZ6P///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q7u7uLo+CfXRzY13Ia1tU/WtbVP9rW1T/a1tU/3doYf+dko7/wLm2/+He + 3f/6+vr///////////////////////////+2r6v/a1tU/3VnYL////8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8qwLy4QYR1cItyY13Oa1tU/Gtb + VP9rW1T/a1tU/2tbVP9sXFX/f3Fr/5WKhf+upaH/wbu4/8vFw/+rop7/a1tU/3BgWtr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8qz8rGOo2Ce3R6bGWncGBZ2WtbVP1rW1T/a1tU/2tbVP9rW1T/a1tU/2tbVP9rW1T/a1tU/2xd + VfX///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////KuDg2zKpnZpTj4J9dIBxbJd2aGG4cWNbz29g + Wt5tXlbsbFtV+XRlX8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////yBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAA + AAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA + 8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAA + AAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA + 8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAA + AAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA + 8gQAAAAAAADyBAAAAAAAAPIEAAAAAAAA8gQAAAAAAADyBAAAAAAAAPIE////////8gQoAAAAIAAAAEAA + AAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kry0sERvX1nse21npravq0b///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8qp56YVHJiXPeUiITzdWdg7X1vaaGuqKRM////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yq5sbFFa1tU/8/Kx//5+Pj/wbq484N1 + cOSAc22pubGxRf///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KtnZ1DVrW1T/w726//// + /////////v7+/9HLyfePhH7fin13oc/Kxjr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Km1c + Vvu4sK3////////////////////////////DvLr8cGJa87avq0b///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr09PQtbV1X/HdoYv+6sq//+vr6/////////////////97a2f9rW1T/n5aRWv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kol6dn9rW1T/fG9p/2tcVf99cGj/087M////////////5OHf/2tbVP+bjolj////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yqto6BObl5X9pyRjP7/////ysTC/3NkXv5rW1T/m5GM//Py8v/q5+b/a1tU/5SI + g2v///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8qw7u7QHBgWumAcWv89PPy/////////////f39/56Tj/9tXVb/d2dh/8S+ + u/9rW1T/j4J9dP///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////KsjEvzxyY1zZdWdg/Ovo6P///////////////////////////9vW + 1v9zZF3+a1tU/2tbVP+KfXd8////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yqto6BOcWFZ53RlX/zg3Nv///////////////////////// + //////////////r5+f+HenX/a1tU/3FjXM/v6ekv////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8qta6qSKWcllXAvLhB7u7uLv///yr5+fkri4F6eW5fV/V+cWv86ufm//////////////////// + //////////////////////////////////+vpqL/bF1W/nZnYcPl5eUx////Kv///yr///8q////Kv// + /yr///8q////Kv///ypvX1nsc2Nc92tbVP9rW1T+cGBZ8G5eWPprW1T/l4yH/fTz8v////////////// + ///////////////////////////////////////////////////Pysj/bV5X/XVlX8fl5eUx////Kv// + /yr///8q////Kv///yr///8q////KnprZamWi4Xxz8rH/8C5tv+yqab/dmdh/3lpZP////////////// + ///////////////////////////////////////////////////////////////////Szcv/bV1W/Xdo + Yrv09PQt////Kv///yr///8q////Kv///yr///8qsKaiTXFiW/L6+vr///////////+1rar/bFxV/97a + 2f/////////////////////////////////z4OL/y3d9/8hvdv/Ib3b/yG92/9qfo/////////////// + ///KxMH/bFxV/3xvaZ7///8q////Kv///yr///8q////Kv///yr///8qdGZgxcS+u/L///////////Lw + 8P9xYVv/f3Fr/////////////////////////////////+W7vv/hsLP//////////////v7/x21z//// + //////////////////+0rKj/a1tU/pSKhmn///8q////Kv///yr///8q////Kv///yqWjIdmfG5p7P// + /////////////7uzsP9sXFX/wbu4////////////////////////////5bu+/+Gws///////WcT7/yOv + +f+8aXP/IrD6/zu5+v/q+P////////7+/v+QhH/9bl9X8r63s0P///8q////Kv///yr///8q////Kvn5 + +StyYlvg2NTS+v///////////Pv7/4FzbP9wYVr/8/Lx///////////////////////lu77/4bCz/+z4 + //8crvr/3fL9/8Vsc//d8/7/UMH7/7Dj/f///////////+/u7f91Zl/8dGVfzPn5+Sv///8q////Kv// + /yr///8q////Koh7dYGNgXzn////////////////4d7d/21eV/+CdW7//////////////////////+nG + yf/RiI3/16qx/3iIr//frLD/xXB8/6iY8f89oPb/c5vz/7Ch8v/39v7//////8/KyP9rW1T/kIN+c/// + /yr///8q////Kv///yr///8q4ODbMm9gWfHMxsT/2NTS/+He3f/n5OP/qaCc/2tbVP+dk47///////// + /////////vv8/+vKzf/bvcT/YZHB/+bAxP92TdH/vbH0/0Sp9/+CrPX/hnDr/8W79f///////////4+D + ff1xYlvm6uTkMP///yr///8q////Kv///yr///8qf3Fql2tbVP9rW1T/a1tU/2tbVP9rW1T/a1tU/2tc + Vf+/uLX///////////////////////P7//8Vq/n/h9T8/zVz7v+I1fz/MbX6/7vn/f+ikfD/v7T1//// + ////////4N3b/2xcVf+Ed3KJ////Kv///yr///8q////Kv///yr5+fksubGxRaifm1KgmJJZm46JY5KG + gm6NgXx3cmJc02xcVf7Bu7j//////////////////////7Lk/f+H1Pz/NXPu/4jV/P+a2/3/+/7//6KR + 8P+/tPX/////////////////nZKO/nBhWe307u4t////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr07u4teGpkrmtbVP+tpKD//Pz8//////////////////7+//9jRuX/3tj6/97Y + +v/e2Pr/lIDt/8G19f/////////////////c2Nb/a1tU/5KGgm7///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr5+fkrgHNskmxcVf2JfHb86Obl/////////////////6uc + 8f+Hcev/h3Hr/4dx6/+Oeuz/7uv8//////////////////////+CdG78dmZgxf///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8qnJGMX3BhWutuXlj9tKuo//j3 + 9////////////////////////////////////////////////////////////7y0sf9sXFX90snJOf// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q2dnUNXxt + Z6FrXFX8dWdg/LuzsP/08/L/////////////////////////////////////////////////5ePh/2tb + VP+QhIBu////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////KrOsqUp4amO1bFxV/W5eWP2elI/+2NTS//7+/v////////////////////////////// + ///+/v7/d2hi/HtsZab///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yrAuLRBgHNsknFiWuhrW1T/eGlj/KCWkf/GwL3/7Orp//// + //////////////////+YjYj/dGVez////yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q+fn5LJuOiWN7bWekcmNc3mtb + VP9rW1T/cWJb/Il7dvyglpL/r6ai/4p9eP9wYVnt////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8qycDAPY+EgHCAcm2UdmhhtXJkXdlxYlrrbV5X93BgWeQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////KAAAABgA + AAAwAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///yr///8q////Kv///yr///8q////Kv///yr///8qwLi0QXNjXeeEdnCZxcG9Pv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8qvrezQ2xdVvzVz832lIeC3Yl8eKDCvro/////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q4ODbMmtb + VP/39/b//////+Xj4fuonprclYmEptXRzDf///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Km5eWPzg3dv/////////////////3drY/3Vl + X+r///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8qrqikTHBhWv1xYlv/pJuX/PTz8v//////6efm/29gWff///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yrh3Nwzd2hh3bSsqPzc2df/fG5o/HJi + XP7KxMH+7+7t/2xcVfz///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8q////Ku7u7i55a2XKlouG+P39/f///////////7u0sP9xY1v+joF7/GtbVP/u7u4u////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q1dHMN3lqZM2MgHr3+vn5//// + ///////////////////u7Oz/fG1n/GtbVP+pn5xQ////Kv///yr///8q////Kv///yr///8q////KpuR + i2GTiIFtn5aRWrmxrkWTjIdodWVf6KCUkPn7+vr//////////////////////////////////v7+/6Wb + mPxxYlvzq6WeT////yr///8q////Kv///yr///8q////KnNkXeiIe3b1fXBq9HJjW/txYVr/xr+9/v// + ///////////////////////////////////////////////////Aubb9cWJb8rCmok3///8q////Kv// + /yr///8q////Kod6dIa/uLXq//////z7+/90ZV7+vLSx/////////////////////////v7/3aaq/9iY + nf/YmJ3/4bG1////////////vre0/XJiXPK5sbFF////Kv///yr///8q////Kt3Y2DR+cGri/v7+//// + //+8s7D+dWdg/fz8/P/////////////////68vP/2p2i///////j9f7/y42W/93z/v/3/P///////6+n + o/t2aGHa7+npL////yr///8q////Kv///yqAc22f0szK8v/////8/Pz/fXBp/pyTjv7///////////// + ///68vP/2p2i/8Lp/v9Gvfv/r4KV/3fO/P9Yw/v///////38/P+Kfnn3gHJsqP///yr///8q////Kv// + /yrAvLhBh3l04f//////////4d7c/29fWP/OyMb////////////89/j/0IaL/7mouf+ro7n/yX6L/7Kk + 8v8ypPf/uKvz//n4/v/w7u7/cWFb+aCYkln///8q////Kv///yr///8qfW9ouKqhnfy1ran/urKv/42B + e/9xYlv+4N3b////////////9+rr/7TK4P+fwuD/kHTe/97Y+v8/s/r/ppbw/9HI9///////u7Ow/Xdp + Ytj5+fkr////Kv///yr///8qubGxRYBya5Z+cWuefnFqsH9xart1Z2Did2hi+ero5////////////+H0 + /v9Uwvv/LpT1/1XC+/+Y2v3/uazz/8/G9///////+/r6/3prZfeSh4Js////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8qhHZxk3RlX/jY09H/////////////////inXs/9PL+P/Ty/j/oI7v/9LK + +P///////////7+4tf56a2XP////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KpCE + gG5wYVv1p52Z+vPx8f//////4Nr6/72x9P+9sfT/wbb1//r6/v////////////b19P9vX1j7ta6qSP// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yrAvLhBfW9otXFhW/m3sKz89/b2//// + //////////////////////////////////+Wiob3hnlzh////yr///8q////Kv///yr///8q////Kv// + /yr///8q////Kv///yr///8q////KqqhmlF7bGXJcGFZ+5+UkPjZ1dP//fz8//////////////////// + ///Bu7j/e21nyf///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv// + /yr///8qvrezQ4N1cJZ0Zl/pcGFZ+5CEfvS2r6v+zsjG/+Th3//Pysj/dGVf7f///yr///8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8qvba2QoyA + e3h+cWuqe21m0XRlX+1vYFn3b2BZ8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /0EAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA + AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABB////QSgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8q////Kv///yr///8q////KsvHxzt6a2bfk4eDgO/p6S////8q////Kv// + /yr///8q////Kv///yr///8q////Kv///yr///8q////Kv///yrZ1dU2koaB6eTi4Paso5/Npp2Zc/T0 + 9C3///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////KoN0b/L9/f3//////9zY + 1vePg36m////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q////Kp2TjmOEdnD4hXZx/NrW + 1f3y8PD/hnlzxv///yr///8q////Kv///yr///8q////Kv///yr///8q////KsjEvzyBc23n8/Hx/+nn + 5v+BdG77rKSg+oR2cc////8q////Kv///yr///8q////Kv///yr///8q////KsXBvT5/cWvf4d7c/v// + /////////f39/5aKhfl5a2Xu6uTkMP///yr///8q////Kv///yqDdG+/hnhyxIJ1cMKCdW7q4+Df/v// + ////////////////////////ysTC+YF0bcb5+fks////Kv///yr///8qkIR+uurn5v+6s7D9mI6J+v// + //////////////Ha3P/jt7r/6sfK//////+/ubX2hnlzsf///yr///8q////KqCVkF7Tz8zo+/r6/35w + a/zy8fD////////////jtbn/5fb+/66iuP+m3/3//////6KXk/CXi4Zu////Kv///yr5+fkro5iUxP// + ///Oycf8iXx2+v//////////4rO2/43E6P/PprH/icv7/8rf+//5+Pj/gnNu6NnV1Tb///8q////KpmP + iX2zq6jzvbaz+H5wav2rop76//////bp6v+ar8z/sZrV/3+19/+PnfL/5+P7/83HxfuLfnmg////Kv// + /yrv6ekvmo+KYpCDfnGJenR/e21m3tDLyPr/////3PP+/16j9f+V2f3/zsb3/9/a+v/+/v7/hHdx6OXl + 5TH///8q////Kv///yr///8q////Kubg4DKBdG7It6+s9v38/P/b1Pn/sqTy/6+h8v/29P7//////721 + svaUh4N3////Kv///yr///8q////Kv///yr///8q+fn5LIyAepKDdnDp19PR/f7+/v////////////// + ///u7Oz/h3hzxf///yr///8q////Kv///yr///8q////Kv///yr///8qwr66P4h6da+CdW7qtq6r9eHe + 3P/8/Pz//////4R2ceL///8q////Kv///yr///8q////Kv///yr///8q////Kv///yr///8q4ODbMpSJ + gm6HenS2f3Fr34N2cOhzY13xAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAA + rEEAAKxBAACsQQAArEEAAKxBAACsQQ== + + + \ No newline at end of file diff --git a/Models/AppOptions.cs b/Models/AppOptions.cs new file mode 100644 index 0000000..afd46e7 --- /dev/null +++ b/Models/AppOptions.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.Drawing; + +namespace RokettoLaunch.Models +{ + public class AppOptions + { + public int TilesPerRow { get; set; } = 8; + + public bool ShowBigIcons { get; set; } = true; + + public RyzStudio.Windows.ThemedForms.ButtonTextBox.ThKeyCodeTextBox.Results ShowToggleHotkey { get; set; } = null; + + public bool HideOnClose { get; set; } = true; + + public bool HideOnExecute { get; set; } = true; + + public bool AlwaysOnTop { get; set; } = false; + + public List Groups { get; set; } = new List(); + + public Point StartPosition { get; set; } = Point.Empty; + + public int Height { get; set; } = 280; + + } +} \ No newline at end of file diff --git a/Models/NewFormModel.cs b/Models/NewFormModel.cs new file mode 100644 index 0000000..7756338 --- /dev/null +++ b/Models/NewFormModel.cs @@ -0,0 +1,10 @@ +namespace RokettoLaunch.Models +{ + public class NewFormModel + { + public int ColumnCount { get; set; } = 8; + + public int GroupCount { get; set; } = 1; + + } +} \ No newline at end of file diff --git a/Models/TileGroupModel.cs b/Models/TileGroupModel.cs new file mode 100644 index 0000000..d5e25ef --- /dev/null +++ b/Models/TileGroupModel.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Drawing; +using System.Text.Json.Serialization; + +namespace RokettoLaunch.Models +{ + public class TileGroupModel + { + public string Title { get; set; } + + public bool IsExpanded { get; set; } = false; + + public List Items { get; set; } = new List(); + + [JsonConverter(typeof(RyzStudio.Text.Json.JsonSizeConverter))] + public Size GridSize { get; set; } = new Size(0, 0); + + } +} \ No newline at end of file diff --git a/Models/TileModel.cs b/Models/TileModel.cs new file mode 100644 index 0000000..e61f02d --- /dev/null +++ b/Models/TileModel.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Text.Json.Serialization; + +namespace RokettoLaunch.Models +{ + public class TileModel + { + public string Title { get; set; } + + public string ProcessFilename { get; set; } + + public string ProcessArgument { get; set; } + + public string ProcessWorkingDirectory { get; set; } + + public ProcessWindowStyle ProcessWindowStyle { get; set; } = ProcessWindowStyle.Normal; + + public bool ProcessAsAdmin { get; set; } = false; + + [JsonConverter(typeof(RyzStudio.Text.Json.JsonPointConverter))] + public Point Position { get; set; } + + public bool IsGroup { get; set; } = false; + + public List Items { get; set; } = new List(); + + public override string ToString() => this.Title ?? string.Empty; + + public string CleanProcessFilename => (string.IsNullOrWhiteSpace(this.ProcessFilename) ? string.Empty : resolvePath(this.ProcessFilename)); + + public string CleanProcessArgument => (string.IsNullOrWhiteSpace(this.ProcessArgument) ? string.Empty : resolvePath(this.ProcessArgument)); + + public string CleanProcessWorkingDirectory => (string.IsNullOrWhiteSpace(this.ProcessWorkingDirectory) ? string.Empty : resolvePath(this.ProcessWorkingDirectory)); + + protected string resolvePath(string value) + { + string rv = Environment.ExpandEnvironmentVariables(value); + + rv = resolveFirstPath(rv); + rv = resolveLastPath(rv); + + return rv; + } + + protected string resolveFirstPath(string value) + { + const string last = "%FIRST%"; + if (!value.Contains(last)) + { + return value; + } + + string head = value.Substring(0, value.IndexOf(last)); + string tail = value.Substring(value.IndexOf(last) + last.Length); + + string[] dirList = new string[0]; + + try + { + dirList = System.IO.Directory.GetDirectories(head, "*", System.IO.SearchOption.TopDirectoryOnly); + } + catch + { + // do nothing + } + + if (dirList.Length <= 0) + { + return value; + } + + return dirList[0] + tail; + } + + protected string resolveLastPath(string value) + { + const string last = "%LAST%"; + if (!value.Contains(last)) + { + return value; + } + + string head = value.Substring(0, value.IndexOf(last)); + string tail = value.Substring(value.IndexOf(last) + last.Length); + + string[] dirList = new string[0]; + + try + { + dirList = System.IO.Directory.GetDirectories(head, "*", System.IO.SearchOption.TopDirectoryOnly); + } + catch + { + // do nothing + } + + if (dirList.Length <= 0) + { + return value; + } + + return dirList[(dirList.Length - 1)] + tail; + } + + } +} diff --git a/NewForm.cs b/NewForm.cs new file mode 100644 index 0000000..d899ef5 --- /dev/null +++ b/NewForm.cs @@ -0,0 +1,136 @@ +using System.Windows.Forms; +using RokettoLaunch.Models; +using RyzStudio.Windows.Forms; +using RyzStudio.Windows.ThemedForms; + +namespace RokettoLaunch +{ + public class NewForm : Form + { + private System.Windows.Forms.Label label1; + private ThNumericBox numericBox1; + private ThNumericBox numericBox2; + private RyzStudio.Windows.ThemedForms.Composite.DialogFooter dialogFooter1; + private Label label2; + + + public NewForm() + { + InitializeComponent(); + + UISetup.Dialog(this); + + numericBox1.Minimum = 4; + numericBox1.Maximum = 24; + numericBox1.Value = 8; + numericBox2.Minimum = 1; + numericBox2.Maximum = 8; + numericBox2.Value = 1; + } + + private void InitializeComponent() + { + label1 = new Label(); + numericBox1 = new ThNumericBox(); + numericBox2 = new ThNumericBox(); + label2 = new Label(); + dialogFooter1 = new RyzStudio.Windows.ThemedForms.Composite.DialogFooter(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.BackColor = System.Drawing.Color.Transparent; + label1.ForeColor = System.Drawing.SystemColors.ControlText; + label1.Location = new System.Drawing.Point(10, 20); + label1.Margin = new Padding(0); + label1.Name = "label1"; + label1.Padding = new Padding(0, 9, 0, 0); + label1.Size = new System.Drawing.Size(76, 24); + label1.TabIndex = 153; + label1.Text = "Tiles Per Row"; + label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // numericBox1 + // + numericBox1.Anchor = AnchorStyles.Top | AnchorStyles.Right; + numericBox1.BackColor = System.Drawing.Color.Transparent; + numericBox1.EnableReactiveVisual = true; + numericBox1.Font = new System.Drawing.Font("Segoe UI", 9F); + numericBox1.Location = new System.Drawing.Point(285, 20); + numericBox1.Maximum = 100; + numericBox1.Minimum = 1; + numericBox1.Name = "numericBox1"; + numericBox1.Size = new System.Drawing.Size(84, 32); + numericBox1.TabIndex = 189; + numericBox1.TabStop = false; + numericBox1.Value = 1; + // + // numericBox2 + // + numericBox2.Anchor = AnchorStyles.Top | AnchorStyles.Right; + numericBox2.BackColor = System.Drawing.Color.Transparent; + numericBox2.EnableReactiveVisual = true; + numericBox2.Font = new System.Drawing.Font("Segoe UI", 9F); + numericBox2.Location = new System.Drawing.Point(285, 63); + numericBox2.Maximum = 100; + numericBox2.Minimum = 1; + numericBox2.Name = "numericBox2"; + numericBox2.Size = new System.Drawing.Size(84, 32); + numericBox2.TabIndex = 191; + numericBox2.TabStop = false; + numericBox2.Value = 1; + // + // label2 + // + label2.AutoSize = true; + label2.BackColor = System.Drawing.Color.Transparent; + label2.ForeColor = System.Drawing.SystemColors.ControlText; + label2.Location = new System.Drawing.Point(10, 63); + label2.Margin = new Padding(0); + label2.Name = "label2"; + label2.Padding = new Padding(0, 9, 0, 0); + label2.Size = new System.Drawing.Size(106, 24); + label2.TabIndex = 190; + label2.Text = "Number of Groups"; + label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // dialogFooter1 + // + dialogFooter1.BackColor = System.Drawing.Color.FromArgb(240, 240, 240); + dialogFooter1.Button1Text = "&OK"; + dialogFooter1.Dialog = this; + dialogFooter1.Dock = DockStyle.Bottom; + dialogFooter1.Location = new System.Drawing.Point(0, 337); + dialogFooter1.Name = "dialogFooter1"; + dialogFooter1.Size = new System.Drawing.Size(384, 84); + // + // NewForm + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = System.Drawing.Color.White; + ClientSize = new System.Drawing.Size(384, 421); + Controls.Add(dialogFooter1); + Controls.Add(numericBox2); + Controls.Add(label2); + Controls.Add(numericBox1); + Controls.Add(label1); + MinimumSize = new System.Drawing.Size(400, 200); + Name = "NewForm"; + Text = "New"; + ResumeLayout(false); + PerformLayout(); + } + + public NewFormModel Result + { + get => new NewFormModel() + { + ColumnCount = numericBox1.Value, + GroupCount = numericBox2.Value + }; + } + + } +} \ No newline at end of file diff --git a/NewForm.resx b/NewForm.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/NewForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OptionsForm.cs b/OptionsForm.cs new file mode 100644 index 0000000..226cd2a --- /dev/null +++ b/OptionsForm.cs @@ -0,0 +1,407 @@ +using System; +using System.Linq; +using System.Windows.Forms; +using RokettoLaunch.Models; +using RyzStudio.Windows.Forms; +using RyzStudio.Windows.ThemedForms; +using RyzStudio.Windows.ThemedForms.ButtonTextBox; +using RyzStudio.Windows.ThemedForms.PickerBox; + +namespace RokettoLaunch +{ + public class OptionsForm : Form + { + private System.Windows.Forms.Label label1; + private ThYesNoPickerBox yesNoPickerBox2; + private System.Windows.Forms.Label label6; + private ThYesNoPickerBox yesNoPickerBox3; + private System.Windows.Forms.Label label7; + private ThKeyCodeTextBox textBox1; + private ThNumericBox numericBox1; + private Label label4; + private FlowLayoutPanel flowLayoutPanel1; + private TTogglePanel tTogglePanel1; + private TTogglePanel tTogglePanel2; + private ThYesNoPickerBox yesNoPickerBox1; + private Label label2; + private ThYesNoPickerBox yesNoPickerBox4; + private Label label3; + private RyzStudio.Windows.ThemedForms.Composite.DialogFooter dialogFooter1; + + + private AppOptions _appSession = null; + + + public OptionsForm(AppOptions appSession) + { + InitializeComponent(); + + UISetup.Dialog(this); + + _appSession = appSession; + + numericBox1.Minimum = 4; + numericBox1.Maximum = 24; + + if (_appSession != null) + { + numericBox1.Value = _appSession.TilesPerRow; + yesNoPickerBox1.Value = _appSession.ShowBigIcons; + textBox1.UpdateKeyCode(_appSession?.ShowToggleHotkey ?? new ThKeyCodeTextBox.Results()); + yesNoPickerBox2.Value = _appSession.HideOnClose; + yesNoPickerBox3.Value = _appSession.HideOnExecute; + yesNoPickerBox4.Value = _appSession.AlwaysOnTop; + } + } + + private void InitializeComponent() + { + ThKeyCodeTextBox.Results results1 = new ThKeyCodeTextBox.Results(); + label1 = new Label(); + yesNoPickerBox2 = new ThYesNoPickerBox(); + label6 = new Label(); + yesNoPickerBox3 = new ThYesNoPickerBox(); + label7 = new Label(); + textBox1 = new ThKeyCodeTextBox(); + numericBox1 = new ThNumericBox(); + label4 = new Label(); + flowLayoutPanel1 = new FlowLayoutPanel(); + tTogglePanel1 = new TTogglePanel(); + yesNoPickerBox1 = new ThYesNoPickerBox(); + label2 = new Label(); + tTogglePanel2 = new TTogglePanel(); + yesNoPickerBox4 = new ThYesNoPickerBox(); + label3 = new Label(); + dialogFooter1 = new RyzStudio.Windows.ThemedForms.Composite.DialogFooter(); + flowLayoutPanel1.SuspendLayout(); + tTogglePanel1.SuspendLayout(); + tTogglePanel2.SuspendLayout(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.BackColor = System.Drawing.Color.Transparent; + label1.ForeColor = System.Drawing.SystemColors.ControlText; + label1.Location = new System.Drawing.Point(1, 22); + label1.Margin = new Padding(0); + label1.Name = "label1"; + label1.Padding = new Padding(0, 8, 0, 0); + label1.Size = new System.Drawing.Size(115, 23); + label1.TabIndex = 153; + label1.Text = "Show Toggle Hotkey"; + label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // yesNoPickerBox2 + // + yesNoPickerBox2.AcceptButton = null; + yesNoPickerBox2.Anchor = AnchorStyles.Top | AnchorStyles.Right; + yesNoPickerBox2.BackColor = System.Drawing.Color.Transparent; + yesNoPickerBox2.EnableReactiveVisual = true; + yesNoPickerBox2.Font = new System.Drawing.Font("Segoe UI", 9F); + yesNoPickerBox2.Location = new System.Drawing.Point(307, 63); + yesNoPickerBox2.Margin = new Padding(10, 10, 10, 0); + yesNoPickerBox2.Name = "yesNoPickerBox2"; + yesNoPickerBox2.Padding = new Padding(4, 4, 3, 3); + yesNoPickerBox2.SelectedIndex = 1; + yesNoPickerBox2.Size = new System.Drawing.Size(84, 34); + yesNoPickerBox2.TabIndex = 183; + yesNoPickerBox2.TabStop = false; + yesNoPickerBox2.Value = true; + // + // label6 + // + label6.AutoSize = true; + label6.BackColor = System.Drawing.Color.Transparent; + label6.ForeColor = System.Drawing.SystemColors.ControlText; + label6.Location = new System.Drawing.Point(1, 63); + label6.Margin = new Padding(0); + label6.Name = "label6"; + label6.Padding = new Padding(0, 8, 0, 0); + label6.Size = new System.Drawing.Size(83, 23); + label6.TabIndex = 182; + label6.Text = "Hide On Close"; + label6.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // yesNoPickerBox3 + // + yesNoPickerBox3.AcceptButton = null; + yesNoPickerBox3.Anchor = AnchorStyles.Top | AnchorStyles.Right; + yesNoPickerBox3.BackColor = System.Drawing.Color.Transparent; + yesNoPickerBox3.EnableReactiveVisual = true; + yesNoPickerBox3.Font = new System.Drawing.Font("Segoe UI", 9F); + yesNoPickerBox3.Location = new System.Drawing.Point(307, 107); + yesNoPickerBox3.Margin = new Padding(10, 10, 10, 0); + yesNoPickerBox3.Name = "yesNoPickerBox3"; + yesNoPickerBox3.Padding = new Padding(4, 4, 3, 3); + yesNoPickerBox3.SelectedIndex = 1; + yesNoPickerBox3.Size = new System.Drawing.Size(84, 34); + yesNoPickerBox3.TabIndex = 185; + yesNoPickerBox3.TabStop = false; + yesNoPickerBox3.Value = true; + // + // label7 + // + label7.AutoSize = true; + label7.BackColor = System.Drawing.Color.Transparent; + label7.ForeColor = System.Drawing.SystemColors.ControlText; + label7.Location = new System.Drawing.Point(1, 107); + label7.Margin = new Padding(0); + label7.Name = "label7"; + label7.Padding = new Padding(0, 8, 0, 0); + label7.Size = new System.Drawing.Size(95, 23); + label7.TabIndex = 184; + label7.Text = "Hide On Execute"; + label7.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // textBox1 + // + textBox1.AcceptButton = null; + textBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox1.BackColor = System.Drawing.Color.Transparent; + textBox1.EnableReactiveVisual = true; + textBox1.Font = new System.Drawing.Font("Segoe UI", 9F); + textBox1.Icon = "O"; + textBox1.IconSize = 13F; + results1.IsAlt = false; + results1.IsCtrl = false; + results1.IsShift = false; + results1.Key = Keys.None; + textBox1.KeyCodeResults = results1; + textBox1.Location = new System.Drawing.Point(192, 21); + textBox1.Margin = new Padding(10, 10, 10, 0); + textBox1.Name = "textBox1"; + textBox1.Padding = new Padding(4, 4, 3, 3); + textBox1.Size = new System.Drawing.Size(199, 32); + textBox1.TabIndex = 189; + textBox1.TabStop = false; + textBox1.UseSystemPasswordChar = false; + // + // numericBox1 + // + numericBox1.AcceptButton = null; + numericBox1.Anchor = AnchorStyles.Top | AnchorStyles.Right; + numericBox1.BackColor = System.Drawing.Color.Transparent; + numericBox1.EnableReactiveVisual = true; + numericBox1.Font = new System.Drawing.Font("Segoe UI", 9F); + numericBox1.Location = new System.Drawing.Point(252, 22); + numericBox1.Margin = new Padding(10, 10, 10, 0); + numericBox1.Maximum = 100; + numericBox1.Minimum = 1; + numericBox1.Name = "numericBox1"; + numericBox1.Padding = new Padding(4, 4, 3, 3); + numericBox1.Size = new System.Drawing.Size(139, 32); + numericBox1.TabIndex = 192; + numericBox1.TabStop = false; + numericBox1.Value = 1; + // + // label4 + // + label4.AutoSize = true; + label4.BackColor = System.Drawing.Color.Transparent; + label4.ForeColor = System.Drawing.SystemColors.ControlText; + label4.Location = new System.Drawing.Point(1, 22); + label4.Margin = new Padding(0); + label4.Name = "label4"; + label4.Padding = new Padding(0, 8, 0, 0); + label4.Size = new System.Drawing.Size(76, 23); + label4.TabIndex = 193; + label4.Text = "Tiles Per Row"; + label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // flowLayoutPanel1 + // + flowLayoutPanel1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + flowLayoutPanel1.AutoScroll = true; + flowLayoutPanel1.BackColor = System.Drawing.Color.Transparent; + flowLayoutPanel1.Controls.Add(tTogglePanel1); + flowLayoutPanel1.Controls.Add(tTogglePanel2); + flowLayoutPanel1.FlowDirection = FlowDirection.TopDown; + flowLayoutPanel1.Location = new System.Drawing.Point(8, 12); + flowLayoutPanel1.Name = "flowLayoutPanel1"; + flowLayoutPanel1.Size = new System.Drawing.Size(436, 412); + flowLayoutPanel1.TabIndex = 194; + flowLayoutPanel1.WrapContents = false; + flowLayoutPanel1.Resize += flowLayoutPanel1_Resize; + // + // tTogglePanel1 + // + tTogglePanel1.AutoScrollMargin = new System.Drawing.Size(0, 0); + tTogglePanel1.AutoScrollMinSize = new System.Drawing.Size(0, 0); + tTogglePanel1.Controls.Add(yesNoPickerBox1); + tTogglePanel1.Controls.Add(label2); + tTogglePanel1.Controls.Add(label4); + tTogglePanel1.Controls.Add(numericBox1); + tTogglePanel1.ExpandedHeight = 100; + tTogglePanel1.ForeColor = System.Drawing.Color.FromArgb(99, 105, 119); + tTogglePanel1.IsOpen = true; + tTogglePanel1.Location = new System.Drawing.Point(0, 0); + tTogglePanel1.Margin = new Padding(0); + tTogglePanel1.Name = "tTogglePanel1"; + tTogglePanel1.Padding = new Padding(0, 22, 0, 0); + tTogglePanel1.PaddingBottom = 0; + tTogglePanel1.PaddingLeft = 4; + tTogglePanel1.Size = new System.Drawing.Size(401, 119); + tTogglePanel1.TabIndex = 0; + tTogglePanel1.Title = "Appearance"; + tTogglePanel1.TitleContextMenuStrip = null; + tTogglePanel1.TitleCursor = Cursors.Default; + // + // yesNoPickerBox1 + // + yesNoPickerBox1.AcceptButton = null; + yesNoPickerBox1.Anchor = AnchorStyles.Top | AnchorStyles.Right; + yesNoPickerBox1.BackColor = System.Drawing.Color.Transparent; + yesNoPickerBox1.EnableReactiveVisual = true; + yesNoPickerBox1.Font = new System.Drawing.Font("Segoe UI", 9F); + yesNoPickerBox1.Location = new System.Drawing.Point(307, 64); + yesNoPickerBox1.Margin = new Padding(10, 10, 10, 0); + yesNoPickerBox1.Name = "yesNoPickerBox1"; + yesNoPickerBox1.Padding = new Padding(4, 4, 3, 3); + yesNoPickerBox1.SelectedIndex = 1; + yesNoPickerBox1.Size = new System.Drawing.Size(84, 34); + yesNoPickerBox1.TabIndex = 195; + yesNoPickerBox1.TabStop = false; + yesNoPickerBox1.Value = true; + // + // label2 + // + label2.AutoSize = true; + label2.BackColor = System.Drawing.Color.Transparent; + label2.ForeColor = System.Drawing.SystemColors.ControlText; + label2.Location = new System.Drawing.Point(1, 64); + label2.Margin = new Padding(0); + label2.Name = "label2"; + label2.Padding = new Padding(0, 8, 0, 0); + label2.Size = new System.Drawing.Size(87, 23); + label2.TabIndex = 194; + label2.Text = "Show Big Icons"; + label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // tTogglePanel2 + // + tTogglePanel2.AutoScrollMargin = new System.Drawing.Size(0, 0); + tTogglePanel2.AutoScrollMinSize = new System.Drawing.Size(0, 0); + tTogglePanel2.Controls.Add(yesNoPickerBox4); + tTogglePanel2.Controls.Add(label3); + tTogglePanel2.Controls.Add(label1); + tTogglePanel2.Controls.Add(textBox1); + tTogglePanel2.Controls.Add(yesNoPickerBox2); + tTogglePanel2.Controls.Add(yesNoPickerBox3); + tTogglePanel2.Controls.Add(label6); + tTogglePanel2.Controls.Add(label7); + tTogglePanel2.ExpandedHeight = 100; + tTogglePanel2.ForeColor = System.Drawing.Color.FromArgb(99, 105, 119); + tTogglePanel2.IsOpen = true; + tTogglePanel2.Location = new System.Drawing.Point(0, 119); + tTogglePanel2.Margin = new Padding(0); + tTogglePanel2.Name = "tTogglePanel2"; + tTogglePanel2.Padding = new Padding(0, 22, 0, 0); + tTogglePanel2.PaddingBottom = 0; + tTogglePanel2.PaddingLeft = 4; + tTogglePanel2.Size = new System.Drawing.Size(401, 206); + tTogglePanel2.TabIndex = 1; + tTogglePanel2.Title = "Behaviour"; + tTogglePanel2.TitleContextMenuStrip = null; + tTogglePanel2.TitleCursor = Cursors.Default; + // + // yesNoPickerBox4 + // + yesNoPickerBox4.AcceptButton = null; + yesNoPickerBox4.Anchor = AnchorStyles.Top | AnchorStyles.Right; + yesNoPickerBox4.BackColor = System.Drawing.Color.Transparent; + yesNoPickerBox4.EnableReactiveVisual = true; + yesNoPickerBox4.Font = new System.Drawing.Font("Segoe UI", 9F); + yesNoPickerBox4.Location = new System.Drawing.Point(307, 151); + yesNoPickerBox4.Margin = new Padding(10, 10, 10, 0); + yesNoPickerBox4.Name = "yesNoPickerBox4"; + yesNoPickerBox4.Padding = new Padding(4, 4, 3, 3); + yesNoPickerBox4.SelectedIndex = 1; + yesNoPickerBox4.Size = new System.Drawing.Size(84, 34); + yesNoPickerBox4.TabIndex = 191; + yesNoPickerBox4.TabStop = false; + yesNoPickerBox4.Value = true; + // + // label3 + // + label3.AutoSize = true; + label3.BackColor = System.Drawing.Color.Transparent; + label3.ForeColor = System.Drawing.SystemColors.ControlText; + label3.Location = new System.Drawing.Point(1, 151); + label3.Margin = new Padding(0); + label3.Name = "label3"; + label3.Padding = new Padding(0, 8, 0, 0); + label3.Size = new System.Drawing.Size(85, 23); + label3.TabIndex = 190; + label3.Text = "Always On Top"; + label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // dialogFooter1 + // + dialogFooter1.BackColor = System.Drawing.Color.FromArgb(240, 240, 240); + dialogFooter1.Button1Text = "&Save"; + dialogFooter1.Dialog = this; + dialogFooter1.Dock = DockStyle.Bottom; + dialogFooter1.Location = new System.Drawing.Point(0, 437); + dialogFooter1.Name = "dialogFooter1"; + dialogFooter1.Size = new System.Drawing.Size(444, 84); + // + // OptionsForm + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = System.Drawing.Color.White; + ClientSize = new System.Drawing.Size(444, 521); + Controls.Add(dialogFooter1); + Controls.Add(flowLayoutPanel1); + MinimumSize = new System.Drawing.Size(460, 560); + Name = "OptionsForm"; + Text = "Options"; + flowLayoutPanel1.ResumeLayout(false); + tTogglePanel1.ResumeLayout(false); + tTogglePanel1.PerformLayout(); + tTogglePanel2.ResumeLayout(false); + tTogglePanel2.PerformLayout(); + ResumeLayout(false); + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + flowLayoutPanel1_Resize(null, e); + } + + private void flowLayoutPanel1_Resize(object sender, EventArgs e) + { + var width = flowLayoutPanel1.ClientRectangle.Width - SystemInformation.VerticalScrollBarWidth; + + foreach (var item in flowLayoutPanel1.Controls.OfType()) + { + item.Width = width; + } + } + + + public AppOptions Result + { + get + { + if (_appSession == null) + { + _appSession = new AppOptions(); + } + + _appSession.TilesPerRow = numericBox1.Value; + _appSession.ShowBigIcons = yesNoPickerBox1.Value; + _appSession.ShowToggleHotkey = textBox1.KeyCodeResults; + _appSession.HideOnClose = yesNoPickerBox2.Value; + _appSession.HideOnExecute = yesNoPickerBox3.Value; + _appSession.AlwaysOnTop = yesNoPickerBox4.Value; + + return _appSession; + } + } + + } +} \ No newline at end of file diff --git a/OptionsForm.resx b/OptionsForm.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/OptionsForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..9470017 --- /dev/null +++ b/Program.cs @@ -0,0 +1,20 @@ +using System; +using System.Windows.Forms; + +namespace RokettoLaunch +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.SetHighDpiMode(HighDpiMode.SystemAware); + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/Resources/cog2.png b/Resources/cog2.png new file mode 100644 index 0000000..d40221f Binary files /dev/null and b/Resources/cog2.png differ diff --git a/Resources/disk2.png b/Resources/disk2.png new file mode 100644 index 0000000..29b59a4 Binary files /dev/null and b/Resources/disk2.png differ diff --git a/Resources/file.png b/Resources/file.png new file mode 100644 index 0000000..c4b89eb Binary files /dev/null and b/Resources/file.png differ diff --git a/Resources/folder.png b/Resources/folder.png new file mode 100644 index 0000000..7ec26c4 Binary files /dev/null and b/Resources/folder.png differ diff --git a/Resources/folder_32.png b/Resources/folder_32.png new file mode 100644 index 0000000..832fd3c Binary files /dev/null and b/Resources/folder_32.png differ diff --git a/Resources/help2.png b/Resources/help2.png new file mode 100644 index 0000000..ae6856d Binary files /dev/null and b/Resources/help2.png differ diff --git a/Resources/icon-128.png b/Resources/icon-128.png new file mode 100644 index 0000000..ab38161 Binary files /dev/null and b/Resources/icon-128.png differ diff --git a/Resources/icon-64.png b/Resources/icon-64.png new file mode 100644 index 0000000..08decc5 Binary files /dev/null and b/Resources/icon-64.png differ diff --git a/RokettoLaunch.csproj b/RokettoLaunch.csproj new file mode 100644 index 0000000..f2bcf75 --- /dev/null +++ b/RokettoLaunch.csproj @@ -0,0 +1,109 @@ + + + + WinExe + net8.0-windows8.0 + true + true + favicon.ico + false + rokettolaunch + Ray Lam + Hi, I'm Ray + RokettoLaunch + Ray Lam + 1.0.0.0 + 1.0.0.0 + 0.3.4.164 + False + x64 + icon-128.png + + + + bin\Debug\ + + + + none + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + AppResource.resx + + + + + + + ResXFileCodeGenerator + AppResource.Designer.cs + + + + + + True + \ + + + + \ No newline at end of file diff --git a/Windows/Forms/TilePanel.Designer.cs b/Windows/Forms/TilePanel.Designer.cs new file mode 100644 index 0000000..2bee63d --- /dev/null +++ b/Windows/Forms/TilePanel.Designer.cs @@ -0,0 +1,44 @@ +namespace RokettoLaunch.Windows.Forms +{ + partial class TilePanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + toolTip1 = new System.Windows.Forms.ToolTip(components); + SuspendLayout(); + // + // TilePanel + // + Name = "TilePanel"; + ResumeLayout(false); + } + + #endregion + private System.Windows.Forms.ToolTip toolTip1; + } +} diff --git a/Windows/Forms/TilePanel.cs b/Windows/Forms/TilePanel.cs new file mode 100644 index 0000000..c8b235b --- /dev/null +++ b/Windows/Forms/TilePanel.cs @@ -0,0 +1,248 @@ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Windows.Forms; +using RokettoLaunch.Models; +using RyzStudio.Windows.Forms; + +namespace RokettoLaunch.Windows.Forms +{ + public partial class TilePanel : RyzStudio.Windows.TileForms.Tile + { + protected TileModel modelInfo = new TileModel(); + + + public TilePanel() + { + InitializeComponent(); + + this.AllowDrop = true; + this.Font = new Font(this.Font.FontFamily, 8.25F); + this.Size = new Size(70, 70); + this.AutoScaleMode = AutoScaleMode.None; + + this.EnableMovable = true; + } + + + [Browsable(false)] + public TileModel ModelInfo => modelInfo; + + public RyzStudio.Windows.TileForms.TileContainer TileContainer { get => UIControl.GetParentsUntil(this); } + + protected MainForm MainForm { get => UIControl.GetParentsUntil(this); } + + + protected override void OnDragOver(DragEventArgs e) + { + base.OnDragDrop(e); + + e.Effect = (e.Data.GetDataPresent(DataFormats.FileDrop)) ? DragDropEffects.Link : DragDropEffects.None; + } + + protected override void OnDragDrop(DragEventArgs e) + { + string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[]; + + if (this.ModelInfo.IsGroup) + { + foreach (var item in fileList ?? new string[0]) + { + var model = GetTileModel(item); + if (model == null) + { + continue; + } + + this.ModelInfo.Items.Add(model); + } + + InvalidateGroupMenu(this.ModelInfo); + } + else + { + if ((fileList?.Length ?? 0) > 0) + { + LoadInfo(fileList[0]); + } + } + } + + protected override void OnMouseClick(MouseEventArgs e) + { + if (Control.ModifierKeys == Keys.Control) + { + return; + } + + if (this.ModelInfo == null) + { + return; + } + + if (e.Button == MouseButtons.Left) + { + if (this.ModelInfo.IsGroup) + { + this.LeftContextMenuStrip?.Show(this, e.Location); + } + else + { + OnMouseDoubleClick(e); + } + } + } + + protected override void OnMouseDoubleClick(MouseEventArgs e) + { + base.OnMouseDoubleClick(e); + + if (Control.ModifierKeys == Keys.Control) + { + return; + } + + if (e.Button == MouseButtons.Left) + { + Execute(this.ModelInfo); + } + } + + + public void LoadInfo(TileModel model) + { + this.modelInfo = model; + + this.LargeIcon = null; + this.Title = model.Title; + + if (this.modelInfo.IsGroup) + { + this.LargeIcon = AppResource.folder_32; + + InvalidateGroupMenu(this.modelInfo); + } + else + { + this.LargeIcon = RyzStudio.IO.File.GetIcon(model.CleanProcessFilename); + } + + toolTip1.SetToolTip(this, this.Title); + } + + public void LoadInfo(string filename) + { + var model = GetTileModel(filename); + if (model == null) + { + return; + } + + LoadInfo(model); + } + + private void Execute(TileModel model) + { + if (model == null) + { + return; + } + + if (model.IsGroup) + { + return; + } + + if (this.MainForm != null) + { + if (this.MainForm.CurrentSession?.HideOnExecute ?? true) + { + this.MainForm.Visible = false; + } + } + + RyzStudio.Diagnostics.Process.Execute(model.CleanProcessFilename, model.CleanProcessWorkingDirectory, model.CleanProcessArgument, model.ProcessWindowStyle, model.ProcessAsAdmin); + } + + private void InvalidateGroupMenu(TileModel model) + { + var iconSize = ((this.MainForm?.CurrentSession?.ShowBigIcons ?? true) ? 24 : 16); + + if (this.LeftContextMenuStrip == null) + { + this.LeftContextMenuStrip = new ContextMenuStrip(); + } + + this.LeftContextMenuStrip.ImageScalingSize = new Size(iconSize, iconSize); + this.LeftContextMenuStrip.Items.Clear(); + + foreach (TileModel item in model?.Items ?? new System.Collections.Generic.List()) + { + ToolStripItem toolItem = this.LeftContextMenuStrip.Items.Add(item.Title); + toolItem.Image = RyzStudio.IO.File.GetIcon(item.CleanProcessFilename); + toolItem.Tag = item; + toolItem.Click += (object sender, EventArgs e) => + { + var menuItem = (System.Windows.Forms.ToolStripMenuItem)sender; + if (menuItem == null) + { + return; + } + + var model = (menuItem.Tag as TileModel); + if (model == null) + { + return; + } + + Execute(model); + }; + } + } + + private TileModel GetTileModel(string filename) + { + if (string.IsNullOrWhiteSpace(filename)) + { + return null; + } + + TileModel model = new TileModel() + { + ProcessFilename = filename, + Title = Path.GetFileName(filename) + }; + + // exe + if (Path.GetExtension(filename).Equals(".exe", StringComparison.CurrentCultureIgnoreCase)) + { + if (File.Exists(filename)) + { + try + { + FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(filename); + if (fvi != null) + { + model.Title = fvi.ProductName; + } + } + catch + { + // do nothing + } + } + + if (string.IsNullOrWhiteSpace(model.Title)) + { + model.Title = Path.GetFileNameWithoutExtension(filename); + } + } + + return model; + } + + } +} \ No newline at end of file diff --git a/Windows/Forms/TilePanel.resx b/Windows/Forms/TilePanel.resx new file mode 100644 index 0000000..a829b1a --- /dev/null +++ b/Windows/Forms/TilePanel.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 172, 17 + + \ No newline at end of file diff --git a/build-installer.iss b/build-installer.iss new file mode 100644 index 0000000..90f83e4 --- /dev/null +++ b/build-installer.iss @@ -0,0 +1,54 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "RokettoLaunch" +#define MyAppVersion "0.3.4.164" +#define MyAppPublisher "Hi, I'm Ray" +#define MyAppURL "https://www.hiimray.co.uk/software-fizzy-launcher" +#define MyAppExeName "rokettolaunch.exe" + +#define AppSourcePath "L:\gitea-hiimray\linear-app-launcher\bin" +#define AppReleasePath "L:\gitea-hiimray\linear-app-launcher\bin" +#define AppReleaseName "rokettolaunch-installer" + + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{472ED37C-C4FC-4B72-8BC3-C281A6E0D2F9} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={autopf}\{#MyAppName} +DefaultGroupName={#MyAppName} +DisableProgramGroupPage=yes +; Remove the following line to run in administrative install mode (install for all users.) +PrivilegesRequired=lowest +OutputDir={#AppReleasePath} +OutputBaseFilename={#AppReleaseName} +Compression=lzma +SolidCompression=yes +WizardStyle=modern + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "{#AppSourcePath}\rokettolaunch.exe"; DestDir: "{app}"; Flags: ignoreversion +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..244bf0b --- /dev/null +++ b/build.bat @@ -0,0 +1,17 @@ +RMDIR /s /q "bin\" +RMDIR /s /q "obj\" + +MKDIR bin + +dotnet restore skye.sln +dotnet publish skye.sln -r win-x64 -c Release /p:PublishSingleFile=true /p:SelfContained=false /p:PublishReadyToRunfalse=true /p:PublishDir="bin\" + +"C:\B\Portable Files (dev)\Inno Setup\v6.0.4-2\app\ISCC.exe" "build-installer.iss" + +"C:\B\Portable Files\7-Zip (Portable)\23.01\App\7-Zip64\7z.exe" a -t7z "bin\rokettolaunch.7z" ".\bin\rokettolaunch.exe" -mx9 + +RMDIR /s /q "bin\debug" +RMDIR /s /q "bin\release" +RMDIR /s /q "obj\" + +PAUSE \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..6f5f7b5 Binary files /dev/null and b/favicon.ico differ diff --git a/skye.sln b/skye.sln new file mode 100644 index 0000000..4e11779 --- /dev/null +++ b/skye.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33205.214 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RokettoLaunch", "RokettoLaunch.csproj", "{4833FB27-0817-4720-A54B-180369B0C374}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4833FB27-0817-4720-A54B-180369B0C374}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4833FB27-0817-4720-A54B-180369B0C374}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4833FB27-0817-4720-A54B-180369B0C374}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4833FB27-0817-4720-A54B-180369B0C374}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CB4C1DB0-19FE-4AA0-9621-D66FAC4CF7C5} + EndGlobalSection +EndGlobal