diff --git a/ConsoleInterface.Tests/TestLocalFileBrowser.cs b/ConsoleInterface.Tests/TestLocalFileBrowser.cs new file mode 100644 index 0000000..7df4fcd --- /dev/null +++ b/ConsoleInterface.Tests/TestLocalFileBrowser.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Xunit; + +namespace ConsoleInterface.Tests; + +public class TestLocalFileBrowser +{ + private readonly string? _testsProjectDirectory; + + public TestLocalFileBrowser() + { + _testsProjectDirectory = Environment.GetEnvironmentVariable("IMAGE_CORE_TESTS"); + if (_testsProjectDirectory == null) throw new Exception("Environment variable IMAGE_CORE_TESTS is not set!"); + } + + [Fact] + public void TestGetFilenamesFromPath_DirectoryNotFound() + { + var filesRetriever = LocalFileBrowser.Create(); + Assert.Throws(() => filesRetriever.GetFilenamesFromPath("a")); + } + + [Fact] + public void TestGetFilenamesFromPath() + { + var filesRetriever = LocalFileBrowser.Create(); + Debug.Assert(_testsProjectDirectory != null, nameof(_testsProjectDirectory) + " != null"); + var filePaths = filesRetriever.GetFilenamesFromPath(Path.Combine(_testsProjectDirectory, "test_pictures")); + Assert.NotNull(filePaths); + var filePathsList = filePaths.ToList(); + var expectedFileNames = new List + { + "IMG_0138.HEIC", "IMG_0138.jpg", "IMG_0140.HEIC" + }; + + Assert.NotEmpty(filePathsList); + for (var i = 0; i < filePathsList.Count; i++) + Assert.Equal(expectedFileNames[i], Path.GetFileName(filePathsList[i])); + } +} \ No newline at end of file diff --git a/ConsoleInterface.Tests/TestSimpleOutputSink.cs b/ConsoleInterface.Tests/TestSimpleOutputSink.cs new file mode 100644 index 0000000..c27c7c4 --- /dev/null +++ b/ConsoleInterface.Tests/TestSimpleOutputSink.cs @@ -0,0 +1,69 @@ +using System; +using System.Diagnostics; +using System.IO; +using Image.Core; +using Moq; +using Xunit; + +namespace ConsoleInterface.Tests; + +public class TestSimpleOutputSink +{ + private readonly string? _testsProjectDirectory; + + public TestSimpleOutputSink() + { + _testsProjectDirectory = Environment.GetEnvironmentVariable("IMAGE_CORE_TESTS"); + if (_testsProjectDirectory == null) throw new Exception("Environment variable IMAGE_CORE_TESTS is not set!"); + } + + [Theory] + [InlineData("", "./", @".\.jpg")] + [InlineData("", @".\", @".\.jpg")] + [InlineData("", "asd", @".\asd.jpg")] + [InlineData("dir", "asd", @"dir\asd.jpg")] + public void TestGetOutputPath(string directory, string file, string expectedPath) + { + var sink = SimpleOutputSink.Create(directory); + Assert.Equal(expectedPath, sink.GetOutputPath(file)); + } + + [Fact] + public void TestGetOutputPathNull() + { + var sink = SimpleOutputSink.Create("directory"); + Assert.Throws(() => sink.GetOutputPath("")); + } + + [Fact] + public void TestSave() + { + // Setup + var sink = SimpleOutputSink.Create("directory"); + var metadataRemoverMock = new Mock(); + metadataRemoverMock.Setup(i => i.GetImagePath()).Returns("alo.wtf"); + + // Test + sink.Save(metadataRemoverMock.Object); + + // Assert + metadataRemoverMock.Verify(i => i.CleanImage("directory\\alo.jpg")); + } + + [Fact] + public void TestSaveFileExists() + { + // Setup + Debug.Assert(_testsProjectDirectory != null, nameof(_testsProjectDirectory) + " != null"); + var sink = SimpleOutputSink.Create(Path.Combine(_testsProjectDirectory, "test_pictures")); + var metadataRemoverMock = new Mock(); + var sourceFileName = Path.Combine(_testsProjectDirectory, "test_pictures\\IMG_0138.HEIC"); + metadataRemoverMock.Setup(i => i.GetImagePath()).Returns(sourceFileName); + + // Test + sink.Save(metadataRemoverMock.Object); + + // Assert + metadataRemoverMock.Verify(i => i.CleanImage(It.IsAny()), Times.Never); + } +} \ No newline at end of file diff --git a/ConsoleInterface/ConsoleInterface.csproj b/ConsoleInterface/ConsoleInterface.csproj index 5fdb02a..314e5a9 100644 --- a/ConsoleInterface/ConsoleInterface.csproj +++ b/ConsoleInterface/ConsoleInterface.csproj @@ -12,10 +12,10 @@ - - - - + + + + diff --git a/ImageCore/Files/FileSystemHelpers.cs b/ConsoleInterface/FileSystemHelpers.cs similarity index 88% rename from ImageCore/Files/FileSystemHelpers.cs rename to ConsoleInterface/FileSystemHelpers.cs index 2d02555..a7230d7 100644 --- a/ImageCore/Files/FileSystemHelpers.cs +++ b/ConsoleInterface/FileSystemHelpers.cs @@ -2,14 +2,14 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -namespace Image.Files +namespace ConsoleInterface { public static class FileSystemHelpers { public static ILogger Logger = NullLogger.Instance; - + /// - /// Creates the directory if it doesn't exist. + /// Creates the directory if it doesn't exist. /// /// The destination directory's path. public static void CreateDestinationDirectory(string directoryPath) @@ -20,7 +20,7 @@ namespace Image.Files } /// - /// CheckIfFileExists checks if file exists. + /// CheckIfFileExists checks if file exists. /// /// The path of the file to be checked. /// Returns true if file exists, False otherwise. diff --git a/ImageCore/Files/IFileBrowser.cs b/ConsoleInterface/IFileBrowser.cs similarity index 94% rename from ImageCore/Files/IFileBrowser.cs rename to ConsoleInterface/IFileBrowser.cs index d1768e6..3e55a0f 100644 --- a/ImageCore/Files/IFileBrowser.cs +++ b/ConsoleInterface/IFileBrowser.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Image.Files +namespace ConsoleInterface { /// /// An to interface enabling implementation of file browsers. diff --git a/ImageCore/Files/IOutputSink.cs b/ConsoleInterface/IOutputSink.cs similarity index 89% rename from ImageCore/Files/IOutputSink.cs rename to ConsoleInterface/IOutputSink.cs index 532435d..2c8a4ed 100644 --- a/ImageCore/Files/IOutputSink.cs +++ b/ConsoleInterface/IOutputSink.cs @@ -1,6 +1,6 @@ using Image.Core; -namespace Image.Files +namespace Image { /// /// IOutputSink is an interface for generating saving the generated files.. @@ -8,7 +8,7 @@ namespace Image.Files public interface IOutputSink { /// - /// Saves the image. + /// Saves the image. /// /// Metadata remover instance. /// True if the image was saved successfully, false otherwise. diff --git a/ImageCore/Files/LocalFileBrowser.cs b/ConsoleInterface/LocalFileBrowser.cs similarity index 97% rename from ImageCore/Files/LocalFileBrowser.cs rename to ConsoleInterface/LocalFileBrowser.cs index 1a281a9..9450e06 100644 --- a/ImageCore/Files/LocalFileBrowser.cs +++ b/ConsoleInterface/LocalFileBrowser.cs @@ -3,7 +3,7 @@ using System.IO; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -namespace Image.Files +namespace ConsoleInterface { /// /// LocalFileBrowser reads files from the provided directory on the local system. diff --git a/ConsoleInterface/Program.cs b/ConsoleInterface/Program.cs index edb4920..2cf899c 100644 --- a/ConsoleInterface/Program.cs +++ b/ConsoleInterface/Program.cs @@ -1,6 +1,4 @@ using CommandLine; -using Image.Files; -using Image.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; diff --git a/ImageCore/Files/SimpleOutputSink.cs b/ConsoleInterface/SimpleOutputSink.cs similarity index 91% rename from ImageCore/Files/SimpleOutputSink.cs rename to ConsoleInterface/SimpleOutputSink.cs index c769763..fe1bef2 100644 --- a/ImageCore/Files/SimpleOutputSink.cs +++ b/ConsoleInterface/SimpleOutputSink.cs @@ -1,10 +1,11 @@ -using System.IO; -using Ardalis.GuardClauses; +using System; +using System.IO; +using Image; using Image.Core; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -namespace Image.Files +namespace ConsoleInterface { /// /// SimpleOutputFormatter keeps the original file name of the image when formatting it. @@ -23,30 +24,12 @@ namespace Image.Files public SimpleOutputSink(string outputDirectory) { if (outputDirectory.Equals("")) - { outputDirectory = "."; - } else - { FileSystemHelpers.CreateDestinationDirectory(outputDirectory); - } _outputDirectory = outputDirectory; } - /// - /// Returns a path containing the file name in the output directory. - /// - /// The initial path of the image. - /// An absolute path of the form output_directory/initialFileName.jpg - public string GetOutputPath(string initialFilePath) - { - Logger.LogDebug($"KeepFilenameFormatter - {_outputDirectory} - {initialFilePath}"); - Guard.Against.NullOrEmpty(initialFilePath, nameof(initialFilePath)); - var fileName = Path.GetFileName(initialFilePath).Split('.')[0]; - var path = Path.Combine(_outputDirectory, $"{fileName}.jpg"); - return path; - } - public bool Save(IMetadataRemover metadataRemover) { var newFilePath = GetOutputPath(metadataRemover.GetImagePath()); @@ -56,11 +39,28 @@ namespace Image.Files Logger.LogWarning($"File {newFilePath} exists, skipping"); return false; } + // Save the image under the same name in the new directory. metadataRemover.CleanImage(newFilePath); return true; } + /// + /// Returns a path containing the file name in the output directory. + /// + /// The initial path of the image. + /// An absolute path of the form output_directory/initialFileName.jpg + public string GetOutputPath(string initialFilePath) + { + Logger.LogDebug($"KeepFilenameFormatter - {_outputDirectory} - {initialFilePath}"); + if (string.IsNullOrEmpty(initialFilePath)) + throw new ArgumentException("The output file path cannot be null or empty!"); + + var fileName = Path.GetFileName(initialFilePath).Split('.')[0]; + var path = Path.Combine(_outputDirectory, $"{fileName}.jpg"); + return path; + } + /// /// Creates an instance of OriginalFilenameFileOutputPathFormatter. /// diff --git a/ImageCore/Tasks/TaskExecutor.cs b/ConsoleInterface/TaskExecutor.cs similarity index 94% rename from ImageCore/Tasks/TaskExecutor.cs rename to ConsoleInterface/TaskExecutor.cs index aa399bb..4eb54e4 100644 --- a/ImageCore/Tasks/TaskExecutor.cs +++ b/ConsoleInterface/TaskExecutor.cs @@ -2,13 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Image; using Image.Core; -using Image.Files; using ImageMagick; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -namespace Image.Tasks +namespace ConsoleInterface { /// /// TaskExecutor is a helper class for executing tasks in parallel. @@ -47,8 +47,9 @@ namespace Image.Tasks { try { - Logger.LogDebug($"Cleaning {filePath}, compression {_options.EnableCompression}, outputFormatter {nameof(_options.OutputSink)}."); - + Logger.LogDebug( + $"Cleaning {filePath}, compression {_options.EnableCompression}, outputFormatter {nameof(_options.OutputSink)}."); + ICompressor compressor = NullCompressor.Instance; if (_options.EnableCompression) compressor = LosslessCompressor.Instance; var imageMagick = new MagickImage(filePath); diff --git a/ImageCore/Tasks/TaskExecutorOptions.cs b/ConsoleInterface/TaskExecutorOptions.cs similarity index 95% rename from ImageCore/Tasks/TaskExecutorOptions.cs rename to ConsoleInterface/TaskExecutorOptions.cs index e4b34cb..c5dbfbb 100644 --- a/ImageCore/Tasks/TaskExecutorOptions.cs +++ b/ConsoleInterface/TaskExecutorOptions.cs @@ -1,7 +1,7 @@ using System; -using Image.Files; +using Image; -namespace Image.Tasks +namespace ConsoleInterface { /// /// TaskExecutorOptions is a class containing various parameters for the class. diff --git a/ImageCore.Tests/ImageCore.Tests.csproj b/ImageCore.Tests/ImageCore.Tests.csproj index 6246d1f..e8cef3a 100644 --- a/ImageCore.Tests/ImageCore.Tests.csproj +++ b/ImageCore.Tests/ImageCore.Tests.csproj @@ -8,9 +8,9 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -22,7 +22,7 @@ - + diff --git a/ImageCore.Tests/TestCompressor.cs b/ImageCore.Tests/TestCompressor.cs index 94a7602..defbd9d 100644 --- a/ImageCore.Tests/TestCompressor.cs +++ b/ImageCore.Tests/TestCompressor.cs @@ -18,35 +18,35 @@ namespace ImageCore.Tests public void TestLosslessCompressor_Compress() { ICompressor compressor = new LosslessCompressor(); - var sourceFileName = Path.Join(_testsProjectDirectory, "test_pictures/IMG_0138.HEIC"); + var sourceFileName = Path.Combine(_testsProjectDirectory, "test_pictures/IMG_0138.HEIC"); var destinationFileName = Path.GetTempFileName(); File.Copy(sourceFileName, destinationFileName, true); compressor.Compress(destinationFileName); var originalFile = File.Open(sourceFileName, FileMode.Open); var compressedFile = File.Open(destinationFileName, FileMode.Open); - + Assert.True(compressedFile.Length <= originalFile.Length); - + originalFile.Close(); compressedFile.Close(); File.Delete(destinationFileName); } - + [Fact] public void TestNullCompressor_Compress() { ICompressor compressor = new NullCompressor(); - var sourceFileName = Path.Join(_testsProjectDirectory, "test_pictures/IMG_0138.HEIC"); + var sourceFileName = Path.Combine(_testsProjectDirectory, "test_pictures/IMG_0138.HEIC"); var destinationFileName = Path.GetTempFileName(); File.Copy(sourceFileName, destinationFileName, true); compressor.Compress(destinationFileName); - + var originalFile = File.Open(sourceFileName, FileMode.Open); var compressedFile = File.Open(destinationFileName, FileMode.Open); - + Assert.True(compressedFile.Length == originalFile.Length); - + originalFile.Close(); compressedFile.Close(); File.Delete(destinationFileName); diff --git a/ImageCore.Tests/TestLocalFileBrowser.cs b/ImageCore.Tests/TestLocalFileBrowser.cs deleted file mode 100644 index 5a764a9..0000000 --- a/ImageCore.Tests/TestLocalFileBrowser.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Image.Files; -using Xunit; - -namespace ImageCore.Tests -{ - public class TestLocalFileBrowser - { - private readonly string _testsProjectDirectory; - - public TestLocalFileBrowser() - { - _testsProjectDirectory = Environment.GetEnvironmentVariable("IMAGE_CORE_TESTS"); - } - - [Fact] - public void TestGetFilenamesFromPath_DirectoryNotFound() - { - var filesRetriever = LocalFileBrowser.Create(); - Assert.Throws(() => filesRetriever.GetFilenamesFromPath("a")); - } - - [Fact] - public void TestGetFilenamesFromPath() - { - var filesRetriever = LocalFileBrowser.Create(); - var filePaths = filesRetriever.GetFilenamesFromPath(Path.Join(_testsProjectDirectory, "test_pictures")); - Assert.NotNull(filePaths); - var filePathsList = filePaths.ToList(); - var expectedFileNames = new List - { - "IMG_0138.HEIC", "IMG_0138.jpg", "IMG_0140.HEIC", - }; - - Assert.NotEmpty(filePathsList); - for (var i = 0; i < filePathsList.Count; i++) - { - Assert.Equal(expectedFileNames[i], Path.GetFileName(filePathsList[i])); - } - } - } -} \ No newline at end of file diff --git a/ImageCore.Tests/TestMetadataRemover.cs b/ImageCore.Tests/TestMetadataRemover.cs index d09212d..3936651 100644 --- a/ImageCore.Tests/TestMetadataRemover.cs +++ b/ImageCore.Tests/TestMetadataRemover.cs @@ -14,14 +14,14 @@ namespace ImageCore.Tests var magicImageMock = new Mock(); var compressorMock = new Mock(); var metadataRemover = new ExifRemoverAndCompressor(magicImageMock.Object, compressorMock.Object); - + // Test metadataRemover.CleanImage("path"); - + // Assert - magicImageMock.Verify( i => i.RemoveProfile("exif")); - magicImageMock.Verify( i => i.Write("path")); - compressorMock.Verify( i => i.Compress("path")); + magicImageMock.Verify(i => i.RemoveProfile("exif")); + magicImageMock.Verify(i => i.Write("path")); + compressorMock.Verify(i => i.Compress("path")); } [Fact] @@ -30,13 +30,13 @@ namespace ImageCore.Tests // Setup var magicImageMock = new Mock(); magicImageMock.Setup(i => i.FileName).Returns("P4th"); - + var compressorMock = new Mock(); var metadataRemover = new ExifRemoverAndCompressor(magicImageMock.Object, compressorMock.Object); // Test var result = metadataRemover.GetImagePath(); - + // Assert Assert.Equal("P4th", result); } diff --git a/ImageCore.Tests/TestSimpleOutputSink.cs b/ImageCore.Tests/TestSimpleOutputSink.cs deleted file mode 100644 index 90f6177..0000000 --- a/ImageCore.Tests/TestSimpleOutputSink.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.IO; -using Image.Core; -using Image.Files; -using Moq; -using Xunit; - -namespace ImageCore.Tests -{ - public class TestSimpleOutputSink - { - private readonly string _testsProjectDirectory; - - public TestSimpleOutputSink() - { - _testsProjectDirectory = Environment.GetEnvironmentVariable("IMAGE_CORE_TESTS"); - } - - [Theory] - [InlineData("", "./", @".\.jpg")] - [InlineData("", @".\", @".\.jpg")] - [InlineData("", "asd", @".\asd.jpg")] - [InlineData("dir", "asd", @"dir\asd.jpg")] - public void TestGetOutputPath(string directory, string file, string expectedPath) - { - var sink = SimpleOutputSink.Create(directory); - Assert.Equal(expectedPath, sink.GetOutputPath(file)); - } - - [Fact] - public void TestGetOutputPathNull() - { - var sink = SimpleOutputSink.Create("directory"); - Assert.Throws(() => sink.GetOutputPath("")); - } - - [Fact] - public void TestSave() - { - // Setup - var sink = SimpleOutputSink.Create("directory"); - var metadataRemoverMock = new Mock(); - metadataRemoverMock.Setup(i => i.GetImagePath()).Returns("alo.wtf"); - - // Test - sink.Save(metadataRemoverMock.Object); - - // Assert - metadataRemoverMock.Verify(i => i.CleanImage("directory\\alo.jpg")); - } - - [Fact] - public void TestSaveFileExists() - { - // Setup - var sink = SimpleOutputSink.Create(Path.Join(_testsProjectDirectory, "test_pictures")); - var metadataRemoverMock = new Mock(); - var sourceFileName = Path.Join(_testsProjectDirectory, "test_pictures\\IMG_0138.HEIC"); - metadataRemoverMock.Setup(i => i.GetImagePath()).Returns(sourceFileName); - - // Test - sink.Save(metadataRemoverMock.Object); - - // Assert - metadataRemoverMock.Verify(i => i.CleanImage(It.IsAny()), Times.Never); - } - } -} \ No newline at end of file diff --git a/ImageCore/Core/IMetadataRemover.cs b/ImageCore/Core/IMetadataRemover.cs index cd62aa3..89c7b59 100644 --- a/ImageCore/Core/IMetadataRemover.cs +++ b/ImageCore/Core/IMetadataRemover.cs @@ -12,7 +12,7 @@ void CleanImage(string newFilePath); /// - /// GetImagePath gets the current image path on the filesystem. + /// GetImagePath gets the current image path on the filesystem. /// /// A string representing the absolute path. string GetImagePath(); diff --git a/ImageCore/ImageCore.csproj b/ImageCore/ImageCore.csproj index 5620b40..17f3584 100644 --- a/ImageCore/ImageCore.csproj +++ b/ImageCore/ImageCore.csproj @@ -2,15 +2,14 @@ Image - net6.0 + netstandard2.0;net6.0 8.0 - - - - + + + diff --git a/ImgMetadataRemover.sln b/ImgMetadataRemover.sln index 2dce599..2dd25ea 100644 --- a/ImgMetadataRemover.sln +++ b/ImgMetadataRemover.sln @@ -9,6 +9,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleInterface", "Console EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageCore.Tests", "ImageCore.Tests\ImageCore.Tests.csproj", "{8EB81515-E62C-4408-84E0-6C27E0293902}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UwpApplication", "UwpApplication\UwpApplication.csproj", "{405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleInterface.Tests", "ConsoleInterface.Tests\ConsoleInterface.Tests.csproj", "{B915AC83-B6E9-4E0A-BA88-915F629F57C8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -83,6 +87,56 @@ Global {8EB81515-E62C-4408-84E0-6C27E0293902}.Release|x64.Build.0 = Release|Any CPU {8EB81515-E62C-4408-84E0-6C27E0293902}.Release|x86.ActiveCfg = Release|Any CPU {8EB81515-E62C-4408-84E0-6C27E0293902}.Release|x86.Build.0 = Release|Any CPU + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|Any CPU.ActiveCfg = Debug|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|Any CPU.Build.0 = Debug|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|Any CPU.Deploy.0 = Debug|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|ARM.ActiveCfg = Debug|ARM + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|ARM.Build.0 = Debug|ARM + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|ARM.Deploy.0 = Debug|ARM + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|ARM64.Build.0 = Debug|ARM64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|x64.ActiveCfg = Debug|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|x64.Build.0 = Debug|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|x64.Deploy.0 = Debug|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|x86.ActiveCfg = Debug|x86 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|x86.Build.0 = Debug|x86 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Debug|x86.Deploy.0 = Debug|x86 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|Any CPU.ActiveCfg = Release|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|Any CPU.Build.0 = Release|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|Any CPU.Deploy.0 = Release|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|ARM.ActiveCfg = Release|ARM + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|ARM.Build.0 = Release|ARM + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|ARM.Deploy.0 = Release|ARM + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|ARM64.ActiveCfg = Release|ARM64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|ARM64.Build.0 = Release|ARM64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|ARM64.Deploy.0 = Release|ARM64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|x64.ActiveCfg = Release|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|x64.Build.0 = Release|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|x64.Deploy.0 = Release|x64 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|x86.ActiveCfg = Release|x86 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|x86.Build.0 = Release|x86 + {405DA0B4-AE2F-40A0-B74E-2F42F1049FDB}.Release|x86.Deploy.0 = Release|x86 + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|ARM.ActiveCfg = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|ARM.Build.0 = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|ARM64.Build.0 = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|x64.ActiveCfg = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|x64.Build.0 = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|x86.ActiveCfg = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Debug|x86.Build.0 = Debug|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|Any CPU.Build.0 = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|ARM.ActiveCfg = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|ARM.Build.0 = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|ARM64.ActiveCfg = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|ARM64.Build.0 = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|x64.ActiveCfg = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|x64.Build.0 = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|x86.ActiveCfg = Release|Any CPU + {B915AC83-B6E9-4E0A-BA88-915F629F57C8}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE