diff --git a/FlybyScript.sln b/FlybyScript.sln new file mode 100644 index 0000000..daacaf8 --- /dev/null +++ b/FlybyScript.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35327.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlybyScript", "FlybyScript\FlybyScript.csproj", "{66DDC36A-9095-4053-941C-8829D44F5F20}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {66DDC36A-9095-4053-941C-8829D44F5F20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66DDC36A-9095-4053-941C-8829D44F5F20}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66DDC36A-9095-4053-941C-8829D44F5F20}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66DDC36A-9095-4053-941C-8829D44F5F20}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {81315C08-1240-44F0-AAEF-36C5A1C885B8} + EndGlobalSection +EndGlobal diff --git a/FlybyScript/App.config b/FlybyScript/App.config new file mode 100644 index 0000000..4bfa005 --- /dev/null +++ b/FlybyScript/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/FlybyScript/AppIcon.ico b/FlybyScript/AppIcon.ico new file mode 100644 index 0000000..fe67c5f Binary files /dev/null and b/FlybyScript/AppIcon.ico differ diff --git a/FlybyScript/FlybyScript.csproj b/FlybyScript/FlybyScript.csproj new file mode 100644 index 0000000..7b2d6a8 --- /dev/null +++ b/FlybyScript/FlybyScript.csproj @@ -0,0 +1,114 @@ + + + + + Debug + AnyCPU + {66DDC36A-9095-4053-941C-8829D44F5F20} + WinExe + FlybyScript + FlybyScript + v4.8 + 512 + true + true + + + + x64 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + app.manifest + + + AppIcon.ico + + + + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + Form + + + MainForm.cs + + + + + + + UserControl + + + ExperienceView.cs + + + MainForm.cs + Designer + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + ExperienceView.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + \ No newline at end of file diff --git a/FlybyScript/Helper/Logger.cs b/FlybyScript/Helper/Logger.cs new file mode 100644 index 0000000..d340ab5 --- /dev/null +++ b/FlybyScript/Helper/Logger.cs @@ -0,0 +1,37 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace FlybyScript +{ + public class Logger + { + private RichTextBox rtbDescription; + + public Logger(RichTextBox rtbDescription) + { + this.rtbDescription = rtbDescription; + } + + public void Log(string message, Color color) + { + if (rtbDescription.InvokeRequired) + { + rtbDescription.Invoke(new Action(() => LogMessage(message, color))); + } + else + { + LogMessage(message, color); + } + } + + private void LogMessage(string message, Color color) + { + rtbDescription.SelectionColor = color; + + rtbDescription.AppendText($"{message}\n"); + + rtbDescription.ScrollToCaret(); + } + } +} \ No newline at end of file diff --git a/FlybyScript/Helper/Views.cs b/FlybyScript/Helper/Views.cs new file mode 100644 index 0000000..e4bfdb1 --- /dev/null +++ b/FlybyScript/Helper/Views.cs @@ -0,0 +1,48 @@ +using System.Linq; +using System.Windows.Forms; + +namespace Views +{ + public static class SwitchView + { + public static Control PreviousView { get; private set; } + public static Control DefaultView { get; set; } // Store the default view (panelMain) + + // Switch to a new view + public static void SetView(Control newView, Panel targetPanel) + { + // If there's already a view in the panel, save it as PreviousView + if (targetPanel.Controls.Count > 0) + { + // Only save the previous view if it's not the default view (panelMain) + if (PreviousView == null) + { + PreviousView = targetPanel.Controls[0]; // Store current view as PreviousView + } + } + + newView.Dock = DockStyle.Fill; + targetPanel.Controls.Clear(); + targetPanel.Controls.Add(newView); // Add new view to the panel + } + + // Go back to the previous view + public static void GoBack(Panel targetPanel) + { + if (PreviousView != null) + { + targetPanel.Controls.Clear(); // Clear the current view + targetPanel.Controls.Add(PreviousView); // Add the previous view back + PreviousView.Dock = DockStyle.Fill; + PreviousView = null; // Reset PreviousView after returning to it + } + else if (DefaultView != null) + { + // If there's no PreviousView, return to the default (panelMain) + targetPanel.Controls.Clear(); + targetPanel.Controls.Add(DefaultView); + DefaultView.Dock = DockStyle.Fill; + } + } + } +} \ No newline at end of file diff --git a/FlybyScript/MainForm.Designer.cs b/FlybyScript/MainForm.Designer.cs new file mode 100644 index 0000000..d874398 --- /dev/null +++ b/FlybyScript/MainForm.Designer.cs @@ -0,0 +1,261 @@ +namespace FlybyScript +{ + partial class MainForm + { + /// + /// Erforderliche Designervariable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Verwendete Ressourcen bereinigen. + /// + /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Vom Windows Form-Designer generierter Code + + /// + /// Erforderliche Methode für die Designerunterstützung. + /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.treeSettings = new System.Windows.Forms.TreeView(); + this.rtbDescription = new System.Windows.Forms.RichTextBox(); + this.btnTogglePatch = new System.Windows.Forms.Button(); + this.linkGitHub = new System.Windows.Forms.LinkLabel(); + this.btnMountRun = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.linkLabel2 = new System.Windows.Forms.LinkLabel(); + this.panelMain = new System.Windows.Forms.Panel(); + this.linkChangeExperience = new System.Windows.Forms.LinkLabel(); + this.panelForm = new System.Windows.Forms.Panel(); + this.panelMain.SuspendLayout(); + this.panelForm.SuspendLayout(); + this.SuspendLayout(); + // + // treeSettings + // + this.treeSettings.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.treeSettings.BackColor = System.Drawing.Color.White; + this.treeSettings.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.treeSettings.CheckBoxes = true; + this.treeSettings.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.treeSettings.ForeColor = System.Drawing.Color.Black; + this.treeSettings.FullRowSelect = true; + this.treeSettings.Indent = 20; + this.treeSettings.ItemHeight = 25; + this.treeSettings.Location = new System.Drawing.Point(36, 168); + this.treeSettings.Name = "treeSettings"; + this.treeSettings.ShowLines = false; + this.treeSettings.ShowNodeToolTips = true; + this.treeSettings.ShowPlusMinus = false; + this.treeSettings.ShowRootLines = false; + this.treeSettings.Size = new System.Drawing.Size(865, 172); + this.treeSettings.TabIndex = 200; + this.treeSettings.TabStop = false; + this.treeSettings.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeSettings_AfterCheck); + this.treeSettings.MouseMove += new System.Windows.Forms.MouseEventHandler(this.treeSettings_MouseMove); + // + // rtbDescription + // + this.rtbDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.rtbDescription.BackColor = System.Drawing.Color.White; + this.rtbDescription.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.rtbDescription.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.rtbDescription.ForeColor = System.Drawing.Color.Black; + this.rtbDescription.Location = new System.Drawing.Point(34, 346); + this.rtbDescription.Name = "rtbDescription"; + this.rtbDescription.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; + this.rtbDescription.Size = new System.Drawing.Size(867, 123); + this.rtbDescription.TabIndex = 199; + this.rtbDescription.TabStop = false; + this.rtbDescription.Text = ""; + // + // btnTogglePatch + // + this.btnTogglePatch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnTogglePatch.BackColor = System.Drawing.Color.White; + this.btnTogglePatch.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnTogglePatch.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnTogglePatch.FlatAppearance.BorderSize = 2; + this.btnTogglePatch.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnTogglePatch.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnTogglePatch.Font = new System.Drawing.Font("Segoe UI Variable Small", 11F); + this.btnTogglePatch.Location = new System.Drawing.Point(629, 497); + this.btnTogglePatch.Name = "btnTogglePatch"; + this.btnTogglePatch.Size = new System.Drawing.Size(222, 40); + this.btnTogglePatch.TabIndex = 201; + this.btnTogglePatch.TabStop = false; + this.btnTogglePatch.Text = "Patch"; + this.btnTogglePatch.UseCompatibleTextRendering = true; + this.btnTogglePatch.UseVisualStyleBackColor = false; + this.btnTogglePatch.Click += new System.EventHandler(this.btnTogglePatch_Click); + // + // linkGitHub + // + this.linkGitHub.ActiveLinkColor = System.Drawing.Color.Magenta; + this.linkGitHub.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.linkGitHub.AutoEllipsis = true; + this.linkGitHub.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.75F); + this.linkGitHub.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; + this.linkGitHub.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(65)))), ((int)(((byte)(17))))); + this.linkGitHub.Location = new System.Drawing.Point(169, 567); + this.linkGitHub.Name = "linkGitHub"; + this.linkGitHub.Size = new System.Drawing.Size(45, 16); + this.linkGitHub.TabIndex = 202; + this.linkGitHub.TabStop = true; + this.linkGitHub.Text = "GitHub"; + this.linkGitHub.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkGitHub_LinkClicked); + // + // btnMountRun + // + this.btnMountRun.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnMountRun.AutoEllipsis = true; + this.btnMountRun.BackColor = System.Drawing.Color.White; + this.btnMountRun.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnMountRun.FlatAppearance.BorderColor = System.Drawing.Color.Gray; + this.btnMountRun.FlatAppearance.BorderSize = 2; + this.btnMountRun.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.btnMountRun.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnMountRun.Font = new System.Drawing.Font("Segoe UI Variable Small", 11F); + this.btnMountRun.Location = new System.Drawing.Point(403, 497); + this.btnMountRun.Name = "btnMountRun"; + this.btnMountRun.Size = new System.Drawing.Size(220, 40); + this.btnMountRun.TabIndex = 203; + this.btnMountRun.TabStop = false; + this.btnMountRun.Text = "Mount and Run ISO"; + this.btnMountRun.UseVisualStyleBackColor = false; + this.btnMountRun.Click += new System.EventHandler(this.btnMountRun_Click); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoEllipsis = true; + this.label1.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 21.25F); + this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.label1.Location = new System.Drawing.Point(30, 38); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(780, 82); + this.label1.TabIndex = 205; + this.label1.Text = "Utilize FlybyScript to Bypass Windows 11 Hardware Restrictions and Install on Uns" + + "upported Devices"; + // + // linkLabel1 + // + this.linkLabel1.ActiveLinkColor = System.Drawing.Color.Magenta; + this.linkLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.linkLabel1.AutoEllipsis = true; + this.linkLabel1.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.75F); + this.linkLabel1.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; + this.linkLabel1.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(164)))), ((int)(((byte)(239))))); + this.linkLabel1.Location = new System.Drawing.Point(27, 567); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(122, 16); + this.linkLabel1.TabIndex = 206; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "A Belim app creation"; + // + // linkLabel2 + // + this.linkLabel2.ActiveLinkColor = System.Drawing.Color.Magenta; + this.linkLabel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.linkLabel2.AutoEllipsis = true; + this.linkLabel2.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.75F); + this.linkLabel2.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; + this.linkLabel2.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(186)))), ((int)(((byte)(0))))); + this.linkLabel2.Location = new System.Drawing.Point(235, 567); + this.linkLabel2.Name = "linkLabel2"; + this.linkLabel2.Size = new System.Drawing.Size(54, 16); + this.linkLabel2.TabIndex = 208; + this.linkLabel2.TabStop = true; + this.linkLabel2.Text = "0.11.31"; + // + // panelMain + // + this.panelMain.Controls.Add(this.linkLabel2); + this.panelMain.Controls.Add(this.linkChangeExperience); + this.panelMain.Controls.Add(this.label1); + this.panelMain.Controls.Add(this.linkLabel1); + this.panelMain.Controls.Add(this.rtbDescription); + this.panelMain.Controls.Add(this.treeSettings); + this.panelMain.Controls.Add(this.btnMountRun); + this.panelMain.Controls.Add(this.btnTogglePatch); + this.panelMain.Controls.Add(this.linkGitHub); + this.panelMain.Dock = System.Windows.Forms.DockStyle.Fill; + this.panelMain.Location = new System.Drawing.Point(0, 0); + this.panelMain.Name = "panelMain"; + this.panelMain.Size = new System.Drawing.Size(943, 592); + this.panelMain.TabIndex = 209; + // + // linkChangeExperience + // + this.linkChangeExperience.ActiveLinkColor = System.Drawing.Color.Fuchsia; + this.linkChangeExperience.AutoSize = true; + this.linkChangeExperience.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.linkChangeExperience.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline; + this.linkChangeExperience.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.linkChangeExperience.Location = new System.Drawing.Point(33, 139); + this.linkChangeExperience.Name = "linkChangeExperience"; + this.linkChangeExperience.Size = new System.Drawing.Size(209, 16); + this.linkChangeExperience.TabIndex = 10; + this.linkChangeExperience.TabStop = true; + this.linkChangeExperience.Text = "Change how you experience Windows"; + this.linkChangeExperience.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkChangeExperience_LinkClicked); + // + // panelForm + // + this.panelForm.Controls.Add(this.panelMain); + this.panelForm.Dock = System.Windows.Forms.DockStyle.Fill; + this.panelForm.Location = new System.Drawing.Point(0, 0); + this.panelForm.Name = "panelForm"; + this.panelForm.Size = new System.Drawing.Size(943, 592); + this.panelForm.TabIndex = 210; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(943, 592); + this.Controls.Add(this.panelForm); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "MainForm"; + this.Text = "Flyby11"; + this.Load += new System.EventHandler(this.MainForm_Load); + this.panelMain.ResumeLayout(false); + this.panelMain.PerformLayout(); + this.panelForm.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView treeSettings; + public System.Windows.Forms.RichTextBox rtbDescription; + private System.Windows.Forms.Button btnTogglePatch; + private System.Windows.Forms.LinkLabel linkGitHub; + private System.Windows.Forms.Button btnMountRun; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.LinkLabel linkLabel2; + private System.Windows.Forms.Panel panelMain; + private System.Windows.Forms.LinkLabel linkChangeExperience; + private System.Windows.Forms.Panel panelForm; + } +} + diff --git a/FlybyScript/MainForm.cs b/FlybyScript/MainForm.cs new file mode 100644 index 0000000..50cd626 --- /dev/null +++ b/FlybyScript/MainForm.cs @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Windows.Forms; +using Views; + +namespace FlybyScript +{ + public partial class MainForm : Form + { + private Dictionary pendingChanges = new Dictionary(); // Store pending changes + private PSPatcher PSPatcher; + + private Logger logger; + + public MainForm() + { + InitializeComponent(); + + // Initialize the logger + logger = new Logger(rtbDescription); + + // Set the default view to the main panel + SwitchView.DefaultView = panelMain; + } + + private async void MainForm_Load(object sender, EventArgs e) + { + // Add NativePatcher parent node + TreeNode nativePatcherNode = new TreeNode("Native (Recommended)"); + treeSettings.Nodes.Add(nativePatcherNode); + + // Add Method 1 as a child of NativePatcher + TreeNode method1Node = new TreeNode("(Method 1) Inplace Upgrade via Server Setup"); + method1Node.Tag = "Method1"; + nativePatcherNode.Nodes.Add(method1Node); + + // Add ScriptPatcher parent node + await ScriptPatcher.LoadPlugins("upgraider", treeSettings.Nodes, logger); + + // Add PSPatcher parent node (for Dependencies) + PSPatcher = new PSPatcher(); + PSPatcher.LoadPowerShellPlugins(treeSettings); + + // Expand all nodes + ExpandAllNodes(treeSettings.Nodes); + } + + private void ExpandAllNodes(TreeNodeCollection nodes) + { + foreach (TreeNode node in nodes) + { + node.Expand(); + ExpandAllNodes(node.Nodes); + } + } + + private void treeSettings_AfterCheck(object sender, TreeViewEventArgs e) + { + // Check if the node's checked status has changed + if (e.Node.Checked) + { + // Add the node and set its status to true (enabled) + pendingChanges[e.Node] = true; + e.Node.BackColor = Color.LightGreen; // Mark the node as active + + // Check the type of node (either JSONPluginLoader/Patch or PowerShell script) + if (e.Node.Tag is ScriptPatcher jsonPlugin) + { + logger.Log($"Patch activated: {jsonPlugin.PlugID}", Color.Black); + } + else if (e.Node.Tag is string psScriptPath) + { + logger.Log($"PowerShell script activated: {Path.GetFileName(psScriptPath)}", Color.Black); + } + } + else + { + // Add the node and set its status to false (disabled) + pendingChanges[e.Node] = false; + e.Node.BackColor = Color.LightGray; // Mark the node as inactive + + // Check the type of node again (either JSONPluginLoader or PowerShell script) + if (e.Node.Tag is ScriptPatcher jsonPlugin) + { + logger.Log($"Patch deactivated: {jsonPlugin.PlugID}", Color.Crimson); + } + else if (e.Node.Tag is string psScriptPath) + { + logger.Log($"PowerShell script deactivated: {Path.GetFileName(psScriptPath)}", Color.Crimson); + } + } + } + + private async void btnTogglePatch_Click(object sender, EventArgs e) + { + btnTogglePatch.Enabled = false; + foreach (var entry in pendingChanges) + { + var node = entry.Key; // So, The TreeNode + bool shouldApply = entry.Value; // Whether this patch should be applied (true) or undone (false) + + // Check if the entry is Method2 and if the patch is enabled + if (node.Tag?.ToString() == "Method1" && shouldApply) + { + // Start Method2 (Setup Server variant) + logger.Log("(Method 1) Automating Windows 11 Inplace Upgrade...", Color.Blue); + NativePatcher automation = new NativePatcher(logger); + await automation.AutomateWindowsInstallation(); + + node.BackColor = Color.LightGreen; + logger.Log("Method 1 Started: Windows 11 Installation Automated", Color.Black); + } + else if (node.Tag is ScriptPatcher plugin) + { + if (shouldApply) + { + // Apply the patch + logger.Log($"Applying patch: {plugin.PlugID}", Color.Blue); + plugin.PlugDoFeature(); + node.BackColor = Color.LightGreen; + logger.Log($"Activated patch: {plugin.PlugID}", Color.Black); + } + else + { + // Undo the patch + logger.Log($"Undoing patch: {plugin.PlugID}", Color.Blue); + plugin.PlugUndoFeature(); + node.BackColor = Color.LightGray; + logger.Log($"Deactivated patch: {plugin.PlugID}", Color.Crimson); + } + } + // Handle PowerShell scripts + else if (node.Tag is string psScriptPath) + { + if (shouldApply) + { + // Log and execute the PowerShell script + logger.Log($"Executing PowerShell script: {Path.GetFileName(psScriptPath)}", Color.Blue); + + var PSPatcher = new PSPatcher(); + await PSPatcher.ExecutePlugin(psScriptPath, logger); + + node.BackColor = Color.LightGreen; + logger.Log($"Executed PowerShell script: {Path.GetFileName(psScriptPath)}", Color.Black); + } + else + { + // Log for deactivation (not reversible for PS scripts) + logger.Log($"PowerShell script cannot be undone: {Path.GetFileName(psScriptPath)}", Color.Crimson); + node.BackColor = Color.LightGray; + } + } + } + + // Clear pending changes after applying + pendingChanges.Clear(); + btnTogglePatch.Enabled = true; + } + + private void treeSettings_MouseMove(object sender, MouseEventArgs e) + { + TreeNode node = treeSettings.GetNodeAt(e.Location); + + if (node != null) + { + // Check if the node's Tag is the native "Method1" + if (node.Tag?.ToString() == "Method1") + { + rtbDescription.Text = "Inplace Upgrade via Server Setup\nThis method leverages the Windows Server variant of the Windows setup, " + + "which skips most hardware compatibility checks. It allows Windows 11 to be installed on unsupported PCs, " + + "bypassing the usual system requirements. Importantly, while the setup runs in server mode, " + + "it installs the standard Windows 11 (not the server version).\n\nHow it works:\n1. " + + "The app automatically downloads the Windows 11 version 24H2 ISO using the 'Fido' dependency script.\n2. " + + "The ISO image is mounted automatically.\n3. Simply follow the on-screen instructions to complete the upgrade.\n\n" + + "**Technical Note:** The POPCNT requirement cannot be bypassed; it is essential for running Windows 11 (24H2), as the operating system requires this feature to be supported by the CPU. " + + "POPCNT has been included in CPUs since around 2010. However, the patch is expected to work for most users with compatible hardware." + + "Please do not blame me; I am working within the constraints of what is technically possible." +; + } + else if (node.Tag is ScriptPatcher plugin) // Handle JSON plugin description + { + string pluginInfo = $"ID: {plugin.PlugID}\nHow-to:\n{plugin.PlugInfo}"; + rtbDescription.Text = pluginInfo; + } + else if (node.Tag is string psScriptPath) // Handle PowerShell script description + { + rtbDescription.Clear(); + string scriptInfo = $"PowerShell Script: {Path.GetFileName(psScriptPath)}\nPath: {psScriptPath}"; + rtbDescription.Text = scriptInfo; + } + else + { + // Clear description if no node is hovered + rtbDescription.Clear(); + } + } + } + + private void linkGitHub_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + Process.Start("https://github.com/builtbybel/Flyby11"); + } + + private async void btnMountRun_Click(object sender, EventArgs e) + { + NativePatcher patcher = new NativePatcher(logger); + await patcher.RunSetupFromMountedISO(); + } + + private void linkChangeExperience_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + ExperienceView exprienceView = new ExperienceView(); + SwitchView.SetView(exprienceView, panelForm); + } + } +} \ No newline at end of file diff --git a/FlybyScript/MainForm.resx b/FlybyScript/MainForm.resx new file mode 100644 index 0000000..063f8e5 --- /dev/null +++ b/FlybyScript/MainForm.resx @@ -0,0 +1,734 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + AAABAAEAXl4AAAEAIACgjgAAFgAAACgAAABeAAAAvAAAAAEAIAAAAAAAEIoAABMLAAATCwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAr5J1AP+PGAD/7csA//W3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+h0AKGWcQAAAAAA58qHAP/y6QD2+mIA+v6gAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9WOAP/sagDLuXgB+uCRA//y + rwP+u34D8PSDAPD/tgD45ZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//usAP/z + qAD46ooC//+XAPnulwD/+5wA/+6cALA3UwDy0KsA+NmnAP/osQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/7+qAP/qtgD92JUE8t2CAOnKhBn23oyO+N+NvPbekH3lto0J5aiPAPTXkwH+7H8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/+mOAP//sQD98ZkD9deCAOvMgSv55pLV/uyW//3kkf/97JX//euVi/j5 + mgD7uXwC//+fAP6ehwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADx150Ar8UPAKCdYgD/344E8dyHAOzPgTX65JDk/uiT//zh + jvn84Iz5/OOM/v/qkPP+5Y8p/+qSAP/soAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD17NwA2aqOAJBWAAD/95ED8t6KAOzQ + g0X65I/u/ueT//zhjfv94o3//eGM//zfiPv95Yv//u6Rcf/zjgD+86IC/f+5AP//sgAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2y5kA6OfcANzB + jQD/7YYD9uiRAO3SglP65I/2/uWT//zhjvv84oz//OGL/v3hiv/834f8/eSJ//7ojMS4y8cB////APP/ + aAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD32IAA67BjAOHEgQH//8sD//SSAO7SgmD65I/8/uSS//zijvv84o3//eGL/vzgif794If+/OCG/vze + g//954r3/e+TNv3+nwD+5I0C/tKBAP/QfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD85GcA8NJjAOSvSgH//7EB//yUAPHWg2795pD//uWT//3ij/z94o3//eKL/vzh + iv/94If//N+F/vzghP/63oH7/uaG//3liIb+5oYA/cZzBP7//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+o0A+/ODAOzWfwL//6AB//+mAPHXhHv96JL//uWS/v3i + jvz9447//OGL/v3hif/84Ij+/OCG/vzghP7834L/+96A+/zdf//96IfM//OfC/8A/wD+95YBAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKWlWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//Z0A+OSHAOzNdgIAAAAA///AAPDY + hIn96ZP//+WS/f3ij/3+447//eKL/vziiv/94Yf+/eCF//3fhP/934L//N6B/vzdfv773n39/+iD+v7l + hUT/5H8A/8t0BP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/s0IAFf//AP8i + AAB3+rIC/r5Zs/OjQv/dkzP745Eu/+mhOP/qrUP/8blM//fEVv/6y17t+tVu3PjYecT43YOi+N6FfPfZ + f1P0zHg17st7bvfikub+65v//+WT+/7kkf//5Y/+/uSN/v3jjP7+44n+/eKH//7hhf/94YP//OCB//3f + f//93n3//N57//vdeP/83Hb/+9t1//zbc//72nH++9pu/vrYbP3+5HP//eJzY//gdAD+33IE//dpAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/wBtAPL3ZADW/9sA1NaSB/m3U8/3lTr/4ok0+9iKMPzZfiT734wr+uWaMfrppTn87K4///G8 + Tf/71Wr//umF//70lv/+85v//uuW/f32q///9rT//+yf+/7mkv/+5Y/+/+SN/v7ki/7944r//uKI//7i + hv/94YP//eCB//zfgP/9333//d57//zdeP/73Hf//Nx0//vbcv/82nH++9pu/vvZbP762Gv7/d1t//3i + cK3/71IA/8lpA/rldAD+r3QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/6FYAP+hVQD6t2AB7NhzAPPafhj3slHp9po9/+9+Lf7khTL/2Icu/9p7 + I//fiCn+45Iu/uWaM/3ooTf87rNE+/nOYPv/4H38/+mO/f/tlf7+8J/8/vSy/f7xqf//6Zb+/uSN/v/k + jP/+44n+/eOI//3ihf/+4YP//eCB//3gf//8337//d97//3eef/83Xf/+9x1//zbcv/72nD//Npu//vZ + bP/62Gr++tdo/fvaaP/+5W7n/NxsKPzVdgD93m4C//8uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/VfQD/1n4A+sxsAfnMYgD40W0y+bNP/PWd + QP/xiTL+7nQo/+GCMP7Xgiv+2ngh/t6DJv7ijSr+5ZUv/+ecM//vtUT/+tJh///he//+6In+/+qM///w + nv/+9K/+/+2f//7mj/7/44r+/uKI//7ihv/94oP//eGC//7ggP/9337//N97//3eef/93Xf//Nx1//vc + cv/723H//Npu//vZbP/62Wr++9ho/vrXZv7612X6/dxn//zfaWv62mUA/OZqA///QgD//18AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/qlYA/6pWAPq8 + XAL90WYA+MtmUfy2UP/1oUH985I3//B9K/7sbyb+4H8v/9aAKf/ZdR/+3oEk/+KLKf7lkiz+5pow/vC3 + Q/781GH+/+N7//7ohv7+6ov+//Gj//7yqf7+6pX//+SK//7ihv/94oT//uKC//3hgf/+4H7//d97//zf + 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 + JP/raCD/6GQg/9t3KP/UcR//2XAb/959IP/hhCL/5Ism/++sNf/80VP//+Fu//7ldf/+6oT///Cb//7p + iv//4nv//t92//3edf/+3XL//d1v//zcbf/922r//Npo//vZZv/82GP/+9hh//zXXv/71lv/+tRZ//vU + Vv7601T++tNS/vvUUvr92VH//NlTiPrSRgD93j8E+daBAP//JwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ykUA9sdjA+7IeADzxmc+/Mdc8vm4T//4tEv9965E/vam + Pf71mzb/848v//GDKv/veSb/7HEj/+tlH//nYx//2XQn/9RvHv/ZcBv/3n0g/+GDIv/kjCX/8rI4//3V + V///4m3//uVz///si//+7pT//+Z///7fdf/93nL//d1w//3cbf/822v//dto//zaZf/72WP/+9hh//zX + Xv/71lz/+9ZZ//rUVv/701T/+tNS/vrST//60k77+9RN//7eUc3001ES7LVDAPrUUAH//1wAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/IQAA/i0AAPauUgTyymgA9MRiVvzE + Wv/4uU/8+LVL/vewRf72qT//9aA4//SWMv/yii3/8H8o/+53JP/sbiH/6mMe/+ZgH//Zcib/020c/9lv + G//efB//4YEh/+WPJv/0ujv//tlZ///jbP/+5nT//+6P///riv/+4Xb//t1w//3dbv/93Gv//Nto//3a + Z//82WT//Nlg//vYXv/811v/+9ZZ//rVV//71FT/+9NQ//rST//50Uz++tFL/vvTSvz92Ev/+dVORvvU + SAD94EED//8AAP//JgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/6gzAPf/ + /wD1t00F8bxVAPTGY3T7v1j/97hR+ve2TP73s0b+96xB//alOv/0nDT/8pEv//GGKv/vfSX/7XQh/+ts + IP/pYR3/5WAe/9dwJP/Tahv/2m8a/958H//hgCD/55Qn//fBP///3Fz//uNp//7oef/+7o///+d+//7f + b//93Gv//dtp//zbZv/82mP//Nlh//zYXv/711v//NZZ//vVVv/61FT/+9NS//rST//60Uz++dBJ/vrQ + SP/60Ef7/NZG//7dSpP/+UoA/+s/Av+7CwD/yjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP/AhQDr0GwA/rlYA/64QgD2xGGV+L1W//e5Uvr4uE3+97RI/vevQv/2qDz/9KA3//OX + Mf/yjiz/8IMo/+56I//scSH/62of/+hfHP/kXh3/1m4j/9JnGv/abxr/3nse/+CAH//pmSj/+sdC///f + Xf/+42f//up+///siP/+43P//txp//3bZ//82mT//dph//zZXv/72Fz//NdZ//zWVv/71VT/+tRR//vS + T//60kz/+dFJ//rQR/76z0X/+tBD/fzTQ//91UPg+tFHE/f/bAD+uzMA/0gAAP9nAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/1sA8r9uAP//JgG786EE/Mhisfm9V//2uVL7+LdO//e1 + SP72sEP/9qs+//WkOP/0nDT/85Qu//GKKv/vgSb/7nci/+xvIP/pZx7/6F0a/+NcHf/VayL/0WYY/9pu + Gf/eeh3/4IAe/+ugK//8zkb//99d//7kaf/+7IL//+l+//7eav/922T//Npi//3ZXv/82Fz//NdZ//vW + Vv/81VP/+9RR//rTT//70kz/+tFJ//rQR//5z0T/+c5C/vrPQf/6zj/9/dc///zZRFb92UUA/NlAAv3m + RAD/60YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+716APLIWwGx2mgA47poEfzK + Y8r5v1j/9rlT+/e4UP/2tkr+9rJF//atQP/1pzr/9KA1//OZMP/ykCz/8Icn/+9/JP/tdSL/620e/+lm + HP/nWxn/4Vsc/9NpIP/RYxf/2m0Y/915G//ggB7/76kt//7USf//4F3//uVt//7rgv//5XL//ttj//3Z + X//82Vz//NhZ//zXVv/71lT/+9VR//zUTv/700z/+9FJ//rRRv/60ET/+s5B//nNP/76zj7/+s48+/3T + O//80zyp/881AP3gPgP33nwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5bx0AOOt + gQDjuWwD16xVAOi/aSvzwl7z971X/va6VP33uVD/9rZL/vazR//1r0L/9ak8//SjN//znDL/8pUu//GN + Kv/whSX/7nwj/+1zIP/rax3/6GQb/+VYGP/fWhz/0mcf/9BhFv/ZbRj/3Xcb/+GCHv/ysC///9dL//7h + XP/+53L//+p7///gZv/92Vz//Nla//zXVv/81lT/+9VR//vUT//800z/+9NJ//rRR//70EP/+s9B//nO + P/75zTz++sw6/vrNOf37zTf//dY55PjUPyLz3S8A+dM+AvzGWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAz75VAKmMJACwTxIA//+3Av//hADpvGSa8MZi/+2+V/vzu1P/9bhQ/va2Tf71tEj/9q9D//Wr + Pf/1pjn/8580//KZL//xkyv/8Ysn/++CJP/teiH/7HEe/+ppHP/nYRr/5VUX/99YG//QZB7/0F8V/9ls + GP/cdhr/4oUe//a6Mv//203//uFd//7pdP//53D//ttc//3XV//911T//NZS//vVTv/81Ev//NNJ//vS + R//60ET/+89B//rPPv/5zTz/+s05//nLN/76zDb++sw0+/3SNP/60DZk+84tAPzTLAT/9gAA/vwpAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8M1RALyhWwC+lVAB//+0Af//rQDhs2R289F4//DMbP3qw17+7L9X//C6 + UP70t0z/9rRJ//WxRP/1rT//9Kg6//SjNv/ynDL/8ZYt//GQKf/wiSX/74Ei/+14IP/qcB3/6Gca/+Zf + Gf/kVBb/3Vca/89iG//QXhP/2WwX/9xzGf/lix//+cI1///cTP/+4mD//uhy///iY//92FX//NZR//zV + Tv/71Uz//NNI//zSRv/70UT/+tBB//vPPv/6zjv/+c05//rLN/76yzX/+csz//rLMfr7zC///dMysPLr + ewL//2EB+sYuAP/+VwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyJ5lANWiQADDlU4B////Af//2QDfsGF89t2K///s + mf7734f99NFz/+3FYf7qv1b/7bpO/vG1Sf/1sUX/9a5B//OpPf/zpDj/858z//KaL//xlCv/8I4n/++H + JP/ufyL/7Hce/+puG//oZBj/5V0X/+JRFf/cVRn/zl4b/89cEv/Yahb/23IX/+iTIP/7yTf//91O//7k + Zf//52v//t1X//3WTv/81Uz/+9RJ//zTRv/80kT/+9FB//rPPv/7zjv/+s05//nMNv/6yjT/+coy/vrK + MP/5yS/9+8ws//7RLe/3yjEq+8IqAP7UJAL//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmohoAK2GUwC8hjgCJgAAAP// + /wDis2WI+OCO///xof3+65r9/+uX//7ljv752X3/8Mpn/uq/V//quU3/7rNG//OuQv/0qz//86c6//Oi + Nf/ynDH/8Zct//CRKf/viyb/74Uj/+5+IP/rdRz/6mwa/+diGP/kWhf/4k8U/9pUGf/MXBn/z1sR/9hq + Ff/bcxf/65sh//3ROv//3lH//uVm//7jX//92E7//NVI//zURv/70kP//NFB//vQPv/6zzv/+844//rM + Nv/5yzT/+soy//nJL/75yC3++sos//rHKfv8yyj//tMtbv/dLQD/vBAD/rAAAP+1AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5xrAMOn + cgDGm10DYwAAAP///wDluGmW++ST///xovv+65v9/uuZ//7rl/7/6pX//+mQ/v3hhP/20nD/7cNb/+i4 + Tf/rskT/8Kw///OoO//yozj/8aA0//GZL//xlCv/8I8o/++KJf/uhCH/7Xwe/+tzG//pahn/5mAX/+NY + Ff/gTRP/2FIY/8tZF//PWhH/12kU/9x0Fv/vpiT//9U8//7fVf/+5WL//t5S//3UR//800P/+9JB//zR + Pv/80Dv/+844//vNNv/6zDT/+csx//rJL//5yC3/+ccq/vrIKf/5xyb8/Mwk//3OJsLDp0YC/88AAN// + bAD/RA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3a5pAMOhXADRoFoDrDIAAA0AAATpvG2j/eiX///xovz+65v+/+yZ///smP7+65b//uqT/v7q + kf//6o///+aI//vbef/yy2P/6btP/+iyQ//sqjz/8aQ5//KgNf/xnDH/8Jct//CSKv/vjSf/7ogi/+6C + H//sexz/6nIa/+hoGP/kXxX/4VYU/95LEf/WUBj/yVcW/85ZD//XZxP/3XYV//OwJv//2ED//uBY///j + Wf/+2Uj//NJA//vRPv/80Dv/+885//rONv/7zDT/+ssx//nKLv/6ySz/+ccq//jGKP75xyb++sgk/vnF + If/9zCH3+9IrNP3cNwD8yR0C/70CAP+7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5rBbAP7ObQDUrVoDwWkpAHwmAAzov3Cy/uyb///xo/r+7Jv+/+2b//7s + mf7/7Jb//uuV/v/rkv//6pD//umO//7pjP//6In//uKA//jVbf/uwlb/57JF/+epO//tojb/8J0z//CZ + MP/vlCz/748o/++LJP/uhiH/7YAe/+t5G//qcRn/52cW/+RdFP/gVRP/3UkR/9ROF//IVBT/zlgO/9Zl + Ev/fexb/97oo///aRP/+4Fb//99N//3UPv/80Tv//NA4//vONv/6zTP/+8ww//rLLv/5ySz/+sgq//nG + KP/4xSX/+cUj/vrGIf/4xB/8/csf//vLIoX6xSEA+cscA/HeAAD/8wMAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9aAAP/XfgDuumgEw3YtAKlSFxTow3PB/u+e///x + pPr+7Jz+/+6c//7tmv7+7Jf//+yW/v/rlP//65H//uqP///pjf/+6Yr//uiI///ohv//5oH//d52//TM + YP/quEr/5ak7/+mgM//umjH/75Yu/+6RKv/ujSf/7okj/+2EIP/sfx3/63gb/+lwGP/nZhX/41wT/99S + Ev/bRhD/0k0W/8dSEv/OVw3/1mMR/+ODF//6xCz//9tG//7gT//+20L//dE5//vPNf/8zjP/+8ww//vL + Lf/6yiv/+ckp//rHJ//5xST/+MQi/vjEIP76xSD++cQf/PvFHv/8yyHM9M44CwAAAAD61CgBAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+fD0A3aZgAO29bwDdqmAE0Y0/ALht + KB/qxXbN//Gh///xpPr+7Z3//+6d/v7tm///7Zn+/+yW/v/slP//65L//+uQ///qjf/+6ov//umI///p + hv/+6IP//ueB///nf//+43n/+tdq//DCUv/mrT7/5J8z/+mWL//tki3/7Y8p/+2LJv/thiL/7IIf/+x9 + HP/qdxn/6W4W/+ZlFP/jWhP/3lAR/9lFEP/QSxX/xk8R/81WDf/WYhD/5o0Y//3LMP//20j//t5G//7V + OP/8zjL/+84w//vLLf/7yiv/+skp//nIJv/6xiT/+cUi//jDIP/5wx//+cQg/vnDH/74xB79/csg+vjF + JEX2vyYA+b8hA+4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxYlKAP// + xgDltGgE3qFUAMF3MijryHnZ//Oj///xpfr+7p7//++e/v7um/7/7pr+/u6Y///tlf//7JP//+yQ///r + jv//64z//+qK///ph//+6YX//+iC//7nf//+5n3//uZ7///leP/932//9s5b/+u3Rf/joTT/5ZQt/+qP + Kv/tiij/64gl/+uEIf/rgB//6nsc/+l1GP/obhb/5mQT/+JZEv/dThD/10QP/85KFP/ETQ//zVUM/9Zj + EP/smRv//9I0///bQ//+2jv//dAx//vMLf/7yyv/+8oo//vJJv/6xyP/+sUh//nEIP/5wh//+MIg/vjD + IP74wx/++MIe+vrEHv/8yyOM/cQMAP29BQP452cA/rsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACKZjcAQxcAAAAAAADuxnYE5KRQAMWFPjXty3zi//Sm//7xpPr+76D///Ce/v7unP7/75r//u6Y///t + lv//7ZT//+yR///sj///643//+uL///qiP//6Yb//+mE//7ogP/+533//+d7//7mef/+5Xb//+V0///j + cP/82WP/8sRP/+apOf/hlS3/5osp/+qHJ//qhST/6oIh/+p9Hv/qeRv/6XMX/+dsFf/lZBP/4VgQ/9xN + D//WQg7/zEcU/8NLDv/NVAv/12YQ//CmHv//1DX//to8//7WMv/8zCr/+sso//vJJf/6yCL/+sYh//nF + IP/5xB//+MIg//fCH//4wh/++cMf//fBHvz5xR7//soh1vC5JhDzrS0A+r0oAfzZAwAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zHkD3bNgAMqLQkLuzn/s//Wn//7xpfr+8KH///Cg/v7v + nv//75v+/+6Z/v/ul///7Zb//+2T///skP//647//+uM///rif//6of//+mE///pgv//6H///ud8//7n + ev/+5nf//+V0//7kcv/+42///+Ns//7gZv/50Vf/7LdB/+GbL//hiif/5oQm/+mCI//pfyD/6Hod/+h2 + Gv/ochf/52wU/+VjEv/gWBD/2ksO/9NADv/JRRL/wUkM/8xSCv/abBH/9LIh///WM//+2DT//tAq//vJ + Jf/6ySL/+scg//rGH//5xR//+cMg//jCIP/3wR//+MEg/vjCH//3wR7+98Ae/PnEHv/5ySZI98UjAPnW + EwL/2AAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3MCUAAAAAADx14cD98tyAM+SSU/w0oT0//aq///y + pfr+8KL///Gh/v7wnv7/8J3+/++a///vmP//7pb//+2U///ukv//7I7//+yM///riv//64j//+qE///p + gv//6YD//+h9///nev//53j//+Z1//7lc///5G///uNs//7jav/+4mf//+Fk//3bW//0xkn/5qg1/9+N + J//igST/538j/+h8H//neB3/53Qa/+dvF//mahT/42IS/99XD//YSg3/0j4N/8ZDEv/ASAz/zFIL/952 + E//5vCP//9Uv//7VKv/8yyL/+scg//rGIP/6xSD/+cQg//jDH//4wiD/98Ef//fAH//4wR/++MEf//a/ + Hvv8xx7/+8kinP/WGQD/qAwC8fcAANn/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD//7oB8ct0ANid + UV3z2Ir7//es//7xpvv+8aP///Ki/v7wn///8Z3//vCc/v/wmf//75f//+6V///uk///7ZD//+2N///s + i///7In//+uG///rg///6oD//+l9///oe///53n//+d2///mc///5XD//uVt///kav/+42f//uJk//7g + Yf//4F7//99a//vUT//vuT3/4Zcr/96CI//jeyH/5nkg/+V2Hf/lcRn/5W0X/+RoFP/iYBH/3lYP/9hJ + Df/PPQ7/w0IS/79IC//MUw3/4YAW//zEJP//0yr//dEj//vHH//6xiD/+sUg//nEH//4wx//98Eg//fA + H//2vx/+98Af/vfAH//2vx79+L8d//nCH+XyyS8W//9oAOCvHAG4iQAAu40AAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqpYAMHm + iADeu3MC77lpAN2nWk333o/7//mu//7ypvv+8qX///Gi/v7yof//8Z/+//Cc///wmv//75n//++W///v + lP//7pH//+2P///tjP//7Ir//+yH///rhf//6oL//+p////pe///6Xn//+d3///mdP//5nD//+Vt///k + a///5Gj//uNk//7iYf//4V7//uBa//7fV///31X//ttP//fJQ//opzH/3Icj/954H//jdh7/5HMc/+Nv + Gv/jaxf/42YU/+FgEv/dVhD/1kkN/8w9Dv/AQRL/vUYM/8tUD//mjxr//con///SJ//9zCD/+sYf//nF + IP/5wyD/+MIf//fBH//3wB//9r8f//e/H/72vx/+974e/vW8Hf38xR//+MQjX/nGJQD2xB0D7rECAO+0 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADpxW4A//+9A///zgD54pOz/ves//7yqPn/8qX///Kk/v7yov7+8p/+//Ge//7x + nP7/8Jn///CW///wlP//75L//+6Q///ujf//7Yr//+yI///shf//64P//+qA///qff//6Xn//+h3///o + df//53L//+Zv///la///5Gj//+Nl///jYv//4l///uBb///fWP/+31T//t5Q//7dTv//3Ev//NVF//G7 + N//hlCf/23oe/99yHf/icRv/4W0Z/+FpFv/hZRT/4F8S/9tWEf/USQ//yj4P/7xAEv+6RQz/zFoR/+ud + Hv/+zCf//s8l//vHIP/5xB//+MMg//jCH//3wB7/9r8e//a+Hv/2vR7/9r4f/va9Hv/1vR37+b8d//zD + IKr/sQAA/7sAA/nIMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/vewAP/9swP//bAA//mxqf72q//+8qX1/vGk/f/z + ov7/86H///Ke//7ynP7+8Zr+//CY//7wlf7/75P+/++R///vj///7oz//+2I///thf//7IT//+uB///q + fv//6nv//+l4///odv//6HL//+dv///mbf//5Wn//+Vl///kYv//417//+Jc///gWf/+4FX//t9S//7e + Tv/+3Ur//ttI///bRf//2kH/+cs5/+moLP/bgiD/2nAb/99uGv/gaxj/4GcW/99jFf/eXxT/2lcT/9JJ + EP/HPRH/uT8S/7lFDf/QYhX/8Kkh//7NJv/9zCL/+cQg//jDH//4wR//98Af//e/H//2vR7/9bwf/va+ + H//1vR7+9bwd/fa8Hf/9xR/m8b4kKO7HMAD3xCMC+nEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+VAP75hwD++K0C/fi1AP76 + tkP++7T0/vSm//71pf/+8qD7/vCd/P7xnP3/8pv///GY//7xlv7+8JT+/++S/v7vj/7/743+/u6L///t + h/7/7IT//+yC///sf///63z//+p5///qdv//6XP//+dw///nbf//5mn//+Vn///kY///5GD//+Nc///i + Wf//4Vb//+BS///fT//+3kv//91H//7cRf/+2kH//tk+///ZO//+1Tj/87wv/+GSI//Xchv/22kZ/99p + GP/eZhf/3WIX/9xfFv/YVxX/z0oT/8Q9E/+3PhL/uUYP/9NsGf/0tCT//s0l//vIIP/4wh//+MIf//fA + H//2vh//9r0e//W8Hv/1vB/+9rwe/vW7Hf70uxz6+L4c//nAImb7uxcA+8MPA7YA/wD+3gAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAA4oT/AP71bwH/9KMA/fSoQ//7raP/+6rh/vWj//74ov/+8pv//u+X/P7wlvv/8JX9//CT/v7w + kP//8I7//u+L/v7uiP7+7oX+/+2C//7tgP7/7H3//+t6///qd///6nT//+lw///obv//52r//+dm///l + ZP//5GD//+Rd///jWf//4lb//+FS///gTv//30v//91I//7dRf/+3EH//9o+//7ZOv/+1zj//9Y1///X + Mv/8zS7/66om/9p+Hf/WaBj/22YY/9xmGP/bYxj/2l8Y/9dYF//OSxX/wj4V/7Q9Ev+5RhH/2nkc//i9 + JP/9zCP/+cQf//fBH//3vx7/9r4f//W8H//1ux7/9bse//W7Hv71ux3/87kc+/e8Hf/9wyC0vZArBAD/ + /wDo2EUA+J4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP74/wD/+IYA//arAvzxnQD/9bIA/uyfG//6qVP/+qal//Wf6f77 + oP/+85f//vCT//7xkPr/7oz6/u6K/f/vif//74b//+6D//7tgP7/7H7+/+x7///reP7/6nT//+py///p + bv//6Gr//+dn///mZf//5WH//+Rd///kWf//4lb//+JS///gT///30z//99I///eRf//3EH//9s+//7a + O//+2Tf//9g0//7WMf/+1S7//9Us///UKv/3vyX/4pMe/9RtGf/WYxn/2mUZ/9ljGf/YXxr/1loZ/85N + F//APhb/sTwT/7pJE//fhh//+sMl//zIIv/3wB//9r8f//a+H//1vB//9Lse//S6Hv/0uh7+9bod//O4 + Hf71uRz++Lwd9vS/Jyv0wyYA/7kTAemVAADjkwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/fAAD99asD//mKA/7r + ngD/96oA///PAP//phf++aBf/vWaq/78m+H+9ZL///KN//7xif/+7IT8/uyB/P7tgP3/7X7+/u17/v/s + eP7+63b+/uty/v/qb/7/6Wz+/+ho///oZf7/5mL//+Ve///lWv//5Ff//+NT///iT///4Ez//+BI///f + RP//3UH//9w+///bO///2jj//9k0//7YMf//1i7//tUs//7TKf/+0ib//9Mj//3NIv/vrCD/2Hwc/9Bj + Gv/WYxv/2GMb/9dgG//VWxv/zU4Z/78/F/+vPBP/vE0W/+aUIf/7xyT/+sMg//a+H//1vR7/9bwe//S6 + Hv/0uR//9Lke//S4Hf70uB3/8bYc/Pu+Hf/7wCN4/8MmAOe4FQP/8gwA//8BAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//PqAP/81AD+9KYB//mWA///fwH//80A/v+jAP3rhAD+85cj/vOSYP79lKb/9Yzr/vSH//7z + hP/+7H3//+t5/P/rePv+6nX9/+ty/v/qcP//6mz//+lp/v7oZv7+6GL+/+de///lW/7/5Vf//+RT///j + UP//4k3//+FJ///fQ///30H//94+///cOv//2zf//9k0///YMP//2C7//tYr//7VKP//0yb//tIj//7P + If//zyD//9Eh//jBIf/jlR//0Gsc/9BgHP/WYxz/12Ec/9RcHP/NTxr/vj8Y/646E//AVBf/7KMj//zH + Iv/3vh7/9bwf//W7H//0uh//87ge//O4Hf7zuB3+87cd//G2HPz2uBz/9rkdyvDOfgLJUAAB27YgAJZh + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//nwA//+nAP//fAD/+18A//eWAf7tmwP+9Y0D/v+mAP3u + kQDtkWAB/uyKH//6jGH+9IS1/vSA7P72fv/+7HX//+xy//7pbfr/52v7/+ho/v/pZf//6GL//+de/v7m + W/7+5lf+/+VU///kUP7/4kz//+JJ///hRf//30H//989///eO///3Df//9s0///ZMf//2C3//9cr///V + J//+1ST//tMi//7RIf//0CH//s8g//3NIP/+ziD//c0h//CxIP/XfR7/zGAd/9JhHf/WYh3/01wc/8xP + Gv+9Pxj/qzkT/8VeGf/ysCP/+sQg//W7Hv/0uh//9Lke//O3Hv/ztx7/8rce//K2Hf7ytRz+8LMb//u8 + HvX3vCY9/70tAPGwHQPaqwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/4QA//dnAP/q + egD/1JAA//iiAP72lgL+8pEE//+4Af7ofQD//5QA//+eAP/6hiL98Xxt/vN5s//3dun+7G3//+1q///p + ZP7/5WD7/uZd/P/mWv3+5Vf+/+VT///kUP/+40z+/uJJ/v/hRf7+4UH//98+/v/eOv//3Tf//9w0///b + Mf//2S7//9gq///XJ///1ST//9Qi///SIP/+0SD//9Ah//7PIf/+ziH//Mwg//zLIP/+ziH/+cMg/+SZ + H//Oax7/zF0e/9NhHv/TXR3/zFAb/7o+GP+qORP/zGsb//e6Iv/4wB//9Lke//O4Hf/zth7/8rYe//K2 + Hf7ytRz+8rQc/vGzG/r2thz/87UgiPu2EAD6rg4E2MVaAPuHAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD+7HgA/8qOAAAAAAAAAAAA+du0AP3ufQD++YIB/uiHAv/rbAH//4oA/f1+APq5 + YAD+63Ir//Bwaf71bbb+7GT1/+9i///qW//+5FX//+RR+v7jTvr+4kv9/+JH///iRP/+4EH//uA9/v7f + Ov7/3jb//90z/v/cMP//2y3//9kq///YJ///1yP//9Uh///UIf//0yH//tEh///RIP/+0CH//s4h//3N + IP/8yyD/+8kh//vKIP/9zCD/8rQf/9d/H//JXx7/zl0e/9NeHf/MURv/uT0Y/6o4E//VfB7/+cEi//W5 + Hv/zth7/8rYd//K1Hv/ytR3+8rQd/vGzHP/wshz78bIa//q6Hs3utSwR4KVXAPS2KAH/zAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+rAD//6gA/lv/AP7X + ggD/sTYA//F/Af3phQT+v2sD/ulpAP7pbQD+uU4E/vBmJf/0Y3H+61rA/+9X7v7rUf/+5Ur//+RH/v7g + Q/r+3j/8/988/v/fOv//3Tb//t0y/v/cL/7/2y3//top/v/ZJv7/1yL//9Yh/v/VIv/+1CL//9Mh//7R + If//0CD//tAh//7OIP/9zSH//Msg//zLIP/7yCD/+sYf//zJIP/5xCD/5Zwf/8tqH//JWR7/0Fwe/81T + HP+3PBj/rTsU/9+NH//6wSH/8rUe//K1Hv/xtB3/8bMe//GzHf/xshv+8LAc/vGwG/z2tBz/77MiRfK1 + HgD3nBYD/wAAAP8xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD/14EA/8lbAP/mhAD/oX0A//+NAP/waAL+7mYD//8wAP7nbgD//2gA/+FaAP/y + Vi3+6E91/u5MuP/rRvP+5UH//uU9///eOP/+3DX8/twx/P/bLv7/2yv+/top///YJv//1yP+/9Yh/v/V + Iv7+1SH//9Qi/v7TIf/+0SH//9Eg//7QIP/+ziD//c0h//zLIP/8yiD/+8kg//rHH//5xSD/+cUf//vI + H//yth//2IMe/8ZcH//LWB7/zVUd/7Y8F/+vQBX/550h//i+H//xsh3/8bMe//CyHv/xsR3+8LEc/vCw + G//urhv687Ab//i3IZT/xw0A/6sAAv+nAAD/sQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6HwA/qGZAP/GPAD/+gAA/v8AAP7Z + YAD++VMB/+JeA//qRAL//FcA/uxNAP/pOAX+5kIx/u1Bcv7pPML/5Tb4/uYz//7dLv//2ir//tkn+v/X + JPv+1yH+/tYh///VIv/+1CL+/tQi/v7TIv7+0iH//9Eh/v7QIP/+zyH//s4h//3MIf/8yyD//Mof//vJ + H//6xyD/+sYg//nEH//4wR//+cUf//nDHv/noB7/zGse/8VVHv/LVR7/tTsX/7VKF//vrCH/9bke//Cv + Hf/wsR7/8LAd/++vHP7wrhv/7q0b/fOuGv/1sh3f57EwEuKiMwD0zRsA//8AAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + Gv7lmBn+5ZgZ/uWZGf/klhj87ZsZ/+qcHnjumxsA4YgUBLuGAACzmwMAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+xAAD/jQgAAAAAAP// + AAD/n/8A69EhAOS2DwL/vRsC////APq9HwDsmRIA9LofG/m2HVL/th6e9asb5fSoHP/woxv/5pwa/+ac + Gvvkmhr645ga/OSXGv7jlRn/4pQa/+OVGf7jlBj/45UY++WVGP/olxrE0emwAv9MAAHpmSgA/zUAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAA9dMAAP9FAADGqgAA/7INAP/HGQH6txsD8bgPA/PCLAD0rxwA/5Y1APnF + HRX+tR5X86cbqPSkHOHyoRv/5pca/+aXGf/hkxn735EZ++CQGf3hkRn/4ZEY/+COGP3ikBf/7Zga8uWX + IDncjiEA5JkaA9S0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyKoAAP+sAgD/qwAA/6QEAP+/ + JwD5uyMB9agUA/+gAAH0oCcA/7smAPCNGAD/xSQY8KYcWvOjHKDznhvf6JQZ/+mTGf/gjRj/3IoY/d6M + GPvfjBf83YoW+eKMF//kkh1/6IYMAPGbBwSoWG8A/8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wUA/qcAAPygAAD/YwAA+b4SAf2uEwLvpxMD//9mAPOmGwDfVAIA6qkcHfWk + HVT0nRuj55Ea6OqPGf/iiRj/3YgX/9yIF/ffiBb/6Y8axM6MKgv/4/8A7JEuANGJAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+rQAA/6UAAP/QAAD/rwEA//8eAPC8 + HQHxjBUE6HcBA/yrJwDxjhkA/3kmAPm2IxTynBxb544ZqOuOGeDliRf/5ogX/+uOG5UAAJoA/7UAAdN+ + LAD1pAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD/1wAA/KwAAAAAAACsuQQA4gAAAPLFOAD8rB0B1Z4OA/GEAgHuxzAA85kiANpmCADuox4f548ZXeSK + GmTVhiQN14UaANiDHQHOdBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8ogAASAAAAKiuAADs7gAA95IRAfSf + FQPgewoD5ME2AOOFEgDdexIAs99TANxqGQHbYxkA4jANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC6rAAA7dQAAP5tAAD/sgMA/903AO6ZHALkgxEE4owQBOKNIgHifRoA4oAVAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/cAAA/7AAAAAAAAD/hw0A//9wAAAAAAD/ajMAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA///////////////8///////////////8///////////////8///////////////8//////// + ///////8///////////////8///////////////8///////////////8/////////h/////8//////// + /f/////8////////+gv////8////////9Av////8////////6AX////8////////0AX////8//////// + oAP////8///////+QAL////8///////8gAL////8///////5AAF////8///////2AAF////8///////s + AAF////8////x//QAAC////8/////B+gAAC////8////g+BAAAC////8///+gB+AAABf///8////AAAA + AABf///8////AAAAAABf///8///9AAAAAAAv///8///9AAAAAAAv///8///9AAAAAAAf///8///9AAAA + AAAX///8///9AAAAAAAX///8///9AAAAAAAH///8///6AAAAAAAL///8///6AAAAAAAL///8///6AAAA + AAAF///8///6AAAAAAAF///8///6AAAAAAAF///8///6AAAAAAAD///8///4AAAAAAAC///8///0AAAA + AAAC///8///0AAAAAAABf//8///0AAAAAAABf//8///IAAAAAAAAf//8//+QAAAAAAAAv//8//9gAAAA + AAAAv//8//7AAAAAAAAAf//8//0AAAAAAAAAX//8//oAAAAAAAAAX//8//QAAAAAAAAAL//8/+gAAAAA + AAAAL//8/9AAAAAAAAAAL//8/6AAAAAAAAAAF//8/0AAAAAAAAAAF//8/oAAAAAAAAAAF//8/QAAAAAA + AAAAC//8+gAAAAAAAAAAC//8+gAAAAAAAAAAC//8+gAAAAAAAAAABf/8+gAAAAAAAAAABf/8/QAAAAAA + AAAAA//8/sAAAAAAAAAAAv/8/zgAAAAAAAAAAv/8/8cAAAAAAAAAAP/8//jAAAAAAAAAAX/8//8cAAAA + AAAAAX/8///jgAAAAAAAAL/8///8YAAAAAAAAL/8////ngAAAAAAAL/8////8YAAAAAAAH/8/////nAA + AAAAAF/8/////84AAAAAAF/8//////jAAAAAAC/8//////84AAAAAC/8///////HAAAAAC/8///////8 + 4AAAABf8////////HAAAABf8////////84AAAB/8/////////nAAAAv8/////////44AAAv8//////// + //nAAAP8//////////44AAX8///////////HAAX8///////////44AP8////////////HAX8//////// + ////44X8/////////////Hv8/////////////4f8///////////////8///////////////8//////// + ///////8///////////////8///////////////8///////////////8///////////////8 + + + \ No newline at end of file diff --git a/FlybyScript/Patcher/NativePatcher.cs b/FlybyScript/Patcher/NativePatcher.cs new file mode 100644 index 0000000..fd876a7 --- /dev/null +++ b/FlybyScript/Patcher/NativePatcher.cs @@ -0,0 +1,345 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +/* + * NativePatcher class is responsible for automating the Windows 11 24H2 installation process. + * It uses the Fido.ps1 script https://github.com/pbatard/Fido to download the ISO, mounts the ISO, and runs Server setupprep.exe + */ + +namespace FlybyScript +{ + public class NativePatcher + { + private Logger _logger; + private string _fidoScriptPath; + + public NativePatcher(Logger logger) + { + this._fidoScriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "upgraider", "Fido.ps1"); + this._logger = logger; + } + + public async Task AutomateWindowsInstallation() + { + // Step 1: Download Windows 24H2 ISO using Fido.ps1 + await DownloadISO(); + + // Step 2: Allow user to select the ISO after download + MessageBox.Show("Please select the ISO file to mount.", "ISO Selection", MessageBoxButtons.OK, MessageBoxIcon.Information); + + // Step 3: Mount the ISO and get the mounted drive letter + string mountedDriveLetter = await MountISO(); + + if (string.IsNullOrEmpty(mountedDriveLetter)) + { + _logger.Log("Failed to mount ISO. Exiting.", Color.Crimson); + return; + } + + // Step 2: Run the setup process with the mounted drive letter + await RunSetup(mountedDriveLetter); + } + + // Step 1: Download Windows 24H2 ISO by running the Fido.ps1 script + private async Task DownloadISO() + { + try + { + _logger.Log("Starting the download of the Windows 24H2 ISO...", Color.Blue); + + // Run Fido.ps1 to download the ISO (PowerShell script) + string downloadCommand = $"& \"{_fidoScriptPath}\""; + await ExecutePowerShellCommand(downloadCommand); + + _logger.Log("Windows 24H2 ISO download completed.", System.Drawing.Color.Green); + + MessageBox.Show("Please wait for the ISO file to download, and then select the ISO file.", + "Information", + MessageBoxButtons.OK, + MessageBoxIcon.Information); + + _logger.Log("Please wait for the ISO file to download, and then select the ISO file. " + + "If you cancel the process here and wait for the ISO download, you will need to restart the patching process, " + + "but you can skip the ISO download.", System.Drawing.Color.Black); + } + catch (Exception ex) + { + _logger.Log($"Error during ISO download: {ex.Message}", System.Drawing.Color.Crimson); + } + } + + private async Task MountISO() + { + try + { + OpenFileDialog openFileDialog = new OpenFileDialog + { + Title = "Select Windows 24H2 ISO File", + Filter = "ISO Files (*.iso)|*.iso|All Files (*.*)|*.*", + InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer) + }; + + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + string isoFilePath = openFileDialog.FileName; + + MessageBox.Show($"Selected ISO file: {isoFilePath}. Now mounting the ISO.", "ISO Selected", MessageBoxButtons.OK, MessageBoxIcon.Information); + + _logger.Log($"Mounting ISO: {isoFilePath}...", System.Drawing.Color.Blue); + + string mountCommand = $"Mount-DiskImage -ImagePath \"{isoFilePath}\""; + await ExecutePowerShellCommand(mountCommand); // Run asynchronously for mounting + + // After mounting, try to get the drive letter + string mountedDriveLetter = await GetMountedDriveLetter(); + + if (string.IsNullOrEmpty(mountedDriveLetter)) + { + _logger.Log("Failed to get mounted drive letter.", System.Drawing.Color.Crimson); + return null; + } + else + { + _logger.Log($"ISO mounted successfully. Drive letter: {mountedDriveLetter}", System.Drawing.Color.Green); + return mountedDriveLetter; // Return the mounted drive letter + } + } + else + { + _logger.Log("No ISO file selected.", System.Drawing.Color.Black); + return null; + } + } + catch (Exception ex) + { + _logger.Log($"Error mounting ISO: {ex.Message}", System.Drawing.Color.Crimson); + return null; + } + } + + private async Task RunSetup(string mountedDriveLetter) + { + try + { + // Check if the mounted drive is available + if (string.IsNullOrEmpty(mountedDriveLetter)) + { + _logger.Log("No mounted drive found. Exiting.", System.Drawing.Color.Crimson); + return; + } + + // Log the drive letter + _logger.Log($"Mounted drive letter: {mountedDriveLetter}", System.Drawing.Color.Gray); + + // Build the path to the Sources folder + string sourcesFolderPath = Path.Combine(mountedDriveLetter, "sources"); + + // Path correct? + _logger.Log($"Checking Sources folder at: {sourcesFolderPath}", System.Drawing.Color.Gray); + + // Check if Sources folder exists + if (Directory.Exists(sourcesFolderPath)) + { + _logger.Log($"Found Sources folder at {sourcesFolderPath}. Opening CMD and running setupprep.exe.", System.Drawing.Color.Green); + + // Prepare the CMD command to open cmd, then run 'setupprep.exe /product server' + string cmdCommand = $"/C \"cd /d {sourcesFolderPath} && start cmd /k setupprep.exe /product server\""; + + // Execute the CMD command, which will open a new CMD window + ProcessStart(cmdCommand); + + MessageBox.Show("Follow the Windows Server Setup window now. You can close the command window and the Flyby11 app.", + "Information", + MessageBoxButtons.OK, + MessageBoxIcon.Information); + } + else + { + _logger.Log($"Sources folder not found at {sourcesFolderPath}.", System.Drawing.Color.Crimson); + } + } + catch (Exception ex) + { + _logger.Log($"Error running setupprep.exe: {ex.Message}", System.Drawing.Color.Crimson); + } + } + + // btnMountRunSetup_Click: Run setup.exe from a mounted ISO on the fly + public async Task RunSetupFromMountedISO() + { + // Choose an ISO file + string isoFilePath = SelectISOFile(); + if (isoFilePath == null) return; + + try + { + // Mount the selected ISO + await ExecutePowerShellCommand($"Mount-DiskImage -ImagePath \"{isoFilePath}\""); + + // Get the mounted drive letter + string mountedDriveLetter = await GetMountedDriveLetter(); + if (string.IsNullOrEmpty(mountedDriveLetter)) + { + _logger.Log("Failed to get mounted drive letter.", Color.Crimson); + return; + } + + // Check if setup.exe exists and start it + string setupPath = Path.Combine(mountedDriveLetter, "setup.exe"); + if (File.Exists(setupPath)) + { + _logger.Log($"Found setup.exe at {setupPath}. Launching setup.", Color.Green); + + Process.Start(new ProcessStartInfo + { + FileName = setupPath, + UseShellExecute = true, + CreateNoWindow = false + }); + + MessageBox.Show("Windows Setup has started. Follow the on-screen instructions.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + _logger.Log($"setup.exe not found at {setupPath}.", Color.Crimson); + } + } + catch (Exception ex) + { + _logger.Log($"Error running setup.exe: {ex.Message}", Color.Crimson); + } + } + + private void ProcessStart(string command) + { + try + { + using (var process = new Process()) + { + process.StartInfo.FileName = "cmd.exe"; + process.StartInfo.Arguments = command; + process.StartInfo.UseShellExecute = true; + process.StartInfo.CreateNoWindow = false; + + // Start the process + process.Start(); + + // Wait for the process to finish + process.WaitForExit(); + } + } + catch (Exception ex) + { + _logger.Log($"Error executing CMD command: {ex.Message}", System.Drawing.Color.Crimson); + } + } + + private async Task ExecutePowerShellCommand(string command) + { + try + { + using (var process = new Process()) + { + process.StartInfo.FileName = "powershell.exe"; + process.StartInfo.Arguments = $"-NoProfile -ExecutionPolicy Bypass -Command \"{command}\""; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.RedirectStandardError = true; + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + + // Output and error handlers + var outputBuilder = new StringBuilder(); + var errorBuilder = new StringBuilder(); + + process.OutputDataReceived += (sender, args) => + { + if (args.Data != null) + { + outputBuilder.AppendLine(args.Data); // Collect output data + _logger.Log(args.Data, System.Drawing.Color.LightPink); + } + }; + + process.ErrorDataReceived += (sender, args) => + { + if (args.Data != null) + { + errorBuilder.AppendLine(args.Data); // Collect error data + _logger.Log(args.Data, System.Drawing.Color.Crimson); + } + }; + + // Start the process + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + // Wait for the process to exit + await Task.Run(() => process.WaitForExit()); + + // Combine the full output and error logs + string output = outputBuilder.ToString(); + string error = errorBuilder.ToString(); + + if (!string.IsNullOrEmpty(error)) + { + _logger.Log(error, System.Drawing.Color.Crimson); + } + + // Return the entire output of ps command + return output; + } + } + catch (Exception ex) + { + _logger.Log($"PowerShell command execution failed: {ex.Message}", System.Drawing.Color.Crimson); + return string.Empty; // Return an empty string if an error occurs + } + } + + // Get the mounted drive letter + private async Task GetMountedDriveLetter() + { + try + { + // List all the drives to find the mounted drive letter + var drives = DriveInfo.GetDrives(); + + foreach (var drive in drives) + { + // Check if the drive is a CD/DVD and if it's mounted + if (drive.DriveType == DriveType.CDRom && drive.IsReady) + { + // Return the letter of the mounted drive + return drive.Name.Substring(0, 2); + } + } + + return null; // Return null if no mounted drive is found + } + catch (Exception ex) + { + _logger.Log($"Error getting mounted drive letter: {ex.Message}", System.Drawing.Color.Crimson); + return null; + } + } + private string SelectISOFile() + { + using (var openFileDialog = new OpenFileDialog + { + Title = "Select Windows 11 ISO File", + Filter = "ISO Files (*.iso)|*.iso|All Files (*.*)|*.*", + InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer) + }) + { + return openFileDialog.ShowDialog() == DialogResult.OK ? openFileDialog.FileName : null; + } + } + + } +} \ No newline at end of file diff --git a/FlybyScript/Patcher/PSPatcher.cs b/FlybyScript/Patcher/PSPatcher.cs new file mode 100644 index 0000000..19cd32e --- /dev/null +++ b/FlybyScript/Patcher/PSPatcher.cs @@ -0,0 +1,98 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using FlybyScript; + +public class PSPatcher +{ + public void LoadPowerShellPlugins(TreeView treeView) + { + var scriptDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "upgraider"); + + if (!Directory.Exists(scriptDirectory)) + { + MessageBox.Show("upgraider directory does not exist."); + return; + } + + // Create a Dependencies category in the TreeView + TreeNode dependencyCategory = new TreeNode("Dependencies"); + treeView.Nodes.Add(dependencyCategory); + + var scriptFiles = Directory.GetFiles(scriptDirectory, "*.ps1"); + + foreach (var file in scriptFiles) + { + var scriptName = Path.GetFileNameWithoutExtension(file); + + // Create a TreeNode for each ps script + var scriptNode = new TreeNode + { + ToolTipText = file, + Text = $"{scriptName} [PS]", + Tag = file // Store the file path as the Tag + }; + + // Add the script node to the Dependecy category + dependencyCategory.Nodes.Add(scriptNode); + } + } + + // Execute the selected PowerShell script + public async Task ExecutePlugin(string pluginPath, Logger logger) + { + try + { + using (var process = new Process()) + { + process.StartInfo.FileName = "powershell.exe"; + process.StartInfo.Arguments = $"-NoProfile -ExecutionPolicy Bypass -File \"{pluginPath}\""; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.RedirectStandardError = true; + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + + var outputBuilder = new StringBuilder(); + var errorBuilder = new StringBuilder(); + + // Handle output from PowerShell script + process.OutputDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + outputBuilder.AppendLine(e.Data); + logger.Log($"PowerShell script output: {e.Data}", System.Drawing.Color.Black); + } + }; + + // Handle error from PowerShell script + process.ErrorDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + errorBuilder.AppendLine(e.Data); + logger.Log($"PowerShell script error: {e.Data}", System.Drawing.Color.Crimson); + } + }; + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + await Task.Run(() => + { + process.WaitForExit(); + }); + + logger.Log($"PowerShell script executed successfully: {pluginPath}", System.Drawing.Color.Green); + } + } + catch (Exception ex) + { + logger.Log($"Error executing PowerShell script: {pluginPath}. Exception: {ex.Message}", System.Drawing.Color.Crimson); + } + } +} \ No newline at end of file diff --git a/FlybyScript/Patcher/ScriptPatcher.cs b/FlybyScript/Patcher/ScriptPatcher.cs new file mode 100644 index 0000000..b3b09fe --- /dev/null +++ b/FlybyScript/Patcher/ScriptPatcher.cs @@ -0,0 +1,238 @@ +using Newtonsoft.Json; +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +/* + * Imported from my xd-AntiSpy app https://github.com/builtbybel/xd-AntiSpy + */ + +namespace FlybyScript +{ + public class ScriptPatcher + { + public string PlugID { get; set; } + public string PlugInfo { get; set; } + public string[] PlugCheck { get; set; } + public string[] PlugDo { get; set; } + public string[] PlugUndo { get; set; } + public string PlugCategory { get; set; } + + private Logger logger; + + public ScriptPatcher(Logger logger) + { + this.logger = logger; + } + + public bool PlugCheckFeature() + { + bool isFeatureActive = true; + foreach (var command in PlugCheck) + { + if (!ExecuteCommandAndCheckResult(command)) + { + isFeatureActive = false; + break; + } + } + logger.Log($"Feature '{PlugID}' is {(isFeatureActive ? "active" : "inactive")}", System.Drawing.Color.Black); + return isFeatureActive; + } + + // PlugCheck Helper to execute commands and check the result + private bool ExecuteCommandAndCheckResult(string command) + { + try + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "cmd.exe", + Arguments = $"/c {command}", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + } + }; + process.Start(); + process.WaitForExit(); + + // Read the output of the command + string output = process.StandardOutput.ReadToEnd(); + + // Check if output contains "1" (indicating active) or "0" (indicating inactive) + bool isActive = output.Contains("1"); + + // logger.Log($"Plugin executed successfully: {command}. Result: {(isActive ? "active" : "inactive")}", System.Drawing.Color.Black); + return isActive; + } + catch (Exception ex) + { + logger.Log($"Error executing plugin: {command}. Exception: {ex.Message}", System.Drawing.Color.Crimson); + return false; + } + } + + public async void PlugDoFeature() + { + await ExecuteFeatureCommands(PlugDo); + } + + public async void PlugUndoFeature() + { + await ExecuteFeatureCommands(PlugUndo); + } + + private async Task ExecuteFeatureCommands(string[] commands) + { + foreach (var command in commands) + { + await ExecuteCommand(command); + } + } + + private async Task ExecuteCommand(string command) + { + try + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = IsPowerShellCommand(command) ? "powershell.exe" : "cmd.exe", + Arguments = IsPowerShellCommand(command) ? $"-Command \"{command}\"" : $"/c \"{command}\"", + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + } + }; + + // Event handler for handling output data + process.OutputDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + logger.Log($"Output: {e.Data}", System.Drawing.Color.Green); + } + }; + + // Event handler for handling error data + process.ErrorDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + logger.Log($"Error: {e.Data}", System.Drawing.Color.Crimson); + } + }; + + process.Start(); + + // Begin asynchronous reading of the output and error streams + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + // Wait for the process to exit + await process.WaitForExitAsync(); + + // Log command execution + logger.Log($"Plugin executed command: {command}", System.Drawing.Color.Green); + } + catch (Exception ex) + { + logger.Log($"Error executing plugin: {command}. Exception: {ex.Message}", System.Drawing.Color.Crimson); + } + } + + // Determine if our command should be run with PowerShell + private bool IsPowerShellCommand(string command) + { + return command.StartsWith("powershell.exe") || command.Contains("Get-") || command.Contains("Set-"); + } + + // Get plugin information + public string GetPluginInformation() + { + return $"{PlugInfo.Replace("\\n", Environment.NewLine)}"; + } + + private static void AddToPluginCategory(TreeNodeCollection pluginCategory, TreeNode node, string category) + { + if (pluginCategory == null) + throw new ArgumentNullException(nameof(pluginCategory)); + var existingCategory = pluginCategory.Cast().FirstOrDefault(n => n.Text == category); + + if (existingCategory == null) + { + existingCategory = new TreeNode(category) + { + BackColor = System.Drawing.Color.LightBlue, + ForeColor = System.Drawing.Color.Black + }; + pluginCategory.Add(existingCategory); + } + + existingCategory.Nodes.Add(node); + } + + public static async Task LoadPlugins(string pluginDirectory, TreeNodeCollection pluginCategory, Logger logger) + { + if (Directory.Exists(pluginDirectory)) + { + var pluginFiles = Directory.GetFiles(pluginDirectory, "*.json"); + + foreach (var file in pluginFiles) + { + // Exclude JSON files of our DLL Plugins as they are loaded separately + if (Path.GetFileName(file).IndexOf("Plugin", StringComparison.OrdinalIgnoreCase) >= 0) + continue; + + try + { + var json = File.ReadAllText(file); + var plugin = JsonConvert.DeserializeObject(json); + + if (plugin != null) + { + plugin.logger = logger; // Set logger for the plugin + + // Execute all commands for the plugin to check its feature + bool isActive = plugin.PlugCheckFeature(); + + var pluginNode = new TreeNode(plugin.PlugID) + { + ToolTipText = plugin.PlugInfo, + Checked = isActive, + Tag = plugin // Store plugin object in Tag property + }; + + // Add to the appropriate category + AddToPluginCategory(pluginCategory, pluginNode, plugin.PlugCategory); + } + } + catch (Exception ex) + { + logger.Log($"Error loading plugin from file '{file}': {ex.Message}", System.Drawing.Color.Crimson); + } + } + } + } + } +} + +// Extension method to make WaitForExit async in ExecuteCommand +public static class ProcessExtensions +{ + public static async Task WaitForExitAsync(this Process process) + { + var tcs = new TaskCompletionSource(); + process.EnableRaisingEvents = true; + process.Exited += (sender, args) => tcs.TrySetResult(true); + await tcs.Task; + } +} \ No newline at end of file diff --git a/FlybyScript/Program.cs b/FlybyScript/Program.cs new file mode 100644 index 0000000..81a9a44 --- /dev/null +++ b/FlybyScript/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Windows.Forms; + +namespace FlybyScript +{ + internal static class Program + { + [STAThread] + private static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} \ No newline at end of file diff --git a/FlybyScript/Properties/AssemblyInfo.cs b/FlybyScript/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9cd86d4 --- /dev/null +++ b/FlybyScript/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die einer Assembly zugeordnet sind. +[assembly: AssemblyTitle("Flyby11")] +[assembly: AssemblyDescription("Bypassing Windows 11 hardware requirements")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Builtbybel")] +[assembly: AssemblyProduct("Flyby11")] +[assembly: AssemblyCopyright("Copyright © 2024 A Belim app creation")] +[assembly: AssemblyTrademark("Builtbybel")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly +// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von +// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("66ddc36a-9095-4053-941c-8829d44f5f20")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +[assembly: AssemblyVersion("0.11.31")] +[assembly: AssemblyFileVersion("0.11.31")] diff --git a/FlybyScript/Properties/Resources.Designer.cs b/FlybyScript/Properties/Resources.Designer.cs new file mode 100644 index 0000000..70c635b --- /dev/null +++ b/FlybyScript/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace FlybyScript.Properties { + using System; + + + /// + /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// + // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// + [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("FlybyScript.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/FlybyScript/Properties/Resources.resx b/FlybyScript/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/FlybyScript/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/FlybyScript/Properties/Settings.Designer.cs b/FlybyScript/Properties/Settings.Designer.cs new file mode 100644 index 0000000..032bf09 --- /dev/null +++ b/FlybyScript/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace FlybyScript.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/FlybyScript/Properties/Settings.settings b/FlybyScript/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/FlybyScript/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/FlybyScript/Views/ExperienceView.Designer.cs b/FlybyScript/Views/ExperienceView.Designer.cs new file mode 100644 index 0000000..aa3102e --- /dev/null +++ b/FlybyScript/Views/ExperienceView.Designer.cs @@ -0,0 +1,100 @@ +namespace Views +{ + partial class ExperienceView + { + /// + /// Erforderliche Designervariable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Verwendete Ressourcen bereinigen. + /// + /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Vom Komponenten-Designer generierter Code + + /// + /// Erforderliche Methode für die Designerunterstützung. + /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. + /// + private void InitializeComponent() + { + this.btnBack = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.SuspendLayout(); + // + // btnBack + // + this.btnBack.AutoSize = true; + this.btnBack.FlatAppearance.BorderColor = System.Drawing.SystemColors.Control; + this.btnBack.FlatAppearance.BorderSize = 0; + this.btnBack.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnBack.Font = new System.Drawing.Font("Segoe MDL2 Assets", 9.75F, System.Drawing.FontStyle.Bold); + this.btnBack.ForeColor = System.Drawing.Color.DarkGray; + this.btnBack.Location = new System.Drawing.Point(3, 3); + this.btnBack.Name = "btnBack"; + this.btnBack.Size = new System.Drawing.Size(29, 25); + this.btnBack.TabIndex = 231; + this.btnBack.Text = "..."; + this.btnBack.UseVisualStyleBackColor = true; + this.btnBack.Click += new System.EventHandler(this.btnBack_Click); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoEllipsis = true; + this.label1.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(192))))); + this.label1.Location = new System.Drawing.Point(131, 201); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(780, 82); + this.label1.TabIndex = 232; + this.label1.Text = "This page is under development and will assist you in personalizing your installa" + + "tion."; + // + // linkLabel1 + // + this.linkLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.linkLabel1.AutoEllipsis = true; + this.linkLabel1.Font = new System.Drawing.Font("Segoe UI Variable Small Light", 10.25F); + this.linkLabel1.LinkColor = System.Drawing.Color.Black; + this.linkLabel1.Location = new System.Drawing.Point(137, 310); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(677, 19); + this.linkLabel1.TabIndex = 233; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "In the meantime, you can enhance this app with xd-AntiSpy plugins by placing them" + + " in the \'upgraider\' folder."; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // ExperienceView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnBack); + this.Name = "ExperienceView"; + this.Size = new System.Drawing.Size(1043, 484); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnBack; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.LinkLabel linkLabel1; + } +} diff --git a/FlybyScript/Views/ExperienceView.cs b/FlybyScript/Views/ExperienceView.cs new file mode 100644 index 0000000..afb3701 --- /dev/null +++ b/FlybyScript/Views/ExperienceView.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Views +{ + public partial class ExperienceView : UserControl + { + public ExperienceView() + { + InitializeComponent(); + SetStyle(); + } + + private void SetStyle() + { + // Segoe MDL2 Assets + btnBack.Text = "\uE72B"; + } + + private void btnBack_Click(object sender, EventArgs e) + { + SwitchView.GoBack(this.Parent as Panel); + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + Process.Start("https://github.com/builtbybel/xd-AntiSpy/tree/main/plugins"); + } + } +} \ No newline at end of file diff --git a/FlybyScript/Views/ExperienceView.resx b/FlybyScript/Views/ExperienceView.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/FlybyScript/Views/ExperienceView.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/FlybyScript/app.manifest b/FlybyScript/app.manifest new file mode 100644 index 0000000..24ca809 --- /dev/null +++ b/FlybyScript/app.manifest @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + + + + + + + + diff --git a/FlybyScript/packages.config b/FlybyScript/packages.config new file mode 100644 index 0000000..c865026 --- /dev/null +++ b/FlybyScript/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file