diff --git a/.editorconfig b/.editorconfig
index 8b0b175..d793869 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -10,7 +10,7 @@ indent_style = space
tab_width = 4
# Naming Conventions
-dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+dotnet_naming_style.camel_case.capitalization = camel_case
# New line preferences
csharp_new_line_before_open_brace = none
diff --git a/.gitignore b/.gitignore
index e68f0aa..7576ac2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.vscode/
obj/
bin/
+Libraries/
diff --git a/README.md b/README.md
index de78ccb..489a5da 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Checksums every file under the current directory
Clone the project
```bash
-git clone http://192.168.0.69:3000/ProfessionalUwU/chksum.git
+git clone https://gitea.hopeless-cloud.xyz/ProfessionalUwU/chksum.git
```
Go to the project directory
@@ -25,22 +25,22 @@ pacman -S dotnet-runtime dotnet-sdk
Build project
```bash
-dotnet build chksum.csproj
+just build
```
Publish project
```bash
-dotnet publish --configuration Release chksum.csproj
+just publish
```
Go to the publish folder
```bash
-cd bin/Release/net7.0/linux-x64/publish
+cd src/Chksum/bin/Release/net7.0/linux-x64/publish
```
Run executable
```bash
-./chksum
-```
+./Chksum
+```
\ No newline at end of file
diff --git a/chksum.cs b/chksum.cs
deleted file mode 100644
index 06af796..0000000
--- a/chksum.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// Go into folder
-// Check if any file is in there
-// If there is a file. Calculate md5sum > filename.md5
-// If there is no file. Repeat
-public class Chksum {
-
- // int getDirectoryCount() {
- // int folderCount = Directory.GetDirectories(Directory.GetCurrentDirectory()).Length; // Get folder count in current directory
- // return folderCount;
- // }
-
- private static int getFileCount() {
- int fileCount = Directory.GetFiles(Directory.GetCurrentDirectory()).Length; // Get file count in current directory
- return fileCount;
- }
-
- // string getParentFolder() {
- // string parentFolder = Directory.GetParent(Directory.GetCurrentDirectory()).ToString(); // Get parent folder of current directory
- // return parentFolder;
- // }
-
- private static string CalculateMD5(string filename) {
- using (var md5 = System.Security.Cryptography.MD5.Create()) {
- using (var stream = File.OpenRead(filename)) {
- var hash = md5.ComputeHash(stream);
- return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
- }
- }
- }
-
- public static void doTheThing() {
- foreach (var directory in Directory.GetDirectories(Directory.GetCurrentDirectory())) {
- Directory.SetCurrentDirectory(directory); // Set new root
- if (getFileCount() >= 1) {
- DirectoryInfo dir = new DirectoryInfo(Directory.GetCurrentDirectory());
- FileInfo[] files = dir.GetFiles();
- foreach (FileInfo file in files) {
- string fileName = file.Name;
- string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
- string checksumFile = Directory.GetCurrentDirectory() + "/" + fileNameWithoutExtension + ".md5";
- File.AppendAllText(checksumFile, CalculateMD5(fileName) + " " + fileName);
- Console.WriteLine(checksumFile);
- }
- }
- doTheThing();
- }
- }
-
- private static int getTotalFileCount() {
- int totalFileCount = Directory.GetFiles(Directory.GetCurrentDirectory(), "*", SearchOption.AllDirectories).Length;
- return totalFileCount - 1; // Remove the program from the totalFileCount
- }
-
- public static void countAllMd5Checksums() {
- int totalMD5FileCount = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.md5", SearchOption.AllDirectories).Length;
- Console.WriteLine("There are " + totalMD5FileCount + " md5 checksums");
- }
-
- public static void deleteAllMd5Checksums() {
- foreach (var directory in Directory.GetDirectories(Directory.GetCurrentDirectory())) {
- Directory.SetCurrentDirectory(directory); // Set new root
- if (getFileCount() >= 1) {
- DirectoryInfo dir = new DirectoryInfo(Directory.GetCurrentDirectory());
- FileInfo[] files = dir.GetFiles();
- foreach (FileInfo file in files) {
- string fileName = file.Name;
- string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
- string checksumFile = Directory.GetCurrentDirectory() + "/" + fileNameWithoutExtension + ".md5";
- File.Delete(checksumFile);
- Console.WriteLine("Deleted " + checksumFile);
- }
- }
- deleteAllMd5Checksums();
- }
- }
-
- public static void compareChecksums() {
- foreach (var directory in Directory.GetDirectories(Directory.GetCurrentDirectory())) {
- Directory.SetCurrentDirectory(directory); // Set new root
- if (getFileCount() >= 1) {
- DirectoryInfo dir = new DirectoryInfo(Directory.GetCurrentDirectory());
- FileInfo[] files = dir.GetFiles();
- // files.ToList().ForEach(i => Console.WriteLine(i.ToString())); // Print all files in files array
- foreach (FileInfo file in files) {
- string fileName = file.Name;
- string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
- string checksumFile = Directory.GetCurrentDirectory() + "/" + fileNameWithoutExtension + ".md5";
- string fileMd5Checksum = fileNameWithoutExtension + ".md5";
- if (File.Exists(fileMd5Checksum)) {
- string newFileChecksum = CalculateMD5(fileName) + " " + fileName;
- string existingFileChecksum = File.ReadAllText(fileMd5Checksum);
- string newFileName = newFileChecksum.Substring(34);
- string existingFileName = existingFileChecksum.Substring(34);
- if (newFileChecksum.Equals(existingFileChecksum)) {
- Console.WriteLine(newFileName + " and " + existingFileName + " are the same.");
- } else {
- Console.WriteLine(newFileName + " and " + existingFileName + " are not the same.");
- Console.WriteLine("The checksum of " + newFileName + " is " + newFileChecksum);
- Console.WriteLine("The checksum of the already exting file " + existingFileName + " is " + existingFileChecksum);
- // TODO Tell the user to check which file is the correct one
- }
- } else {
- File.AppendAllText(checksumFile, CalculateMD5(fileName) + " " + fileName);
- Console.WriteLine("Calculated checksum for: " + checksumFile);
- }
- }
- }
- compareChecksums();
- }
- }
-}
\ No newline at end of file
diff --git a/justfile b/justfile
index d9be799..6b0b79a 100644
--- a/justfile
+++ b/justfile
@@ -1,2 +1,31 @@
+default:
+ @just --list
+
+project_name := `printf '%s\n' "${PWD##*/}"`
+uppercase_project_name := capitalize(project_name)
+
+setup:
+ @mkdir src
+ @dotnet new sln --name src/{{project_name}}
+ @dotnet new classlib -o src/{{uppercase_project_name}}
+ @dotnet new xunit -o src/{{uppercase_project_name}}.Tests
+ @dotnet sln add src/{{uppercase_project_name}}/{{uppercase_project_name}}.csproj
+ @dotnet sln add src/{{uppercase_project_name}}.Tests/{{uppercase_project_name}}.Tests.csproj
+ @dotnet add src/{{uppercase_project_name}}/{{uppercase_project_name}}.csproj reference src/{{uppercase_project_name}}.Tests/{{uppercase_project_name}}.Tests.csproj
+
+run:
+ @dotnet run
+
+build:
+ @dotnet build src/{{uppercase_project_name}}/{{uppercase_project_name}}.csproj
+ @dotnet build src/{{uppercase_project_name}}.Tests/{{uppercase_project_name}}.Tests.csproj
+
publish:
- @dotnet publish --configuration Release chksum.csproj
+ @dotnet publish --configuration Release src/{{uppercase_project_name}}/{{uppercase_project_name}}.csproj
+
+format:
+ @dotnet format src/{{uppercase_project_name}}
+ @dotnet format src/{{uppercase_project_name}}.Tests
+
+test: build
+ @dotnet test src/{{uppercase_project_name}}.Tests
diff --git a/src/Chksum.Tests/Chksum.Tests.csproj b/src/Chksum.Tests/Chksum.Tests.csproj
new file mode 100644
index 0000000..10cd649
--- /dev/null
+++ b/src/Chksum.Tests/Chksum.Tests.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
diff --git a/src/Chksum.Tests/Usings.cs b/src/Chksum.Tests/Usings.cs
new file mode 100644
index 0000000..7fef4b0
--- /dev/null
+++ b/src/Chksum.Tests/Usings.cs
@@ -0,0 +1,2 @@
+global using Xunit;
+global using FluentAssertions;
\ No newline at end of file
diff --git a/src/Chksum.Tests/doTheThingTest.cs b/src/Chksum.Tests/doTheThingTest.cs
new file mode 100644
index 0000000..94ae38e
--- /dev/null
+++ b/src/Chksum.Tests/doTheThingTest.cs
@@ -0,0 +1,8 @@
+namespace Chksum.Tests;
+
+public class doTheThingTest {
+ [Fact]
+ public void doTheThing_willNotThrowAnException() {
+
+ }
+}
\ No newline at end of file
diff --git a/chksum.csproj b/src/Chksum/Chksum.csproj
similarity index 61%
rename from chksum.csproj
rename to src/Chksum/Chksum.csproj
index b19ce67..fc84e00 100644
--- a/chksum.csproj
+++ b/src/Chksum/Chksum.csproj
@@ -1,5 +1,10 @@
+
+
+
+
+
Exe
net7.0
@@ -11,4 +16,8 @@
enable
+
+
+
+
diff --git a/Program.cs b/src/Chksum/Program.cs
similarity index 57%
rename from Program.cs
rename to src/Chksum/Program.cs
index d0873c6..613c886 100644
--- a/Program.cs
+++ b/src/Chksum/Program.cs
@@ -1,4 +1,6 @@
-public class Program {
+using Chksum.Utils;
+
+public class Program {
static void Main(string[] args) {
Console.ForegroundColor = ConsoleColor.Red;
@@ -6,45 +8,39 @@
Console.WriteLine("Please specify an option.");
PrintAvailableOptions();
return;
- } else if (args.Length > 1) {
+ } else if (args.Length > 1 && args[0] != "compareDatabases") {
Console.WriteLine("Too many options.");
return;
}
+ ChksumUtils utils = new ChksumUtils();
+
+ utils.getBaseDir();
+
+ utils.ExtractEmbeddedLibrary();
+
Console.ForegroundColor = ConsoleColor.Green;
switch (args[0]) {
case "checksum":
Console.WriteLine("Starting the checksum process.");
Console.ResetColor();
- Chksum.doTheThing();
+ utils.doTheThing();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Checksum process finished");
break;
- case "countmd5":
- Console.WriteLine("Counting md5 checksum files.");
+ case "compareDatabases":
Console.ResetColor();
- Chksum.countAllMd5Checksums();
-
- Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine("Finished counting all md5 checksum files.");
+ utils.compareDatabases(args[1]);
break;
- case "deletemd5":
- Console.WriteLine("Deleting all md5 checksum files.");
- Console.ResetColor();
-
- Chksum.deleteAllMd5Checksums();
-
- Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine("Deleted all md5 checksum files.");
+ case "createDB":
+ utils.initializeDB();
break;
- case "compareChecksums":
- Console.WriteLine("Comparing all md5 checksum files. If there is none, creating one.");
+ case "checkIfFileWasDeleted":
Console.ResetColor();
-
- Chksum.compareChecksums();
+ utils.checkIfFileWasDeleted();
break;
case "help":
PrintAvailableOptions();
@@ -55,20 +51,21 @@
PrintAvailableOptions();
break;
}
+
+ utils.cleanup();
}
static void PrintAvailableOptions() {
String[] options = {
"checksum",
- "countmd5",
- "deletemd5",
"compareChecksums",
+ "createDB",
+ "checkIfFileWasDeleted",
"help"
};
Console.ResetColor();
- Console.WriteLine("usage: chksum [option]");
- Console.WriteLine("Here is a list of all available options:");
+ Console.WriteLine("usage: chksum [option] \nHere is a list of all available options:");
foreach (String option in options) {
Console.WriteLine("\t" + option);
}
diff --git a/src/Chksum/chksum.cs b/src/Chksum/chksum.cs
new file mode 100644
index 0000000..8f0f1a6
--- /dev/null
+++ b/src/Chksum/chksum.cs
@@ -0,0 +1,268 @@
+using System.Reflection;
+using Microsoft.Data.Sqlite;
+namespace Chksum.Utils;
+public class ChksumUtils {
+
+ private int getFileCount() {
+ int fileCount = Directory.GetFiles(Directory.GetCurrentDirectory()).Length; // Get file count in current directory
+ return fileCount;
+ }
+
+ public string DatabaseRoot { get; set; } = string.Empty;
+ public void getBaseDir() {
+ DatabaseRoot = AppDomain.CurrentDomain.BaseDirectory;
+ }
+
+ public string libraryPath { get; set; } = string.Empty;
+ public void ExtractEmbeddedLibrary() {
+ libraryPath = Path.Combine(DatabaseRoot, "libe_sqlite3.so");
+
+ using (Stream? resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Chksum.Libraries.libe_sqlite3.so")) {
+ if (resourceStream != null) {
+ byte[] buffer = new byte[resourceStream.Length];
+ resourceStream.Read(buffer, 0, buffer.Length);
+ File.WriteAllBytes(libraryPath, buffer);
+ } else {
+ throw new Exception(libraryPath + " could not be loaded");
+ }
+ }
+ }
+
+ public void initializeDB() {
+ if (File.Exists("chksum.db")) {
+ return;
+ }
+
+ using (var connection = new SqliteConnection("Data Source=chksum.db")) {
+ connection.Open();
+
+ var command = connection.CreateCommand();
+ command.CommandText =
+ @"
+ CREATE TABLE file (
+ filehash TEXT NOT NULL PRIMARY KEY,
+ filename TEXT NOT NULL,
+ pathtofile TEXT NOT NULL,
+ artist TEXT,
+ playbacklength INTEGER
+ );
+ ";
+ command.ExecuteNonQuery();
+ }
+ }
+
+ public void cleanDB() {
+ using (var connection = new SqliteConnection("Data Source=" + DatabaseRoot + "chksum.db")) {
+ var command = connection.CreateCommand();
+ command.CommandText =
+ @"
+ vacuum;
+ ";
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private string CalculateMD5(string filename) {
+ using (var md5 = System.Security.Cryptography.MD5.Create()) {
+ using (var stream = File.OpenRead(filename)) {
+ var hash = md5.ComputeHash(stream);
+ return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
+ }
+ }
+ }
+
+ public void doTheThing() {
+ foreach (var directory in Directory.GetDirectories(Directory.GetCurrentDirectory()))
+ using (var connection = new SqliteConnection("Data Source=" + DatabaseRoot + "chksum.db;Mode=ReadWrite")) {
+ Directory.SetCurrentDirectory(directory); // Set new root
+ if (getFileCount() >= 1) {
+ DirectoryInfo dir = new DirectoryInfo(Directory.GetCurrentDirectory());
+ FileInfo[] files = dir.GetFiles();
+ foreach (FileInfo file in files) {
+ string fileName = file.Name;
+ string absolutePathToFile = Path.GetFullPath(fileName);
+ string pathToFile = Path.GetRelativePath(DatabaseRoot, absolutePathToFile);
+ string fileHash = CalculateMD5(fileName);
+
+ if (checkIfFileMovedAndUpdatePathToFile(fileHash, fileName, pathToFile) == false && checkIfFileAlreadyExistsInDatabase(fileHash, fileName) == false) {
+ connection.Open();
+
+ var command = connection.CreateCommand();
+ command.CommandText =
+ @"
+ INSERT INTO file (filehash, filename, pathtofile)
+ VALUES ($filehash, $filename, $pathtofile)
+ ";
+ command.Parameters.AddWithValue("$filehash", fileHash);
+ command.Parameters.AddWithValue("$filename", fileName);
+ command.Parameters.AddWithValue("$pathtofile", pathToFile);
+ command.ExecuteNonQuery();
+ }
+ }
+ }
+ doTheThing();
+ }
+ }
+
+ private bool checkIfFileAlreadyExistsInDatabase(string fileHash, string pathToFile) {
+ string filehash = string.Empty;
+ string pathtofile = string.Empty;
+ bool doesExist = false;
+
+ using (var connection = new SqliteConnection("Data Source=" + DatabaseRoot + "chksum.db;Mode=ReadOnly")) {
+ connection.Open();
+
+ var command = connection.CreateCommand();
+ command.CommandText =
+ @"
+ SELECT filehash, pathtofile FROM file WHERE filehash = $filehash
+ ";
+ command.Parameters.AddWithValue("$filehash", fileHash);
+
+ using (var reader = command.ExecuteReader()) {
+ while (reader.Read()) {
+ filehash = reader.GetString(0);
+ pathtofile = reader.GetString(1);
+ }
+ }
+ }
+
+ if (fileHash == filehash) {
+ doesExist = true;
+ }
+ return doesExist;
+ }
+
+ private bool checkIfFileMovedAndUpdatePathToFile(string fileHash, string fileName, string pathToFile) {
+ string pathtofile = string.Empty;
+ bool wasMoved = false;
+
+ using (var connection = new SqliteConnection("Data Source=" + DatabaseRoot + "chksum.db;Mode=ReadWrite")) {
+ connection.Open();
+
+ var command = connection.CreateCommand();
+ command.CommandText =
+ @"
+ SELECT pathtofile FROM file WHERE filehash = $filehash
+ ";
+ command.Parameters.AddWithValue("$filehash", fileHash);
+
+ using (var reader = command.ExecuteReader()) {
+ while (reader.Read()) {
+ pathtofile = reader.GetString(0);
+ }
+ }
+
+ if (pathToFile != pathtofile && pathtofile != "") {
+ var command2 = connection.CreateCommand();
+ command2.CommandText =
+ @"
+ UPDATE file
+ SET pathtofile = $newpathtofile
+ WHERE filehash = $filehash
+ ";
+ command2.Parameters.AddWithValue("$newpathtofile", pathToFile);
+ command2.Parameters.AddWithValue("$filehash", fileHash);
+ command2.ExecuteNonQuery();
+
+ Console.WriteLine("File moved:");
+ Console.WriteLine($"\tfrom\t{pathToFile}");
+ Console.WriteLine($"\tto \t{pathtofile}\n");
+ wasMoved = true;
+ }
+ return wasMoved;
+ }
+ }
+
+ public void checkIfFileWasDeleted() {
+ string pathToFile = string.Empty;
+
+ using (var connection = new SqliteConnection("Data Source=" + DatabaseRoot + "chksum.db;Mode=ReadWrite")) {
+ connection.Open();
+
+ var selectCommand = connection.CreateCommand();
+ selectCommand.CommandText =
+ @"
+ Select pathtofile FROM file
+ ";
+
+ using (var reader = selectCommand.ExecuteReader()) {
+ while (reader.Read()) {
+ pathToFile = reader.GetString(0);
+
+ if (!File.Exists(pathToFile)) {
+ var deleteCommand = connection.CreateCommand();
+ deleteCommand.CommandText =
+ @"
+ DELETE FROM file
+ WHERE pathtofile = $pathtofile
+ ";
+ deleteCommand.Parameters.AddWithValue("$pathtofile", pathToFile);
+ deleteCommand.ExecuteNonQuery();
+
+ Console.WriteLine("File deleted:");
+ Console.WriteLine($"\t{pathToFile}\n");
+ }
+ }
+ }
+ }
+ }
+
+ private List getFilehashesFromDatabase(string connectionString) {
+ List filehashesFromDatabase = new List();
+
+ using (var connection = new SqliteConnection(connectionString)) {
+ string filehash = string.Empty;
+
+ connection.Open();
+
+ var selectCommand = connection.CreateCommand();
+ selectCommand.CommandText =
+ @"
+ Select filehash FROM file
+ ";
+
+ using (var reader = selectCommand.ExecuteReader()) {
+ while (reader.Read()) {
+ filehash = reader.GetString(0);
+ filehashesFromDatabase.Add(filehash);
+ }
+ }
+ }
+
+ return filehashesFromDatabase;
+ }
+
+ public void compareDatabases(string filePathToOtherDatabase) {
+ List filesThatDoNotExistsInTheRemote = getFilehashesFromDatabase("Data Source=" + DatabaseRoot + "chksum.db;Mode=ReadOnly").Except(getFilehashesFromDatabase("Data Source=" + filePathToOtherDatabase + ";Mode=ReadOnly")).ToList();
+ //List filesThatDoNotExistsInTheOrigin = filehashesOfRemoteDatabase.Except(filehashesOfOriginDatabase).ToList();
+
+ foreach (string file in filesThatDoNotExistsInTheRemote) {
+ using (var connection = new SqliteConnection("Data Source=" + DatabaseRoot + "chksum.db;Mode=ReadOnly")) {
+ string filename = string.Empty;
+
+ connection.Open();
+
+ var selectCommand = connection.CreateCommand();
+ selectCommand.CommandText =
+ @"
+ Select filename FROM file WHERE filehash = $filehash
+ ";
+ selectCommand.Parameters.AddWithValue("$filehash", file);
+
+ using (var reader = selectCommand.ExecuteReader()) {
+ while (reader.Read()) {
+ filename = reader.GetString(0);
+
+ Console.WriteLine("File not found in remote:");
+ Console.WriteLine($"\t{filename}\n");
+ }
+ }
+ }
+ }
+ }
+
+ public void cleanup() {
+ File.Delete(libraryPath);
+ }
+}
\ No newline at end of file
diff --git a/debugchksum.cs b/src/Chksum/debugchksum.cs
similarity index 100%
rename from debugchksum.cs
rename to src/Chksum/debugchksum.cs
diff --git a/src/chksum.sln b/src/chksum.sln
new file mode 100644
index 0000000..b5f119a
--- /dev/null
+++ b/src/chksum.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chksum", "Chksum\Chksum.csproj", "{BBC56294-03CF-42E0-A838-75AF41EEE32B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chksum.Tests", "Chksum.Tests\Chksum.Tests.csproj", "{239727BC-7124-4985-A6F3-2700295AA06F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BBC56294-03CF-42E0-A838-75AF41EEE32B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BBC56294-03CF-42E0-A838-75AF41EEE32B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BBC56294-03CF-42E0-A838-75AF41EEE32B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BBC56294-03CF-42E0-A838-75AF41EEE32B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {239727BC-7124-4985-A6F3-2700295AA06F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {239727BC-7124-4985-A6F3-2700295AA06F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {239727BC-7124-4985-A6F3-2700295AA06F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {239727BC-7124-4985-A6F3-2700295AA06F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal