Compare commits

...

4 Commits

Author SHA1 Message Date
bmgjet 5aa6b7b700
External Py, Update Checker, Python Crash Checker 2024-12-25 01:27:28 +13:00
bmgjet 94e97027ad
Use External Python File Instead Of Embedded, 2024-12-25 01:26:31 +13:00
bmgjet cd94663283
Add Error Checking, Lora Support, Mp4 Res Support 2024-12-24 23:27:54 +13:00
bmgjet 48984f7be8
Add Some Error Checking 2024-12-24 23:27:06 +13:00
5 changed files with 1537 additions and 1175 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<configuration> <configuration>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup> </startup>
</configuration> </configuration>

File diff suppressed because it is too large Load Diff

View File

@ -1,326 +1,531 @@
using System; /*
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Security.Cryptography;
using System.Text; */
using System.Threading; using System;
using System.Threading.Tasks; using System.Collections.Generic;
using System.Windows.Forms; using System.Diagnostics;
using System.Drawing;
namespace Ruyi_GUI using System.IO;
{ using System.IO.Compression;
public partial class Form1 : Form using System.Linq;
{ using System.Reflection;
public static List<string> LogMessages = new List<string>(); using System.Security.Cryptography;
public string PythonCode; using System.Text;
public bool DoingJobs = false; using System.Threading;
public bool Not100 = true; using System.Threading.Tasks;
using System.Windows.Forms;
public Form1()
{ namespace Ruyi_GUI
InitializeComponent(); {
PythonCode = Encoding.UTF8.GetString(Convert.FromBase64String(Decompress(Convert.FromBase64String("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")))); public partial class Form1 : Form
if (File.Exists("Config.cfg")) { LoadSettings(File.ReadAllText("Config.cfg")); } {
else public static List<string> LogMessages = new List<string>();
{ public string[] PythonCode;
FrameRate.SelectedIndex = 0; public bool DoingJobs = false;
AspectRatio.SelectedIndex = 0; public bool Not100 = true;
Resolution.SelectedIndex = 0;
Direction.SelectedIndex = 0; public Form1()
Motion.SelectedIndex = 0; {
Scheduler.SelectedIndex = 0; InitializeComponent();
SaveSettings(); if (File.Exists("Config.cfg")) { LoadSettings(File.ReadAllText("Config.cfg")); }
} else { SaveSettings(); }
} if(!File.Exists("environment.bat"))
{
private string SettingsString() { return Img1.Text + "|" + Img2.Text + "|" + VideoOut.Text + "|" + FrameRate.SelectedIndex + "|" + AspectRatio.SelectedIndex + "|" + Resolution.SelectedIndex + "|" + Direction.SelectedIndex + "|" + Motion.SelectedIndex + "|" + GPUOffload.Text + "|" + LowMemoryMode.Checked + "|" + Steps.Text + "|" + Cfg.Text + "|" + Seed.Text + "|" + Scheduler.SelectedIndex; } MessageBox.Show("environment.bat file missing, Is this exe being ran from Forge Install folder?","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
private void SaveSettings() { File.WriteAllText("Config.cfg", SettingsString()); } if (!Directory.Exists("Ruyi-Models"))
{
private void LoadSettings(string Settings) MessageBox.Show("Missing Ruyi-Models Folder", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
{ return;
string[] SSettings = Settings.Split('|'); }
Img1.Text = SSettings[0]; if(!File.Exists(Path.Combine("Ruyi-Models", "predict_i2v.py")))
Img2.Text = SSettings[1]; {
VideoOut.Text = SSettings[2]; MessageBox.Show("Missing predict_i2v.py", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
FrameRate.SelectedIndex = int.Parse(SSettings[3]); return;
AspectRatio.SelectedIndex = int.Parse(SSettings[4]); }
Resolution.SelectedIndex = int.Parse(SSettings[5]); PythonCode = File.ReadAllLines(Path.Combine("Ruyi-Models", "predict_i2v.py"));
Direction.SelectedIndex = int.Parse(SSettings[6]); }
Motion.SelectedIndex = int.Parse(SSettings[7]);
GPUOffload.Text = SSettings[8]; private string SettingsString() { return Img1.Text + "|" + Img2.Text + "|" + VideoOut.Text + "|" + FrameRate.Text + "|" + AspectRatio.Text + "|" + Resolution.Text + "|" + Direction.Text + "|" + Motion.Text + "|" + GPUOffload.Text + "|" + LowMemoryMode.Checked + "|" + Steps.Text + "|" + Cfg.Text + "|" + Seed.Text + "|" + Scheduler.Text + "|" + VideoRes.Text + "|" + Loratxt.Text + "|" + Weighttxt.Text + "|" + Updates.Checked; }
LowMemoryMode.Checked = bool.Parse(SSettings[9]);
Steps.Text = SSettings[10]; private void SaveSettings() { File.WriteAllText("Config.cfg", SettingsString()); }
Cfg.Text = SSettings[11];
Seed.Text = SSettings[12]; private void LoadSettings(string Settings)
Scheduler.SelectedIndex = int.Parse(SSettings[13]); {
if (File.Exists(Img1.Text)) { pictureBox1.BackgroundImage = new Bitmap(Img1.Text); } try
if (File.Exists(Img2.Text)) { pictureBox2.BackgroundImage = new Bitmap(Img2.Text); } {
else { pictureBox2.BackgroundImage = null; } string[] SSettings = Settings.Split('|');
} Img1.Text = SSettings[0];
Img2.Text = SSettings[1];
private string GetTimestamp() VideoOut.Text = SSettings[2];
{ FrameRate.Text = SSettings[3];
DateTime currentTime = DateTime.UtcNow; AspectRatio.Text = SSettings[4];
long unixTime = ((DateTimeOffset)currentTime).ToUnixTimeSeconds(); Resolution.Text = SSettings[5];
return unixTime.ToString(); Direction.Text = SSettings[6];
} Motion.Text = SSettings[7];
GPUOffload.Text = SSettings[8];
private void AppendTextBox(string value) LowMemoryMode.Checked = bool.Parse(SSettings[9]);
{ Steps.Text = SSettings[10];
if (InvokeRequired) Cfg.Text = SSettings[11];
{ Seed.Text = SSettings[12];
this.Invoke(new Action<string>(AppendTextBox), new object[] { value }); Scheduler.Text = SSettings[13];
return; VideoRes.Text = SSettings[14];
} Loratxt.Text = SSettings[15];
this.Text = "Ruyi-GUI " + value; Weighttxt.Text = SSettings[16];
} Updates.Checked = bool.Parse(SSettings[17]);
}
private string AssemblyDirectory() catch
{ {
string codeBase = Assembly.GetExecutingAssembly().CodeBase; MessageBox.Show("Fault loading Config.cfg, Maybe Try Delete it so it can regenerate.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
UriBuilder uri = new UriBuilder(codeBase); }
string path = Uri.UnescapeDataString(uri.Path); if (File.Exists(Img1.Text)) { pictureBox1.BackgroundImage = new Bitmap(Img1.Text); }
return Path.GetDirectoryName(path); if (File.Exists(Img2.Text)) { pictureBox2.BackgroundImage = new Bitmap(Img2.Text); }
} else { pictureBox2.BackgroundImage = null; }
}
public byte[] GetHash(string inputString)
{ private string GetTimestamp()
using (HashAlgorithm algorithm = SHA256.Create()) { return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString)); } {
} DateTime currentTime = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)currentTime).ToUnixTimeSeconds();
public string GetHashString(string inputString) return unixTime.ToString();
{ }
StringBuilder sb = new StringBuilder();
foreach (byte b in GetHash(inputString)) { sb.Append(b.ToString("X2")); } private void AppendTextBox(string value)
return sb.ToString(); {
} if (InvokeRequired)
{
private void LogFiltered(string message) this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
{ return;
if (string.IsNullOrEmpty(message)) { return; } }
LogMessages.Add(message); this.Text = "Ruyi-GUI " + value;
if (message.Contains("%")) { AppendTextBox(message); } }
if (message.Contains("100%") && Not100) { Not100 = false; return; }
if (message.Contains("100%")) private string AssemblyDirectory()
{ {
Not100 = true; string codeBase = Assembly.GetExecutingAssembly().CodeBase;
AppendTextBox("Saving Mp4..."); UriBuilder uri = new UriBuilder(codeBase);
GenerateButton.BeginInvoke(new Action(() => { GenerateButton.Enabled = true; })); string path = Uri.UnescapeDataString(uri.Path);
panel1.BeginInvoke(new Action(() => { panel1.Enabled = true; })); return Path.GetDirectoryName(path);
if (DoingJobs) }
{
while (!File.Exists(VideoOut.Text)) { Thread.Sleep(1000); } public byte[] GetHash(string inputString)
DoingJobs = false; {
string Job = Path.Combine("Jobs", JobList.Items[0].ToString()); using (HashAlgorithm algorithm = SHA256.Create()) { return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString)); }
if (File.Exists(Job)) { File.Delete(Job); } }
JobList.Items.RemoveAt(0);
return; public string GetHashString(string inputString)
} {
Task.Run(() => StringBuilder sb = new StringBuilder();
{ foreach (byte b in GetHash(inputString)) { sb.Append(b.ToString("X2")); }
while (!File.Exists(VideoOut.Text)) { Thread.Sleep(1000); } return sb.ToString();
AppendTextBox(""); }
});
} private void LogFiltered(string message)
} {
if (string.IsNullOrEmpty(message) || message.Contains(" attn_output = torch.nn.functional.scaled_dot_product_attention(")) { return; }
public static string Decompress(byte[] data) LogMessages.Add(message);
{ if (message.Contains("%") || message.StartsWith("Fetching ")) { AppendTextBox(message); }
MemoryStream input = new MemoryStream(data); if (message.StartsWith("Fetching ")) { return; }
MemoryStream output = new MemoryStream(); if (message.Contains("100%") && Not100) { Not100 = false; return; }
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress)) if (message.Contains("100%"))
{ {
dstream.CopyTo(output); Not100 = true;
} timer3.Enabled = false;
return Convert.ToBase64String(output.ToArray()); AppendTextBox("Saving Mp4...");
} GenerateButton.BeginInvoke(new Action(() => { GenerateButton.Enabled = true; }));
panel1.BeginInvoke(new Action(() => { panel1.Enabled = true; }));
private void GenerateButton_Click(object sender, EventArgs e) LogMessages.Add("Finished Generation @ " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
{ if (DoingJobs)
if (string.IsNullOrEmpty(VideoOut.Text)) { MessageBox.Show("You Must Select A Video Output", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } {
if (string.IsNullOrEmpty(Img1.Text)) { MessageBox.Show("You Must Select A Input Image", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } while (!File.Exists(VideoOut.Text)) { Thread.Sleep(1000); }
ExecuteCommand(); DoingJobs = false;
} string Job = Path.Combine("Jobs", JobList.Items[0].ToString());
if (File.Exists(Job)) { File.Delete(Job); }
private void ExecuteCommand() JobList.Items.RemoveAt(0);
{ return;
string Image2 = string.IsNullOrEmpty(Img2.Text) ? "None" : @"""" + Img2.Text.Replace(@"\", @"\\") + @""""; }
string CallCode = PythonCode.Replace("{$IMAGE1}", Img1.Text.Replace(@"\", @"\\")).Replace("{$IMAGE2}", Image2).Replace("{$VIDEO}", VideoOut.Text.Replace(@"\", @"\\")).Replace("{$FRAMES}", FrameRate.Text).Replace("{$RES}", Resolution.Text).Replace("{$ASPECT}", AspectRatio.Text).Replace("{$MOTION}", Motion.Text).Replace("{$DIRECTION}", Direction.Text).Replace("{$STEPS}", Steps.Text).Replace("{$CFG}", Cfg.Text).Replace("{$SCHEDULER}", Scheduler.Text).Replace("{$LOWMEM}", LowMemoryMode.Checked.ToString()).Replace("{$OFFLOAD}", GPUOffload.Text).Replace("{$SEED}", Seed.Text); Task.Run(() =>
File.WriteAllText(Path.Combine("Ruyi-Models", "i2v.py"), CallCode); {
if (File.Exists(VideoOut.Text)) { File.Move(VideoOut.Text, VideoOut.Text.Replace(".mp4", "-" + GetTimestamp() + ".mp4")); } while (!File.Exists(VideoOut.Text)) { Thread.Sleep(1000); }
Task.Run(() => AppendTextBox("");
{ });
GenerateButton.BeginInvoke(new Action(() => { GenerateButton.Enabled = false; })); }
panel1.BeginInvoke(new Action(() => { panel1.Enabled = false; })); }
AppendTextBox("Loading AI Please Wait...");
var processInfo = new ProcessStartInfo("cmd.exe", "/c call " + Path.Combine(AssemblyDirectory(), "environment.bat") + " && cd " + Path.Combine(AssemblyDirectory(), "Ruyi-Models") + " && python i2v.py %*"); public static string Decompress(byte[] data)
processInfo.CreateNoWindow = true; {
processInfo.UseShellExecute = false; MemoryStream input = new MemoryStream(data);
processInfo.RedirectStandardError = true; MemoryStream output = new MemoryStream();
processInfo.RedirectStandardOutput = true; using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
var process = Process.Start(processInfo); {
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => LogFiltered(e.Data); dstream.CopyTo(output);
process.BeginOutputReadLine(); }
process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => LogFiltered(e.Data); return Convert.ToBase64String(output.ToArray());
process.BeginErrorReadLine(); }
process.WaitForExit();
process.Close(); private void GenerateButton_Click(object sender, EventArgs e)
}); {
} if (ValidateInOut())
{
private string SelectImageButton() if (this.Width == 810) { this.Width = 575; JobList.Items.Clear(); }
{ ExecuteCommand();
string path = ""; }
var dialog = new OpenFileDialog(); }
dialog.Title = "Open Image";
dialog.Filter = "Image Files (*.jpg;*.jpeg,*.png)|*.JPG;*.JPEG;*.PNG"; private string ParsePythonCode()
if (dialog.ShowDialog() == DialogResult.OK) { path = dialog.FileName; } {
dialog.Dispose(); string code = "";
return path; string Image2 = string.IsNullOrEmpty(Img2.Text) ? "None" : @"""" + Img2.Text.Replace(@"\", @"\\") + @"""";
} string Lora = string.IsNullOrEmpty(Loratxt.Text) ? "None" : @"""" + Loratxt.Text.Replace(@"\", @"\\") + @"""";
foreach (string line in PythonCode)
private void SelectImg1_Click(object sender, EventArgs e) {
{ if(line.StartsWith("start_image_path = "))
Img1.Text = SelectImageButton(); {
if (string.IsNullOrEmpty(Img1.Text)) code += @"start_image_path = """ + Img1.Text.Replace(@"\", @"\\") + @""""+ System.Environment.NewLine;
{ continue;
pictureBox1.BackgroundImage = null; }
return; if (line.StartsWith("end_image_path = "))
} {
pictureBox1.BackgroundImage = new Bitmap(Img1.Text); code += "end_image_path = " + Image2.Replace(@"\", @"\\") + System.Environment.NewLine;
} continue;
}
private void SelectImg2_Click(object sender, EventArgs e) if (line.StartsWith("output_video_path = "))
{ {
Img2.Text = SelectImageButton(); code += @"output_video_path = """ + VideoOut.Text.Replace(@"\", @"\\") + @"""" + System.Environment.NewLine;
if (string.IsNullOrEmpty(Img2.Text)) continue;
{ }
pictureBox2.BackgroundImage = null; if (line.StartsWith("video_length = "))
return; {
} code += @"video_length = " + FrameRate.Text + System.Environment.NewLine;
pictureBox2.BackgroundImage = new Bitmap(Img2.Text); continue;
} }
if (line.StartsWith("base_resolution = "))
private void SelectVideoOut_Click(object sender, EventArgs e) {
{ code += @"base_resolution = " + Resolution.Text + System.Environment.NewLine;
SaveFileDialog saveFileDialog1 = new SaveFileDialog(); continue;
saveFileDialog1.Filter = "Video Output|*.mp4"; }
saveFileDialog1.Title = "Save an Video File"; if (line.StartsWith("video_size = "))
saveFileDialog1.ShowDialog(); {
VideoOut.Text = saveFileDialog1.FileName; code += @"video_size = " + VideoRes.Text.Replace("auto","None") + System.Environment.NewLine;
} continue;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { SaveSettings(); } if (line.StartsWith("aspect_ratio = "))
{
private void PlayVideo_Click(object sender, EventArgs e) code += @"aspect_ratio = """ + AspectRatio.Text + @"""" + System.Environment.NewLine;
{ continue;
if (File.Exists(VideoOut.Text)) }
{ if (line.StartsWith("motion = "))
System.Diagnostics.Process.Start(VideoOut.Text); {
} code += @"motion = """ + Motion.Text + @"""" + System.Environment.NewLine;
} continue;
}
private void timer1_Tick(object sender, EventArgs e) if (line.StartsWith("camera_direction = "))
{ {
if (File.Exists(VideoOut.Text)) { PlayVideo.Enabled = true; } code += @"camera_direction = """ + Direction.Text + @"""" + System.Environment.NewLine;
else { PlayVideo.Enabled = false; } continue;
if (LogMessages.Count > 0) }
{ if (line.StartsWith("steps = "))
File.AppendAllLines("log.txt", LogMessages); {
LogMessages.Clear(); code += @"steps = " + Steps.Text + System.Environment.NewLine;
} continue;
} }
if (line.StartsWith("cfg = "))
private void AddJob_Click(object sender, EventArgs e) {
{ code += @"cfg = " + Cfg.Text + System.Environment.NewLine;
string Settings = SettingsString(); continue;
string Job = GetHashString(Settings); }
if (JobList.Items.Contains(Job)) { return; } if (line.StartsWith("scheduler_name = "))
if (!Directory.Exists("Jobs")) { Directory.CreateDirectory("Jobs"); } {
File.WriteAllText(Path.Combine("Jobs", Job), Settings); code += @"scheduler_name = """ + Scheduler.Text + @"""" + System.Environment.NewLine;
JobList.Items.Add(Job); continue;
} }
if (line.StartsWith("low_gpu_memory_mode = "))
private void RemoveJob_Click(object sender, EventArgs e) {
{ code += @"low_gpu_memory_mode = " + LowMemoryMode.Checked.ToString() + System.Environment.NewLine;
if (JobList.SelectedIndex == -1) return; continue;
string Job = Path.Combine("Jobs", JobList.Items[JobList.SelectedIndex].ToString()); }
if (File.Exists(Job)) { File.Delete(Job); } if (line.StartsWith("gpu_offload_steps = "))
JobList.Items.RemoveAt(JobList.SelectedIndex); {
} code += @"gpu_offload_steps = " + GPUOffload.Text + System.Environment.NewLine;
continue;
private void RunJobs_Click(object sender, EventArgs e) }
{ if (line.StartsWith("seed = "))
timer2.Enabled = true; {
RunJobs.Enabled = false; code += @"seed = " + Seed.Text + System.Environment.NewLine;
JobList.Enabled = false; continue;
AddJob.Enabled = false; }
RemoveJob.Enabled = false; if (line.StartsWith("lora_path = "))
JobList.SelectedIndex = -1; {
} code += @"lora_path = " + Lora + System.Environment.NewLine;
continue;
private void timer2_Tick(object sender, EventArgs e) }
{ if (line.StartsWith("lora_weight = "))
if (DoingJobs) { return; } {
if (JobList.Items.Count > 0) code += @"lora_weight = " + Weighttxt.Text + System.Environment.NewLine;
{ continue;
DoingJobs = true; }
UpdateJobList(true); if (line.StartsWith("auto_update = "))
this.Update(); {
ExecuteCommand(); code += @"auto_update = " + Updates.Checked.ToString() + System.Environment.NewLine;
} continue;
else }
{ code += line + System.Environment.NewLine;
AppendTextBox(""); }
RunJobs.Enabled = true; return code;
JobList.Enabled = true; }
AddJob.Enabled = true;
RemoveJob.Enabled = true; private void ExecuteCommand()
timer2.Enabled = false; {
DoingJobs = false; string CallCode = ParsePythonCode();
return; if (string.IsNullOrEmpty(CallCode)) { MessageBox.Show("Bad Python Code", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }
} File.WriteAllText(Path.Combine("Ruyi-Models", "i2v.py"), CallCode);
} if (File.Exists(VideoOut.Text)) { File.Move(VideoOut.Text, VideoOut.Text.Replace(".mp4", "-" + GetTimestamp() + ".mp4")); }
LogMessages.Add("Starting Generation: ["+FrameRate.Text + "-"+ Resolution.Text +"] " + Path.GetFileName(Img1.Text) + " @ " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
private void UpdateJobList(bool Force = false) Task.Run(() =>
{ {
if (JobList.SelectedIndex == -1 && !Force) { return; } GenerateButton.BeginInvoke(new Action(() => { GenerateButton.Enabled = false; }));
int index = (JobList.SelectedIndex == -1) ? 0 : JobList.SelectedIndex; panel1.BeginInvoke(new Action(() => { panel1.Enabled = false; }));
if (File.Exists(Path.Combine("Jobs", JobList.Items[index].ToString()))) AppendTextBox("Loading AI Please Wait...");
{ var processInfo = new ProcessStartInfo("cmd.exe", "/c call " + Path.Combine(AssemblyDirectory(), "environment.bat") + " && cd " + Path.Combine(AssemblyDirectory(), "Ruyi-Models") + " && python i2v.py %*");
LoadSettings(File.ReadAllText(Path.Combine("Jobs", JobList.Items[index].ToString()))); processInfo.CreateNoWindow = true;
} processInfo.UseShellExecute = false;
} processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
private void JobList_SelectedIndexChanged(object sender, EventArgs e) { UpdateJobList(); } var process = Process.Start(processInfo);
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => LogFiltered(e.Data);
private void Batch_Click(object sender, EventArgs e) process.BeginOutputReadLine();
{ process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => LogFiltered(e.Data);
if (this.Width == 810) { this.Width = 575; JobList.Items.Clear(); } process.BeginErrorReadLine();
else process.WaitForExit();
{ process.Close();
if (Directory.Exists("Jobs")) });
{ timer3.Enabled = true;
DirectoryInfo d = new DirectoryInfo("Jobs"); }
FileInfo[] Files = d.GetFiles("*"); //Getting Text files
foreach (FileInfo file in Files) private string SelectImageButton()
{ {
if (file.Name.Length == 64) string path = "";
{ var dialog = new OpenFileDialog();
if (!JobList.Items.Contains(file.Name)) dialog.Title = "Open Image";
{ dialog.Filter = "Image Files (*.jpg;*.jpeg,*.png)|*.JPG;*.JPEG;*.PNG";
JobList.Items.Add(file.Name); if (dialog.ShowDialog() == DialogResult.OK) { path = dialog.FileName; }
} dialog.Dispose();
} return path;
} }
}
this.Width = 810; private void SelectImg1_Click(object sender, EventArgs e)
} {
} Img1.Text = SelectImageButton();
} if (string.IsNullOrEmpty(Img1.Text))
{
pictureBox1.BackgroundImage = null;
return;
}
pictureBox1.BackgroundImage = new Bitmap(Img1.Text);
}
private void SelectImg2_Click(object sender, EventArgs e)
{
Img2.Text = SelectImageButton();
if (string.IsNullOrEmpty(Img2.Text))
{
pictureBox2.BackgroundImage = null;
return;
}
pictureBox2.BackgroundImage = new Bitmap(Img2.Text);
}
private void SelectVideoOut_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Video Output|*.mp4";
saveFileDialog1.Title = "Save an Video File";
saveFileDialog1.ShowDialog();
VideoOut.Text = saveFileDialog1.FileName;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { SaveSettings(); }
private void PlayVideo_Click(object sender, EventArgs e)
{
if (File.Exists(VideoOut.Text))
{
System.Diagnostics.Process.Start(VideoOut.Text);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (File.Exists(VideoOut.Text)) { PlayVideo.Enabled = true; }
else { PlayVideo.Enabled = false; }
if (LogMessages.Count > 0)
{
File.AppendAllLines("log.txt", LogMessages);
LogMessages.Clear();
}
}
private bool ValidateInOut()
{
if (string.IsNullOrEmpty(VideoOut.Text)) { MessageBox.Show("You Must Select A Video Output", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Img1.Text)) { MessageBox.Show("You Must Select A Input Image", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(FrameRate.Text)) { MessageBox.Show("Frame Rate Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(AspectRatio.Text)) { MessageBox.Show("Aspect Ratio Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Resolution.Text)) { MessageBox.Show("Resolution Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Direction.Text)) { MessageBox.Show("Direction Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Motion.Text)) { MessageBox.Show("Motion Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(VideoRes.Text)) { MessageBox.Show("Mp4 Resolution Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(GPUOffload.Text)) { MessageBox.Show("GPU Offload Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Steps.Text)) { MessageBox.Show("Steps Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Cfg.Text)) { MessageBox.Show("Cfg Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Seed.Text)) { MessageBox.Show("Seed Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Scheduler.Text)) { MessageBox.Show("Scheduler Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (string.IsNullOrEmpty(Weighttxt.Text)) { MessageBox.Show("Lora Weight Can't Be Null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if(!AspectRatio.Text.Contains(":")){ MessageBox.Show("Aspect Ratio Not Valid Format", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
if (!VideoRes.Text.Contains(", ") && !VideoRes.Text.Contains("None") && !VideoRes.Text.Contains("auto")) { MessageBox.Show("Mp4 Resolution Not Valid Format", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
return true;
}
private void AddJob_Click(object sender, EventArgs e)
{
if (ValidateInOut())
{
string Settings = SettingsString();
string Job = GetHashString(Settings);
if (JobList.Items.Contains(Job)) { return; }
if (!Directory.Exists("Jobs")) { Directory.CreateDirectory("Jobs"); }
File.WriteAllText(Path.Combine("Jobs", Job), Settings);
JobList.Items.Add(Job);
}
}
private void RemoveJob_Click(object sender, EventArgs e)
{
if (JobList.SelectedIndex == -1) return;
string Job = Path.Combine("Jobs", JobList.Items[JobList.SelectedIndex].ToString());
if (File.Exists(Job)) { File.Delete(Job); }
JobList.Items.RemoveAt(JobList.SelectedIndex);
}
private void RunJobs_Click(object sender, EventArgs e)
{
timer2.Enabled = true;
RunJobs.Enabled = false;
JobList.Enabled = false;
AddJob.Enabled = false;
RemoveJob.Enabled = false;
JobList.SelectedIndex = -1;
}
private void timer2_Tick(object sender, EventArgs e)
{
if (DoingJobs) { return; }
if (JobList.Items.Count > 0)
{
DoingJobs = true;
UpdateJobList(true);
this.Update();
ExecuteCommand();
}
else
{
AppendTextBox("");
RunJobs.Enabled = true;
JobList.Enabled = true;
AddJob.Enabled = true;
RemoveJob.Enabled = true;
timer2.Enabled = false;
DoingJobs = false;
return;
}
}
private void UpdateJobList(bool Force = false)
{
if (JobList.SelectedIndex == -1 && !Force) { return; }
int index = (JobList.SelectedIndex == -1) ? 0 : JobList.SelectedIndex;
if (File.Exists(Path.Combine("Jobs", JobList.Items[index].ToString())))
{
LoadSettings(File.ReadAllText(Path.Combine("Jobs", JobList.Items[index].ToString())));
}
}
private void JobList_SelectedIndexChanged(object sender, EventArgs e) { UpdateJobList(); }
private void Batch_Click(object sender, EventArgs e)
{
if (this.Width == 810) { this.Width = 575; JobList.Items.Clear(); GenerateButton.Enabled = true; }
else
{
GenerateButton.Enabled = false;
if (Directory.Exists("Jobs"))
{
DirectoryInfo d = new DirectoryInfo("Jobs");
FileInfo[] Files = d.GetFiles("*"); //Getting Text files
foreach (FileInfo file in Files)
{
if (file.Name.Length == 64)
{
if (!JobList.Items.Contains(file.Name))
{
JobList.Items.Add(file.Name);
}
}
}
}
this.Width = 810;
}
}
private void AspectRatio_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar) && e.KeyChar != ':';
}
private void NumberOnly(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}
private void Cfg_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar) && e.KeyChar != '.';
}
private void NumberAndAuto(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar) && e.KeyChar != 'a' && e.KeyChar != 'u' && e.KeyChar != 't' && e.KeyChar != 'o';
}
private void VideoRes_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar) && e.KeyChar != ',' && e.KeyChar != ' ' && e.KeyChar != 'N' && e.KeyChar != 'o' && e.KeyChar != 'n' && e.KeyChar != 'e' && e.KeyChar != 'a' && e.KeyChar != 'u' && e.KeyChar != 't';
}
private void LoraButton_Click(object sender, EventArgs e)
{
var dialog = new OpenFileDialog();
dialog.Title = "Select Lora File";
dialog.Filter = "safetensors (*.safetensors)|*.safetensors";
if (dialog.ShowDialog() == DialogResult.OK) { Loratxt.Text = dialog.FileName; }
dialog.Dispose();
}
private void timer3_Tick(object sender, EventArgs e)
{
Process[] processes = Process.GetProcesses();
bool isPythonRunning = processes.Any(p => p.ProcessName.Equals("python", StringComparison.OrdinalIgnoreCase));
if (!isPythonRunning)
{
timer3.Enabled = false;
MessageBox.Show("python.exe is not running. Maybe it crashed, Please check the log.txt","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
}
} }

View File

@ -1,203 +1,206 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value> <value>[base64 mime encoded serialized .NET Framework object]</value>
</data> </data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType> <xsd:complexType>
<xsd:choice maxOccurs="unbounded"> <xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata"> <xsd:element name="metadata">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" /> <xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="assembly"> <xsd:element name="assembly">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="data"> <xsd:element name="data">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="resheader"> <xsd:element name="resheader">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" /> <xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:schema> </xsd:schema>
<resheader name="resmimetype"> <resheader name="resmimetype">
<value>text/microsoft-resx</value> <value>text/microsoft-resx</value>
</resheader> </resheader>
<resheader name="version"> <resheader name="version">
<value>2.0</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>
<metadata name="timer2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="timer2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>105, 17</value> <value>105, 17</value>
</metadata> </metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <metadata name="timer3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <value>193, 17</value>
<value> </metadata>
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA <value>
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVEgwAaVVVADEp AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
JQg2LSoXNi4sGjQtKxozKykbMSknHC4nJR4tJSMfLCQhHi0kIB0tJCAeLCMgHywjHx0qIh4dJx8bFyAb AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
FwZCNjMACAcDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtKSIAQzc1ADsy AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
LRg+NDFrQDYytj41MtY7MzDaOjEw2zkwLts5Ly3cNy0r3TUrKd4zKSfeMygl3TMoJN4yJyTfMick3jEn AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVEgwAaVVVADEp
JN0xJyTWMikmsjQrJ2w0LCcYNywpACspIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMysnAEY6 JQg2LSoXNi4sGjQtKxozKykbMSknHC4nJR4tJSMfLCQhHi0kIB0tJCAeLCMgHywjHx0qIh4dJx8bFyAb
NwA+NDA1QTczw0E2M/1IOzr/VEpI/1RLSf9LQkH/Qzo5/zwzMf88MjD/OjAt/zkuLP85Liv/OCwp/zcr FwZCNjMACAcDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtKSIAQzc1ADsy
Kf83Kyn/PDEv/z80Mf85Ly3/OjAt/TsxLsI6MC00PzQyADEsJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAsJ LRg+NDFrQDYytj41MtY7MzDaOjEw2zkwLts5Ly3cNy0r3TUrKd4zKSfeMygl3TMoJN4yJyTfMick3jEn
BwBANTIAPzQwJkE3NM5BNzT/YVdU/pyUk/6spqf+raiq/oV+gP5eU1L+Wk5N/l9SUf5oWln+XE5N/k9B JN0xJyTWMikmsjQrJ2w0LCcYNywpACspIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMysnAEY6
QP5BNTL+PDAu/kg7Ov5hU1D9cWNf/WRWUv5IPDn+PjMx/z0zMM07MS0kOzIuABghFAAAAAAAAAAAAAAA NwA+NDA1QTczw0E2M/1IOzr/VEpI/1RLSf9LQkH/Qzo5/zwzMf88MjD/OjAt/zkuLP85Liv/OCwp/zcr
AAAAAAAAOjAsADMpJgNBNjKXQTYz/2hdXP6gmZj+bGVm/mZfY/5+d3v9f3R1/m1fXf6Kenb+mImI/p2Q Kf83Kyn/PDEv/z80Mf85Ly3/OjAt/TsxLsI6MC00PzQyADEsJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAsJ
kv6HeHf+eWdh/m9fWf5NQD7+XlBN/lhMS/5VTE3+eXBw/H5ycPtNQT3+PTMw/z0zL5I2LScCOzEtAAAA BwBANTIAPzQwJkE3NM5BNzT/YVdU/pyUk/6spqf+raiq/oV+gP5eU1L+Wk5N/l9SUf5oWln+XE5N/k9B
AAAAAAAAAAAAAAAAAABAMi8APzEvKkE1MuRPREL/m5SU/oF7gP1sZGn+g3l+/piNj/6DdG/+d2hl/qeb QP5BNTL+PDAu/kg7Ov5hU1D9cWNf/WRWUv5IPDn+PjMx/z0zMM07MS0kOzIuABghFAAAAAAAAAAAAAAA
mv6mm5v+p5ye/pOGhv6Le3f+kH93/nVlYP5/bmn+YFBL/kg+P/5lXGH9l5KZ+ntvbv1CNjP/PDIv3zsx AAAAAAAAOjAsADMpJgNBNjKXQTYz/2hdXP6gmZj+bGVm/mZfY/5+d3v9f3R1/m1fXf6Kenb+mImI/p2Q
LSQ7MS4AAAAAAAAAAAAAAAAAAAAAAEEyMAA/Mi9ZPzIw/HRqaf16dHf4YFlg/XVsdP6XkJj+rKSr/oR3 kv6HeHf+eWdh/m9fWf5NQD7+XlBN/lhMS/5VTE3+eXBw/H5ycPtNQT3+PTMw/z0zL5I2LScCOzEtAAAA
eP5wZmf+u7a6/sbCx/63sbb+rKSo/qacnf6UhoX+dmpr/pmMiv16Z17+W0xK/llQVf6XlJ77npmg/FpN AAAAAAAAAAAAAAAAAABAMi8APzEvKkE1MuRPREL/m5SU/oF7gP1sZGn+g3l+/piNj/6DdG/+d2hl/qeb
TP48MS76PDEuUDwxLwAAAAAAAAAAAAAAAAAAAAAAPTIvAD4yMHM9MTD/hHp792ljZvFXTlP+aWJo/rKw mv6mm5v+p5ye/pOGhv6Le3f+kH93/nVlYP5/bmn+YFBL/kg+P/5lXGH9l5KZ+ntvbv1CNjP/PDIv3zsx
uv7Cvsj+n5ef/omCiP6tqKz+pKGk/oiDiP5+d3v+h31//oJ2dv56bnD+qaGn/Ip5c/xlU0z9XVRZ/ndw LSQ7MS4AAAAAAAAAAAAAAAAAAAAAAEEyMAA/Mi9ZPzIw/HRqaf16dHf4YFlg/XVsdP6XkJj+rKSr/oR3
d/ydm6X5dm1w/DwxLv88MS5rPTIvAAAAAAAAAAAAAAAAAAAAAAA5LywAPTIwdjswLv9ZUFDwa2Vo721l eP5wZmf+u7a6/sbCx/63sbb+rKSo/qacnf6UhoX+dmpr/pmMiv16Z17+W0xK/llQVf6XlJ77npmg/FpN
av59eID+u7rH/sC/y/6uqbT+qaOq/mpjZ/5JQkf+QztA/jIqLf43MDP+VkxM/oBwa/6QgH79hXNt/GhV TP48MS76PDEuUDwxLwAAAAAAAAAAAAAAAAAAAAAAPTIvAD4yMHM9MTD/hHp792ljZvFXTlP+aWJo/rKw
TfxZTU79bGVq/I2Kk/l8dnv7PTIv/zwxLnI+Mi8AAAAAAAAAAAAAAAAAAAAAADctKwA7MS51OS8s/0xD uv7Cvsj+n5ef/omCiP6tqKz+pKGk/oiDiP5+d3v+h31//oJ2dv56bnD+qaGn/Ip5c/xlU0z9XVRZ/ndw
ROdzbXHme3R6+5KRm/vMztv+u7nF/qGZof5nX2T+V1BY/n11fP55b3P+ZFdV/VpOTv04LzH+UUI+/oVz d/ydm6X5dm1w/DwxLv88MS5rPTIvAAAAAAAAAAAAAAAAAAAAAAA5LywAPTIwdjswLv9ZUFDwa2Vo721l
bP2Bb2n8c2BX/FNGRP1PRkn+bGVq+3dvc/o+Mi//PDEucj4yMAAAAAAAAAAAAAAAAAAAAAAANy0rADow av59eID+u7rH/sC/y/6uqbT+qaOq/mpjZ/5JQkf+QztA/jIqLf43MDP+VkxM/oBwa/6QgH79hXNt/GhV
LnQ4Ly3/TUVF3GplaOJ8d336WlZd866vuP2inqn+g3p+/ldPVv5/d379hX2A/oyDg/6JfXv+ZldV/kU2 TfxZTU79bGVq/I2Kk/l8dnv7PTIv/zwxLnI+Mi8AAAAAAAAAAAAAAAAAAAAAADctKwA7MS51OS8s/0xD
Nf43Kyr+dGRg/mVXVf1iUkr9QDY2/lBHSv5tZ2v7gnyB9T4yMP87MC1zPTEvAAAAAAAAAAAAAAAAAAAA ROdzbXHme3R6+5KRm/vMztv+u7nF/qGZof5nX2T+V1BY/n11fP55b3P+ZFdV/VpOTv04LzH+UUI+/oVz
AAA4KysAOy8udDgtLf9MRETXamVp142MmvtSTVn1l5ag/IiDi/5nXmP+f3mA+5+Xmf1zZ2b+X1NQ/nFm bP2Bb2n8c2BX/FNGRP1PRkn+bGVq+3dvc/o+Mi//PDEucj4yMAAAAAAAAAAAAAAAAAAAAAAANy0rADow
Y/6ajoz+Xk5K/jUrKv5rX17+ZVla/lVGQv5IP0L+XVVb/lxSU/1dU1T8PDEv/zkvLXM7MS4AAAAAAAAA LnQ4Ly3/TUVF3GplaOJ8d336WlZd866vuP2inqn+g3p+/ldPVv5/d379hX2A/oyDg/6JfXv+ZldV/kU2
AAAAAAAAAAAAADcrKwA6Ly50Ny0t/1BJS9dsZ23XlJOh+WBaZvnCwsr9yMbL/mJXXP6Lho38d21s/jsv Nf43Kyr+dGRg/mVXVf1iUkr9QDY2/lBHSv5tZ2v7gnyB9T4yMP87MC1zPTEvAAAAAAAAAAAAAAAAAAAA
K/4uIx7+Myci/mxgXf5vYVz+RDc1/nx1eP6wp6n9bl9a/ltRVf5sYWf+UkZF/lxSUf47Mi//OTAtczox AAA4KysAOy8udDgtLf9MRETXamVp142MmvtSTVn1l5ag/IiDi/5nXmP+f3mA+5+Xmf1zZ2b+X1NQ/nFm
LgAAAAAAAAAAAAAAAAAAAAAANisrADovL3Q1Kyv/Ylpd8ZOQmfWWlKH5Y15p+sTEzf3Y1tv+cmlv/peU Y/6ajoz+Xk5K/jUrKv5rX17+ZVla/lVGQv5IP0L+XVVb/lxSU/1dU1T8PDEv/zkvLXM7MS4AAAAAAAAA
mv57cXH+VEpJ/iofHP4kGRX+Qjcz/nBjX/5QQkD+iIGE/raur/1vYFv+YVhc/nFlav5XSEf+VUlI/Tsx AAAAAAAAAAAAADcrKwA6Ly50Ny0t/1BJS9dsZ23XlJOh+WBaZvnCwsr9yMbL/mJXXP6Lho38d21s/jsv
L/85MC10OTAtAAAAAAAAAAAAAAAAAAAAAAA2KisAOi4vdDUrK/9mYGTtnpyr7qqpuPhcWWz5mZej/b66 K/4uIx7+Myci/mxgXf5vYVz+RDc1/nx1eP6wp6n9bl9a/ltRVf5sYWf+UkZF/lxSUf47Mi//OTAtczox
wf6JgYj+ioaM/rKsrf7Cvbz+RTs5/iAVEv5WTEr+aVpW/ks/P/6gmZz+fHFu/lBCPf5qY2r+iICL/lpO LgAAAAAAAAAAAAAAAAAAAAAANisrADovL3Q1Kyv/Ylpd8ZOQmfWWlKH5Y15p+sTEzf3Y1tv+cmlv/peU
Uv5KPz/9OjEu/zkvLXU5MC0AAAAAAAAAAAAAAAAAAAAAADUoKgA5LS50NSkr/1BKTvOMiZPvgoGQ7EpH mv57cXH+VEpJ/iofHP4kGRX+Qjcz/nBjX/5QQkD+iIGE/raur/1vYFv+YVhc/nFlav5XSEf+VUlI/Tsx
VfilpK7+4+Hm/qOdov5oYmf+p6Cj/pWLif5uY1/+cGVj/o2Cgv5jU0/+XFNU/q2kpP6KenT+UkQ//kxG L/85MC10OTAtAAAAAAAAAAAAAAAAAAAAAAA2KisAOi4vdDUrK/9mYGTtnpyr7qqpuPhcWWz5mZej/b66
TP5mYGz+Z1xg/FFGRvg5Lyz/OS8sdTguLAAAAAAAAAAAAAAAAAAAAAAANScpADotL3Q1KCv/Vk5R9pKP wf6JgYj+ioaM/rKsrf7Cvbz+RTs5/iAVEv5WTEr+aVpW/ks/P/6gmZz+fHFu/lBCPf5qY2r+iICL/lpO
mPWAeoH2gXqD+bi4xv309vr+z8vQ/oqEiv6zrrH+raao/qegoP6poaL+pZyc/nFmZf6YkZP9rKGf/pGA Uv5KPz/9OjEu/zkvLXU5MC0AAAAAAAAAAAAAAAAAAAAAADUoKgA5LS50NSkr/1BKTvOMiZPvgoGQ7EpH
ef5qWlf+U0VD/U5APf5YTEr+UEZH/DguLP83LSt2NywqAAAAAAAAAAAAAAAAAAAAAAA0JykAOS4vczIn VfilpK7+4+Hm/qOdov5oYmf+p6Cj/pWLif5uY1/+cGVj/o2Cgv5jU0/+XFNU/q2kpP6KenT+UkQ//kxG
KP9uZ2r1wcDF9srJzfbAvsPksrG79ODh5/6xrbL8lI+T/ODf4PzOysr839zc/cXAv/yaj477d2xt/JWP TP5mYGz+Z1xg/FFGRvg5Lyz/OS8sdTguLAAAAAAAAAAAAAAAAAAAAAAANScpADotL3Q1KCv/Vk5R9pKP
k/2tpKT8lIV//XhpZviJfHjqdGNc+Hhsavx1bW76Nywr/zYsKnY2KyoAAAAAAAAAAAAAAAAAAAAAADQo mPWAeoH2gXqD+bi4xv309vr+z8vQ/oqEiv6zrrH+raao/qegoP6poaL+pZyc/nFmZf6YkZP9rKGf/pGA
KQA7MDB0MSYn/0xERvucmZz4vLm7+sLAw+zNy83v4+Pm/dHO0v6po6f9q6ep/be0tfySjY38gXp5/G1l ef5qWlf+U0VD/U5APf5YTEr+UEZH/DguLP83LSt2NywqAAAAAAAAAAAAAAAAAAAAAAA0JykAOS4vczIn
ZPuAd3r7q6Om/Ly0tPykmZb9jYF/75SKiOeIe3j3mI+O+WBXV/s0Kin/NSsqdjYrKwAAAAAAAAAAAAAA KP9uZ2r1wcDF9srJzfbAvsPksrG79ODh5/6xrbL8lI+T/ODf4PzOysr839zc/cXAv/yaj477d2xt/JWP
AAAAAAAAPjI0AEI3OHAzJyn/PTQ2/Y2Iivaln6H7ramr9JWQkPjCwML+6Obo/uro6f7V0tT+trO2/oeC k/2tpKT8lIV//XhpZviJfHjqdGNc+Hhsavx1bW76Nywr/zYsKnY2KyoAAAAAAAAAAAAAAAAAAAAAADQo
hv1xaWv9kYeH/b+4t/zQycj8y8TE/qSbmv6MgoD4oZeW+IyDgvdyamv3QTc3/DQpKf8zKSluNSoqAAAA KQA7MDB0MSYn/0xERvucmZz4vLm7+sLAw+zNy83v4+Pm/dHO0v6po6f9q6ep/be0tfySjY38gXp5/G1l
AAAAAAAAAAAAAAAAAABLQUMASkBBUjkvMfouJCb+ZF1f97Gtr/aVkJH3lJCP7aWhofOkn6H82tfZ/uzq ZPuAd3r7q6Om/Ly0tPykmZb9jYF/75SKiOeIe3j3mI+O+WBXV/s0Kin/NSsqdjYrKwAAAAAAAAAAAAAA
6v7V09b+kouP/ntwcP6jmJX+xLy6/bWtrP2lnZz+o5qY/o6Dgf6BeHf9YFZV/EI4OPwzKCn+NCgp+DMo AAAAAAAAPjI0AEI3OHAzJyn/PTQ2/Y2Iivaln6H7ramr9JWQkPjCwML+6Obo/uro6f7V0tT+trO2/oeC
KE0zKCgAAAAAAAAAAAAAAAAAAAAAAEtDRABPR0gcSD5A1TAnKP80Kyz9f3l79ZCMj9t7dnbKkYyM67+8 hv1xaWv9kYeH/b+4t/zQycj8y8TE/qSbmv6MgoD4oZeW+IyDgvdyamv3QTc3/DQpKf8zKSluNSoqAAAA
vfXU0NL+9/X1/vHv8P7Lx8j7xsHB++Le3v7EvLr8rKKi/bWtrf6gl5b8bWRj/VlQUPxNQkL9Ny0t/jIn AAAAAAAAAAAAAAAAAABLQUMASkBBUjkvMfouJCb+ZF1f97Gtr/aVkJH3lJCP7aWhofOkn6H82tfZ/uzq
Kf8zKCnONSoqGDUpKgAAAAAAAAAAAAAAAAAAAAAAUEhKAHdvbQBcVVZuSkFC+i8lJf8zKCr9RDw86kM8 6v7V09b+kouP/ntwcP6jmJX+xLy6/bWtrP2lnZz+o5qY/o6Dgf6BeHf9YFZV/EI4OPwzKCn+NCgp+DMo
O9ZeV1fwgXt66aumpvHW1NP+2dfW/aynpt6no6Ld0M3M/qylovyIfXv5joWE+JKKie5fVlX5Qjg4/Tcs KE0zKCgAAAAAAAAAAAAAAAAAAAAAAEtDRABPR0gcSD5A1TAnKP80Kyz9f3l79ZCMj9t7dnbKkYyM67+8
Lf4xJij/NSor9jcsLWI0KCkAOjAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAeXJzAHx1dw10bW2XXFNT+z0y vfXU0NL+9/X1/vHv8P7Lx8j7xsHB++Le3v7EvLr8rKKi/bWtrf6gl5b8bWRj/VlQUPxNQkL9Ny0t/jIn
M/8wJSb/MSYn/zQqKf0zKCf7OC4t+0I5OP9COTj/OS8u+zcuLPtBODf/PjU0/zctLP42Kyr+OzEw/DQq Kf8zKCnONSoqGDUpKgAAAAAAAAAAAAAAAAAAAAAAUEhKAHdvbQBcVVZuSkFC+i8lJf8zKCr9RDw86kM8
Kf8xJyf/Niss/0A0NfREODmCPTIyCD80NQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlY+PAJ6X O9ZeV1fwgXt66aumpvHW1NP+2dfW/aynpt6no6Ld0M3M/qylovyIfXv5joWE+JKKie5fVlX5Qjg4/Tcs
lw6LhYVwfXV0zmphYPFeU1L3WU9N91dNSvVVSkjzU0hG8FJHRO5TSEXsU0hF7FNIRetTSUbrVElG7FRJ Lf4xJij/NSor9jcsLWI0KCkAOjAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAeXJzAHx1dw10bW2XXFNT+z0y
RuxUSUbuVUpH8FVKSedWSUm4U0hHVU5EQgdQRUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA M/8wJSb/MSYn/zQqKf0zKCf7OC4t+0I5OP9COTj/OS8u+zcuLPtBODf/PjU0/zctLP42Kyr+OzEw/DQq
AAAAAAAAzsvKAPLz8gGpo6EVmJGPOIuCf0Z9dXFFcmpmQmhgXD5eVVI5WlBNM1tRTTBeVE8uYFVRLmJX Kf8xJyf/Niss/0A0NfREODmCPTIyCD80NQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlY+PAJ6X
Ui1iV1MuYldSL2JYUzFjWVU0YVdUKFpRTgtuXl8AREY9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA lw6LhYVwfXV0zmphYPFeU1L3WU9N91dNSvVVSkjzU0hG8FJHRO5TSEXsU0hF7FNIRetTSUbrVElG7FRJ
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RuxUSUbuVUpH8FVKSedWSUm4U0hHVU5EQgdQRUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAzsvKAPLz8gGpo6EVmJGPOIuCf0Z9dXFFcmpmQmhgXD5eVVI5WlBNM1tRTTBeVE8uYFVRLmJX
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Ui1iV1MuYldSL2JYUzFjWVU0YVdUKFpRTgtuXl8AREY9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA/////////////////wAA//wAAD/4AAAf8AAAD+AAAAfgAAAH4AAAB+AA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB/AA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AA/wAAAP+AAAH/wAAH////////////////8= AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
</value> AAAAAAAAAAAAAAAAAAAAAAAA/////////////////wAA//wAAD/4AAAf8AAAD+AAAAfgAAAH4AAAB+AA
</data> AAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB/AA
AA/wAAAP+AAAH/wAAH////////////////8=
</value>
</data>
</root> </root>

Binary file not shown.